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 4 commits
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
19 changes: 18 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,10 @@ 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 is not None:
self.exclude_code_analysis = eval(exclude_code_analysis)
assert isinstance(self.exclude_code_analysis, (bool, list))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@memsharded I've applied your suggestions, but now, string pattern doesn't work any longer, as you accept only bool and list here.

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 +160,14 @@ 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_analysis = False
if isinstance(self.exclude_code_analysis, list):
for pattern in self.exclude_code_analysis :
if fnmatch.fnmatch(name, pattern):
exclude_code_analysis = True
break
else:
exclude_code_analysis = self.exclude_code_analysis
fields = {
'name': name,
'root_folder': cpp_info.rootpath,
Expand All @@ -164,7 +180,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{}IncludeDirectories)'.format(name) if exclude_code_analysis else ''
}
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)