Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add property "cmake_target_aliases" to create some CMake alias targets (CMakeDeps) #8533

Merged
merged 9 commits into from
Oct 21, 2021
46 changes: 45 additions & 1 deletion conan/tools/cmake/cmakedeps/templates/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@ def context(self):
target_pattern = "" if not self.find_module_mode else "module-"
target_pattern += "{}-Target-*.cmake".format(self.file_name)

cmake_target_aliases = self.conanfile.cpp_info.\
get_property("cmake_target_aliases", "CMakeDeps") or dict()

target = "%s::%s" % (self.target_namespace, self.global_target_name)
cmake_target_aliases = {alias: target for alias in cmake_target_aliases}

cmake_component_target_aliases = dict()
for comp_name in self.conanfile.cpp_info.components:
aliases = \
self.conanfile.cpp_info.components[comp_name].\
get_property("cmake_target_aliases", "CMakeDeps") or dict()

target = "%s::%s" % (self.target_namespace,
self.get_component_alias(self.conanfile, comp_name))
cmake_component_target_aliases[comp_name] = {alias: target for alias in aliases}

ret = {"pkg_name": self.pkg_name,
"target_namespace": self.target_namespace,
"global_target_name": self.global_target_name,
"file_name": self.file_name,
"data_pattern": data_pattern,
"target_pattern": target_pattern}
"target_pattern": target_pattern,
"cmake_target_aliases": cmake_target_aliases,
"cmake_component_target_aliases": cmake_component_target_aliases}

return ret

Expand Down Expand Up @@ -58,6 +76,32 @@ def template(self):
conan_message(STATUS "Conan: Target declared '{{ target_namespace }}::{{ global_target_name }}'")
endif()

{%- for alias, target in cmake_target_aliases.items() %}

if(NOT TARGET {{alias}})
add_library({{alias}} INTERFACE IMPORTED)
set_property(TARGET {{ alias }} PROPERTY INTERFACE_LINK_LIBRARIES {{target}})
else()
message(WARNING "target '{{alias}}' already exists, alias for target '{{target}}' won't be created!")
endif()
lasote marked this conversation as resolved.
Show resolved Hide resolved

{%- endfor %}

{%- for comp_name, component_aliases in cmake_component_target_aliases.items() %}

{%- for alias, target in component_aliases.items() %}

if(NOT TARGET {{alias}})
add_library({{alias}} INTERFACE IMPORTED)
set_property(TARGET {{ alias }} PROPERTY INTERFACE_LINK_LIBRARIES {{target}})
else()
message(WARNING "target '{{alias}}' already exists, alias for target '{{target}}' won't be created!")
endif()

{%- endfor %}

{%- endfor %}

# Load the debug and release library finders
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/{{ target_pattern }}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import textwrap
import pytest

from conans.test.utils.tools import TestClient

consumer = textwrap.dedent("""
from conans import ConanFile
from conan.tools.cmake import CMake

class Consumer(ConanFile):
name = "consumer"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain"
exports_sources = ["CMakeLists.txt"]
requires = "hello/1.0"

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


@pytest.mark.tool_cmake
def test_global_alias():
conanfile = textwrap.dedent("""
from conans import ConanFile

class Hello(ConanFile):
name = "hello"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"

def package_info(self):
# the default global target is "hello::hello"
self.cpp_info.set_property("cmake_target_aliases", ["hello"])
""")

cmakelists = textwrap.dedent("""
cmake_minimum_required(VERSION 2.8)

find_package(hello REQUIRED)
get_target_property(link_libraries hello INTERFACE_LINK_LIBRARIES)
message("hello link libraries: ${link_libraries}")
""")

client = TestClient()
client.save({"conanfile.py": conanfile})
client.run("create .")

client.save({"conanfile.py": consumer, "CMakeLists.txt": cmakelists})
client.run("create .")

assert "hello link libraries: hello::hello" in client.out


@pytest.mark.tool_cmake
def test_component_alias():
conanfile = textwrap.dedent("""
from conans import ConanFile

class Hello(ConanFile):
name = "hello"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"

def package_info(self):
self.cpp_info.components["buy"].set_property("cmake_target_aliases",
["hola::adios"])
""")

cmakelists = textwrap.dedent("""
cmake_minimum_required(VERSION 2.8)

find_package(hello REQUIRED)
get_target_property(link_libraries hola::adios INTERFACE_LINK_LIBRARIES)
message("hola::adios link libraries: ${link_libraries}")
""")

client = TestClient()
client.save({"conanfile.py": conanfile})
client.run("create .")

client.save({"conanfile.py": consumer, "CMakeLists.txt": cmakelists})
client.run("create .")

assert "hola::adios link libraries: hello::buy" in client.out
lasote marked this conversation as resolved.
Show resolved Hide resolved


@pytest.mark.tool_cmake
def test_custom_name():
conanfile = textwrap.dedent("""
from conans import ConanFile

class Hello(ConanFile):
name = "hello"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"

def package_info(self):
self.cpp_info.set_property("cmake_target_namespace", "ola")
self.cpp_info.set_property("cmake_target_name", "comprar")
self.cpp_info.set_property("cmake_target_aliases", ["hello"])
""")

cmakelists = textwrap.dedent("""
cmake_minimum_required(VERSION 2.8)

find_package(hello REQUIRED)
get_target_property(link_libraries hello INTERFACE_LINK_LIBRARIES)
message("hello link libraries: ${link_libraries}")
""")

client = TestClient()
client.save({"conanfile.py": conanfile})
client.run("create .")

client.save({"conanfile.py": consumer, "CMakeLists.txt": cmakelists})
client.run("create .")

assert "hello link libraries: ola::comprar" in client.out