diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py index e033137d445..9abe6ef6632 100644 --- a/conan/tools/cmake/toolchain/blocks.py +++ b/conan/tools/cmake/toolchain/blocks.py @@ -542,9 +542,9 @@ class UserToolchain(Block): def context(self): # This is global [conf] injection of extra toolchain files - user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain") - toolchains = [user_toolchain.replace("\\", "/")] if user_toolchain else [] - return {"paths": toolchains if toolchains else []} + user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain", + default=[], check_type=list) + return {"paths": [ut.replace("\\", "/") for ut in user_toolchain]} class CMakeFlagsInitBlock(Block): diff --git a/conans/model/conf.py b/conans/model/conf.py index f84e8d2d1db..307e47f2b24 100644 --- a/conans/model/conf.py +++ b/conans/model/conf.py @@ -16,7 +16,7 @@ "tools.cmake.cmaketoolchain:generator": "User defined CMake generator to use instead of default", "tools.cmake.cmaketoolchain:find_package_prefer_config": "Argument for the CMAKE_FIND_PACKAGE_PREFER_CONFIG", "tools.cmake.cmaketoolchain:toolchain_file": "Use other existing file rather than conan_toolchain.cmake one", - "tools.cmake.cmaketoolchain:user_toolchain": "Inject existing user toolchain at the beginning of conan_toolchain.cmake", + "tools.cmake.cmaketoolchain:user_toolchain": "Inject existing user toolchains at the beginning of conan_toolchain.cmake", "tools.cmake.cmaketoolchain:system_name": "Define CMAKE_SYSTEM_NAME in CMakeToolchain", "tools.cmake.cmaketoolchain:system_version": "Define CMAKE_SYSTEM_VERSION in CMakeToolchain", "tools.cmake.cmaketoolchain:system_processor": "Define CMAKE_SYSTEM_PROCESSOR in CMakeToolchain", @@ -67,6 +67,10 @@ def __repr__(self): @property def value(self): + if self._value_type is list and _ConfVarPlaceHolder in self._value: + v = self._value[:] + v.remove(_ConfVarPlaceHolder) + return v return self._value def copy(self): diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py index c673dcf829f..a77a3bf119f 100644 --- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py +++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py @@ -47,7 +47,7 @@ def test_cmake_toolchain_user_toolchain(): client = TestClient(path_with_spaces=False) conanfile = GenConanfile().with_settings("os", "compiler", "build_type", "arch").\ with_generator("CMakeToolchain") - save(client.cache.new_config_path, "tools.cmake.cmaketoolchain:user_toolchain=mytoolchain.cmake") + save(client.cache.new_config_path, "tools.cmake.cmaketoolchain:user_toolchain+=mytoolchain.cmake") client.save({"conanfile.py": conanfile}) client.run("install .") @@ -79,7 +79,7 @@ def package(self): self.copy("*") def package_info(self): f = os.path.join(self.package_folder, "mytoolchain.cmake") - self.conf_info["tools.cmake.cmaketoolchain:user_toolchain"] = f + self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f) """) client.save({"conanfile.py": conanfile, "mytoolchain.cmake": 'message(STATUS "mytoolchain.cmake !!!running!!!")'}) @@ -136,7 +136,7 @@ def package(self): self.copy("*") def package_info(self): f = os.path.join(self.package_folder, "mytoolchain.cmake") - self.conf_info["tools.cmake.cmaketoolchain:user_toolchain"] = f + self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f) """) client.save({"conanfile.py": conanfile, "mytoolchain.cmake": 'message(STATUS "mytoolchain1.cmake !!!running!!!")'}) @@ -147,26 +147,12 @@ def package_info(self): conanfile = textwrap.dedent(""" from conans import ConanFile - from conan.tools.cmake import CMake, CMakeToolchain + from conan.tools.cmake import CMake class Pkg(ConanFile): settings = "os", "compiler", "arch", "build_type" exports_sources = "CMakeLists.txt" tool_requires = "toolchain1/0.1", "toolchain2/0.1" - - - def generate(self): - # Get the toolchains from "tools.cmake.cmaketoolchain:user_toolchain" conf at the - # tool_requires - user_toolchains = [] - for dep in self.dependencies.direct_build.values(): - ut = dep.conf_info["tools.cmake.cmaketoolchain:user_toolchain"] - if ut: - user_toolchains.append(ut.replace('\\\\', '/')) - - # Modify the context of the user_toolchain block - t = CMakeToolchain(self) - t.blocks["user_toolchain"].values["paths"] = user_toolchains - t.generate() + generators = "CMakeToolchain" def build(self): cmake = CMake(self) diff --git a/conans/test/integration/configuration/conf/test_conf_from_br.py b/conans/test/integration/configuration/conf/test_conf_from_br.py index 51addbf3e91..5faec750767 100644 --- a/conans/test/integration/configuration/conf/test_conf_from_br.py +++ b/conans/test/integration/configuration/conf/test_conf_from_br.py @@ -79,7 +79,7 @@ def test_declared_generators_get_conf(): from conans import ConanFile class Pkg(ConanFile): def package_info(self): - self.conf_info["tools.cmake.cmaketoolchain:user_toolchain"] = "mytoolchain.cmake" + self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", "mytoolchain.cmake") """) client.save({"conanfile.py": conanfile}) client.run("create . mytool/1.0@") diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py index ab433d62978..dad51dde5c2 100644 --- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py +++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py @@ -52,7 +52,7 @@ def test_cross_build_user_toolchain(): arch=armv8 build_type=Release [conf] - tools.cmake.cmaketoolchain:user_toolchain=rpi_toolchain.cmake + tools.cmake.cmaketoolchain:user_toolchain+=rpi_toolchain.cmake """) client = TestClient(path_with_spaces=False) diff --git a/conans/test/unittests/model/test_conf.py b/conans/test/unittests/model/test_conf.py index c84de92d3bd..1bb50e1f337 100644 --- a/conans/test/unittests/model/test_conf.py +++ b/conans/test/unittests/model/test_conf.py @@ -200,6 +200,7 @@ def test_conf_get_check_type_and_default(): zlib:user.company.check:shared=! zlib:user.company.check:shared_str="False" zlib:user.company.check:static_str=off + user.company.list:newnames+=myname """) c = ConfDefinition() c.loads(text) @@ -210,10 +211,12 @@ def test_conf_get_check_type_and_default(): assert "[conf] user.company.cpu:jobs must be a list-like object." in str(exc_info.value) # Check type does not affect to default value assert c.get("non:existing:conf", default=0, check_type=dict) == 0 + assert c.get("zlib:user.company.check:shared") is None # unset value assert c.get("zlib:user.company.check:shared_str") == '"False"' assert c.get("zlib:user.company.check:shared_str", check_type=bool) is False # smart conversion assert c.get("zlib:user.company.check:static_str") == "off" assert c.get("zlib:user.company.check:static_str", check_type=bool) is False # smart conversion + assert c.get("user.company.list:newnames") == ["myname"] # Placeholder is removed def test_conf_pop():