Ejemplo n.º 1
0
def test_cpp_info_merge_aggregating_components_first():
    cppinfo = NewCppInfo()
    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        setattr(cppinfo.components["foo"], n,
                ["var_{}_1".format(n), "var_{}_2".format(n)])
        setattr(cppinfo.components["foo2"], n,
                ["var2_{}_1".format(n), "var2_{}_2".format(n)])

    cppinfo.components["foo"].requires = ["foo2"]  # Deterministic order

    other = NewCppInfo()
    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        setattr(other.components["boo"], n,
                ["jar_{}_1".format(n), "jar_{}_2".format(n)])
        setattr(other.components["boo2"], n,
                ["jar2_{}_1".format(n), "jar2_{}_2".format(n)])

    other.components["boo"].requires = ["boo2"]  # Deterministic order

    cppinfo.aggregate_components()
    other.aggregate_components()

    cppinfo.merge(other)

    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        assert getattr(cppinfo, n) == [
            "var_{}_1".format(n), "var_{}_2".format(n), "var2_{}_1".format(n),
            "var2_{}_2".format(n), "jar_{}_1".format(n), "jar_{}_2".format(n),
            "jar2_{}_1".format(n), "jar2_{}_2".format(n)
        ]
Ejemplo n.º 2
0
 def _get_cpp_info(self):
     ret = NewCppInfo()
     for dep in self.ordered_deps:
         dep_cppinfo = dep.cpp_info.aggregated_components()
         # In case we have components, aggregate them, we do not support isolated
         # "targets" with autotools
         ret.merge(dep_cppinfo)
     return ret
Ejemplo n.º 3
0
 def _get_cpp_info(self):
     ret = NewCppInfo()
     for dep in self._conanfile.dependencies.host.values():
         dep_cppinfo = dep.cpp_info.aggregated_components()
         # In case we have components, aggregate them, we do not support isolated
         # "targets" with autotools
         ret.merge(dep_cppinfo)
     return ret
Ejemplo n.º 4
0
def test_components_order():
    cppinfo = NewCppInfo()
    cppinfo.components["c1"].requires = ["c4", "OtherPackage::OtherComponent2"]
    cppinfo.components["c2"].requires = ["OtherPackage::OtherComponent"]
    cppinfo.components["c3"].requires = ["c2"]
    cppinfo.components["c4"].requires = ["c3"]
    sorted_c = list(cppinfo.get_sorted_components().keys())
    assert sorted_c == ["c2", "c3", "c4", "c1"]
Ejemplo n.º 5
0
class AutotoolsDeps:
    def __init__(self, conanfile):
        # Set the generic objects before mapping to env vars to let the user
        # alter some value
        self._conanfile = conanfile
        self._cpp_info = None

    @property
    def cpp_info(self):
        if self._cpp_info is None:
            self._cpp_info = NewCppInfo()
            for dep in self._conanfile.dependencies.host.values():
                dep_cppinfo = dep.new_cpp_info.copy()
                dep_cppinfo.set_relative_base_folder(dep.package_folder)
                # In case we have components, aggregate them, we do not support isolated
                # "targets" with autotools
                dep_cppinfo.aggregate_components()
                self._cpp_info.merge(dep_cppinfo)
        return self._cpp_info

    def environment(self):
        flags = AutoToolsDepsFlags(self._conanfile, self.cpp_info)

        # cpp_flags
        cpp_flags = []
        cpp_flags.extend(flags.include_paths)
        cpp_flags.extend(flags.defines)

        # Ldflags
        ldflags = flags.sharedlinkflags
        ldflags.extend(flags.exelinkflags)
        ldflags.extend(flags.frameworks)
        ldflags.extend(flags.framework_paths)
        ldflags.extend(flags.lib_paths)
        # FIXME: Previously we had an argument "include_rpath_flags" defaulted to False
        ldflags.extend(flags.rpath_flags)

        # cflags
        cflags = flags.cflags
        cxxflags = flags.cxxflags

        srf = flags.sysroot
        if srf:
            cflags.append(srf)
            cxxflags.append(srf)
            ldflags.append(srf)

        env = Environment()
        env.append("CPPFLAGS", cpp_flags)
        env.append("LIBS", flags.libs)
        env.append("LDFLAGS", ldflags)
        env.append("CXXFLAGS", cxxflags)
        env.append("CFLAGS", cflags)
        return env

    def generate(self, env=None):
        env = env or self.environment()
        env.save_script("conanautotoolsdeps")
