Skip to content

Commit

Permalink
Feature/cmakedeps files (#8655)
Browse files Browse the repository at this point in the history
* create new variables file

* change name to dynamic vars

* test components implementation

* implement components

* fix target template

* improve tests

* renamed variables

* Revert "renamed variables"

This reverts commit 662785c.
  • Loading branch information
danimtb committed Mar 17, 2021
1 parent 54c9c8d commit 9d955bf
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 61 deletions.
144 changes: 85 additions & 59 deletions conan/tools/cmake/cmakedeps.py
Expand Up @@ -83,10 +83,8 @@
""")


target_template = """
variables_template = """
set({name}_INCLUDE_DIRS{build_type_suffix} {deps.include_paths})
set({name}_INCLUDE_DIR{build_type_suffix} {deps.include_path})
set({name}_INCLUDES{build_type_suffix} {deps.include_paths})
set({name}_RES_DIRS{build_type_suffix} {deps.res_paths})
set({name}_DEFINITIONS{build_type_suffix} {deps.defines})
set({name}_LINKER_FLAGS{build_type_suffix}_LIST
Expand All @@ -98,44 +96,31 @@
set({name}_COMPILE_OPTIONS{build_type_suffix}_LIST "{deps.cxxflags_list}" "{deps.cflags_list}")
set({name}_COMPILE_OPTIONS_C{build_type_suffix} "{deps.cflags_list}")
set({name}_COMPILE_OPTIONS_CXX{build_type_suffix} "{deps.cxxflags_list}")
set({name}_LIBRARIES_TARGETS{build_type_suffix} "") # Will be filled later, if CMake 3
set({name}_LIBRARIES{build_type_suffix} "") # Will be filled later
set({name}_LIBS{build_type_suffix} "") # Same as {name}_LIBRARIES
set({name}_LIB_DIRS{build_type_suffix} {deps.lib_paths})
set({name}_LIBS{build_type_suffix} {deps.libs})
set({name}_SYSTEM_LIBS{build_type_suffix} {deps.system_libs})
set({name}_FRAMEWORK_DIRS{build_type_suffix} {deps.framework_paths})
set({name}_FRAMEWORKS{build_type_suffix} {deps.frameworks})
set({name}_FRAMEWORKS_FOUND{build_type_suffix} "") # Will be filled later
set({name}_BUILD_MODULES_PATHS{build_type_suffix} {deps.build_modules_paths})
"""

conan_find_apple_frameworks({name}_FRAMEWORKS_FOUND{build_type_suffix} "${{{name}_FRAMEWORKS{build_type_suffix}}}" "${{{name}_FRAMEWORK_DIRS{build_type_suffix}}}")

mark_as_advanced({name}_INCLUDE_DIRS{build_type_suffix}
{name}_INCLUDE_DIR{build_type_suffix}
{name}_INCLUDES{build_type_suffix}
{name}_DEFINITIONS{build_type_suffix}
{name}_LINKER_FLAGS{build_type_suffix}_LIST
{name}_COMPILE_DEFINITIONS{build_type_suffix}
{name}_COMPILE_OPTIONS{build_type_suffix}_LIST
{name}_LIBRARIES{build_type_suffix}
{name}_LIBS{build_type_suffix}
{name}_LIBRARIES_TARGETS{build_type_suffix})
# Find the real .lib/.a and add them to {name}_LIBS and {name}_LIBRARY_LIST
set({name}_LIBRARY_LIST{build_type_suffix} {deps.libs})
set({name}_LIB_DIRS{build_type_suffix} {deps.lib_paths})
dynamic_variables_template = """
set({name}_FRAMEWORKS_FOUND{build_type_suffix} "") # Will be filled later
conan_find_apple_frameworks({name}_FRAMEWORKS_FOUND{build_type_suffix} "${{{name}_FRAMEWORKS{build_type_suffix}}}" "${{{name}_FRAMEWORK_DIRS{build_type_suffix}}}")
# Gather all the libraries that should be linked to the targets (do not touch existing variables):
set(_{name}_DEPENDENCIES{build_type_suffix} "${{{name}_FRAMEWORKS_FOUND{build_type_suffix}}} ${{{name}_SYSTEM_LIBS{build_type_suffix}}} {deps_names}")
conan_package_library_targets("${{{name}_LIBRARY_LIST{build_type_suffix}}}" # libraries
"${{{name}_LIB_DIRS{build_type_suffix}}}" # package_libdir
set({name}_LIBRARIES_TARGETS{build_type_suffix} "") # Will be filled later, if CMake 3
set({name}_LIBRARIES{build_type_suffix} "") # Will be filled later
conan_package_library_targets("${{{name}_LIBS{build_type_suffix}}}" # libraries
"${{{name}_LIB_DIRS{build_type_suffix}}}" # package_libdir
"${{_{name}_DEPENDENCIES{build_type_suffix}}}" # deps
{name}_LIBRARIES{build_type_suffix} # out_libraries
{name}_LIBRARIES_TARGETS{build_type_suffix} # out_libraries_targets
"{build_type_suffix}" # build_type
"{name}") # package_name
set({name}_LIBS{build_type_suffix} ${{{name}_LIBRARIES{build_type_suffix}}})
{name}_LIBRARIES{build_type_suffix} # out_libraries
{name}_LIBRARIES_TARGETS{build_type_suffix} # out_libraries_targets
"{build_type_suffix}" # build_type
"{name}") # package_name
foreach(_FRAMEWORK ${{{name}_FRAMEWORKS_FOUND{build_type_suffix}}})
list(APPEND {name}_LIBRARIES_TARGETS{build_type_suffix} ${{_FRAMEWORK}})
Expand Down Expand Up @@ -289,8 +274,13 @@ class CMakeDeps(object):
# Load the debug and release library finders
get_filename_component(_DIR "${{CMAKE_CURRENT_LIST_FILE}}" PATH)
file(GLOB CONFIG_FILES "${{_DIR}}/{filename}Target-*.cmake")
file(GLOB DATA_FILES "${{_DIR}}/{filename}-*-*-data.cmake")
foreach(f ${{DATA_FILES}})
include(${{f}})
endforeach()
file(GLOB CONFIG_FILES "${{_DIR}}/{filename}Target-*.cmake")
foreach(f ${{CONFIG_FILES}})
include(${{f}})
endforeach()
Expand Down Expand Up @@ -356,24 +346,18 @@ class CMakeDeps(object):
endif()
""")

