From 2ddd17fc06794430b14377d462b9fa511370b8c7 Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Fri, 17 Jun 2022 10:59:02 +0200 Subject: [PATCH] Feature/components default new cppinfo (#11471) * Pending abs path to components * on it * apparently working? * Better test * Explanation * Removed comment * Bindirs * Fix test for bindirs * Do not include default resdirs * Fix mac test --- conan/tools/gnu/autotoolstoolchain.py | 2 +- conans/client/installer.py | 1 - conans/model/conan_file.py | 2 +- conans/model/layout.py | 2 +- conans/model/new_build_info.py | 19 +++-- .../layout/test_editables_layout.py | 6 +- .../layout/test_layout_autopackage.py | 8 +- .../toolchains/gnu/autotools/test_ios.py | 3 + .../test/integration/command/create_test.py | 80 +++++++++++++++++++ 9 files changed, 108 insertions(+), 15 deletions(-) diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py index a8608bbc386..52ee17a3939 100644 --- a/conan/tools/gnu/autotoolstoolchain.py +++ b/conan/tools/gnu/autotoolstoolchain.py @@ -203,7 +203,7 @@ def _get_argument(argument_name, cppinfo_name): _get_argument("includedir", "includedirs"), _get_argument("oldincludedir", "includedirs"), _get_argument("datarootdir", "resdirs")]) - return configure_install_flags + return [el for el in configure_install_flags if el] def _default_autoreconf_flags(self): return ["--force", "--install"] diff --git a/conans/client/installer.py b/conans/client/installer.py index 08428d31039..65649b942d0 100644 --- a/conans/client/installer.py +++ b/conans/client/installer.py @@ -675,7 +675,6 @@ def _call_package_info(self, conanfile, package_folder, ref, is_editable): conanfile.cpp_info = CppInfo(conanfile.name, package_folder, default_values=CppInfoDefaultValues()) if not is_editable: - conanfile.cpp.package.set_relative_base_folder(conanfile.package_folder) # Copy the infos.package into the old cppinfo fill_old_cppinfo(conanfile.cpp.package, conanfile.cpp_info) else: diff --git a/conans/model/conan_file.py b/conans/model/conan_file.py index 8216549bb52..ce9a2ba2a8e 100644 --- a/conans/model/conan_file.py +++ b/conans/model/conan_file.py @@ -175,7 +175,7 @@ def __init__(self, output, runner, display_name="", user=None, channel=None): self.cpp.package.includedirs = ["include"] self.cpp.package.libdirs = ["lib"] self.cpp.package.bindirs = ["bin"] - self.cpp.package.resdirs = ["res"] + self.cpp.package.resdirs = [] self.cpp.package.builddirs = [""] self.cpp.package.frameworkdirs = [] diff --git a/conans/model/layout.py b/conans/model/layout.py index f6f60c7a41f..cce15ddd59f 100644 --- a/conans/model/layout.py +++ b/conans/model/layout.py @@ -8,7 +8,7 @@ class Infos(object): def __init__(self): self.source = NewCppInfo() self.build = NewCppInfo() - self.package = NewCppInfo() + self.package = NewCppInfo(with_defaults=True) class Folders(object): diff --git a/conans/model/new_build_info.py b/conans/model/new_build_info.py index 91d206c32de..78c27a83edb 100644 --- a/conans/model/new_build_info.py +++ b/conans/model/new_build_info.py @@ -2,7 +2,7 @@ import os from collections import OrderedDict -from conans.model.build_info import DefaultOrderedDict +from conans.model.build_info import DefaultOrderedDict, CppInfoDefaultValues _DIRS_VAR_NAMES = ["includedirs", "srcdirs", "libdirs", "resdirs", "bindirs", "builddirs", "frameworkdirs", "objects"] @@ -13,7 +13,7 @@ class _NewComponent(object): - def __init__(self): + def __init__(self, with_defaults=False): # ###### PROPERTIES self._generator_properties = None @@ -40,6 +40,11 @@ def __init__(self): self.sysroot = None self.requires = None + if with_defaults: + self.includedirs = ["include"] + self.libdirs = ["lib"] + self.bindirs = ["bin"] + @property def required_component_names(self): """ Names of the required components of the same package (not scoped with ::)""" @@ -70,10 +75,10 @@ def get_init(self, attribute, default): class NewCppInfo(object): - def __init__(self): - self.components = DefaultOrderedDict(lambda: _NewComponent()) + def __init__(self, with_defaults=False): + self.components = DefaultOrderedDict(lambda: _NewComponent(with_defaults)) # Main package is a component with None key - self.components[None] = _NewComponent() + self.components[None] = _NewComponent(with_defaults) self._aggregated = None # A _NewComponent object with all the components aggregated def __getattr__(self, attr): @@ -271,3 +276,7 @@ def fill_old_cppinfo(origin, old_cpp): setattr(old_cpp, varname, copy.copy(value)) if origin._generator_properties is not None: old_cpp._generator_properties = copy.copy(origin._generator_properties) + + # We change the defaults so the new components the user is going to declare in package_info + # have also defaults, not only the declared in the `self.cpp.package` + old_cpp._default_values = CppInfoDefaultValues(includedir="include", libdir="lib", bindir="bin") diff --git a/conans/test/functional/layout/test_editables_layout.py b/conans/test/functional/layout/test_editables_layout.py index efdc3c01d78..d81dad55264 100644 --- a/conans/test/functional/layout/test_editables_layout.py +++ b/conans/test/functional/layout/test_editables_layout.py @@ -213,8 +213,8 @@ def build(self): client2.run("create . lib/1.0@") out = str(client2.out).replace(r"\\", "/").replace(package_folder, "") assert "**FOO includedirs:['package_include_foo']**" in out - assert "**FOO libdirs:[]**" in out # The components don't have default dirs - assert "**FOO builddirs:[]**" in out # The components don't have default dirs + assert "**FOO libdirs:['lib']**" in out # The components does have default dirs + assert "**FOO builddirs:[]**" in out # The components don't have default dirs for builddirs assert "**FOO libs:['lib_when_package_foo', 'lib_when_package2_foo']**" in out assert "**FOO objects:['myobject.o']**" in out assert "**FOO build_modules:['mymodules/mybuildmodule']**" in out @@ -222,7 +222,7 @@ def build(self): assert "**FOO cflags:['my_c_flag_foo']**" in out assert "**VAR includedirs:['package_include_var']**" in out - assert "**VAR libdirs:[]**" in out # The components don't have default dirs + assert "**VAR libdirs:['lib']**" in out # The components does have default dirs assert "**VAR builddirs:[]**" in out # The components don't have default dirs assert "**VAR libs:['lib_when_package_var', 'lib_when_package2_var']**" in out assert "**VAR cxxflags:['my_cxx_flag2_var']**" in out diff --git a/conans/test/functional/layout/test_layout_autopackage.py b/conans/test/functional/layout/test_layout_autopackage.py index e2947f8b6aa..c05d59580d2 100644 --- a/conans/test/functional/layout/test_layout_autopackage.py +++ b/conans/test/functional/layout/test_layout_autopackage.py @@ -295,6 +295,7 @@ def test_auto_package_default_folders_with_components(): conan_file += """ def layout(self): for el in [self.cpp.source, self.cpp.build]: + # The defaults for cpp.build and cpp.source are empty assert el.components["foo"].includedirs is None assert el.components["foo"].libdirs is None assert el.components["foo"].bindirs is None @@ -302,9 +303,10 @@ def layout(self): assert el.components["foo"].srcdirs is None assert el.components["foo"].resdirs is None - assert self.cpp.package.components["foo"].includedirs is None - assert self.cpp.package.components["foo"].libdirs is None - assert self.cpp.package.components["foo"].bindirs is None + # The defaults for cpp.package are filled includedirs and libdirs and bindirs + assert self.cpp.package.components["foo"].includedirs is not None + assert self.cpp.package.components["foo"].libdirs is not None + assert self.cpp.package.components["foo"].bindirs is not None assert self.cpp.package.components["foo"].frameworkdirs is None assert self.cpp.package.components["foo"].srcdirs is None assert self.cpp.package.components["foo"].resdirs is None diff --git a/conans/test/functional/toolchains/gnu/autotools/test_ios.py b/conans/test/functional/toolchains/gnu/autotools/test_ios.py index d0a6c45c2de..51f17f3c0ba 100644 --- a/conans/test/functional/toolchains/gnu/autotools/test_ios.py +++ b/conans/test/functional/toolchains/gnu/autotools/test_ios.py @@ -53,6 +53,9 @@ class TestConan(ConanFile): exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsToolchain", "AutotoolsDeps" + def layout(self): + self.cpp.package.resdirs = ["res"] + def build(self): autotools = Autotools(self) autotools.autoreconf() diff --git a/conans/test/integration/command/create_test.py b/conans/test/integration/command/create_test.py index 7f1f35ee3dc..048a366e74a 100644 --- a/conans/test/integration/command/create_test.py +++ b/conans/test/integration/command/create_test.py @@ -1,7 +1,9 @@ import json import os +import re import textwrap import unittest +import pytest from parameterized.parameterized import parameterized @@ -579,3 +581,81 @@ def package_info(self): client.save({"conanfile.py": conanfile}) client.run("create .") assert "FRAMEWORKS: []" in client.out + + +import pytest +import re +@pytest.mark.parametrize("with_layout", [True, False]) +def test_defaults_in_components_without_layout(with_layout): + lib_conan_file = textwrap.dedent(""" + from conan import ConanFile + + class LibConan(ConanFile): + name = "lib" + version = "1.0" + + def layout(self): + pass + + def package_info(self): + self.cpp_info.components["foo"].libs = ["foolib"] + + """) + if not with_layout: + lib_conan_file = lib_conan_file.replace("def layout(", "def potato(") + client = TestClient() + client.save({"conanfile.py": lib_conan_file}) + client.run("create . ") + + consumer_conanfile = textwrap.dedent(""" + from conan import ConanFile + + class Consumer(ConanFile): + name = "consumer" + version = "1.0" + requires = "lib/1.0" + + def layout(self): + pass + + def generate(self): + if hasattr(self, "layout"): + cppinfo = self.dependencies["lib"].cpp_info + else: + cppinfo = dict(self.deps_cpp_info.dependencies)["lib"] + + components = cppinfo.components + self.output.warn("BINDIRS: {}".format(cppinfo.bindirs)) + self.output.warn("LIBDIRS: {}".format(cppinfo.libdirs)) + self.output.warn("INCLUDEDIRS: {}".format(cppinfo.includedirs)) + self.output.warn("RESDIRS: {}".format(cppinfo.resdirs)) + self.output.warn("FOO LIBDIRS: {}".format(components["foo"].libdirs)) + self.output.warn("FOO INCLUDEDIRS: {}".format(components["foo"].includedirs)) + self.output.warn("FOO RESDIRS: {}".format(components["foo"].resdirs)) + + """) + + if not with_layout: + consumer_conanfile = consumer_conanfile.replace("def layout(", "def potato(") + + client.save({"conanfile.py": consumer_conanfile}) + client.run("create . ") + + if with_layout: + # The paths are absolute and the components have defaults + # ".+" Check that there is a path, not only "lib" + assert re.search("BINDIRS: \['.+bin'\]", str(client.out)) + assert re.search("LIBDIRS: \['.+lib'\]", str(client.out)) + assert re.search("INCLUDEDIRS: \['.+include'\]", str(client.out)) + assert "WARN: RES DIRS: []" + assert bool(re.search("WARN: FOO LIBDIRS: \['.+lib'\]", str(client.out))) is with_layout + assert bool(re.search("WARN: FOO INCLUDEDIRS: \['.+include'\]", str(client.out))) is with_layout + assert "WARN: FOO RESDIRS: []" in client.out + else: + # The paths are not absolute and the components have defaults + assert "BINDIRS: ['bin']" in client.out + assert "LIBDIRS: ['lib']" in client.out + assert "INCLUDEDIRS: ['include']" in client.out + assert "FOO LIBDIRS: ['lib']" in client.out + assert "FOO INCLUDEDIRS: ['include']" in client.out + assert "FOO RESDIRS: ['res']" in client.out