CMake: binding a common C ++ object from an external project creates binaries with a relative path, not absolute

Problem: I am creating an external project in CMake. The project has a Makefile that ultimately creates a shared object. I want to link and set this object in my super project, as if it were one of the libraries in the project. The problem is that the ExternalProject library connects to my applications and libraries with a relative path, and not with an absolute path, which causes problems when starting from any directory other than where CMake puts it.

I have created a sample SSCCE sample project to demonstrate my general setup. Feel free to learn and compile if necessary ( git clone https://github.com/calebwherry/cmake-SO-question-main --recursive && cd cmake-SO-question-main && mkdir build && cd build && cmake .. && make && cd src/app/testApp && ldd testApp ).

Whenever I run ldd in the executable and libs, I get the output as follows:

  linux-vdso.so.1 => (0x00007fff8b5a2000) libTestLib.so => /home/jwherry3/repos/cmake-superprj-main-test/build/src/lib/TestLib/libTestLib.so (0x00007f592da57000) ../../lib/libExtLib.so (0x00007f592d855000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f592d539000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f592d2b7000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f592d0a0000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f592cd14000) /lib64/ld-linux-x86-64.so.2 (0x00007f592dc5a000) 

I tried all sorts of things related to RPATHS, but cannot get ExtLib to reference correctly. The library local to the project ( libTestLib.so ) is very simple.

I also tried setting LD_LIBRARY_PATH to override the relative path when the application starts, but even when I do this, it still cannot find the library. I suppose because it is relative, does it not correspond to the normal order of binding? The result is that the binary will not work if I do not get into the directory in which it is located.

It seems to me that I am doing something really stupid when creating dependencies with ExternalProject, and this is my problem, but I hit my head for 3 days and did not come up with anything.

System setup: Debian Wheezy 64-bit, CMake 3.0.2, g ++ - 4.9.2.

+5
source share
1 answer

Took some time, but I finally came to an answer using the CMake user manager, specifically @ brad-king.

The main problem is that I am not compiling my generic object correctly in my external project. Brad answers my question:

Thanks for the complete / simple example. The problem is that the libExtLib.so file created by the external project is not DT_SONAME set by the linker. When the linker is given the path to a shared library file that does not have a name, and then the path is copied to the consumer's DT_NEEDED field, since it has no name to use.

There are two solutions:

  • Verify that DT_SONAME is correctly configured by the external build system.

  • Tell CMake that the imported library file does not have a name:

    set_property (TARGET ExtLib PROPERTY IMPORTED_NO_SONAME 1)

    Then CMake will link it through -lExtLib, and the linker will not save the file path to DT_NEEDED, but only the file name.

Any of them should solve the problem. Number 1 is cleaner.

Since I have control over the Make files in the external library, I chose the first cleaner solution by compiling the shared object as follows:

$(SHARED_TARGET): $(OBJECTS) $(CXX) $(CXXFLAGS) $(OBJECTS) -o $@ $(LDFLAGS) -Wl,-soname, $@

I revised my original example and made it much simpler: https://github.com/calebwherry/cmake-SO-question-main . I will leave this as a reference for those who came across this post later.

PS

There is another fix that is not optimal. If I didn’t do any of the above, I could just specify target_link_library the full path to the library I was contacting and not use the target of the imported library. I noted this in the CMake file in the repo and commented on this. Not a great solution, but it solves the problem in a different way.

+1
source

Source: https://habr.com/ru/post/1208197/


All Articles