[CMake] Why does CMake use relative linking when I replace a shared object?
Michael Hertling
mhertling at online.de
Fri Nov 25 13:19:24 EST 2011
On 11/25/2011 12:28 PM, Mathias Gaunard wrote:
> There is some strange CMake behaviour I don't quite understand.
>
> In the project attached, I build a shared library for which I want to
> specify a custom build command; to do this I generate a dummy library
> which I then replace by another file in a POST_BUILD command
> (alternatives involving imported libraries do not work properly across
> different scopes).
>
> If I do not replace the library, then the executable correctly links
> against libtest.so.
> If I do, it links instead with ../baz/libtest.so (sic), which of course,
> fails when trying to run the program.
>
> Why is it putting a relative path into my executable? Why is it
> different depending on whether I replace the .so by another one or not?
>
> Thank you very much for any insight on what's happening.
That's caused by the absence of an SONAME in your baz/libtest.so. If
there's no DT_SONAME tag in a shared library you are linking against,
the linker will write a DT_NEEDED tag to the resulting binary which
points to the library as it has been specified in the linker command
line, i.e. ../baz/libtest.so in your case; examine with "readelf -d".
Then, of course, libtest.so can be found only if the search starts in
the appropriate directories, e.g. in bar since it's a sibling of baz:
"cd bar && ./foo" works. If there is an DT_SONAME tag in the library,
the linker uses this to set the DT_NEEDED tag in the resulting binary,
and CMake places an SONAME in each shared library by default, even if
the VERSION/SOVERSION property isn't specified. See [1] for a related
discussion. If you really want to create a shared library by yourself,
do it right, e.g. with
COMMAND g++ -shared ${CMAKE_CURRENT_SOURCE_DIR}/dummy.cpp
-o ${CMAKE_CURRENT_BINARY_DIR}/test.so
-Wl,-soname,libtest.so
-fPIC
and note that PRE_BUILD is actually PRE_LINK for Makefiles,
LIBRARY_OUTPUT_PATH has been obsolete for a long time, and
the LINK_DIRECTORIES() command means asking for trouble.
Regards,
Michael
[1] http://www.mail-archive.com/cmake@cmake.org/msg33482.html
More information about the CMake
mailing list