Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSBuildDeps traits #11680

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions conan/tools/microsoft/msbuilddeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")

Expand Down
28 changes: 28 additions & 0 deletions conans/test/functional/toolchains/conftest.py
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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 "<ConanlibaIncludeDirectories></ConanlibaIncludeDirectories>" in liba_data
assert "<ConanlibaLibraryDirectories>$(ConanlibaRootFolder)/lib;</ConanlibaLibraryDirectories>" \
in liba_data
assert "<ConanlibaLibraries>liba.lib;</ConanlibaLibraries>" 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 "<ConanlibbDependencies></ConanlibbDependencies>" in libb_data