如何链接到柯南中的特定packageid

问题描述

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

该软件包是一个库。现在如何将该程序包链接到我需要的特定程序包?

解决方法

选项很少:

您可以使用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*",keep_path=False)
        self.copy("*.so",keep_path=False)
        self.copy("*.a",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的程序包,并且每个库使用不同的组件。由于CamelCase是CMake目标的首选,因此名称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

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

这两个演示都能满足您的要求,但我更喜欢第二个演示,因为这样做更安全,因为您可以创建特定的目标,并且避免客户方面的任何错误。

注意:功能部件要求柯南> = 1.27。