From 254523667eb1d43c6854d2fdbd8344cf231645b6 Mon Sep 17 00:00:00 2001 From: SSE4 Date: Fri, 19 Feb 2021 16:41:48 +0700 Subject: [PATCH] - add tools.create_cmake_module_alias_targets Signed-off-by: SSE4 --- .../generators/cmake_find_package_multi.py | 40 ++++++++- .../cmake_find_package_multi_test.py | 85 +++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/conans/client/generators/cmake_find_package_multi.py b/conans/client/generators/cmake_find_package_multi.py index 7ad8f3ec9fb..b806180ccdd 100644 --- a/conans/client/generators/cmake_find_package_multi.py +++ b/conans/client/generators/cmake_find_package_multi.py @@ -35,6 +35,8 @@ class CMakeFindPackageMultiGenerator(CMakeFindPackageGenerator): add_library({name}::{name} INTERFACE IMPORTED) endif() + {aliases} + # Load the debug and release library finders get_filename_component(_DIR "${{CMAKE_CURRENT_LIST_FILE}}" PATH) file(GLOB CONFIG_FILES "${{_DIR}}/{filename}Target-*.cmake") @@ -44,6 +46,15 @@ class CMakeFindPackageMultiGenerator(CMakeFindPackageGenerator): endforeach() """) + alias_template = Template(textwrap.dedent("""\ + {%- for alias, target in aliases.items() %} + if(NOT TARGET {alias}) + add_library({{ alias }} INTERFACE IMPORTED) + set_property(TARGET {{ alias }} PROPERTY INTERFACE_LINK_LIBRARIES {{target}}) + endif() + {%- endfor %} + """)) + # This template takes the "name" of the target name::name and configs = ["Release", "Debug"..] target_properties = Template(""" # Assign target properties @@ -172,6 +183,13 @@ class CMakeFindPackageMultiGenerator(CMakeFindPackageGenerator): {%- endfor %} + {%- for alias, target in aliases.items() %} + if(NOT TARGET {alias}) + add_library({{ alias }} INTERFACE IMPORTED) + set_property(TARGET {{ alias }} PROPERTY INTERFACE_LINK_LIBRARIES {{target}}) + endif() + {%- endfor %} + if(NOT TARGET {{ pkg_name }}::{{ pkg_name }}) add_library({{ pkg_name }}::{{ pkg_name }} INTERFACE IMPORTED) endif() @@ -332,8 +350,16 @@ def content(self): version=cpp_info.version, public_deps_names=pkg_public_deps_filenames ) + + aliases = cpp_info.get_property("aliases", self.name) or {} + if isinstance(aliases, (list, tuple)): + target = "{name}::{name}".format(name=pkg_findname) + aliases = {alias: target for alias in aliases} + + aliases_section = self.alias_template.render(aliases=aliases) + ret["{}Targets.cmake".format(pkg_filename)] = self.targets_template.format( - filename=pkg_filename, name=pkg_findname) + filename=pkg_filename, name=pkg_findname, aliases=aliases_section) # If any config matches the build_type one, add it to the cpp_info dep_cpp_info = extend(cpp_info, build_type.lower()) @@ -352,6 +378,15 @@ def content(self): global_target_variables = target_template.format(name=pkg_findname, deps=pkg_info, build_type_suffix=build_type_suffix, deps_names=deps_names) + + aliases = {} + for component in cpp_info.components: + component_aliases = cpp_info.components[component].get_property("aliases", self.name) or {} + if isinstance(component_aliases, (tuple, list)): + target = "{name}::{name}".format(name=pkg_findname) + component_aliases = {alias: target for alias in component_aliases} + aliases.update(component_aliases) + variables = self.components_target_build_type_tpl.render( pkg_name=pkg_findname, global_target_variables=global_target_variables, @@ -366,7 +401,8 @@ def content(self): pkg_name=pkg_findname, pkg_filename=pkg_filename, components=components, - build_type=build_type + build_type=build_type, + aliases=aliases ) ret["{}Targets.cmake".format(pkg_filename)] = targets target_config = self.components_config_tpl.render( diff --git a/conans/test/functional/generators/cmake_find_package_multi_test.py b/conans/test/functional/generators/cmake_find_package_multi_test.py index c3893cc7b79..57aae62820f 100644 --- a/conans/test/functional/generators/cmake_find_package_multi_test.py +++ b/conans/test/functional/generators/cmake_find_package_multi_test.py @@ -11,6 +11,91 @@ from conans.util.files import load +@pytest.mark.tool_cmake +class TestCreateModuleOfficialCMakeTargets: + + consumer = textwrap.dedent(""" + from conans import ConanFile, CMake + + class Conan(ConanFile): + name = "consumer" + version = "1.0" + settings = "os", "compiler", "build_type", "arch" + exports_sources = ["CMakeLists.txt"] + generators = "cmake_find_package_multi" + requires = "hello/1.0" + + def build(self): + cmake = CMake(self) + cmake.configure() + """) + + def test_global_alias(self): + client = TestClient() + + conanfile = textwrap.dedent(""" + import os + from conans import ConanFile, CMake, tools + + class Conan(ConanFile): + name = "hello" + version = "1.0" + settings = "os", "arch", "compiler", "build_type" + + def package_info(self): + self.cpp_info.set_property("aliases", ["hello"], "cmake_find_package_multi") + """) + + client.save({"conanfile.py": conanfile}) + client.run("create .") + + cmakelists = textwrap.dedent(""" + cmake_minimum_required(VERSION 3.0) + project(test) + find_package(hello REQUIRED) + get_target_property(link_libraries hello INTERFACE_LINK_LIBRARIES) + message("hello link libraries: ${link_libraries}") + """) + + client.save({"conanfile.py": self.consumer, "CMakeLists.txt": cmakelists}) + client.run("create .") + + assert "hello link libraries: hello::hello" in client.out + + def test_component_alias(self): + client = TestClient() + + conanfile = textwrap.dedent(""" + import os + from conans import ConanFile, CMake, tools + + class Conan(ConanFile): + name = "hello" + version = "1.0" + settings = "os", "arch", "compiler", "build_type" + + def package_info(self): + self.cpp_info.components["adios"].set_property("aliases", + {"hola::adios": "hello::adios"}, "cmake_find_package_multi") + """) + + client.save({"conanfile.py": conanfile}) + client.run("create .") + + cmakelists = textwrap.dedent(""" + cmake_minimum_required(VERSION 3.0) + project(test) + find_package(hello REQUIRED) + get_target_property(link_libraries hola::adios INTERFACE_LINK_LIBRARIES) + message("hola::adios link libraries: ${link_libraries}") + """) + + client.save({"conanfile.py": self.consumer, "CMakeLists.txt": cmakelists}) + client.run("create .") + + assert "hola::adios link libraries: hello::adios" in client.out + + @pytest.mark.tool_cmake class TestCMakeFindPackageMultiGenerator: