[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