From a065cca47caa0a5a35adcc894f977db29a9a2d75 Mon Sep 17 00:00:00 2001 From: memsharded Date: Thu, 8 Feb 2024 11:35:20 +0100 Subject: [PATCH] fix MSBuildDeps with components and skipped deps --- conan/tools/microsoft/msbuilddeps.py | 7 ++- .../toolchains/microsoft/test_msbuilddeps.py | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py index 6c7500fe3e3..d8e06c1b5c0 100644 --- a/conan/tools/microsoft/msbuilddeps.py +++ b/conan/tools/microsoft/msbuilddeps.py @@ -315,6 +315,7 @@ def _package_props_files(self, require, dep, build=False): condition = self._condition() dep_name = self._dep_name(dep, build) result = {} + pkg_deps = get_transitive_requires(self._conanfile, dep) # only non-skipped dependencies if dep.cpp_info.has_components: pkg_aggregated_content = None for comp_name, comp_info in dep.cpp_info.components.items(): @@ -327,8 +328,9 @@ def _package_props_files(self, require, dep, build=False): public_deps = [] # To store the xml dependencies/file names for required_pkg, required_comp in comp_info.parsed_requires(): if required_pkg is not None: # Points to a component of a different package - public_deps.append(required_pkg if required_pkg == required_comp - else "{}_{}".format(required_pkg, required_comp)) + if required_pkg in pkg_deps: # The transitive dep might have been skipped + public_deps.append(required_pkg if required_pkg == required_comp + else "{}_{}".format(required_pkg, required_comp)) else: # Points to a component of same package public_deps.append("{}_{}".format(dep_name, required_comp)) public_deps = [self._get_valid_xml_format(d) for d in public_deps] @@ -348,7 +350,6 @@ def _package_props_files(self, require, dep, build=False): vars_filename = "conan_%s_vars%s.props" % (dep_name, conf_name) activate_filename = "conan_%s%s.props" % (dep_name, conf_name) pkg_filename = "conan_%s.props" % dep_name - pkg_deps = get_transitive_requires(self._conanfile, dep) public_deps = [self._dep_name(d, build) for d in pkg_deps.values()] result[vars_filename] = self._vars_props_file(require, dep, dep_name, cpp_info, diff --git a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py index 14b04bab618..00deb04e986 100644 --- a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py +++ b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py @@ -4,6 +4,7 @@ import pytest +from conans.test.assets.genconanfile import GenConanfile from conans.test.utils.tools import TestClient @@ -65,3 +66,57 @@ def package_info(self): minidom.parseString(content) counter += 1 assert counter == 8 + + +class TestMSBuildDepsSkips: + # https://github.com/conan-io/conan/issues/15624 + def test_msbuilddeps_skipped_deps(self): + c = TestClient() + c.save({"liba/conanfile.py": GenConanfile("liba", "0.1").with_package_type("header-library"), + "libb/conanfile.py": GenConanfile("libb", "0.1").with_package_type("static-library") + .with_requires("liba/0.1"), + "app/conanfile.py": GenConanfile().with_requires("libb/0.1") + .with_settings("arch", "build_type")}) + c.run("create liba") + c.run("create libb") + c.run("install app -g MSBuildDeps") + assert not os.path.exists(os.path.join(c.current_folder, "app", "conan_liba.props")) + assert os.path.exists(os.path.join(c.current_folder, "app", "conan_libb.props")) + libb = c.load("app/conan_libb.props") + assert "conan_liba" not in libb + libb = c.load("app/conan_libb_release_x64.props") + assert "conan_liba" not in libb + libb = c.load("app/conan_libb_vars_release_x64.props") + assert "conan_liba" not in libb + + def test_msbuilddeps_skipped_deps_components(self): + c = TestClient() + libb = textwrap.dedent(""" + from conan import ConanFile + class Libb(ConanFile): + name = "libb" + version = "0.1" + package_type = "static-library" + requires = "liba/0.1" + def package_info(self): + self.cpp_info.components["mycomp"].libs = ["mycomplib"] + self.cpp_info.components["mycomp"].requires = ["liba::liba"] + """) + + c.save({"liba/conanfile.py": GenConanfile("liba", "0.1").with_package_type("header-library"), + "libb/conanfile.py": libb, + "app/conanfile.py": GenConanfile().with_requires("libb/0.1") + .with_settings("arch", "build_type")}) + c.run("create liba") + c.run("create libb") + c.run("install app -g MSBuildDeps") + assert not os.path.exists(os.path.join(c.current_folder, "app", "conan_liba.props")) + assert os.path.exists(os.path.join(c.current_folder, "app", "conan_libb.props")) + libb = c.load("app/conan_libb.props") + assert "conan_liba" not in libb + libb = c.load("app/conan_libb_mycomp.props") + assert "conan_liba" not in libb + libb = c.load("app/conan_libb_mycomp_release_x64.props") + assert "conan_liba" not in libb + libb = c.load("app/conan_libb_mycomp_vars_release_x64.props") + assert "conan_liba" not in libb