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

Feature: MSBuildDeps generator: CAExcludePath #8682

Merged
merged 7 commits into from Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 21 additions & 1 deletion conan/tools/microsoft/msbuilddeps.py
@@ -1,3 +1,4 @@
import fnmatch
import os
import textwrap
from xml.dom import minidom
Expand Down Expand Up @@ -25,6 +26,7 @@ class MSBuildDeps(object):
<Conan{name}BinaryDirectories>{bin_dirs}</Conan{name}BinaryDirectories>
<Conan{name}Libraries>{libs}</Conan{name}Libraries>
<Conan{name}SystemDeps>{system_libs}</Conan{name}SystemDeps>
<Conan{name}CAExcludeDirectories>{ca_exclude_dirs}</Conan{name}CAExcludeDirectories>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not new "data" definition, shouldn't be defined here, but just in the group below, as an if ca_exclude_path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I follow - it uses the same structure as another definitions...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section contains the pure translation of cpp_info fields, nothing more.
The custom logic of this generator is not defined in this section, but somewhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, then I agree it shouldn't be there

</PropertyGroup>
</Project>
""")
Expand All @@ -42,6 +44,7 @@ class MSBuildDeps(object):
<PropertyGroup>
<LocalDebuggerEnvironment>PATH=%PATH%;$(Conan{name}BinaryDirectories)$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<CAExcludePath>$(Conan{name}CAExcludeDirectories);$(CAExcludePath)</CAExcludePath>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the conditional here, to define it or not (by default, this line shouldn't appear)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do I need condition here? $(Conan{name}CAExcludeDirectories) will just resolve to an empty string, so line will have no effect.

</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
Expand Down Expand Up @@ -74,6 +77,7 @@ def __init__(self, conanfile):
'x86_64': 'x64'}.get(str(conanfile.settings.arch))
# TODO: this is ugly, improve this
self.output_path = os.getcwd()
self.exclude_code_analysis = None

def generate(self):
# TODO: Apply config from command line, something like
Expand All @@ -84,6 +88,14 @@ def generate(self):
# config_filename
# TODO: This is duplicated in write_generators() function, would need to be moved
# to generators and called from there
exclude_code_analysis = self._conanfile.conf["tools.microsoft.msbuilddeps"].exclude_code_analysis
if exclude_code_analysis:
if isinstance(exclude_code_analysis, str):
self.exclude_code_analysis = exclude_code_analysis.split(";")
if self.exclude_code_analysis in [["True"], True]:
self.exclude_code_analysis = ["*"]
elif self.exclude_code_analysis in [["False"], False]:
self.exclude_code_analysis = None
SSE4 marked this conversation as resolved.
Show resolved Hide resolved
if self.configuration is None:
raise ConanException("MSBuildDeps.configuration is None, it should have a value")
if self.platform is None:
Expand Down Expand Up @@ -152,6 +164,13 @@ def add_valid_ext(libname):
ext = os.path.splitext(libname)[1]
return '%s;' % libname if ext in VALID_LIB_EXTENSIONS else '%s.lib;' % libname

exclude_code_analisys = False
if self.exclude_code_analysis:
for pattern in self.exclude_code_analysis:
if fnmatch.fnmatch(name, pattern):
exclude_code_analisys = True
break

SSE4 marked this conversation as resolved.
Show resolved Hide resolved
fields = {
'name': name,
'root_folder': cpp_info.rootpath,
Expand All @@ -164,7 +183,8 @@ def add_valid_ext(libname):
'definitions': "".join("%s;" % d for d in cpp_info.defines),
'compiler_flags': " ".join(cpp_info.cxxflags + cpp_info.cflags),
'linker_flags': " ".join(cpp_info.sharedlinkflags),
'exe_flags': " ".join(cpp_info.exelinkflags)
'exe_flags': " ".join(cpp_info.exelinkflags),
'ca_exclude_dirs': '$(Conan%sIncludeDirectories)' % name if exclude_code_analisys else ''
SSE4 marked this conversation as resolved.
Show resolved Hide resolved
}
formatted_template = self._vars_conf_props.format(**fields)
return formatted_template
Expand Down
49 changes: 49 additions & 0 deletions conans/test/functional/generators/msbuild_test.py
Expand Up @@ -5,6 +5,8 @@

import pytest

from parameterized import parameterized

from conans.test.assets.cpp_test_files import cpp_hello_conan_files
from conans.test.assets.genconanfile import GenConanfile
from conans.test.assets.sources import gen_function_cpp
Expand Down Expand Up @@ -607,3 +609,50 @@ def build(self):
self.assertIn("conan_tool.props", deps)
client.run("create . pkg/0.1@")
self.assertIn("Conan_tools.props in deps", client.out)


@parameterized.expand([("True", True, True),
("*", True, True),
("pkga", True, False),
("pkgb", False, True),
("pkg*", True, True),
("pkga;pkgb", True, True),
("*a;*b", True, True),
("False", False, False),
])
def test_exclude_code_analysis(self, pattern, exclude_a, exclude_b):
client = TestClient()
client.save({"conanfile.py": GenConanfile()})
client.run("create . pkga/1.0@")
client.save({"conanfile.py": GenConanfile()})
client.run("create . pkgb/1.0@")

conanfile = textwrap.dedent("""
from conans import ConanFile, MSBuild
class HelloConan(ConanFile):
settings = "os", "build_type", "compiler", "arch"
requires = "pkgb/1.0@", "pkga/1.0"
generators = "msbuild"
def build(self):
msbuild = MSBuild(self)
msbuild.build("MyProject.sln")
""")
profile = textwrap.dedent("""
include(default)
[conf]
tools.microsoft.msbuilddeps:exclude_code_analysis = %s
""" % pattern)

client.save({"conanfile.py": conanfile,
"profile": profile})
client.run("install . --profile profile")
depa = client.load("conan_pkga_release_x64.props")
depb = client.load("conan_pkgb_release_x64.props")

pattern = "$(ConanpkgaIncludeDirectories)" if exclude_a else ""
pattern = "<ConanpkgaCAExcludeDirectories>%s</ConanpkgaCAExcludeDirectories>" % pattern
self.assertIn(pattern, depa)

pattern = "$(ConanpkgbIncludeDirectories)" if exclude_b else ""
pattern = "<ConanpkgbCAExcludeDirectories>%s</ConanpkgbCAExcludeDirectories>" % pattern
self.assertIn(pattern, depb)