diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py
index 5c84e68e267..60c566725c9 100644
--- a/conan/tools/microsoft/msbuilddeps.py
+++ b/conan/tools/microsoft/msbuilddeps.py
@@ -140,7 +140,7 @@ def _dep_name(dep, build):
dep_name += "_build"
return dep_name
- def _vars_props_file(self, dep, name, cpp_info, deps, build):
+ def _vars_props_file(self, require, dep, name, cpp_info, deps, build):
"""
content for conan_vars_poco_x86_release.props, containing the variables for 1 config
This will be for 1 package or for one component of a package
@@ -176,11 +176,11 @@ def join_paths(paths):
fields = {
'name': name,
'root_folder': package_folder,
- 'bin_dirs': join_paths(cpp_info.bindirs),
+ 'bin_dirs': join_paths(cpp_info.bindirs) if require.run else "",
'res_dirs': join_paths(cpp_info.resdirs),
- 'include_dirs': join_paths(cpp_info.includedirs),
- 'lib_dirs': join_paths(cpp_info.libdirs),
- 'libs': "".join([add_valid_ext(lib) for lib in cpp_info.libs]),
+ 'include_dirs': join_paths(cpp_info.includedirs) if require.headers else "",
+ 'lib_dirs': join_paths(cpp_info.libdirs) if require.libs else "",
+ 'libs': "".join([add_valid_ext(lib) for lib in cpp_info.libs]) if require.libs else "",
# TODO: Missing objects
'system_libs': "".join([add_valid_ext(sys_dep) for sys_dep in cpp_info.system_libs]),
'definitions': "".join("%s;" % d for d in cpp_info.defines),
@@ -276,7 +276,7 @@ def _conandeps(self):
content=pkg_aggregated_content)
return {conandeps_filename: pkg_aggregated_content}
- def _package_props_files(self, dep, build=False):
+ def _package_props_files(self, require, dep, build=False):
""" all the files for a given package:
- conan_pkgname_vars_config.props: definition of variables, one per config
- conan_pkgname_config.props: The one using those variables. This is very different for
@@ -305,8 +305,8 @@ def _package_props_files(self, dep, build=False):
public_deps.append(pkg if pkg == cmp_name else "{}_{}".format(pkg, cmp_name))
else: # Points to a component of same package
public_deps.append("{}_{}".format(dep_name, r))
- result[vars_filename] = self._vars_props_file(dep, full_comp_name, comp_info,
- public_deps, build=build)
+ result[vars_filename] = self._vars_props_file(require, dep, full_comp_name,
+ comp_info, public_deps, build=build)
result[activate_filename] = self._activate_props_file(full_comp_name, vars_filename,
public_deps, build=build)
result[comp_filename] = self._dep_props_file(full_comp_name, comp_filename,
@@ -323,7 +323,7 @@ def _package_props_files(self, dep, build=False):
pkg_filename = "conan_%s.props" % dep_name
public_deps = [self._dep_name(d, build)
for r, d in dep.dependencies.direct_host.items() if r.visible]
- result[vars_filename] = self._vars_props_file(dep, dep_name, cpp_info,
+ result[vars_filename] = self._vars_props_file(require, dep, dep_name, cpp_info,
public_deps, build=build)
result[activate_filename] = self._activate_props_file(dep_name, vars_filename,
public_deps, build=build)
@@ -336,14 +336,12 @@ def _content(self):
raise ConanException("The 'msbuild' generator requires a 'build_type' setting value")
result = {}
- host_req = list(self._conanfile.dependencies.host.values())
- test_req = list(self._conanfile.dependencies.test.values())
- for dep in host_req + test_req:
- result.update(self._package_props_files(dep, build=False))
-
- build_req = list(self._conanfile.dependencies.build.values())
- for dep in build_req:
- result.update(self._package_props_files(dep, build=True))
+ for req, dep in self._conanfile.dependencies.host.items():
+ result.update(self._package_props_files(req, dep, build=False))
+ for req, dep in self._conanfile.dependencies.test.items():
+ result.update(self._package_props_files(req, dep, build=False))
+ for req, dep in self._conanfile.dependencies.build.items():
+ result.update(self._package_props_files(req, dep, build=True))
# Include all direct build_requires for host context. This might change
result.update(self._conandeps())
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_transitivity.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_transitivity.py
index 0d881eaa673..aec37ec1c10 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_transitivity.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_transitivity.py
@@ -5,20 +5,13 @@
from conan.tools.env.environment import environment_wrap_command
from conans.test.assets.cmake import gen_cmakelists
-from conans.test.assets.pkg_cmake import pkg_cmake
from conans.test.assets.sources import gen_function_cpp
-from conans.test.utils.tools import TestClient
@pytest.mark.skipif(platform.system() != "Windows", reason="Requires MSBuild")
@pytest.mark.tool("cmake")
-def test_transitive_headers_not_public():
- c = TestClient()
-
- c.save(pkg_cmake("liba", "0.1"))
- c.run("create .")
- c.save(pkg_cmake("libb", "0.1", requires=["liba/0.1"]), clean_first=True)
- c.run("create .")
+def test_transitive_headers_not_public(transitive_libraries):
+ c = transitive_libraries
conanfile = textwrap.dedent("""\
from conan import ConanFile
@@ -57,13 +50,8 @@ def build(self):
@pytest.mark.skipif(platform.system() != "Windows", reason="Requires MSBuild")
@pytest.mark.tool("cmake")
-def test_shared_requires_static():
- c = TestClient()
-
- c.save(pkg_cmake("liba", "0.1"))
- c.run("create .")
- c.save(pkg_cmake("libb", "0.1", requires=["liba/0.1"]), clean_first=True)
- c.run("create . -o libb/*:shared=True")
+def test_shared_requires_static(transitive_libraries):
+ c = transitive_libraries
conanfile = textwrap.dedent("""\
from conan import ConanFile
@@ -97,13 +85,8 @@ def build(self):
@pytest.mark.skipif(platform.system() != "Windows", reason="Requires MSBuild")
@pytest.mark.tool("cmake")
-def test_transitive_binary_skipped():
- c = TestClient()
-
- c.save(pkg_cmake("liba", "0.1"))
- c.run("create .")
- c.save(pkg_cmake("libb", "0.1", requires=["liba/0.1"]), clean_first=True)
- c.run("create . -o libb/*:shared=True")
+def test_transitive_binary_skipped(transitive_libraries):
+ c = transitive_libraries
# IMPORTANT: liba binary can be removed, no longer necessary
c.run("remove liba* -p -f")
diff --git a/conans/test/functional/toolchains/conftest.py b/conans/test/functional/toolchains/conftest.py
new file mode 100644
index 00000000000..0ebdd659865
--- /dev/null
+++ b/conans/test/functional/toolchains/conftest.py
@@ -0,0 +1,28 @@
+import os
+import shutil
+
+import pytest
+
+from conans.test.assets.pkg_cmake import pkg_cmake
+from conans.test.utils.test_files import temp_folder
+from conans.test.utils.tools import TestClient
+
+
+@pytest.fixture(scope="session")
+def _transitive_libraries():
+ c = TestClient()
+
+ c.save(pkg_cmake("liba", "0.1"))
+ c.run("create .")
+ c.save(pkg_cmake("libb", "0.1", requires=["liba/0.1"]), clean_first=True)
+ c.run("create .")
+ c.run("create . -o libb/*:shared=True")
+ return c
+
+
+@pytest.fixture()
+def transitive_libraries(_transitive_libraries):
+ c = TestClient()
+ c.cache_folder = os.path.join(temp_folder(), ".conan2")
+ shutil.copytree(_transitive_libraries.cache_folder, c.cache_folder)
+ return c
diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps_traits.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_traits.py
new file mode 100644
index 00000000000..e55d24d6645
--- /dev/null
+++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_traits.py
@@ -0,0 +1,39 @@
+import os
+import platform
+import textwrap
+
+import pytest
+
+from conan.tools.env.environment import environment_wrap_command
+from conans.test.assets.cmake import gen_cmakelists
+from conans.test.assets.genconanfile import GenConanfile
+from conans.test.assets.sources import gen_function_cpp
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="Requires MSBuild")
+def test_transitive_headers_not_public(transitive_libraries):
+ c = transitive_libraries
+ c.save({"conanfile.py": GenConanfile().with_settings("build_type", "arch")
+ .with_generator("MSBuildDeps").with_requires("libb/0.1")},
+ clean_first=True)
+
+ c.run("install .")
+ liba_data = c.load("conan_liba_vars_release_x64.props")
+ assert "" in liba_data
+ assert "$(ConanlibaRootFolder)/lib;" \
+ in liba_data
+ assert "liba.lib;" in liba_data
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="Requires MSBuild")
+def test_shared_requires_static(transitive_libraries):
+ c = transitive_libraries
+ c.save({"conanfile.py": GenConanfile().with_settings("build_type", "arch")
+ .with_generator("MSBuildDeps").with_requires("libb/0.1")},
+ clean_first=True)
+
+ c.run("install . -o libb*:shared=True")
+ assert not os.path.exists(os.path.join(c.current_folder, "conan_liba_vars_release_x64.props"))
+ libb_data = c.load("conan_libb_vars_release_x64.props")
+ # No dependency to liba, it has been skipped as unnecessary
+ assert "" in libb_data