Hi,
Am 2017-11-13 13:23, schrieb wf...@niif.hu:
I'm packaging a program which wants to dlopen() some library. It finds
this library via pkg-config (PKG_CHECK_MODULES). How to best determine
the filename to use in the dlopen() call? It should work cross-distro,
for cross-compilation and whatnot. Is it always safe to use the SONAME
as the filename?
The SONAME is the right thing to do here, as that is what's encoded in
the DT_NEEDED field by the linker.
I'm currently considering something like
ld -shared -o dummy.so $(my_LIBS)
objdump -p dummy.so | fgrep NEEDED
That might work, but I'm not sure that's very stable.
I've created the following example code that works for me with libpng:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example)
enable_language(C)
find_library(PNG_LIBRARY_FILE NAMES png)
if(PNG_LIBRARY_FILE)
execute_process(COMMAND objdump -p "${PNG_LIBRARY_FILE}"
OUTPUT_VARIABLE PNG_CONTENTS)
if (PNG_CONTENTS)
string(REGEX MATCH "\n[ \t]*SONAME[ \t]+([^ \t\r\n]*)"
DUMMY "${PNG_CONTENTS}")
if (DUMMY)
set(PNG_SONAME "${CMAKE_MATCH_1}" CACHE STRING "The SONAME of the
PNG library")
message(STATUS "Got libpng soname: ${PNG_SONAME}")
else()
message(FATAL_ERROR "Could not extract SONAME from
${PNG_LIBRARY_FILE}")
endif()
else()
message(FATAL_ERROR "Could not run objdump -p on
${PNG_LIBRARY_FILE}")
endif()
else()
message(FATAL_ERROR "Could not find -lpng")
endif()
Important:
- This assumes that objdump -p actually works. This is basically only
true if you use the GNU toolchain on ELF systems. If you have another
platform then you need to call different things:
- On Mac OS X you need to do otool -D $LIBRARY and then parse that
(it will give you back something like (notice the newline!)
$filename:\n$library_id_abspath
The base name of the second line of that output is what you're
looking for for dlopen().
- On other UNIX platforms I don't really know.
- On Windows with the MinGW toolchain, when you have an import
library (*.dll.a MinGW style or *.lib Microsoft style) then you
may use dlltool -I $IMPORTLIB to extract the DLL name from
that. However, MinGW does support linking directly against DLLs
in some cases (when they were also compiled with MinGW, for
example, and fulfill some additional criteria), and it may be
the case that your linker finds the DLL directly if no import
library is found, in which case dlltool -I will fail, but you
can just use the basename of the DLL.
Note that objdump -p does work on MinGW on Windows, but doesn't
give you a SONAME. (It does mention the DLL name multiple times,
but I'm not sure that's easy to parse.)
- On Windows with MSVC I have no idea how to get the DLL name
from an import library (*.lib), but there's definitely going
to be a tool you'll be able to use.
- No idea on yet other operating systems.
- I'm hacked this together and am not sure this is the sanest way of
parsing this in CMake... YMMV.
- CMake might only find a static library depending on how your search
path is set up (*.a on UNIX systems including Mac OS X, as well as
on MinGW, but *.lib on Windows system with MSVC). On Windows the
fact that import libraries and static libraries share the same
extension actually makes it quite difficult to handle this case
properly.
- If you do manage to write some relatively generic code, I would
urge you to contribute that to CMake as a macro, so that other
people could also profit from it.
Regards,
Christian