Reputation: 2888
The package's consumer couldn't load the package's binary's shared libraries.
find_package(MyThirdParty REQUIRED) # MyThirdParty is installed using Conan
find_program(binary_paty MyThirdParty REQUIRED)
execute_process(COMMAND ${binary_path} COMMAND_ERROR_IS_FATAL ANY)
The execute_process
command will fail because the MyThirdParty
's shared libraries are missing.
How could I package the third-party binary projects?
Third-party project:
file(WRITE Library.hh "void Func();")
file(WRITE Library.cc "void Func() {}")
add_library(Library SHARED Library.hh Library.cc)
file(WRITE Main.cc "#include \"Library.hh\"\nint main() { Func(); }")
add_executable(MyThirdParty Main.cc)
target_link_libraries(MyThirdParty PRIVATE Library)
install(TARGETS MyThirdParty Library EXPORT MyThirdPartyConfig)
install(EXPORT MyThirdPartyConfig
NAMESPACE MyThirdParty::
DESTINATION lib/cmake/MyThirdParty
)
My attempt for packaging the third-party with Conan:
from conans import ConanFile, CMake, tools
class MyThirdPartyConan(ConanFile):
name = "MyThirdParty"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
def source(self):
tools.download(
filename = "CMakeLists.txt",
url = "https://gist.githubusercontent.com/gccore/9007084e1b307592ae040ceb5745bf5f/raw/419a96712145e8d24d4c9982ab3b7fd31d44b9f0/CMakeLists.txt")
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
The consumer:
find_package(MyThirdParty REQUIRED)
find_program(binary_paty MyThirdParty REQUIRED)
execute_process(COMMAND ${binary_path} COMMAND_ERROR_IS_FATAL ANY)
And finally the conanfile.txt
:
[requires]
MyThirdParty/1.0.0@Ghasem/Test
[generators]
cmake_find_package
But the consumer's CMake with the Conan package fails because of the third-party's shared library. When the consumer's CMake tries to execute the MyThirdParty
binary it will fail because it couldn't find the libLibrary.so
file.
My Environment:
Fedora 35
Linux 5.18.9-100.fc35.x86_64
GCC 11.3.1 20220421
3.22.2
1.47.0
Upvotes: 0
Views: 407
Reputation: 2888
On Linux we could use patchelf
and change the binary RPATH during the packaging state:
def package(self):
cmake = CMake(self);
cmake.install();
self.run("patchelf --set-rpath '$ORIGIN/../lib' " +
self.package_folder + "/bin/MyThirdParty");
And for Windows just put the shared libraries files besides the binary, the Windows Linker/Loader doesn't try hard to be smart(like Linux's Linker/Loader does).
Upvotes: 2