Michael A
Michael A

Reputation: 327

Conan: Combining conanfile.py recipe with conanfile.txt

A header-only library dependency I plan to use does not provide a conan recipe.

I am trying to make one myself and combine it with the existing conanfile.txt dependencies I have.

In detail: I am calling conan 1.60 from within cmake (see cmake-conan) to load these dependencies: conanfile.txt

[requires]
gtest/1.13.0
pybind11/2.10.4
range-v3/0.12.0
fmt/10.1.1
xtensor/0.24.3

[generators]
cmake
cmake_find_package
cmake_paths

I would also like to use conan to pull in xtensor-python which provides pybind11 bindings for xtensor. Since this repo does not have a conan-recipe I created my own (perhaps faulty) by adapting xtensor's recipe:

import os
import textwrap

from conan import ConanFile
from conan.tools.files import apply_conandata_patches, get, save
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps


class XTensorPythonRecipe(ConanFile):
    name = "xtensor-python"
    license = "BSD 3-Clause"
    url = "https://github.com/xtensor-stack/xtensor-python"
    description = "Python bindings for the xtensor C++ multi-dimensional array library."
    topics = ("numpy", "multidimensional-arrays", "tensors")
    settings = "os", "compiler", "build_type", "arch"
    package_type = "header-library"

    exports_sources = "include/*"

    def source(self):
        get(
            self,
            **self.conan_data["sources"][self.version],
            destination=self.source_folder,
            strip_root=True,
        )

    def build(self):
        apply_conandata_patches(self)
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def requirements(self):
        self.requires("xtensor/0.24.3")
        self.requires("pybind11/2.10.4")

    def layout(self):
        cmake_layout(self)

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_id(self):
        self.info.clear()

    def package_info(self):
        self.cpp_info.set_property("cmake_file_name", "xtensor-python")
        self.cpp_info.set_property("cmake_target_name", "xtensor-python")
        self.cpp_info.set_property("pkg_config_name", "xtensor-python")
        self.cpp_info.bindirs = []
        self.cpp_info.libdirs = []

        # TODO: to remove in conan v2 once cmake_find_package* generators removed
        self.cpp_info.build_modules["cmake_find_package"] = [self._module_file_rel_path]
        self.cpp_info.build_modules["cmake_find_package_multi"] = [
            self._module_file_rel_path
        ]

    def _create_cmake_module_alias_targets(self, module_file, targets):
        content = ""
        for alias, aliased in targets.items():
            content += textwrap.dedent(
                f"""\
                if(TARGET {aliased} AND NOT TARGET {alias})
                    add_library({alias} INTERFACE IMPORTED)
                    set_property(TARGET {alias} PROPERTY INTERFACE_LINK_LIBRARIES {aliased})
                endif()
            """
            )
        save(self, module_file, content)

    @property
    def _module_file_rel_path(self):
        return os.path.join("lib", "cmake", f"conan-official-{self.name}-targets.cmake")

The sources are pulled from a conandata.yml file.

My question now is: how do I combine this recipe with my existing requirements in the conanfile.txt?

Currently the cmake call to conan does this:

for CONANFILE in [deps/xtensor-python/conanfile.py, deps/conanfile.txt]:
    conan install CONANFILE -pr=default -s BUILDSETTINGS

in each iteration of the loop this gives me a conanbuildinfo.cmake file that I include, but ends up in errors of duplicated targets:

CMake Error at cmake-build-debug/conanbuildinfo.cmake:509 (add_library):
  add_library cannot create imported target "CONAN_PKG::pybind11" because
  another target with the same name already exists.

since both recipes pull in e.g. pybind11 and define the targets individually.

Is my approach wrong and if so, what is the correct approach to doing this?

Upvotes: 0

Views: 341

Answers (0)

Related Questions