【问题标题】:How to link against to specific packageid in Conan如何链接到柯南中的特定 packageid
【发布时间】:2020-08-15 12:38:26
【问题描述】:

我有一个包含 2 个二进制文件的包。二进制文件只有一个选项不同。

这个包是一个库。现在如何将此包链接到我需要的特定包?

【问题讨论】:

    标签: conan


    【解决方案1】:

    有几个选项:

    您可以使用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 个库的包,foobar,并为每个库使用不同的组件。由于 CMake 目标首选 CamelCase,因此名称 MyPackage 将用于文件名和目标命名空间。结果将是MyPackage::fooMyPackage::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
    

    柯南将在build/ 中生成FindMyPackage.cmake,并由您的CMakeLists.txt 加载。

    两个演示都达到了你的要求,但我更喜欢第二个,因为更安全,因为你可以创建一个特定的目标,并避免客户方面的任何错误。

    注意:功能组件需要柯南 >=1.27。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-31
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多