[CMake] CMAKE uses wrong symlink to so

Michael Wild themiwi at gmail.com
Fri Dec 31 09:43:56 EST 2010


On 12/31/2010 02:48 PM, Michael Hertling wrote:
> On 12/31/2010 11:56 AM, Michael Wild wrote:
>> On 12/30/2010 07:55 PM, j s wrote:
>>> Hello Michael Wild,
>>>
>>> I regret deciding to go with an Python parser for my application.  I use
>>> such a small subset of the API, I was hoping to be able to rerelease my app
>>> everytime it changes.
>>>
>>> Apparently Python 2.6 is frozen.
>>>
>>> In the future, the Python people are hoping to stabilize the ABI in the 3
>>> series so that I can just link against a libpython3.so:
>>> http://www.python.org/dev/peps/pep-0384/
>>>
>>> As stated by Michael Hertling, the symlinks are not being recursively
>>> resolved.  The soname is encoded into the so, so the linker chooses to
>>> ignore the original filename.
>>>
>>> Regards,
>>>
>>> Juan
>>>
>>> On Thu, Dec 30, 2010 at 6:23 AM, Michael Wild <themiwi at gmail.com> wrote:
>>>
>>>> On 12/30/2010 12:28 AM, j s wrote:
>>>>> I specified the full name to an so in CMAKE 2.8.1.  Unfortunately it
>>>> links
>>>>> against the versioned so name,
>>>>> libpython2.6.so.1.0
>>>>>
>>>>> instead of the exact name I specified.
>>>>> /usr/lib/libpython2.6.so
>>>>>
>>>>> SET (PYTHON_ARCHIVE /usr/lib/libpython2.6.so)
>>>>> TARGET_LINK_LIBRARIES (myapp  parser engine ${PYTHON_ARCHIVE}
>>>>> ${OPENSSL_ARCHIVE})
>>>>>
>>>>> Is there any way to tell cmake to do the right thing in Linux?  For some
>>>>> strange reason using -l on the link line, and doesn't even use the
>>>>> corresponding -L to the path I specify.
>>>>>   -lpython2.6
>>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Juan
>>>>
>>>> There's nothing CMake can do about this, this is the linker getting in
>>>> your way. E.g. on my Ubuntu, /usr/lib/libpython2.6.so is a symlink to
>>>> /usr/lib/libpython2.6.so.1 which itself is a symlink to
>>>> /usr/lib/libpython2.6.so.1.0. The linker recursively resolves all
>>>> symlinks during the linking, and CMake can't do anything about it. You
>>>> could pass the full path to the /usr/lib/libpython2.6.so symlink instead
>>>> of -lpython2.6 and you would still get the same result.
>>>>
>>>> Actually, this is considered to be a feature. This way, newly compiled
>>>> programs will always link against the "current" version (the one pointed
>>>> to by the symlink-chain), while old programs can still use  older
>>>> versions of the library without requiring to be recompiled.
>>>>
>>>> Michael
>>
>>
>> Huh?
>>
>> $ echo "int main(){}" | gcc -x c -c -o test.o -
>> $ gcc test.o /usr/lib/libpython2.6.so
>> $ ldd a.out | grep libpython2.6
>> libpython2.6.so.1.0 => /usr/lib/libpython2.6.so.1.0 (0x00007fbb350f1000)
>>
>> $ ls -l /usr/lib/libpython2.6.so*
>> ... /usr/lib/libpython2.6.so -> libpython2.6.so.1
>> ... /usr/lib/libpython2.6.so.1 -> libpython2.6.so.1.0
>> ... /usr/lib/libpython2.6.so.1.0
>>
>> Sure looks like recursive symlink resolution to me...
> 
> No, it's the soname that gets incorporated in the resulting binary;
> recursively resolving the symlinks is insignificant in this regard:
> 
> echo "void f(void){}" > f.c
> echo "void g(void){}" > g.c
> gcc -o libf.so -shared -fPIC -Wl,-soname,xyz f.c
> gcc -o libg.so.1.0 -shared -fPIC g.c
> ln -sf libg.so.1.0 libg.so.1
> ln -sf libg.so.1 libg.so
> ls -l libg.so*
> ... libg.so -> libg.so.1
> ... libg.so.1 -> libg.so.1.0
> ... libg.so.1.0
> 
> echo "int main(void){return 0;}" > main.c
> gcc -o main main.c libf.so libg.so
> LD_LIBRARY_PATH=. ldd main
> ...
>         xyz => not found
>         libg.so => ./libg.so (0xb7fbd000)
> ...
> 
> A recursive symlink resolution would make the main executable being
> linked against libg.so.1.0 instead of libg.so. In fact, main is linked
> against the library specified by the soname - if present - even if that
> library doesn't exist at all like xyz in the example above. If there is
> no soname the linker incorporates the library as denoted on the command
> line. With libpython2.6, the executable is linked against .so.1.0 since
> this is the library's soname, but not due to the .so-->so.1-->.so.1.0
> symlink resolution. BTW, the soname denoting the non-existing xyz is
> completely artificial, of course, and designed only to clarify the
> concern. Usually, ldconfig ensures that there is a valid symlink
> soname --> actual library file.
> 
> Regards,
> 
> Michael


Ahh, yes, I see. Learned something new ;-) But still, not exactly a
CMake-issue, although replacing full paths with -l flags might cause
wrong libraries from being picked up if a -L flag happens to be
specified before the library, right?

Michael



More information about the CMake mailing list