Ejemplo n.º 6
0
 def _get_cpp_info(self):
     ret = NewCppInfo()
     for dep in self._conanfile.dependencies.host.values():
         dep_cppinfo = dep.cpp_info.copy()
         dep_cppinfo.set_relative_base_folder(dep.package_folder)
         # In case we have components, aggregate them, we do not support isolated "targets"
         dep_cppinfo.aggregate_components()
         ret.merge(dep_cppinfo)
     return ret
Ejemplo n.º 7
0
 def cpp_info(self):
     if self._cpp_info is None:
         self._cpp_info = NewCppInfo()
         for dep in self._conanfile.dependencies.host.values():
             dep_cppinfo = dep.new_cpp_info.copy()
             dep_cppinfo.set_relative_base_folder(dep.package_folder)
             # In case we have components, aggregate them, we do not support isolated
             # "targets" with autotools
             dep_cppinfo.aggregate_components()
             self._cpp_info.merge(dep_cppinfo)
     return self._cpp_info
Ejemplo n.º 8
0
def test_component_aggregation():
    cppinfo = NewCppInfo()

    cppinfo.includedirs = ["includedir"]
    cppinfo.libdirs = ["libdir"]
    cppinfo.srcdirs = ["srcdir"]
    cppinfo.bindirs = ["bindir"]
    cppinfo.builddirs = ["builddir"]
    cppinfo.frameworkdirs = ["frameworkdir"]

    cppinfo.components["c2"].includedirs = ["includedir_c2"]
    cppinfo.components["c2"].libdirs = ["libdir_c2"]
    cppinfo.components["c2"].srcdirs = ["srcdir_c2"]
    cppinfo.components["c2"].bindirs = ["bindir_c2"]
    cppinfo.components["c2"].builddirs = ["builddir_c2"]
    cppinfo.components["c2"].frameworkdirs = ["frameworkdir_c2"]
    cppinfo.components["c2"].cxxflags = ["cxxflags_c2"]
    cppinfo.components["c2"].defines = ["defines_c2"]

    cppinfo.components["c1"].requires = ["c2", "LIB_A::C1"]
    cppinfo.components["c1"].includedirs = ["includedir_c1"]
    cppinfo.components["c1"].libdirs = ["libdir_c1"]
    cppinfo.components["c1"].srcdirs = ["srcdir_c1"]
    cppinfo.components["c1"].bindirs = ["bindir_c1"]
    cppinfo.components["c1"].builddirs = ["builddir_c1"]
    cppinfo.components["c1"].frameworkdirs = ["frameworkdir_c1"]
    cppinfo.components["c1"].cxxflags = ["cxxflags_c1"]
    cppinfo.components["c1"].defines = ["defines_c1"]

    ret = cppinfo.copy()
    ret.aggregate_components()

    assert ret.includedirs == ["includedir_c1", "includedir_c2"]
    assert ret.libdirs == ["libdir_c1", "libdir_c2"]
    assert ret.srcdirs == ["srcdir_c1", "srcdir_c2"]
    assert ret.bindirs == ["bindir_c1", "bindir_c2"]
    assert ret.builddirs == ["builddir_c1", "builddir_c2"]
    assert ret.frameworkdirs == ["frameworkdir_c1", "frameworkdir_c2"]
    assert ret.cxxflags == ["cxxflags_c1", "cxxflags_c2"]
    assert ret.defines == ["defines_c1", "defines_c2"]

    # If we change the internal graph the order is different
    cppinfo.components["c1"].requires = []
    cppinfo.components["c2"].requires = ["c1"]

    ret = cppinfo.copy()
    ret.aggregate_components()

    assert ret.includedirs == ["includedir_c2", "includedir_c1"]
    assert ret.libdirs == ["libdir_c2", "libdir_c1"]
    assert ret.srcdirs == ["srcdir_c2", "srcdir_c1"]
    assert ret.bindirs == ["bindir_c2", "bindir_c1"]
    assert ret.builddirs == ["builddir_c2", "builddir_c1"]
    assert ret.frameworkdirs == ["frameworkdir_c2", "frameworkdir_c1"]
Ejemplo n.º 9
0
def test_cpp_info_merge_with_components():
    """If we try to merge a cpp info with another one and some of them have components, assert"""
    cppinfo = NewCppInfo()
    cppinfo.components["foo"].cxxflags = ["var"]

    other = NewCppInfo()
    other.components["foo2"].cxxflags = ["var2"]

    with pytest.raises(ConanException) as exc:
        cppinfo.merge(other)

    assert "Cannot aggregate two cppinfo objects with components" in str(
        exc.value)
Ejemplo n.º 10
0
    def test_pc(self):
        tmp_dir = temp_folder()
        filename = os.path.join(tmp_dir, 'libastral.pc')
        save(filename, libastral_pc)

        conanfile = ConanFileMock()
        pkg_config = PkgConfig(conanfile, "libastral", pkg_config_path=tmp_dir)

        assert pkg_config.provides == "libastral = 6.6.6"
        assert pkg_config.version == "6.6.6"
        assert pkg_config.includedirs == ['/usr/local/include/libastral']
        assert pkg_config.defines == ['_USE_LIBASTRAL']
        assert pkg_config.libs == ['astral', 'm']
        assert pkg_config.libdirs == ['/usr/local/lib/libastral']
        assert pkg_config.linkflags == ['-Wl,--whole-archive']
        assert pkg_config.variables['prefix'] == '/usr/local'

        cpp_info = NewCppInfo()
        pkg_config.fill_cpp_info(cpp_info, is_system=False, system_libs=["m"])

        assert cpp_info.includedirs == ['/usr/local/include/libastral']
        assert cpp_info.defines == ['_USE_LIBASTRAL']
        assert cpp_info.libs == ['astral']
        assert cpp_info.system_libs == ['m']
        assert cpp_info.libdirs == ['/usr/local/lib/libastral']
        assert cpp_info.sharedlinkflags == ['-Wl,--whole-archive']
Ejemplo n.º 11
0
def test_from_old_cppinfo_no_components():
    oldcppinfo = CppInfo("ref", "/root/")
    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        setattr(oldcppinfo, n, ["var_{}_1".format(n), "var_{}_2".format(n)])

    cppinfo = NewCppInfo.from_old_cppinfo(oldcppinfo)

    assert isinstance(cppinfo, NewCppInfo)

    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        assert getattr(cppinfo,
                       n) == ["var_{}_1".format(n), "var_{}_2".format(n)]
Ejemplo n.º 12
0
def test_fill_old_cppinfo_simple():
    """ The previous test but simpler, just with one cppinfo simulating the package layout"""
    package_info = NewCppInfo()
    package_info.libs = []  # This is explicit declaration too
    package_info.includedirs = ["other_include"]

    old_cpp = CppInfo("lib/1.0", "/root/folder")
    old_cpp.filter_empty = False
    old_cpp.libs = ["this_is_discarded"]
    old_cpp.libdirs = ["package_libdir"]
    old_cpp.cxxflags = ["package_cxxflags"]
    old_cpp.cflags = ["package_cflags"]
    old_cpp.frameworkdirs = ["package_frameworks"]

    fill_old_cppinfo(package_info, old_cpp)
    assert [e.replace("\\", "/") for e in old_cpp.lib_paths] == \
           ["/root/folder/package_libdir"]
    assert old_cpp.cxxflags == ["package_cxxflags"]
    assert old_cpp.cflags == ["package_cflags"]
    assert old_cpp.frameworkdirs == ["package_frameworks"]
    assert old_cpp.libs == []
    assert old_cpp.includedirs == ["other_include"]
Ejemplo n.º 13
0
def test_generator_properties_copy():
    cppinfo = NewCppInfo()
    cppinfo.set_property("foo", "foo_value", "generator1")
    cppinfo.set_property("foo", "var_value", "generator2")
    cppinfo.set_property("foo2", "foo2_value", "generator1")

    copied = cppinfo.copy()

    assert copied.get_property("foo") is None
    assert copied.get_property("foo", "generator1") == "foo_value"
    assert copied.get_property("foo", "generator2") == "var_value"
Ejemplo n.º 14
0
def test_from_old_cppinfo_components():
    oldcppinfo = CppInfo("ref", "/root/")
    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        setattr(oldcppinfo.components["foo"], n,
                ["var_{}_1".format(n), "var_{}_2".format(n)])
        setattr(oldcppinfo.components["foo2"], n,
                ["var2_{}_1".format(n), "var2_{}_2".format(n)])

    # The names and filenames are not copied to the new model
    oldcppinfo.components["foo"].names["Gen"] = ["MyName"]
    oldcppinfo.filenames["Gen"] = ["Myfilename"]

    cppinfo = NewCppInfo.from_old_cppinfo(oldcppinfo)

    assert isinstance(cppinfo, NewCppInfo)

    for n in _DIRS_VAR_NAMES + _FIELD_VAR_NAMES:
        assert getattr(cppinfo.components["foo"],
                       n) == ["var_{}_1".format(n), "var_{}_2".format(n)]
        assert getattr(cppinfo.components["foo2"],
                       n) == ["var2_{}_1".format(n), "var2_{}_2".format(n)]
Ejemplo n.º 15
0
    def __init__(self):

        self.source = NewCppInfo()
        self.build = NewCppInfo()
        self.package = NewCppInfo()
Ejemplo n.º 16
0
def test_cpp_info_sysroot_merge():
    # If the value was already set is kept in the merge
    one = NewCppInfo()
    one.sysroot = "sys1"
    two = NewCppInfo()
    two.sysroot = "sys2"
    one.merge(two)
    assert one.sysroot == "sys1"

    # If the value was not set it is assigned
    one = NewCppInfo()
    two = NewCppInfo()
    two.sysroot = "sys2"
    one.merge(two)
    assert one.sysroot == "sys2"
Ejemplo n.º 17
0
def test_fill_old_cppinfo():
    """The source/build have priority unless it is not declared at all"""
    source = NewCppInfo()
    source.libdirs = ["source_libdir"]
    source.cxxflags = ["source_cxxflags"]
    build = NewCppInfo()
    build.libdirs = ["build_libdir"]
    build.frameworkdirs = [
    ]  # An empty list is an explicit delaration with priority too
    build.set_property("cmake_build_modules", ["my_cmake.cmake"])
    build.builddirs = ["my_build"]

    old_cpp = CppInfo("lib/1.0", "/root/folder")
    old_cpp.filter_empty = False
    old_cpp.libdirs = ["package_libdir"]
    old_cpp.cxxflags = ["package_cxxflags"]
    old_cpp.cflags = ["package_cflags"]
    old_cpp.frameworkdirs = ["package_frameworks"]

    full_editables = NewCppInfo()
    full_editables.merge(source)
    full_editables.merge(build)

    fill_old_cppinfo(full_editables, old_cpp)
    assert [e.replace("\\", "/") for e in old_cpp.lib_paths] == \
           ["/root/folder/source_libdir", "/root/folder/build_libdir"]
    assert old_cpp.cxxflags == ["source_cxxflags"]
    assert old_cpp.cflags == ["package_cflags"]
    assert old_cpp.frameworkdirs == []
    assert old_cpp.get_property("cmake_build_modules")
    assert old_cpp.builddirs == ["my_build"]
Ejemplo n.º 18
0
def test_component_aggregation():
    cppinfo = NewCppInfo()

    cppinfo.includedirs = ["includedir"]
    cppinfo.libdirs = ["libdir"]
    cppinfo.srcdirs = ["srcdir"]
    cppinfo.bindirs = ["bindir"]
    cppinfo.builddirs = ["builddir"]
    cppinfo.frameworkdirs = ["frameworkdir"]
    cppinfo.set_property("foo", "bar")

    cppinfo.components["c2"].includedirs = ["includedir_c2"]
    cppinfo.components["c2"].libdirs = ["libdir_c2"]
    cppinfo.components["c2"].srcdirs = ["srcdir_c2"]
    cppinfo.components["c2"].bindirs = ["bindir_c2"]
    cppinfo.components["c2"].builddirs = ["builddir_c2"]
    cppinfo.components["c2"].frameworkdirs = ["frameworkdir_c2"]
    cppinfo.components["c2"].cxxflags = ["cxxflags_c2"]
    cppinfo.components["c2"].defines = ["defines_c2"]
    cppinfo.components["c2"].set_property("my_foo", ["bar", "bar2"])
    cppinfo.components["c2"].set_property(
        "cmake_build_modules", ["build_module_c2", "build_module_c22"])

    cppinfo.components["c1"].requires = ["c2", "LIB_A::C1"]
    cppinfo.components["c1"].includedirs = ["includedir_c1"]
    cppinfo.components["c1"].libdirs = ["libdir_c1"]
    cppinfo.components["c1"].srcdirs = ["srcdir_c1"]
    cppinfo.components["c1"].bindirs = ["bindir_c1"]
    cppinfo.components["c1"].builddirs = ["builddir_c1"]
    cppinfo.components["c1"].frameworkdirs = ["frameworkdir_c1"]
    cppinfo.components["c1"].cxxflags = ["cxxflags_c1"]
    cppinfo.components["c1"].defines = ["defines_c1"]
    cppinfo.components["c1"].set_property("my_foo", "jander")
    cppinfo.components["c1"].set_property("my_foo2", "bar2")

    ret = cppinfo.aggregated_components()

    assert ret.get_property("foo") == "bar"
    assert ret.includedirs == ["includedir_c1", "includedir_c2"]
    assert ret.libdirs == ["libdir_c1", "libdir_c2"]
    assert ret.srcdirs == ["srcdir_c1", "srcdir_c2"]
    assert ret.bindirs == ["bindir_c1", "bindir_c2"]
    assert ret.builddirs == ["builddir_c1", "builddir_c2"]
    assert ret.frameworkdirs == ["frameworkdir_c1", "frameworkdir_c2"]
    assert ret.cxxflags == ["cxxflags_c1", "cxxflags_c2"]
    assert ret.defines == ["defines_c1", "defines_c2"]
    # The properties are not aggregated because we cannot generalize the meaning of a property
    # that belongs to a component, it could make sense to aggregate it or not, "cmake_target_name"
    # for example, cannot be aggregated. But "cmake_build_modules" is aggregated.
    assert ret.get_property("my_foo") is None
    assert ret.get_property("my_foo2") is None
    assert ret.get_property("cmake_build_modules") == None

    # If we change the internal graph the order is different
    cppinfo.components["c1"].requires = []
    cppinfo.components["c2"].requires = ["c1"]

    cppinfo._aggregated = None  # Dirty, just to force recomputation
    ret = cppinfo.aggregated_components()

    assert ret.includedirs == ["includedir_c2", "includedir_c1"]
    assert ret.libdirs == ["libdir_c2", "libdir_c1"]
    assert ret.srcdirs == ["srcdir_c2", "srcdir_c1"]
    assert ret.bindirs == ["bindir_c2", "bindir_c1"]
    assert ret.builddirs == ["builddir_c2", "builddir_c1"]
    assert ret.frameworkdirs == ["frameworkdir_c2", "frameworkdir_c1"]
Ejemplo n.º 19
0
    def _call_package_info(self, conanfile, package_folder, ref, is_editable):
        conanfile.cpp_info = CppInfo(conanfile.name, package_folder)
        conanfile.cpp_info.version = conanfile.version
        conanfile.cpp_info.description = conanfile.description

        conanfile.env_info = EnvInfo()
        conanfile.user_info = UserInfo()

        # Get deps_cpp_info from upstream nodes
        public_deps = [
            name for name, req in conanfile.requires.items()
            if not req.private and not req.override
        ]
        conanfile.cpp_info.public_deps = public_deps
        # Once the node is build, execute package info, so it has access to the
        # package folder and artifacts
        # Minimal pythonpath, not the whole context, make it 50% slower
        # FIXME Conan 2.0, Remove old ways of reusing python code
        with pythonpath(conanfile):
            with tools.chdir(package_folder):
                with conanfile_exception_formatter(str(conanfile),
                                                   "package_info"):
                    self._hook_manager.execute("pre_package_info",
                                               conanfile=conanfile,
                                               reference=ref)
                    if hasattr(conanfile, "layout"):
                        # Old cpp info without defaults (the defaults are in the new one)
                        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:
                            conanfile.cpp_info.filter_empty = False

                    conanfile.package_info()

                    if hasattr(conanfile, "layout") and is_editable:
                        # Adjust the folders of the layout to consolidate the rootfolder of the
                        # cppinfos inside
                        # convert directory entries to be relative to the declared folders.build
                        conanfile.cpp.build.set_relative_base_folder(
                            conanfile.build_folder)

                        # convert directory entries to be relative to the declared folders.source
                        conanfile.cpp.source.set_relative_base_folder(
                            conanfile.source_folder)

                        full_editable_cppinfo = NewCppInfo()
                        full_editable_cppinfo.merge(conanfile.cpp.source)
                        full_editable_cppinfo.merge(conanfile.cpp.build)
                        # Paste the editable cpp_info but prioritizing it, only if a
                        # variable is not declared at build/source, the package will keep the value
                        fill_old_cppinfo(full_editable_cppinfo,
                                         conanfile.cpp_info)

                    if conanfile._conan_dep_cpp_info is None:
                        try:
                            if not is_editable and not hasattr(
                                    conanfile, "layout"):
                                # FIXME: The default for the cppinfo from build are not the same
                                #        so this check fails when editable
                                # FIXME: Remove when new cppinfo model. If using the layout method
                                #        the cppinfo object is filled from self.cpp.package new
                                #        model and we cannot check if the defaults have been modified
                                #        because it doesn't exist in the new model where the defaults
                                #        for the components are always empty
                                conanfile.cpp_info._raise_incorrect_components_definition(
                                    conanfile.name, conanfile.requires)
                        except ConanException as e:
                            raise ConanException("%s package_info(): %s" %
                                                 (str(conanfile), e))
                        conanfile._conan_dep_cpp_info = DepCppInfo(
                            conanfile.cpp_info)
                    self._hook_manager.execute("post_package_info",
                                               conanfile=conanfile,
                                               reference=ref)
Ejemplo n.º 20
0
 def new_cpp_info(self):
     if not self._conan_new_cpp_info:
         self._conan_new_cpp_info = NewCppInfo.from_old_cppinfo(self.cpp_info)
     return self._conan_new_cpp_info