From 6a0cce969fa39ad2294a2eeb7975041218677597 Mon Sep 17 00:00:00 2001 From: czoido Date: Mon, 20 Jun 2022 16:19:17 +0200 Subject: [PATCH 01/19] wip --- conan/tools/apple/xcodedeps.py | 65 ++++++++++------------------------ 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 2cc64fbe6e6..56aef019f9c 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -59,36 +59,17 @@ def _add_includes_to_file_or_create(filename, template, files_to_include): class XcodeDeps(object): general_name = "conandeps.xcconfig" - _vars_xconfig = textwrap.dedent("""\ - // Definition of Conan variables for {{pkg_name}}::{{comp_name}} - CONAN_{{pkg_name}}_{{comp_name}}_BINARY_DIRECTORIES{{condition}} = {{bin_dirs}} - CONAN_{{pkg_name}}_{{comp_name}}_C_COMPILER_FLAGS{{condition}} = {{c_compiler_flags}} - CONAN_{{pkg_name}}_{{comp_name}}_CXX_COMPILER_FLAGS{{condition}} = {{cxx_compiler_flags}} - CONAN_{{pkg_name}}_{{comp_name}}_LINKER_FLAGS{{condition}} = {{linker_flags}} - CONAN_{{pkg_name}}_{{comp_name}}_PREPROCESSOR_DEFINITIONS{{condition}} = {{definitions}} - CONAN_{{pkg_name}}_{{comp_name}}_INCLUDE_DIRECTORIES{{condition}} = {{include_dirs}} - CONAN_{{pkg_name}}_{{comp_name}}_RESOURCE_DIRECTORIES{{condition}} = {{res_dirs}} - CONAN_{{pkg_name}}_{{comp_name}}_LIBRARY_DIRECTORIES{{condition}} = {{lib_dirs}} - CONAN_{{pkg_name}}_{{comp_name}}_LIBRARIES{{condition}} = {{libs}} - CONAN_{{pkg_name}}_{{comp_name}}_SYSTEM_LIBS{{condition}} = {{system_libs}} - CONAN_{{pkg_name}}_{{comp_name}}_FRAMEWORKS_DIRECTORIES{{condition}} = {{frameworkdirs}} - CONAN_{{pkg_name}}_{{comp_name}}_FRAMEWORKS{{condition}} = {{frameworks}} - """) - _conf_xconfig = textwrap.dedent("""\ - // Include {{pkg_name}}::{{comp_name}} vars - #include "{{vars_filename}}" - // Compiler options for {{pkg_name}}::{{pkg_name}} - HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_INCLUDE_DIRECTORIES) - GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_PREPROCESSOR_DEFINITIONS) - OTHER_CFLAGS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_C_COMPILER_FLAGS) - OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_CXX_COMPILER_FLAGS) - FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_FRAMEWORKS_DIRECTORIES) + HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{include_dirs}} + GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}{{condition}} = {{definitions}} + OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{c_compiler_flags}} + OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{cxx_compiler_flags}} + FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{frameworkdirs}} // Link options for {{name}} - LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_LIBRARY_DIRECTORIES) - OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}} = $(CONAN_{{pkg_name}}_{{comp_name}}_LINKER_FLAGS) $(CONAN_{{pkg_name}}_{{comp_name}}_LIBRARIES) $(CONAN_{{pkg_name}}_{{comp_name}}_SYSTEM_LIBS) $(CONAN_{{pkg_name}}_{{comp_name}}_FRAMEWORKS) + LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{lib_dirs}} + OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{linker_flags}} {{libs}} {{system_libs}} {{frameworks}} """) _dep_xconfig = textwrap.dedent("""\ @@ -100,15 +81,15 @@ class XcodeDeps(object): {% endfor %} #include "{{dep_xconfig_filename}}" - HEADER_SEARCH_PATHS = $(inherited) $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) - GCC_PREPROCESSOR_DEFINITIONS = $(inherited) $(GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}) - OTHER_CFLAGS = $(inherited) $(OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}) - OTHER_CPLUSPLUSFLAGS = $(inherited) $(OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}) - FRAMEWORK_SEARCH_PATHS = $(inherited) $(FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}) + OTHER_CFLAGS = $(OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}) + OTHER_CPLUSPLUSFLAGS = $(OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}) + FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) // Link options for {{pkg_name}}_{{comp_name}} - LIBRARY_SEARCH_PATHS = $(inherited) $(LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) - OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}) + LIBRARY_SEARCH_PATHS = $(LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + OTHER_LDFLAGS = $(OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}) """) _all_xconfig = textwrap.dedent("""\ @@ -140,9 +121,9 @@ def generate(self): for generator_file, content in generator_files.items(): save(generator_file, content) - def _vars_xconfig_file(self, pkg_name, comp_name, cpp_info): + def _conf_xconfig_file(self, pkg_name, comp_name, cpp_info): """ - returns a .xcconfig file with the variables definition for one package for one configuration + content for conan_poco_x86_release.xcconfig, containing the activation """ fields = { @@ -163,16 +144,9 @@ def _vars_xconfig_file(self, pkg_name, comp_name, cpp_info): 'exe_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.exelinkflags), 'condition': _xcconfig_conditional(self._conanfile.settings) } - formatted_template = Template(self._vars_xconfig).render(**fields) - return formatted_template - def _conf_xconfig_file(self, pkg_name, comp_name, vars_xconfig_name): - """ - content for conan_poco_x86_release.xcconfig, containing the activation - """ template = Template(self._conf_xconfig) - content_multi = template.render(pkg_name=pkg_name, comp_name=comp_name, - vars_filename=vars_xconfig_name) + content_multi = template.render(**fields) return content_multi def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filename, reqs): @@ -225,12 +199,9 @@ def get_content_for_component(self, pkg_name, component_name, cpp_info, reqs): result = {} conf_name = _xcconfig_settings_filename(self._conanfile.settings) - # One file per configuration, with just the variables - vars_xconfig_name = "conan_{}_{}_vars{}.xcconfig".format(pkg_name, component_name, conf_name) - result[vars_xconfig_name] = self._vars_xconfig_file(pkg_name, component_name, cpp_info) props_name = "conan_{}_{}{}.xcconfig".format(pkg_name, component_name, conf_name) - result[props_name] = self._conf_xconfig_file(pkg_name, component_name, vars_xconfig_name) + result[props_name] = self._conf_xconfig_file(pkg_name, component_name, cpp_info) # The entry point for each package file_dep_name = "conan_{}_{}.xcconfig".format(pkg_name, component_name) From 503b300958ab0596ba2b8533d85192bcc452281d Mon Sep 17 00:00:00 2001 From: czoido Date: Mon, 20 Jun 2022 16:40:05 +0200 Subject: [PATCH 02/19] wip --- conan/tools/apple/xcodedeps.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 56aef019f9c..b6bc4b67325 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -81,15 +81,15 @@ class XcodeDeps(object): {% endfor %} #include "{{dep_xconfig_filename}}" - HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) - GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}) - OTHER_CFLAGS = $(OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}) - OTHER_CPLUSPLUSFLAGS = $(OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}) - FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + HEADER_SEARCH_PATHS = $(inherited) $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + GCC_PREPROCESSOR_DEFINITIONS = $(inherited) $(GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}) + OTHER_CFLAGS = $(inherited) $(OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}) + OTHER_CPLUSPLUSFLAGS = $(inherited) $(OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}) + FRAMEWORK_SEARCH_PATHS = $(inherited) $(FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) // Link options for {{pkg_name}}_{{comp_name}} - LIBRARY_SEARCH_PATHS = $(LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) - OTHER_LDFLAGS = $(OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}) + LIBRARY_SEARCH_PATHS = $(inherited) $(LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) + OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}) """) _all_xconfig = textwrap.dedent("""\ From 4522575eda5723c062da3bcf18f051ac1d395168 Mon Sep 17 00:00:00 2001 From: czoido Date: Mon, 20 Jun 2022 16:45:56 +0200 Subject: [PATCH 03/19] fix tests --- .../functional/toolchains/apple/test_xcodedeps_build_configs.py | 2 +- .../functional/toolchains/apple/test_xcodedeps_components.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_build_configs.py b/conans/test/functional/toolchains/apple/test_xcodedeps_build_configs.py index 93f89b95d11..7ff37ff78df 100644 --- a/conans/test/functional/toolchains/apple/test_xcodedeps_build_configs.py +++ b/conans/test/functional/toolchains/apple/test_xcodedeps_build_configs.py @@ -114,7 +114,7 @@ def test_xcodedeps_dashes_names_and_arch(): "project.yml": xcode_project}, clean_first=True) client.run("install . -s arch=armv8 --build=missing -g XcodeDeps") assert os.path.exists(os.path.join(client.current_folder, - "conan_hello_dashes_hello_dashes_vars_release_arm64.xcconfig")) + "conan_hello_dashes_hello_dashes_release_arm64.xcconfig")) client.run_command("xcodegen generate") client.run_command("xcodebuild -project app.xcodeproj -arch arm64") assert "BUILD SUCCEEDED" in client.out diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py index 397b3d1fbc4..4ccd40f286d 100644 --- a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py +++ b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py @@ -225,5 +225,4 @@ def build_requirements(self): assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest.xcconfig")) assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest_gtest.xcconfig")) assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest_gtest_release_x86_64.xcconfig")) - assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest_gtest_vars_release_x86_64.xcconfig")) assert '#include "conan_gtest.xcconfig"' in client.load("conandeps.xcconfig") From 998cc15525b41fda7835f227f8f02fe77c8b45bd Mon Sep 17 00:00:00 2001 From: czoido Date: Mon, 20 Jun 2022 16:54:01 +0200 Subject: [PATCH 04/19] update test --- .../toolchains/apple/test_xcodedeps.py | 43 ++++--------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index a992463a779..1a5ddb5f430 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -17,30 +17,14 @@ "OTHER_LDFLAGS = $(inherited) $(OTHER_LDFLAGS_{name}_{name})", ] -_expected_vars_xconfig = [ - "CONAN_{name}_{name}_BINARY_DIRECTORIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_C_COMPILER_FLAGS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_CXX_COMPILER_FLAGS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_LINKER_FLAGS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_PREPROCESSOR_DEFINITIONS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_INCLUDE_DIRECTORIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_RESOURCE_DIRECTORIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_LIBRARY_DIRECTORIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_LIBRARIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = -l{name}", - "CONAN_{name}_{name}_SYSTEM_LIBS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_FRAMEWORKS_DIRECTORIES[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] =", - "CONAN_{name}_{name}_FRAMEWORKS[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = -framework framework_{name}" -] - _expected_conf_xconfig = [ - "#include \"{vars_name}\"", - "HEADER_SEARCH_PATHS_{name}_{name} = $(CONAN_{name}_{name}_INCLUDE_DIRECTORIES", - "GCC_PREPROCESSOR_DEFINITIONS_{name}_{name} = $(CONAN_{name}_{name}_PREPROCESSOR_DEFINITIONS", - "OTHER_CFLAGS_{name}_{name} = $(CONAN_{name}_{name}_C_COMPILER_FLAGS", - "OTHER_CPLUSPLUSFLAGS_{name}_{name} = $(CONAN_{name}_{name}_CXX_COMPILER_FLAGS", - "FRAMEWORK_SEARCH_PATHS_{name}_{name} = $(CONAN_{name}_{name}_FRAMEWORKS_DIRECTORIES", - "LIBRARY_SEARCH_PATHS_{name}_{name} = $(CONAN_{name}_{name}_LIBRARY_DIRECTORIES", - "OTHER_LDFLAGS_{name}_{name} = $(CONAN_{name}_{name}_LINKER_FLAGS) $(CONAN_{name}_{name}_LIBRARIES) $(CONAN_{name}_{name}_SYSTEM_LIBS) $(CONAN_{name}_{name}_FRAMEWORKS" + "HEADER_SEARCH_PATHS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "GCC_PREPROCESSOR_DEFINITIONS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "OTHER_CFLAGS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "OTHER_CPLUSPLUSFLAGS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "FRAMEWORK_SEARCH_PATHS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "LIBRARY_SEARCH_PATHS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = ", + "OTHER_LDFLAGS_{name}_{name}[config={configuration}][arch={architecture}][sdk={sdk}{sdk_version}] = " ] @@ -50,8 +34,6 @@ def expected_files(current_folder, configuration, architecture, sdk, sdk_version deps = ["hello", "goodbye"] files.extend( [os.path.join(current_folder, "conan_{dep}_{dep}{name}.xcconfig".format(dep=dep, name=name)) for dep in deps]) - files.extend( - [os.path.join(current_folder, "conan_{dep}_{dep}_vars{name}.xcconfig".format(dep=dep, name=name)) for dep in deps]) files.append(os.path.join(current_folder, "conandeps.xcconfig")) return files @@ -67,17 +49,10 @@ def check_contents(client, deps, configuration, architecture, sdk, sdk_version): line = var.format(name=dep_name) assert line in dep_xconfig - vars_name = "conan_{}_{}_vars{}.xcconfig".format(dep_name, dep_name, - _get_filename(configuration, architecture, sdk, sdk_version)) - conan_vars = client.load(vars_name) - for var in _expected_vars_xconfig: - line = var.format(name=dep_name, configuration=configuration, architecture=architecture, - sdk=sdk, sdk_version=sdk_version) - assert line in conan_vars - conan_conf = client.load(conf_name) for var in _expected_conf_xconfig: - assert var.format(vars_name=vars_name, name=dep_name) in conan_conf + assert var.format(name=dep_name, configuration=configuration, architecture=architecture, + sdk=sdk, sdk_version=sdk_version) in conan_conf @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") From 708f8da6770d9d18833df7aa81ed991a14e57156 Mon Sep 17 00:00:00 2001 From: czoido Date: Mon, 20 Jun 2022 17:19:51 +0200 Subject: [PATCH 05/19] add test --- .../toolchains/apple/test_xcodedeps.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index 1a5ddb5f430..fdc9a1a63ec 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -1,5 +1,6 @@ import os import platform +import textwrap import pytest @@ -85,3 +86,47 @@ def test_generator_files(): assert '#include "conandeps.xcconfig"' in conan_config check_contents(client, ["hello", "goodbye"], build_type, "x86_64", "macosx", "12.1") + + +@pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") +def test_xcodedeps_aggregate_components(): + client = TestClient() + + conanfile_py = textwrap.dedent(""" + from conan import ConanFile + class LibConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + def package_info(self): + self.cpp_info.components["liba_comp1"].includedirs = ["liba_comp1"] + """) + + client.save({"conanfile.py": conanfile_py}) + + client.run("create . liba/1.0@") + + conanfile_py = textwrap.dedent(""" + from conan import ConanFile + class LibConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + requires = "liba/1.0" + def package_info(self): + self.cpp_info.components["libb_comp1"].includedirs = ["libb_comp1"] + self.cpp_info.components["libb_comp2"].includedirs = ["libb_comp2"] + self.cpp_info.components["libb_comp2"].requires = ["libb_comp1"] + self.cpp_info.components["libb_comp3"].includedirs = ["libb_comp3"] + self.cpp_info.components["libb_comp3"].requires = ["libb_comp1", "liba::liba_comp1"] + self.cpp_info.components["libb_comp4"].includedirs = ["libb_comp4"] + self.cpp_info.components["libb_comp4"].requires = ["libb_comp2", "libb_comp3"] + self.cpp_info.components["libb_comp5"].includedirs = ["libb_comp5"] + self.cpp_info.components["libb_comp6"].includedirs = ["libb_comp6"] + self.cpp_info.components["libb_comp7"].includedirs = ["libb_comp7"] + self.cpp_info.components["libb_comp7"].requires = ["libb_comp4", "libb_comp5", "libb_comp6"] + """) + + client.save({"conanfile.py": conanfile_py}) + + client.run("create . libb/1.0@") + + client.run("install libb/1.0@ -g XcodeDeps") + + print(client.out) From 1956598bc638359f223d0e546859518b520bc9b0 Mon Sep 17 00:00:00 2001 From: czoido Date: Tue, 21 Jun 2022 17:13:46 +0200 Subject: [PATCH 06/19] wip --- conan/tools/apple/xcodedeps.py | 105 +++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 32 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index b6bc4b67325..a9d51c2ec03 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -1,5 +1,6 @@ import os import textwrap +from collections import OrderedDict from jinja2 import Template @@ -75,10 +76,7 @@ class XcodeDeps(object): _dep_xconfig = textwrap.dedent("""\ // Conan XcodeDeps generated file for {{pkg_name}}::{{comp_name}} // Includes all configurations for each dependency - {% for dep in deps %} - // Includes for {{dep[0]}}::{{dep[1]}} dependency - #include "conan_{{dep[0]}}_{{dep[1]}}.xcconfig" - {% endfor %} + #include "{{dep_xconfig_filename}}" HEADER_SEARCH_PATHS = $(inherited) $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) @@ -121,27 +119,30 @@ def generate(self): for generator_file, content in generator_files.items(): save(generator_file, content) - def _conf_xconfig_file(self, pkg_name, comp_name, cpp_info): + def _conf_xconfig_file(self, pkg_name, comp_name, transitive_cpp_infos): """ content for conan_poco_x86_release.xcconfig, containing the activation """ + def _merged_vars(name): + merged = [bindir for cpp_info in transitive_cpp_infos for bindir in getattr(cpp_info, name)] + return list(OrderedDict.fromkeys(merged).keys()) fields = { 'pkg_name': pkg_name, 'comp_name': comp_name, - 'bin_dirs': " ".join('"{}"'.format(p) for p in cpp_info.bindirs), - 'res_dirs': " ".join('"{}"'.format(p) for p in cpp_info.resdirs), - 'include_dirs': " ".join('"{}"'.format(p) for p in cpp_info.includedirs), - 'lib_dirs': " ".join('"{}"'.format(p) for p in cpp_info.libdirs), - 'libs': " ".join("-l{}".format(lib) for lib in cpp_info.libs), - 'system_libs': " ".join("-l{}".format(sys_lib) for sys_lib in cpp_info.system_libs), - 'frameworksdirs': " ".join('"{}"'.format(p) for p in cpp_info.frameworkdirs), - 'frameworks': " ".join("-framework {}".format(framework) for framework in cpp_info.frameworks), - 'definitions': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.defines), - 'c_compiler_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.cflags), - 'cxx_compiler_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.cxxflags), - 'linker_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.sharedlinkflags), - 'exe_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in cpp_info.exelinkflags), + 'bin_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("bindirs")), + 'res_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("resdirs")), + 'include_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("includedirs")), + 'lib_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("libdirs")), + 'libs': " ".join("-l{}".format(lib) for lib in _merged_vars("libs")), + 'system_libs': " ".join("-l{}".format(sys_lib) for sys_lib in _merged_vars("system_libs")), + 'frameworksdirs': " ".join('"{}"'.format(p) for p in _merged_vars("frameworkdirs")), + 'frameworks': " ".join("-framework {}".format(framework) for framework in _merged_vars("frameworks")), + 'definitions': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in _merged_vars("defines")), + 'c_compiler_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in _merged_vars("cflags")), + 'cxx_compiler_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in _merged_vars("cxxflags")), + 'linker_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in _merged_vars("sharedlinkflags")), + 'exe_flags': " ".join('"{}"'.format(p.replace('"', '\\"')) for p in _merged_vars("exelinkflags")), 'condition': _xcconfig_conditional(self._conanfile.settings) } @@ -149,7 +150,7 @@ def _conf_xconfig_file(self, pkg_name, comp_name, cpp_info): content_multi = template.render(**fields) return content_multi - def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filename, reqs): + def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filename): # Current directory is the generators_folder multi_path = name_general if os.path.isfile(multi_path): @@ -158,8 +159,7 @@ def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filen content_multi = self._dep_xconfig content_multi = Template(content_multi).render({"pkg_name": pkg_name, "comp_name": comp_name, - "dep_xconfig_filename": dep_xconfig_filename, - "deps": reqs}) + "dep_xconfig_filename": dep_xconfig_filename}) if dep_xconfig_filename not in content_multi: content_multi = content_multi.replace('.xcconfig"', @@ -210,27 +210,68 @@ def get_content_for_component(self, pkg_name, component_name, cpp_info, reqs): result[file_dep_name] = dep_content return result + def _new_get_content_for_component(self, pkg_name, transitives): + result = {} + + conf_name = _xcconfig_settings_filename(self._conanfile.settings) + + props_name = "conan_{}_{}{}.xcconfig".format(pkg_name, transitives[0].name, conf_name) + result[props_name] = self._conf_xconfig_file(pkg_name, transitives[0].name, transitives) + + # The entry point for each package + file_dep_name = "conan_{}_{}.xcconfig".format(pkg_name, transitives[0].name) + dep_content = self._dep_xconfig_file(pkg_name, transitives[0].name, file_dep_name, props_name) + + result[file_dep_name] = dep_content + return result + def _content(self): result = {} # Generate the config files for each component with name conan_pkgname_compname.xcconfig # If a package has no components the name is conan_pkgname_pkgname.xcconfig # Then all components are included in the conan_pkgname.xcconfig file - host_req = self._conanfile.dependencies.host - test_req = self._conanfile.dependencies.test - for dep in list(host_req.values()) + list(test_req.values()): + for dep in list(self._conanfile.dependencies.host.values()) + \ + list(self._conanfile.dependencies.test.values()): + dep_name = _format_name(dep.ref.name) include_components_names = [] if dep.cpp_info.has_components: - for comp_name, comp_cpp_info in dep.cpp_info.get_sorted_components().items(): - component_deps = [] - for req in comp_cpp_info.requires: - req_pkg, req_cmp = req.split("::") if "::" in req else (dep_name, req) - component_deps.append((req_pkg, req_cmp)) - - component_content = self.get_content_for_component(dep_name, comp_name, comp_cpp_info, component_deps) - include_components_names.append((dep_name, comp_name)) + # for each component get the list of cpp_infos for the required components to + # later aggregate all variables in one file + sorted_components = dep.cpp_info.get_sorted_components().items() + for comp_name, comp_cpp_info in sorted_components: + + def _get_component_requires(component): + requires = [] + for req in component.requires: + req_pkg, req_cmp = req.split("::") if "::" in req else (dep_name, req) + pkg = self._conanfile.dependencies.host.get(req_pkg) or self._conanfile.dependencies.test.get(req_pkg) + requires.append(pkg.cpp_info.components.get(req_cmp)) + return requires + + transitive = [] + + def _transitive_deps(component): + print("--->", component, transitive) + if component is not None: + print("@@@@@>", component) + requires = _get_component_requires(component) + print(component) + transitive.append(component) + if requires is not None: + transitive.extend(requires) + for require in requires: + print(component.name, require) + _transitive_deps(require) + return transitive + + transitives = _transitive_deps(comp_cpp_info) + print(comp_name, "-----", transitives) + # remove duplicates + transitives = list(OrderedDict.fromkeys(transitives).keys()) + component_content = self._new_get_content_for_component(dep_name, transitives) result.update(component_content) else: public_deps = [(_format_name(d.ref.name),) * 2 for r, d in From 498c351624d8081d90d5f70bb384eb6e4c52be40 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 08:36:34 +0200 Subject: [PATCH 07/19] wip --- conan/tools/apple/xcodedeps.py | 14 ++++++++++++++ .../integration/toolchains/apple/test_xcodedeps.py | 2 ++ 2 files changed, 16 insertions(+) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index a9d51c2ec03..88c48f41124 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -246,6 +246,10 @@ def _content(self): def _get_component_requires(component): requires = [] for req in component.requires: + if "libbacktrace::libbacktrace" in component.requires: + print("sdasdasda") + print("sdasdasda") + print("sdasdasda") req_pkg, req_cmp = req.split("::") if "::" in req else (dep_name, req) pkg = self._conanfile.dependencies.host.get(req_pkg) or self._conanfile.dependencies.test.get(req_pkg) requires.append(pkg.cpp_info.components.get(req_cmp)) @@ -255,12 +259,22 @@ def _get_component_requires(component): def _transitive_deps(component): print("--->", component, transitive) + if None in transitive: + print("dasdasda") + print("dasdasda") + print("dasdasda") + print("dasdasda") if component is not None: print("@@@@@>", component) requires = _get_component_requires(component) print(component) transitive.append(component) if requires is not None: + # THE PROBLEM IS LIBBACKTRACE:: + if None in requires: + print("dasdasda") + print("dasdasda") + print("dasdasda") transitive.extend(requires) for require in requires: print(component.name, require) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index fdc9a1a63ec..e93f49bc726 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -91,6 +91,8 @@ def test_generator_files(): @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") def test_xcodedeps_aggregate_components(): client = TestClient() + client.cache_folder = "/Users/carlosz/.conan" + client.run("install boost/1.79.0@ --install-folder=generators -g XcodeDeps -s build_type=Debug") conanfile_py = textwrap.dedent(""" from conan import ConanFile From 019d252e808e1bdc64a87e758e83c1305a4838e4 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 11:28:55 +0200 Subject: [PATCH 08/19] wip --- conan/tools/apple/xcodedeps.py | 46 +++++++++++++--------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 88c48f41124..c1cf3bc80b0 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -124,6 +124,9 @@ def _conf_xconfig_file(self, pkg_name, comp_name, transitive_cpp_infos): content for conan_poco_x86_release.xcconfig, containing the activation """ def _merged_vars(name): + if "zlib" in pkg_name: + print("sdasdaasdasada") + print(pkg_name, comp_name) merged = [bindir for cpp_info in transitive_cpp_infos for bindir in getattr(cpp_info, name)] return list(OrderedDict.fromkeys(merged).keys()) @@ -246,43 +249,28 @@ def _content(self): def _get_component_requires(component): requires = [] for req in component.requires: - if "libbacktrace::libbacktrace" in component.requires: - print("sdasdasda") - print("sdasdasda") - print("sdasdasda") req_pkg, req_cmp = req.split("::") if "::" in req else (dep_name, req) pkg = self._conanfile.dependencies.host.get(req_pkg) or self._conanfile.dependencies.test.get(req_pkg) - requires.append(pkg.cpp_info.components.get(req_cmp)) + req_cpp_info = pkg.cpp_info.components.get(req_cmp) if pkg.cpp_info.has_components else pkg.cpp_info.components[None] + if not pkg.cpp_info.has_components: + print("sdasdasda") + requires.append(req_cpp_info) return requires transitive = [] - def _transitive_deps(component): - print("--->", component, transitive) - if None in transitive: - print("dasdasda") - print("dasdasda") - print("dasdasda") - print("dasdasda") - if component is not None: - print("@@@@@>", component) - requires = _get_component_requires(component) - print(component) - transitive.append(component) - if requires is not None: - # THE PROBLEM IS LIBBACKTRACE:: - if None in requires: - print("dasdasda") - print("dasdasda") - print("dasdasda") - transitive.extend(requires) - for require in requires: - print(component.name, require) - _transitive_deps(require) + # return just the transitive components inside the library + # the components required from other direct requirements are + # handled including the files, not aggregated + def _transitive_internal_components(component): + requires = _get_component_requires(component) + transitive.append(component) + transitive.extend(requires) + for require in requires: + _transitive_internal_components(require) return transitive - transitives = _transitive_deps(comp_cpp_info) - print(comp_name, "-----", transitives) + transitives = _transitive_internal_components(comp_cpp_info) # remove duplicates transitives = list(OrderedDict.fromkeys(transitives).keys()) component_content = self._new_get_content_for_component(dep_name, transitives) From 6594bf3bb1bd5df28657e374094945b5fde68217 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 13:29:59 +0200 Subject: [PATCH 09/19] wip --- conan/tools/apple/xcodedeps.py | 89 ++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index c1cf3bc80b0..3d26b50b107 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -76,7 +76,10 @@ class XcodeDeps(object): _dep_xconfig = textwrap.dedent("""\ // Conan XcodeDeps generated file for {{pkg_name}}::{{comp_name}} // Includes all configurations for each dependency - + {% for dep in deps %} + // Includes for {{dep[0]}}::{{dep[1]}} dependency + #include "conan_{{dep[0]}}_{{dep[1]}}.xcconfig" + {% endfor %} #include "{{dep_xconfig_filename}}" HEADER_SEARCH_PATHS = $(inherited) $(HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}) @@ -124,9 +127,6 @@ def _conf_xconfig_file(self, pkg_name, comp_name, transitive_cpp_infos): content for conan_poco_x86_release.xcconfig, containing the activation """ def _merged_vars(name): - if "zlib" in pkg_name: - print("sdasdaasdasada") - print(pkg_name, comp_name) merged = [bindir for cpp_info in transitive_cpp_infos for bindir in getattr(cpp_info, name)] return list(OrderedDict.fromkeys(merged).keys()) @@ -153,7 +153,7 @@ def _merged_vars(name): content_multi = template.render(**fields) return content_multi - def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filename): + def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filename, reqs): # Current directory is the generators_folder multi_path = name_general if os.path.isfile(multi_path): @@ -162,7 +162,8 @@ def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filen content_multi = self._dep_xconfig content_multi = Template(content_multi).render({"pkg_name": pkg_name, "comp_name": comp_name, - "dep_xconfig_filename": dep_xconfig_filename}) + "dep_xconfig_filename": dep_xconfig_filename, + "deps": reqs}) if dep_xconfig_filename not in content_multi: content_multi = content_multi.replace('.xcconfig"', @@ -213,17 +214,17 @@ def get_content_for_component(self, pkg_name, component_name, cpp_info, reqs): result[file_dep_name] = dep_content return result - def _new_get_content_for_component(self, pkg_name, transitives): + def _new_get_content_for_component(self, pkg_name, component_name, transitive_internal, transitive_external): result = {} conf_name = _xcconfig_settings_filename(self._conanfile.settings) - props_name = "conan_{}_{}{}.xcconfig".format(pkg_name, transitives[0].name, conf_name) - result[props_name] = self._conf_xconfig_file(pkg_name, transitives[0].name, transitives) + props_name = "conan_{}_{}{}.xcconfig".format(pkg_name, component_name, conf_name) + result[props_name] = self._conf_xconfig_file(pkg_name, component_name, transitive_internal) # The entry point for each package - file_dep_name = "conan_{}_{}.xcconfig".format(pkg_name, transitives[0].name) - dep_content = self._dep_xconfig_file(pkg_name, transitives[0].name, file_dep_name, props_name) + file_dep_name = "conan_{}_{}.xcconfig".format(pkg_name, component_name) + dep_content = self._dep_xconfig_file(pkg_name, component_name, file_dep_name, props_name, transitive_external) result[file_dep_name] = dep_content return result @@ -247,41 +248,45 @@ def _content(self): for comp_name, comp_cpp_info in sorted_components: def _get_component_requires(component): - requires = [] + requires_external = [] + requires_internal = [] for req in component.requires: - req_pkg, req_cmp = req.split("::") if "::" in req else (dep_name, req) - pkg = self._conanfile.dependencies.host.get(req_pkg) or self._conanfile.dependencies.test.get(req_pkg) - req_cpp_info = pkg.cpp_info.components.get(req_cmp) if pkg.cpp_info.has_components else pkg.cpp_info.components[None] - if not pkg.cpp_info.has_components: - print("sdasdasda") - requires.append(req_cpp_info) - return requires - - transitive = [] - - # return just the transitive components inside the library - # the components required from other direct requirements are - # handled including the files, not aggregated - def _transitive_internal_components(component): - requires = _get_component_requires(component) - transitive.append(component) - transitive.extend(requires) - for require in requires: - _transitive_internal_components(require) - return transitive - - transitives = _transitive_internal_components(comp_cpp_info) + if "::" in req: + requires_external.append((req.split("::")[0], req.split("::")[1])) + else: + pkg = self._conanfile.dependencies.host.get(dep_name) or self._conanfile.dependencies.test.get(dep_name) + req_cpp_info = pkg.cpp_info.components.get(req) + requires_internal.append(req_cpp_info) + return requires_internal, requires_external + + transitive_internal = [] + transitive_external = [] + + # return the internal and external components separated + def _transitive_components(component): + requires_internal, requires_external = _get_component_requires(component) + transitive_internal.append(component) + transitive_internal.extend(requires_internal) + transitive_external.extend(requires_external) + for require in requires_internal: + _transitive_components(require) + return transitive_internal, transitive_external + transitive_internal, transitive_external = _transitive_components(comp_cpp_info) + # remove duplicates - transitives = list(OrderedDict.fromkeys(transitives).keys()) - component_content = self._new_get_content_for_component(dep_name, transitives) + transitive_internal = list(OrderedDict.fromkeys(transitive_internal).keys()) + transitive_external = list(OrderedDict.fromkeys(transitive_external).keys()) + + component_content = self._new_get_content_for_component(dep_name, comp_name, transitive_internal, transitive_external) result.update(component_content) else: - public_deps = [(_format_name(d.ref.name),) * 2 for r, d in - dep.dependencies.direct_host.items() if r.visible] - required_components = dep.cpp_info.required_components if dep.cpp_info.required_components else public_deps - root_content = self.get_content_for_component(dep_name, dep_name, dep.cpp_info, required_components) - include_components_names.append((dep_name, dep_name)) - result.update(root_content) + pass # FIXME + # public_deps = [(_format_name(d.ref.name),) * 2 for r, d in + # dep.dependencies.direct_host.items() if r.visible] + # required_components = dep.cpp_info.required_components if dep.cpp_info.required_components else public_deps + # root_content = self.get_content_for_component(dep_name, dep_name, dep.cpp_info, required_components) + # include_components_names.append((dep_name, dep_name)) + # result.update(root_content) result["conan_{}.xcconfig".format(dep_name)] = self._pkg_xconfig_file(include_components_names) From 9462712ca168bee025fcdaa23ffa3550a74cfb1b Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 15:30:16 +0200 Subject: [PATCH 10/19] wip --- conan/tools/apple/xcodedeps.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 3d26b50b107..4d8118af632 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -235,8 +235,9 @@ def _content(self): # Generate the config files for each component with name conan_pkgname_compname.xcconfig # If a package has no components the name is conan_pkgname_pkgname.xcconfig # Then all components are included in the conan_pkgname.xcconfig file - for dep in list(self._conanfile.dependencies.host.values()) + \ - list(self._conanfile.dependencies.test.values()): + host_req = self._conanfile.dependencies.host + test_req = self._conanfile.dependencies.test + for dep in list(host_req.values()) + list(test_req.values()): dep_name = _format_name(dep.ref.name) @@ -278,15 +279,13 @@ def _transitive_components(component): transitive_external = list(OrderedDict.fromkeys(transitive_external).keys()) component_content = self._new_get_content_for_component(dep_name, comp_name, transitive_internal, transitive_external) + include_components_names.append((dep_name, comp_name)) result.update(component_content) else: - pass # FIXME - # public_deps = [(_format_name(d.ref.name),) * 2 for r, d in - # dep.dependencies.direct_host.items() if r.visible] - # required_components = dep.cpp_info.required_components if dep.cpp_info.required_components else public_deps - # root_content = self.get_content_for_component(dep_name, dep_name, dep.cpp_info, required_components) - # include_components_names.append((dep_name, dep_name)) - # result.update(root_content) + public_deps = [(_format_name(d.ref.name),) * 2 for r, d in dep.dependencies.direct_host.items() if r.visible] + root_content = self._new_get_content_for_component(dep_name, dep_name, [dep.cpp_info], public_deps) + include_components_names.append((dep_name, dep_name)) + result.update(root_content) result["conan_{}.xcconfig".format(dep_name)] = self._pkg_xconfig_file(include_components_names) From d13c6f5ea7f38ee324e126c25ea7b62c85ef0512 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 16:43:19 +0200 Subject: [PATCH 11/19] wip --- conan/tools/apple/xcodedeps.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 4d8118af632..f9cfba2f470 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -61,14 +61,14 @@ class XcodeDeps(object): general_name = "conandeps.xcconfig" _conf_xconfig = textwrap.dedent("""\ - // Compiler options for {{pkg_name}}::{{pkg_name}} + // Compiler options for {{pkg_name}}::{{comp_name}} HEADER_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{include_dirs}} GCC_PREPROCESSOR_DEFINITIONS_{{pkg_name}}_{{comp_name}}{{condition}} = {{definitions}} OTHER_CFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{c_compiler_flags}} OTHER_CPLUSPLUSFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{cxx_compiler_flags}} FRAMEWORK_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{frameworkdirs}} - // Link options for {{name}} + // Link options for {{pkg_name}}::{{comp_name}} LIBRARY_SEARCH_PATHS_{{pkg_name}}_{{comp_name}}{{condition}} = {{lib_dirs}} OTHER_LDFLAGS_{{pkg_name}}_{{comp_name}}{{condition}} = {{linker_flags}} {{libs}} {{system_libs}} {{frameworks}} """) @@ -77,8 +77,8 @@ class XcodeDeps(object): // Conan XcodeDeps generated file for {{pkg_name}}::{{comp_name}} // Includes all configurations for each dependency {% for dep in deps %} - // Includes for {{dep[0]}}::{{dep[1]}} dependency - #include "conan_{{dep[0]}}_{{dep[1]}}.xcconfig" + // Includes for {{dep}} dependency + #include "conan_{{dep}}.xcconfig" {% endfor %} #include "{{dep_xconfig_filename}}" @@ -160,10 +160,11 @@ def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filen content_multi = load(multi_path) else: content_multi = self._dep_xconfig + reqs_include_names = [f"{req[0]}::{req[1]}" if req[1] is not None else f"{req[0]}" for req in reqs] content_multi = Template(content_multi).render({"pkg_name": pkg_name, "comp_name": comp_name, "dep_xconfig_filename": dep_xconfig_filename, - "deps": reqs}) + "deps": reqs_include_names}) if dep_xconfig_filename not in content_multi: content_multi = content_multi.replace('.xcconfig"', @@ -237,7 +238,8 @@ def _content(self): # Then all components are included in the conan_pkgname.xcconfig file host_req = self._conanfile.dependencies.host test_req = self._conanfile.dependencies.test - for dep in list(host_req.values()) + list(test_req.values()): + all_deps = list(host_req.values()) + list(test_req.values()) + for dep in all_deps: dep_name = _format_name(dep.ref.name) @@ -282,8 +284,10 @@ def _transitive_components(component): include_components_names.append((dep_name, comp_name)) result.update(component_content) else: - public_deps = [(_format_name(d.ref.name),) * 2 for r, d in dep.dependencies.direct_host.items() if r.visible] - root_content = self._new_get_content_for_component(dep_name, dep_name, [dep.cpp_info], public_deps) + public_deps = [(_format_name(d.ref.name), None) for r, d in + dep.dependencies.direct_host.items() if r.visible] + root_content = self._new_get_content_for_component(dep_name, dep_name, [dep.cpp_info], + public_deps) include_components_names.append((dep_name, dep_name)) result.update(root_content) From e1aeb292b0e7c5c5df2a7fc563e88634850c04f7 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 16:46:20 +0200 Subject: [PATCH 12/19] wip --- .../toolchains/apple/test_xcodedeps.py | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index e93f49bc726..7d043ee6bfb 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -91,8 +91,6 @@ def test_generator_files(): @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") def test_xcodedeps_aggregate_components(): client = TestClient() - client.cache_folder = "/Users/carlosz/.conan" - client.run("install boost/1.79.0@ --install-folder=generators -g XcodeDeps -s build_type=Debug") conanfile_py = textwrap.dedent(""" from conan import ConanFile @@ -106,6 +104,17 @@ def package_info(self): client.run("create . liba/1.0@") + r"""" + 1 a + / \ / + 2 3 + \ / + 4 5 6 + | | / + \ / / + 7 + """ + conanfile_py = textwrap.dedent(""" from conan import ConanFile class LibConan(ConanFile): @@ -113,15 +122,22 @@ class LibConan(ConanFile): requires = "liba/1.0" def package_info(self): self.cpp_info.components["libb_comp1"].includedirs = ["libb_comp1"] + self.cpp_info.components["libb_comp1"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp2"].includedirs = ["libb_comp2"] + self.cpp_info.components["libb_comp2"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp2"].requires = ["libb_comp1"] self.cpp_info.components["libb_comp3"].includedirs = ["libb_comp3"] + self.cpp_info.components["libb_comp3"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp3"].requires = ["libb_comp1", "liba::liba_comp1"] self.cpp_info.components["libb_comp4"].includedirs = ["libb_comp4"] + self.cpp_info.components["libb_comp4"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp4"].requires = ["libb_comp2", "libb_comp3"] self.cpp_info.components["libb_comp5"].includedirs = ["libb_comp5"] + self.cpp_info.components["libb_comp5"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp6"].includedirs = ["libb_comp6"] + self.cpp_info.components["libb_comp6"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp7"].includedirs = ["libb_comp7"] + self.cpp_info.components["libb_comp7"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp7"].requires = ["libb_comp4", "libb_comp5", "libb_comp6"] """) @@ -131,4 +147,19 @@ def package_info(self): client.run("install libb/1.0@ -g XcodeDeps") - print(client.out) + lib_entry = client.load("conan_libb.xcconfig") + + for index in range(1, 8): + assert f"conan_libb_libb_comp{index}.xcconfig" in lib_entry + + component7_entry = client.load("conan_libb_libb_comp7.xcconfig") + assert '#include "conan_liba::liba_comp1.xcconfig"' in component7_entry + + component7_vars = client.load("conan_libb_libb_comp7_release_x86_64.xcconfig") + + # all of the transitive required components and the component itself are added + for index in range(1, 8): + assert f"libb_comp{index}" in component7_vars + + # folders are aggregated + assert component7_vars.count("mylibdir") == 1 From 7c7b5bdc75a4826f2de96bf5d84b4230e2108864 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 16:55:22 +0200 Subject: [PATCH 13/19] wip --- conans/test/integration/toolchains/apple/test_xcodedeps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index 7d043ee6bfb..6fc7cb3f0bc 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -162,4 +162,4 @@ def package_info(self): assert f"libb_comp{index}" in component7_vars # folders are aggregated - assert component7_vars.count("mylibdir") == 1 + assert "mylibdir" in component7_vars From edaf4ad86b217f26eda4b191aac02e216c69377a Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 17:15:31 +0200 Subject: [PATCH 14/19] wip --- conan/tools/apple/xcodedeps.py | 2 +- conans/test/integration/toolchains/apple/test_xcodedeps.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index f9cfba2f470..20cf0e4ad63 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -235,7 +235,7 @@ def _content(self): # Generate the config files for each component with name conan_pkgname_compname.xcconfig # If a package has no components the name is conan_pkgname_pkgname.xcconfig - # Then all components are included in the conan_pkgname.xcconfig file + # All components are included in the conan_pkgname.xcconfig file host_req = self._conanfile.dependencies.host test_req = self._conanfile.dependencies.test all_deps = list(host_req.values()) + list(test_req.values()) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index 6fc7cb3f0bc..4ed32ca3ee1 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -97,7 +97,7 @@ def test_xcodedeps_aggregate_components(): class LibConan(ConanFile): settings = "os", "compiler", "build_type", "arch" def package_info(self): - self.cpp_info.components["liba_comp1"].includedirs = ["liba_comp1"] + self.cpp_info.includedirs = ["liba_include"] """) client.save({"conanfile.py": conanfile_py}) @@ -128,7 +128,7 @@ def package_info(self): self.cpp_info.components["libb_comp2"].requires = ["libb_comp1"] self.cpp_info.components["libb_comp3"].includedirs = ["libb_comp3"] self.cpp_info.components["libb_comp3"].libdirs = ["mylibdir"] - self.cpp_info.components["libb_comp3"].requires = ["libb_comp1", "liba::liba_comp1"] + self.cpp_info.components["libb_comp3"].requires = ["libb_comp1", "liba::liba"] self.cpp_info.components["libb_comp4"].includedirs = ["libb_comp4"] self.cpp_info.components["libb_comp4"].libdirs = ["mylibdir"] self.cpp_info.components["libb_comp4"].requires = ["libb_comp2", "libb_comp3"] @@ -153,7 +153,7 @@ def package_info(self): assert f"conan_libb_libb_comp{index}.xcconfig" in lib_entry component7_entry = client.load("conan_libb_libb_comp7.xcconfig") - assert '#include "conan_liba::liba_comp1.xcconfig"' in component7_entry + assert '#include "conan_liba::liba.xcconfig"' in component7_entry component7_vars = client.load("conan_libb_libb_comp7_release_x86_64.xcconfig") From 05cac5bc05eb5270c99ee39c16a7476aebd9bef1 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 17:22:57 +0200 Subject: [PATCH 15/19] wip --- conan/tools/apple/xcodedeps.py | 25 +++++-------------- .../toolchains/apple/test_xcodedeps.py | 13 +++++++++- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 20cf0e4ad63..197b2b60f9a 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -200,22 +200,7 @@ def _global_xconfig_content(self): GLOBAL_XCCONFIG_TEMPLATE, [self.general_name]) - def get_content_for_component(self, pkg_name, component_name, cpp_info, reqs): - result = {} - - conf_name = _xcconfig_settings_filename(self._conanfile.settings) - - props_name = "conan_{}_{}{}.xcconfig".format(pkg_name, component_name, conf_name) - result[props_name] = self._conf_xconfig_file(pkg_name, component_name, cpp_info) - - # The entry point for each package - file_dep_name = "conan_{}_{}.xcconfig".format(pkg_name, component_name) - dep_content = self._dep_xconfig_file(pkg_name, component_name, file_dep_name, props_name, reqs) - - result[file_dep_name] = dep_content - return result - - def _new_get_content_for_component(self, pkg_name, component_name, transitive_internal, transitive_external): + def get_content_for_component(self, pkg_name, component_name, transitive_internal, transitive_external): result = {} conf_name = _xcconfig_settings_filename(self._conanfile.settings) @@ -280,14 +265,16 @@ def _transitive_components(component): transitive_internal = list(OrderedDict.fromkeys(transitive_internal).keys()) transitive_external = list(OrderedDict.fromkeys(transitive_external).keys()) - component_content = self._new_get_content_for_component(dep_name, comp_name, transitive_internal, transitive_external) + component_content = self.get_content_for_component(dep_name, comp_name, + transitive_internal, + transitive_external) include_components_names.append((dep_name, comp_name)) result.update(component_content) else: public_deps = [(_format_name(d.ref.name), None) for r, d in dep.dependencies.direct_host.items() if r.visible] - root_content = self._new_get_content_for_component(dep_name, dep_name, [dep.cpp_info], - public_deps) + root_content = self.get_content_for_component(dep_name, dep_name, [dep.cpp_info], + public_deps) include_components_names.append((dep_name, dep_name)) result.update(root_content) diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index 4ed32ca3ee1..73aac33be69 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -161,5 +161,16 @@ def package_info(self): for index in range(1, 8): assert f"libb_comp{index}" in component7_vars - # folders are aggregated assert "mylibdir" in component7_vars + + component4_vars = client.load("conan_libb_libb_comp4_release_x86_64.xcconfig") + + # all of the transitive required components and the component itself are added + for index in range(1, 5): + assert f"libb_comp{index}" in component4_vars + + for index in range(5, 8): + assert f"libb_comp{index}" not in component4_vars + + # folders are aggregated + assert "mylibdir" in component4_vars From 9cf99ee444153db096dd094cc24020b88dad1d44 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 17:35:39 +0200 Subject: [PATCH 16/19] wip --- conan/tools/apple/xcodedeps.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 197b2b60f9a..0678559333d 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -230,27 +230,25 @@ def _content(self): include_components_names = [] if dep.cpp_info.has_components: - # for each component get the list of cpp_infos for the required components to - # later aggregate all variables in one file + sorted_components = dep.cpp_info.get_sorted_components().items() for comp_name, comp_cpp_info in sorted_components: + # returns: ("list of cpp infos from required components in same package", + # "list of names from required components from other packages") def _get_component_requires(component): - requires_external = [] - requires_internal = [] - for req in component.requires: - if "::" in req: - requires_external.append((req.split("::")[0], req.split("::")[1])) - else: - pkg = self._conanfile.dependencies.host.get(dep_name) or self._conanfile.dependencies.test.get(dep_name) - req_cpp_info = pkg.cpp_info.components.get(req) - requires_internal.append(req_cpp_info) + requires_external = [(req.split("::")[0], req.split("::")[1]) for req in + component.requires if "::" in req] + requires_internal = [dep.cpp_info.components.get(req) for req in + component.requires if "::" not in req] return requires_internal, requires_external + # these are the transitive dependencies between components of the same package transitive_internal = [] + # these are the transitive dependencies to components from other packages transitive_external = [] - # return the internal and external components separated + # return the internal cpp_infos and external components names def _transitive_components(component): requires_internal, requires_external = _get_component_requires(component) transitive_internal.append(component) From 53b6074505c2a25c8aa674f6932a3247c2e85d01 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 17:45:37 +0200 Subject: [PATCH 17/19] minor changes --- conan/tools/apple/xcodedeps.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 0678559333d..ee491d079dc 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -127,14 +127,12 @@ def _conf_xconfig_file(self, pkg_name, comp_name, transitive_cpp_infos): content for conan_poco_x86_release.xcconfig, containing the activation """ def _merged_vars(name): - merged = [bindir for cpp_info in transitive_cpp_infos for bindir in getattr(cpp_info, name)] + merged = [var for cpp_info in transitive_cpp_infos for var in getattr(cpp_info, name)] return list(OrderedDict.fromkeys(merged).keys()) fields = { 'pkg_name': pkg_name, 'comp_name': comp_name, - 'bin_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("bindirs")), - 'res_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("resdirs")), 'include_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("includedirs")), 'lib_dirs': " ".join('"{}"'.format(p) for p in _merged_vars("libdirs")), 'libs': " ".join("-l{}".format(lib) for lib in _merged_vars("libs")), From a2d747ead1e45843126a2b09babc31d2530279a7 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 22 Jun 2022 18:50:20 +0200 Subject: [PATCH 18/19] fix tests --- conan/tools/apple/xcodedeps.py | 12 ++++++------ .../toolchains/apple/test_xcodedeps_components.py | 3 --- .../integration/toolchains/apple/test_xcodedeps.py | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index ee491d079dc..8af041cea38 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -77,8 +77,8 @@ class XcodeDeps(object): // Conan XcodeDeps generated file for {{pkg_name}}::{{comp_name}} // Includes all configurations for each dependency {% for dep in deps %} - // Includes for {{dep}} dependency - #include "conan_{{dep}}.xcconfig" + // Includes for {{dep[0]}}::{{dep[1]}} dependency + #include "conan_{{dep[0]}}_{{dep[1]}}.xcconfig" {% endfor %} #include "{{dep_xconfig_filename}}" @@ -158,11 +158,10 @@ def _dep_xconfig_file(self, pkg_name, comp_name, name_general, dep_xconfig_filen content_multi = load(multi_path) else: content_multi = self._dep_xconfig - reqs_include_names = [f"{req[0]}::{req[1]}" if req[1] is not None else f"{req[0]}" for req in reqs] content_multi = Template(content_multi).render({"pkg_name": pkg_name, "comp_name": comp_name, "dep_xconfig_filename": dep_xconfig_filename, - "deps": reqs_include_names}) + "deps": reqs}) if dep_xconfig_filename not in content_multi: content_multi = content_multi.replace('.xcconfig"', @@ -267,10 +266,11 @@ def _transitive_components(component): include_components_names.append((dep_name, comp_name)) result.update(component_content) else: - public_deps = [(_format_name(d.ref.name), None) for r, d in + public_deps = [(_format_name(d.ref.name),) * 2 for r, d in dep.dependencies.direct_host.items() if r.visible] + required_components = dep.cpp_info.required_components if dep.cpp_info.required_components else public_deps root_content = self.get_content_for_component(dep_name, dep_name, [dep.cpp_info], - public_deps) + required_components) include_components_names.append((dep_name, dep_name)) result.update(root_content) diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py index 4ccd40f286d..5e46a3792fb 100644 --- a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py +++ b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py @@ -8,9 +8,6 @@ @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") -@pytest.mark.tool_cmake -@pytest.mark.tool_xcodebuild -@pytest.mark.tool_xcodegen def test_xcodedeps_components(): """ tcp/1.0 is a lib without components diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py index 73aac33be69..c60ea523ad8 100644 --- a/conans/test/integration/toolchains/apple/test_xcodedeps.py +++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py @@ -153,7 +153,7 @@ def package_info(self): assert f"conan_libb_libb_comp{index}.xcconfig" in lib_entry component7_entry = client.load("conan_libb_libb_comp7.xcconfig") - assert '#include "conan_liba::liba.xcconfig"' in component7_entry + assert '#include "conan_liba_liba.xcconfig"' in component7_entry component7_vars = client.load("conan_libb_libb_comp7_release_x86_64.xcconfig") From 81ff9a366cb7da893c332ab1ef67474115a81b58 Mon Sep 17 00:00:00 2001 From: czoido Date: Wed, 29 Jun 2022 07:31:49 +0200 Subject: [PATCH 19/19] review --- conan/tools/apple/xcodedeps.py | 4 ++-- .../functional/toolchains/apple/test_xcodedeps_components.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py index 8af041cea38..e972423d243 100644 --- a/conan/tools/apple/xcodedeps.py +++ b/conan/tools/apple/xcodedeps.py @@ -253,8 +253,8 @@ def _transitive_components(component): transitive_external.extend(requires_external) for require in requires_internal: _transitive_components(require) - return transitive_internal, transitive_external - transitive_internal, transitive_external = _transitive_components(comp_cpp_info) + + _transitive_components(comp_cpp_info) # remove duplicates transitive_internal = list(OrderedDict.fromkeys(transitive_internal).keys()) diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py index 5e46a3792fb..d4898bff134 100644 --- a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py +++ b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py @@ -8,6 +8,7 @@ @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS") +@pytest.mark.tool_cmake def test_xcodedeps_components(): """ tcp/1.0 is a lib without components