Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

private linking of transitive dependencies #13302

Open
memsharded opened this issue Mar 2, 2023 · 7 comments
Open

private linking of transitive dependencies #13302

memsharded opened this issue Mar 2, 2023 · 7 comments
Assignees
Milestone

Comments

@memsharded
Copy link
Member

I've setup a small example. If this is not related to the topic of the discussion above, we can also move this into a new issue.

The relationship is as follows ("->" == "depends on"):
app -> libB
libB -> libA
libA -> libX & libY

Build via:

cd libX
conan create . -pr:h default -pr:b default -s build_type=Release

cd libY
conan create . -pr:h default -pr:b default -s build_type=Release

cd libA
conan create . -pr:h default -pr:b default -s build_type=Release

cd app
conan create . -pr:h default -pr:b default -s build_type=Release

This is failing with:

Scanning dependencies of target app
[ 80%] Building CXX object src/app/CMakeFiles/app.dir/app.cpp.o
[ 80%] Building CXX object src/app/CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable app
/usr/bin/ld: warning: liblibX.so, needed by /home/user/.conan/data/libA/1.0.0/_/_/package/b2bcf496ea6094c509a11d681ff126c83f01fc2f/lib/liblibA.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: liblibY.so, needed by /home/user/.conan/data/libA/1.0.0/_/_/package/b2bcf496ea6094c509a11d681ff126c83f01fc2f/lib/liblibA.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /home/user/.conan/data/libA/1.0.0/_/_/package/b2bcf496ea6094c509a11d681ff126c83f01fc2f/lib/liblibA.so: undefined reference to `libY()'
/usr/bin/ld: /home/user/.conan/data/libA/1.0.0/_/_/package/b2bcf496ea6094c509a11d681ff126c83f01fc2f/lib/liblibA.so: undefined reference to `libX()'
collect2: error: ld returned 1 exit status
make[2]: *** [src/app/CMakeFiles/app.dir/build.make:100: src/app/app] Error 1
make[1]: *** [CMakeFiles/Makefile2:160: src/app/CMakeFiles/app.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

The error is gone once you link libB PUBLIC against libA.
target_link_libraries(libB PUBLIC libA::libA)

I was wondering whether this is related to this issue, but I might be wrong.

$ conan --version
Conan version 1.53.0

Originally posted by @tbsuht in #7192 (comment)

@memsharded
Copy link
Member Author

quick hint @tbsuht: do not use package names in uppercase, as that will be incompatible with 2.0. please start using packages lowercase

I am having a quick check in Windows first, and it builds in Windows correctly (except it fails in the final app package(), but the app.exe is built correctly. So this seems exclusively a failure in Linux. Lets move to Linux to check

@memsharded
Copy link
Member Author

I have been able to dig deep into this.

The issue is originated because the liba::liba Conan generated target is an interface target, that depends on the real CONAN_LIB::liba target that is unknown imported (because Conan doesn't have enough information on that). It seems that CMake is unable to propagate correctly the linkage requirements in this case.

So you are correct, the workaround would be to define PUBLIC dependency on it.
We will be improving CMakeDeps generator to better handle these cases, but this is complicated, so it might take a bit of time. Assigning this for the 2.X roadmap.

@memsharded memsharded added this to the 2.X milestone Mar 2, 2023
@tbsuht
Copy link

tbsuht commented Mar 3, 2023

@memsharded thanks for the fast response!

So this seems exclusively a failure in Linux. Lets move to Linux to check

Do you know why this is not a problem on Windows if that is related to the generated CMake files?

because Conan doesn't have enough information on that

I can fix the linking manually by providing the lib paths via "-rpath-link". But those path infos are not available as it's an imported target?

We will be improving CMakeDeps generator to better handle these cases. Assigning this for the 2.X roadmap.

Will this also be available in Conan 1.X?


I was wondering a little bit: is this an uncommon use case?
For us this is used regularly. Whenever there is an executable & library inside a conan package where the executable is also using the library and the lib has some dependencies managed by conan.

@tbsuht
Copy link

tbsuht commented Mar 3, 2023

Another workaround instead of using PUBLIC for linking:

In the conanfile of app:

    def imports(self):
        self.copy("*.so*", "lib", "lib")

and its CMakeLists.txt

target_link_libraries(app PRIVATE libB "-Wl,-rpath-link ${CMAKE_BINARY_DIR}/lib")

what do you think makes more sense to use?

PengZheng added a commit to apache/celix that referenced this issue Jun 9, 2023
@PengZheng
Copy link

PengZheng commented Jun 9, 2023

target_link_libraries(app PRIVATE libB "-Wl,-rpath-link ${CMAKE_BINARY_DIR}/lib")

I'd rather fix it at the conan level:

apache/celix@40df914

Anyway, thanks for a workaround much better than previous ones.

@memsharded
Copy link
Member Author

Hi @PengZheng, @tbsuht

It is better not to use the imports() anymore, it has been deprecated and removed in Conan 2.0. So to be ready, the best is to use generate() method and do a explicit copy() there (not a self.copy(), note the free copy() is imported from conan.tools.files import copy, the self.copy() has also been removed in Conan 2.0)

@tbsuht
Copy link

tbsuht commented Jun 20, 2023

To be considered in #13018.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants