Как связать с конкретным packageid в Conan

#conan

#conan

Вопрос:

У меня есть пакет с 2 двоичными файлами. Двоичные файлы отличаются только одним параметром.

Пакет представляет собой библиотеку. Как теперь связать этот пакет с конкретным пакетом, который мне требуется?

Ответ №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 amp;amp; 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"]
  

Как вы можете видеть, рецепт создает пакет с двумя библиотеками, 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 amp;amp; cd build
conan install ..
cmake ..
cmake --build .
./myapp
  

Conan сгенерирует FindMyPackage.cmake in build/ , который будет загружен вашим CMakeLists.txt .

Обе демонстрации достигают того, что вы просили, но я предпочитаю вторую, потому что она безопаснее, поскольку вы можете создать конкретную цель и избежать любой ошибки со стороны клиента.

ПРИМЕЧАНИЕ: Для компонентов функций требуется Conan > = 1.27.