我有一个包含2个二进制文件的软件包。二进制文件只有一个选项不同。
该软件包是一个库。现在如何将该程序包链接到我需要的特定程序包?
答案 0 :(得分:0)
选项很少:
您可以使用cmake_paths并找到库名称:
首先,您添加一个conanfile.txt
,声明程序包名称和cmake_paths
生成器
[requires]
my_package/0.1.0@user/channel
[generators]
cmake_paths
第二,您从软件包中按cmake文件中的名称搜索所需的库:
cmake_minimum_required(VERSION 3.0)
project(myapp)
find_library(MY_LIBRARY foo REQUIRED) # the library name foo in this example
add_executable(myapp app.cpp)
target_link_libraries (myapp ${MY_LIBRARY})
最后,您将cmake_paths传递给cmake,这样它将找到您的库
mkdir build && cd build
conan install ..
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_paths.cmake
cmake --build .
./myapp
它可以工作,但是有点脆弱,因为用户现在需要库名称,并且当找到库时CMake不会发出警告,因此您必须添加条件进行检查。
第二个可能的选项是使用Components功能,但需要修改配方,您可以为每个库提供不同的目标:
首先,您需要更新conanfile.py,添加以下组件:
from conans import ConanFile, CMake
class MyPackage(ConanFile):
name = "my_package"
version = "0.1.0"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = {"shared": False}
generators = "cmake"
exports_sources = "src/*"
def build(self):
cmake = CMake(self)
cmake.configure(source_folder="src")
cmake.build()
def package(self):
self.copy("*.h", dst="include", src="src")
self.copy("*.lib", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.dylib*", dst="lib", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.a", dst="lib", keep_path=False)
def package_info(self):
self.cpp_info.names["cmake_find_package"] = "MyPackage"
self.cpp_info.names["cmake_find_package_multi"] = "MyPackage"
self.cpp_info.components["libfoo"].names["cmake_find_package"] = "foo"
self.cpp_info.components["libfoo"].names["cmake_find_package_multi"] = "foo"
self.cpp_info.components["libfoo"].libs = ["foo"]
self.cpp_info.components["libbar"].names["cmake_find_package"] = "bar"
self.cpp_info.components["libbar"].names["cmake_find_package_multi"] = "bar"
self.cpp_info.components["libbar"].libs = ["bar"]
如您所见,该配方构建了一个包含2个库foo
和bar
的程序包,并且每个库使用不同的组件。由于CamelCase是CMake目标的首选,因此名称MyPackage
将用于文件名和目标命名空间。结果将是MyPackage::foo
和MyPackage::bar
。
作为使用者,您也必须更新项目:
现在,我们将使用cmake_find_package生成器,以避免在命令行中使用CMAKE_TOOLCHAIN_FILE
:
[requires]
my_package/0.1.0@user/channel
[generators]
cmake_find_package
CMake文件现在需要软件包名称,但是已由CMake检查:
cmake_minimum_required(VERSION 3.0)
project(myapp)
find_package(MyPackage REQUIRED)
add_executable(myapp app.cpp)
target_link_libraries (myapp MyPackage::foo) # We only need libfoo here
最后,但现在更简单,命令行:
mkdir build && cd build
conan install ..
cmake ..
cmake --build .
./myapp
柯南将在FindMyPackage.cmake
中生成build/
,并由您的CMakeLists.txt
加载。
这两个演示都能满足您的要求,但我更喜欢第二个演示,因为这样做更安全,因为您可以创建特定的目标,并且避免客户方面的任何错误。
注意:功能部件要求柯南> = 1.27。