components_target_build_type_tpl = Template(textwrap.dedent("""\
########## MACROS ###########################################################################
#############################################################################################
include(${CMAKE_CURRENT_LIST_DIR}/cmakedeps_macros.cmake)
components_variables_tpl = Template(textwrap.dedent("""\
########### VARIABLES #######################################################################
#############################################################################################
{{ global_target_variables }}
{{ global_variables }}
set({{ pkg_name }}_COMPONENTS_{{ build_type }} {{ pkg_components }})
{%- for comp_name, comp in components %}
########### COMPONENT {{ comp_name }} VARIABLES #############################################
set({{ pkg_name }}_{{ comp_name }}_INCLUDE_DIRS_{{ build_type }} {{ comp.include_paths }})
set({{ pkg_name }}_{{ comp_name }}_INCLUDE_DIR_{{ build_type }} {{ comp.include_path }})
set({{ pkg_name }}_{{ comp_name }}_INCLUDES_{{ build_type }} {{ comp.include_paths }})
set({{ pkg_name }}_{{ comp_name }}_LIB_DIRS_{{ build_type }} {{ comp.lib_paths }})
set({{ pkg_name }}_{{ comp_name }}_RES_DIRS_{{ build_type }} {{ comp.res_paths }})
set({{ pkg_name }}_{{ comp_name }}_DEFINITIONS_{{ build_type }} {{ comp.defines }})
Expand All @@ -391,6 +375,20 @@ class CMakeDeps(object):
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:{{ comp.sharedlinkflags_list }}>
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:{{ comp.exelinkflags_list }}>
)
{%- endfor %}
"""))

components_dynamic_variables_tpl = Template(textwrap.dedent("""\
########## MACROS ###########################################################################
#############################################################################################
include(${CMAKE_CURRENT_LIST_DIR}/cmakedeps_macros.cmake)
########### VARIABLES #######################################################################
#############################################################################################
{{ global_dynamic_variables }}
{%- for comp_name, comp in components %}
########## COMPONENT {{ comp_name }} FIND LIBRARIES & FRAMEWORKS / DYNAMIC VARS #############
Expand Down Expand Up @@ -426,6 +424,14 @@ class CMakeDeps(object):
add_library({{ pkg_name }}::{{ pkg_name }} INTERFACE IMPORTED)
endif()
# Load the debug and release variables
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB DATA_FILES "${_DIR}/{{ pkg_filename }}-*-*-data.cmake")
foreach(f ${DATA_FILES})
include(${f})
endforeach()
# Load the debug and release library finders
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/{{ pkg_filename }}Target-*.cmake")
Expand Down Expand Up @@ -536,7 +542,7 @@ class CMakeDeps(object):

