Skip to content

Commit

Permalink
Feature: create alias targets (#8533)
Browse files Browse the repository at this point in the history
* - CMakeDeps: add cmake_target_aliases property

Signed-off-by: SSE4 <[email protected]>

* - automatically deduce an alias target

Signed-off-by: SSE4 <[email protected]>

* Update conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_aliases.py

Co-authored-by: Luis Martinez de Bartolome Izquierdo <[email protected]>

* Update conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_aliases.py

Co-authored-by: Luis Martinez de Bartolome Izquierdo <[email protected]>

* - add comment

Signed-off-by: SSE4 <[email protected]>

* - use cpp_info instead of new_cpp_info

Signed-off-by: SSE4 <[email protected]>

* - remove useless checks

Signed-off-by: SSE4 <[email protected]>

* - show a warning if target already exists

Signed-off-by: SSE4 <[email protected]>

* - test case for cmake_target_name/cmake_target_namespace

Signed-off-by: SSE4 <[email protected]>

Co-authored-by: Luis Martinez de Bartolome Izquierdo <[email protected]>
  • Loading branch information
SSE4 and lasote authored Oct 21, 2021
1 parent e17ab7e commit f7cfc22
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 1 deletion.
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()
{%- 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


@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

0 comments on commit f7cfc22

Please sign in to comment.