def __init__(self, conanfile):
self._conanfile = conanfile

self.arch = str(self._conanfile.settings.arch)
self.configuration = str(self._conanfile.settings.build_type)
self.configurations = [v for v in conanfile.settings.build_type.values_range if v != "None"]
# FIXME: Ugly way to define the output path
Expand Down Expand Up @@ -663,6 +669,24 @@ def content(self):
config_version = self.config_version_template.format(version=pkg_version)
ret[self._config_version_filename(pkg_filename)] = config_version
if not cpp_info.components:
# If any config matches the build_type one, add it to the cpp_info
dep_cpp_info = extend(cpp_info, build_type.lower())
deps = DepsCppCmake(dep_cpp_info, self.name)
variables = {
"{name}-{build_type}-{arch}-data.cmake".format(name=pkg_filename,
build_type=self.configuration.lower(),
arch=self.arch):
variables_template.format(name=pkg_findname, deps=deps,
build_type_suffix=build_type_suffix)
}
dynamic_variables = {
"{}Target-{}.cmake".format(pkg_filename, self.configuration.lower()):
dynamic_variables_template.format(name=pkg_findname, deps=deps,
build_type_suffix=build_type_suffix,
deps_names=deps_names)
}
ret.update(variables)
ret.update(dynamic_variables)
ret[self._config_filename(pkg_filename)] = self._config(
filename=pkg_filename,
name=pkg_findname,
Expand All @@ -671,32 +695,34 @@ def content(self):
)
ret["{}Targets.cmake".format(pkg_filename)] = self.targets_template.format(
filename=pkg_filename, name=pkg_findname)

# If any config matches the build_type one, add it to the cpp_info
dep_cpp_info = extend(cpp_info, build_type.lower())
deps = DepsCppCmake(dep_cpp_info, self.name)
find_lib = target_template.format(name=pkg_findname, deps=deps,
build_type_suffix=build_type_suffix,
deps_names=deps_names)
ret["{}Target-{}.cmake".format(pkg_filename, self.configuration.lower())] = find_lib
else:
cpp_info = extend(cpp_info, build_type.lower())
pkg_info = DepsCppCmake(cpp_info, self.name)
components = self._get_components(pkg_name, cpp_info)
# Note these are in reversed order, from more dependent to less dependent
pkg_components = " ".join(["{p}::{c}".format(p=pkg_findname, c=comp_findname) for
comp_findname, _ in reversed(components)])
global_target_variables = target_template.format(name=pkg_findname, deps=pkg_info,
build_type_suffix=build_type_suffix,
deps_names=deps_names)
variables = self.components_target_build_type_tpl.render(
pkg_name=pkg_findname,
global_target_variables=global_target_variables,
pkg_components=pkg_components,
build_type=build_type,
components=components
)
ret["{}Target-{}.cmake".format(pkg_filename, build_type.lower())] = variables
global_variables = variables_template.format(name=pkg_findname, deps=pkg_info,
build_type_suffix=build_type_suffix,
deps_names=deps_names)
variables = {
"{}-{}-{}-data.cmake".format(pkg_filename, build_type.lower(), self.arch):
self.components_variables_tpl.render(
pkg_name=pkg_findname, global_variables=global_variables,
pkg_components=pkg_components, build_type=build_type, components=components)
}
ret.update(variables)
global_dynamic_variables = dynamic_variables_template.format(name=pkg_findname,
deps=pkg_info,
build_type_suffix=build_type_suffix,
deps_names=deps_names)
dynamic_variables = {
"{}Target-{}.cmake".format(pkg_filename, build_type.lower()):
self.components_dynamic_variables_tpl.render(
pkg_name=pkg_findname, global_dynamic_variables=global_dynamic_variables,
pkg_components=pkg_components, build_type=build_type, components=components)
}
ret.update(dynamic_variables)
targets = self.components_targets_tpl.render(
pkg_name=pkg_findname,
pkg_filename=pkg_filename,
Expand Down
11 changes: 9 additions & 2 deletions conans/test/unittests/tools/cmake/test_cmakedeps.py
Expand Up @@ -17,6 +17,8 @@ def test_cpp_info_name_cmakedeps():
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["x86"]}), EnvValues())
conanfile.settings.build_type = "Release"
conanfile.settings.arch = "x86"

cpp_info = CppInfo("mypkg", "dummy_root_folder1")
cpp_info.names["cmake_find_package_multi"] = "MySuperPkg1"
Expand All @@ -26,6 +28,7 @@ def test_cpp_info_name_cmakedeps():
cmakedeps = CMakeDeps(conanfile)
files = cmakedeps.content
assert "TARGET MySuperPkg1::MySuperPkg1" in files["ComplexFileName1Config.cmake"]
assert "set(MySuperPkg1_INCLUDE_DIRS_RELEASE )" in files["ComplexFileName1-release-x86-data.cmake"]

with pytest.raises(ConanException,
match="'mypkg' defines information for 'cmake_find_package_multi'"):
Expand All @@ -38,8 +41,10 @@ def test_cpp_info_name_cmakedeps_components():
conanfile.settings = "os", "compiler", "build_type", "arch"
conanfile.initialize(Settings({"os": ["Windows"],
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["x86"]}), EnvValues())
"build_type": ["Release", "Debug"],
"arch": ["x86", "x64"]}), EnvValues())
conanfile.settings.build_type = "Debug"
conanfile.settings.arch = "x64"

cpp_info = CppInfo("mypkg", "dummy_root_folder1")
cpp_info.names["cmake_find_package_multi"] = "GlobakPkgName1"
Expand All @@ -50,6 +55,8 @@ def test_cpp_info_name_cmakedeps_components():
cmakedeps = CMakeDeps(conanfile)
files = cmakedeps.content
assert "TARGET GlobakPkgName1::MySuperPkg1" in files["ComplexFileName1Config.cmake"]
assert "set(GlobakPkgName1_INCLUDE_DIRS_DEBUG )" in files["ComplexFileName1-debug-x64-data.cmake"]
assert "set(GlobakPkgName1_MySuperPkg1_INCLUDE_DIRS_DEBUG )" in files["ComplexFileName1-debug-x64-data.cmake"]

with pytest.raises(ConanException,
match="'mypkg' defines information for 'cmake_find_package_multi'"):
Expand Down

0 comments on commit 9d955bf

Please sign in to comment.