From 7a60623866146d89296755e43217c73594fe8cb0 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Sat, 31 Dec 2022 15:12:10 +0100 Subject: [PATCH 01/31] MSBuild: ensure to consume props files generated by MSBuildToolchain & MSBuildDeps with highest precedence --- conan/tools/microsoft/msbuild.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index e7a8df5fb37..80c2801e20a 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -1,3 +1,5 @@ +import os + from conans.errors import ConanException @@ -46,6 +48,15 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) + props_paths = [] + for props_file in ("conantoolchain.props", "conandeps.props"): + props_path = os.path.join(self._conanfile.generators_folder, props_file) + if os.path.exists(props_path): + props_paths.append(props_path) + if props_paths: + props_paths = ";".join(props_paths) + cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" + return cmd def build(self, sln, targets=None): From 5326ef5bc4f34805f4d8a0ac50865abc7fc58a17 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Sat, 31 Dec 2022 18:11:31 +0100 Subject: [PATCH 02/31] rely on predictable props names from generators --- conan/tools/microsoft/msbuild.py | 4 +++- conan/tools/microsoft/msbuilddeps.py | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 80c2801e20a..c7787ca7aa1 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -1,5 +1,7 @@ import os +from conan.tools.microsoft.msbuilddeps import MSBuildDeps +from conan.tools.microsoft.toolchain import MSBuildToolchain from conans.errors import ConanException @@ -49,7 +51,7 @@ def command(self, sln, targets=None): cmd += " /target:{}".format(";".join(targets)) props_paths = [] - for props_file in ("conantoolchain.props", "conandeps.props"): + for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): props_path = os.path.join(self._conanfile.generators_folder, props_file) if os.path.exists(props_path): props_paths.append(props_path) diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py index 8e0ab92dcda..99be49ad156 100644 --- a/conan/tools/microsoft/msbuilddeps.py +++ b/conan/tools/microsoft/msbuilddeps.py @@ -19,6 +19,8 @@ class MSBuildDeps(object): """ + filename = "conandeps.props" + _vars_props = textwrap.dedent("""\ @@ -251,7 +253,6 @@ def _conandeps(self): """ this is a .props file including direct declared dependencies """ # Current directory is the generators_folder - conandeps_filename = "conandeps.props" direct_deps = self._conanfile.dependencies.filter({"direct": True}) pkg_aggregated_content = textwrap.dedent("""\ @@ -262,12 +263,12 @@ def _conandeps(self): """) for req, dep in direct_deps.items(): dep_name = self._dep_name(dep, req.build) - filename = "conan_%s.props" % dep_name + dep_filename = "conan_%s.props" % dep_name comp_condition = "'$(conan_%s_props_imported)' != 'True'" % dep_name - pkg_aggregated_content = self._dep_props_file("", conandeps_filename, filename, + pkg_aggregated_content = self._dep_props_file("", self.filename, dep_filename, condition=comp_condition, content=pkg_aggregated_content) - return {conandeps_filename: pkg_aggregated_content} + return {self.filename: pkg_aggregated_content} def _package_props_files(self, dep, build=False): """ all the files for a given package: From 297677677df8ef440251056a7603003c181e09e6 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Sun, 1 Jan 2023 02:18:22 +0100 Subject: [PATCH 03/31] adapt template & tests --- conans/assets/templates/new_v2_msbuild.py | 13 +++------- .../toolchains/microsoft/test_msbuild.py | 14 +++++------ .../toolchains/microsoft/test_msbuilddeps.py | 24 ++----------------- .../microsoft/test_msbuilddeps_components.py | 9 +------ .../microsoft/test_msbuildtoolchain.py | 14 ----------- 5 files changed, 12 insertions(+), 62 deletions(-) diff --git a/conans/assets/templates/new_v2_msbuild.py b/conans/assets/templates/new_v2_msbuild.py index e7f2cc6eef1..3baa3702845 100644 --- a/conans/assets/templates/new_v2_msbuild.py +++ b/conans/assets/templates/new_v2_msbuild.py @@ -61,10 +61,6 @@ {{name}} - - - {{dependencies}} - {{type}} true @@ -399,14 +395,12 @@ def test(self): def get_msbuild_lib_files(name, version, package_name="Pkg"): - d = {"name": name, "version": version, "pkg_name": package_name, "type": "StaticLibrary", - "dependencies": ""} + d = {"name": name, "version": version, "pkg_name": package_name, "type": "StaticLibrary"} sln = Template(sln_file, keep_trailing_newline=True).render(d) vcp = Template(vcxproj, keep_trailing_newline=True).render(d) conanfile = Template(conanfile_sources_v2, keep_trailing_newline=True).render(d) test_d = {"name": "test_" + name, "version": version, "pkg_name": package_name, - "type": "Application", - "dependencies": ''} + "type": "Application"} test_sln = Template(sln_file, keep_trailing_newline=True).render(test_d) test_vcp = Template(vcxproj, keep_trailing_newline=True).render(test_d) test_conanfile = Template(test_conanfile_v2, keep_trailing_newline=True).render(test_d) @@ -496,8 +490,7 @@ def test(self): def get_msbuild_exe_files(name, version, package_name="Pkg"): - d = {"name": name, "version": version, "pkg_name": package_name, "type": "Application", - "dependencies": ""} + d = {"name": name, "version": version, "pkg_name": package_name, "type": "Application"} sln = Template(sln_file, keep_trailing_newline=True).render(d) vcp = Template(vcxproj, keep_trailing_newline=True).render(d) conanfile = Template(conanfile_exe, keep_trailing_newline=True).render(d) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index aeb24a05c2b..d1f23b663bf 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -132,12 +132,6 @@ true Unicode - - - - - @@ -581,9 +575,13 @@ def test_toolchain_win_multi(self): configuration = build_type # The "conan build" command is not good enough, cannot do the switch between configs + props_paths = ";".join([ + os.path.join(client.current_folder, "conan", "conantoolchain.props"), + os.path.join(client.current_folder, "conan", "conandeps.props"), + ]) cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' - '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' - '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) + f'"{vcvars_path}" x64 && msbuild "MyProject.sln" /p:Configuration={configuration} ' + f'/p:Platform={platform_arch} /p:ForceImportBeforeCppTargets="{props_paths}"') client.run_command(cmd) self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py index f36d3bedea6..70554f3a6ee 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py @@ -115,9 +115,6 @@ - - - - - - ' - new = old + ''.format(props=props) - files["MyProject/MyProject.vcxproj"] = files["MyProject/MyProject.vcxproj"].replace(old, new) client.save(files, clean_first=True) client.run('install . -s compiler="Visual Studio"' ' -s compiler.version={vs_version}'.format(vs_version=vs_version)) @@ -828,10 +816,6 @@ def build(self): main_cpp = gen_function_cpp(name="main", includes=["mydep_pkg_team"], calls=["mydep_pkg_team"]) files["MyProject/main.cpp"] = main_cpp files["conanfile.py"] = consumer - props = os.path.join(client.current_folder, "conandeps.props") - old = r'' - new = old + ''.format(props=props) - files["MyProject/MyProject.vcxproj"] = files["MyProject/MyProject.vcxproj"].replace(old, new) client.save(files, clean_first=True) client.run('install . -s compiler.version={vs_version}'.format(vs_version=vs_version)) client.run("build .") @@ -915,10 +899,6 @@ def build(self): - - - - diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py index ae62297b99a..ac58fb24a49 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py @@ -153,16 +153,9 @@ def package_info(self): 'requires="chat/1.0"\n' ' generators = "MSBuildDeps"\n' ' settings = ') - vcproj = client.load("greet.vcxproj") - vcproj2 = vcproj.replace(r'', - r""" - - """) - assert vcproj2 != vcproj client.save({"conanfile.py": conanfile, "src/greet.cpp": gen_function_cpp(name="main", includes=["chat"], - calls=["chat"]), - "greet.vcxproj": vcproj2}) + calls=["chat"])}) client.run("create .") assert "main: Release!" in client.out assert "core/1.0: Hello World Release!" in client.out diff --git a/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py b/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py index c60a56fbae6..2ae688e5981 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py @@ -1,22 +1,11 @@ import platform import sys import textwrap -import os import pytest -try: - from unittest.mock import MagicMock -except: - from mock import MagicMock -from conan.tools.files import replace_in_file from conans.test.utils.tools import TestClient -toolchain_props = """ - - -""" - @pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2") @pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows") @@ -42,9 +31,6 @@ def test_msbuildtoolchain_props_with_extra_flags(): client.save({ "myprofile": profile }) - # Let's import manually the created conantoolchain_release_x64.props - replace_in_file(MagicMock(), os.path.join(client.current_folder, "hello.vcxproj"), - r' ', toolchain_props) client.run("create . -pr myprofile -tf None") assert "/analyze:quiet /doc src/hello.cpp" in client.out assert r"/VERBOSE:UNUSEDLIBS /PDB:mypdbfile x64\Release\hello.obj" in client.out From f6da5206b86b8ab182f82a99293b2e3e48c5e4ae Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Sun, 1 Jan 2023 02:48:32 +0100 Subject: [PATCH 04/31] force PlatformToolset from msbuild command line --- conan/tools/microsoft/msbuild.py | 5 +++ conan/tools/microsoft/toolchain.py | 35 ++----------------- conan/tools/microsoft/visual.py | 32 +++++++++++++++++ .../toolchains/microsoft/test_msbuild.py | 3 +- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index c7787ca7aa1..15bf81930da 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -2,6 +2,7 @@ from conan.tools.microsoft.msbuilddeps import MSBuildDeps from conan.tools.microsoft.toolchain import MSBuildToolchain +from conan.tools.microsoft.visual import msvs_toolset from conans.errors import ConanException @@ -31,6 +32,7 @@ def __init__(self, conanfile): if conanfile.settings.get_safe("os") == "WindowsCE": msvc_arch = conanfile.settings.get_safe("os.platform") self.platform = msvc_arch + self.toolset = msvs_toolset(conanfile) def command(self, sln, targets=None): cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' @@ -50,6 +52,9 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) + if self.toolset: + cmd += f" /p:PlatformToolset=\"{self.toolset}\"" + props_paths = [] for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): props_path = os.path.join(self._conanfile.generators_folder, props_file) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index b98f6be4560..f3a0781789a 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -7,7 +7,7 @@ from conan.tools._check_build_profile import check_using_build_profile from conan.tools.build import build_jobs from conan.tools.intel.intel_cc import IntelCC -from conan.tools.microsoft.visual import VCVars, msvc_version_to_toolset_version +from conan.tools.microsoft.visual import msvs_toolset, VCVars from conans.errors import ConanException from conans.util.files import save, load @@ -54,7 +54,7 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.build_type self.runtime_library = self._runtime_library(conanfile.settings) self.cppstd = conanfile.settings.get_safe("compiler.cppstd") - self.toolset = self._msvs_toolset(conanfile) + self.toolset = msvs_toolset(conanfile) self.properties = {} check_using_build_profile(self._conanfile) @@ -82,37 +82,6 @@ def generate(self): else: VCVars(self._conanfile).generate() - @staticmethod - def _msvs_toolset(conanfile): - settings = conanfile.settings - compiler = settings.get_safe("compiler") - compiler_version = settings.get_safe("compiler.version") - if compiler == "msvc": - subs_toolset = settings.get_safe("compiler.toolset") - if subs_toolset: - return subs_toolset - return msvc_version_to_toolset_version(compiler_version) - if compiler == "intel": - compiler_version = compiler_version if "." in compiler_version else \ - "%s.0" % compiler_version - return "Intel C++ Compiler " + compiler_version - if compiler == "intel-cc": - return IntelCC(conanfile).ms_toolset - if compiler == "Visual Studio": - toolset = settings.get_safe("compiler.toolset") - if not toolset: - toolsets = {"17": "v143", - "16": "v142", - "15": "v141", - "14": "v140", - "12": "v120", - "11": "v110", - "10": "v100", - "9": "v90", - "8": "v80"} - toolset = toolsets.get(compiler_version) - return toolset or "" - @staticmethod def _runtime_library(settings): compiler = settings.compiler diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index 882b867e5d5..72dddfdb6ac 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -1,6 +1,7 @@ import os import textwrap +from conan.tools.intel.intel_cc import IntelCC from conans.client.tools import vs_installation_path from conans.client.tools.version import Version from conans.errors import ConanException, ConanInvalidConfiguration @@ -268,3 +269,34 @@ def is_msvc_static_runtime(conanfile): :return: True, if msvc + runtime MT. Otherwise, False """ return is_msvc(conanfile) and "MT" in msvc_runtime_flag(conanfile) + + +def msvs_toolset(conanfile): + settings = conanfile.settings + compiler = settings.get_safe("compiler") + compiler_version = settings.get_safe("compiler.version") + if compiler == "msvc": + subs_toolset = settings.get_safe("compiler.toolset") + if subs_toolset: + return subs_toolset + return msvc_version_to_toolset_version(compiler_version) + if compiler == "intel": + compiler_version = compiler_version if "." in compiler_version else \ + "%s.0" % compiler_version + return "Intel C++ Compiler " + compiler_version + if compiler == "intel-cc": + return IntelCC(conanfile).ms_toolset + if compiler == "Visual Studio": + toolset = settings.get_safe("compiler.toolset") + if not toolset: + toolsets = {"17": "v143", + "16": "v142", + "15": "v141", + "14": "v140", + "12": "v120", + "11": "v110", + "10": "v100", + "9": "v90", + "8": "v80"} + toolset = toolsets.get(compiler_version) + return toolset or "" diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index d1f23b663bf..8cdee79e74f 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -581,7 +581,8 @@ def test_toolchain_win_multi(self): ]) cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' f'"{vcvars_path}" x64 && msbuild "MyProject.sln" /p:Configuration={configuration} ' - f'/p:Platform={platform_arch} /p:ForceImportBeforeCppTargets="{props_paths}"') + f'/p:Platform={platform_arch} /p:PlatformToolset={self.toolset} ' + f'/p:ForceImportBeforeCppTargets="{props_paths}"') client.run_command(cmd) self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) From d0fc429198fa8a95f18d937b8db15ad82eb3ad97 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Sun, 1 Jan 2023 18:02:19 +0100 Subject: [PATCH 05/31] move /p options first --- conan/tools/microsoft/msbuild.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 15bf81930da..4d49c612401 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -35,8 +35,17 @@ def __init__(self, conanfile): self.toolset = msvs_toolset(conanfile) def command(self, sln, targets=None): - cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' - % (sln, self.build_type, self.platform)) + cmd = (f'msbuild "{sln}" /p:Configuration={self.build_type} ' + f"/p:Platform={self.platform} /p:PlatformToolset={self.toolset}") + + props_paths = [] + for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): + props_path = os.path.join(self._conanfile.generators_folder, props_file) + if os.path.exists(props_path): + props_paths.append(props_path) + if props_paths: + props_paths = ";".join(props_paths) + cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" verbosity = msbuild_verbosity_cmd_line_arg(self._conanfile) if verbosity: @@ -52,18 +61,6 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) - if self.toolset: - cmd += f" /p:PlatformToolset=\"{self.toolset}\"" - - props_paths = [] - for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): - props_path = os.path.join(self._conanfile.generators_folder, props_file) - if os.path.exists(props_path): - props_paths.append(props_path) - if props_paths: - props_paths = ";".join(props_paths) - cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" - return cmd def build(self, sln, targets=None): From 86762f7c2c2b97e4e82159075ca24a086d511077 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:17:42 +0100 Subject: [PATCH 06/31] allow to disable automatic injection of dependencies props --- conan/tools/microsoft/msbuild.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 4d49c612401..8031a07713d 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -34,12 +34,16 @@ def __init__(self, conanfile): self.platform = msvc_arch self.toolset = msvs_toolset(conanfile) - def command(self, sln, targets=None): + def command(self, sln, targets=None, auto_inject_deps_props=True): cmd = (f'msbuild "{sln}" /p:Configuration={self.build_type} ' f"/p:Platform={self.platform} /p:PlatformToolset={self.toolset}") + # Autoconsume toolchain props, but opt-out dependencies props props_paths = [] - for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): + props_candidates = [MSBuildToolchain.filename] + if auto_inject_deps_props: + props_candidates.append(MSBuildDeps.filename) + for props_file in props_candidates: props_path = os.path.join(self._conanfile.generators_folder, props_file) if os.path.exists(props_path): props_paths.append(props_path) @@ -63,8 +67,8 @@ def command(self, sln, targets=None): return cmd - def build(self, sln, targets=None): - cmd = self.command(sln, targets=targets) + def build(self, sln, targets=None, auto_inject_deps_props=True): + cmd = self.command(sln, targets=targets, auto_inject_deps_props=auto_inject_deps_props) self._conanfile.run(cmd) @staticmethod From 17d39c25ba53884e14ad2535da5c9a6a2d92d7f2 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:43:13 +0100 Subject: [PATCH 07/31] Revert "allow to disable automatic injection of dependencies props" This reverts commit 86762f7c2c2b97e4e82159075ca24a086d511077. --- conan/tools/microsoft/msbuild.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 8031a07713d..4d49c612401 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -34,16 +34,12 @@ def __init__(self, conanfile): self.platform = msvc_arch self.toolset = msvs_toolset(conanfile) - def command(self, sln, targets=None, auto_inject_deps_props=True): + def command(self, sln, targets=None): cmd = (f'msbuild "{sln}" /p:Configuration={self.build_type} ' f"/p:Platform={self.platform} /p:PlatformToolset={self.toolset}") - # Autoconsume toolchain props, but opt-out dependencies props props_paths = [] - props_candidates = [MSBuildToolchain.filename] - if auto_inject_deps_props: - props_candidates.append(MSBuildDeps.filename) - for props_file in props_candidates: + for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): props_path = os.path.join(self._conanfile.generators_folder, props_file) if os.path.exists(props_path): props_paths.append(props_path) @@ -67,8 +63,8 @@ def command(self, sln, targets=None, auto_inject_deps_props=True): return cmd - def build(self, sln, targets=None, auto_inject_deps_props=True): - cmd = self.command(sln, targets=targets, auto_inject_deps_props=auto_inject_deps_props) + def build(self, sln, targets=None): + cmd = self.command(sln, targets=targets) self._conanfile.run(cmd) @staticmethod From 9ea12f87466d2a3e24ea63d68d9fdf90b25ef72c Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:43:25 +0100 Subject: [PATCH 08/31] Revert "move /p options first" This reverts commit d0fc429198fa8a95f18d937b8db15ad82eb3ad97. --- conan/tools/microsoft/msbuild.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 4d49c612401..15bf81930da 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -35,17 +35,8 @@ def __init__(self, conanfile): self.toolset = msvs_toolset(conanfile) def command(self, sln, targets=None): - cmd = (f'msbuild "{sln}" /p:Configuration={self.build_type} ' - f"/p:Platform={self.platform} /p:PlatformToolset={self.toolset}") - - props_paths = [] - for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): - props_path = os.path.join(self._conanfile.generators_folder, props_file) - if os.path.exists(props_path): - props_paths.append(props_path) - if props_paths: - props_paths = ";".join(props_paths) - cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" + cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' + % (sln, self.build_type, self.platform)) verbosity = msbuild_verbosity_cmd_line_arg(self._conanfile) if verbosity: @@ -61,6 +52,18 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) + if self.toolset: + cmd += f" /p:PlatformToolset=\"{self.toolset}\"" + + props_paths = [] + for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): + props_path = os.path.join(self._conanfile.generators_folder, props_file) + if os.path.exists(props_path): + props_paths.append(props_path) + if props_paths: + props_paths = ";".join(props_paths) + cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" + return cmd def build(self, sln, targets=None): From 8730bae5c122af25c844f90905c6d4dce0a3023b Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:43:36 +0100 Subject: [PATCH 09/31] Revert "force PlatformToolset from msbuild command line" This reverts commit f6da5206b86b8ab182f82a99293b2e3e48c5e4ae. --- conan/tools/microsoft/msbuild.py | 5 --- conan/tools/microsoft/toolchain.py | 35 +++++++++++++++++-- conan/tools/microsoft/visual.py | 32 ----------------- .../toolchains/microsoft/test_msbuild.py | 3 +- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 15bf81930da..c7787ca7aa1 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -2,7 +2,6 @@ from conan.tools.microsoft.msbuilddeps import MSBuildDeps from conan.tools.microsoft.toolchain import MSBuildToolchain -from conan.tools.microsoft.visual import msvs_toolset from conans.errors import ConanException @@ -32,7 +31,6 @@ def __init__(self, conanfile): if conanfile.settings.get_safe("os") == "WindowsCE": msvc_arch = conanfile.settings.get_safe("os.platform") self.platform = msvc_arch - self.toolset = msvs_toolset(conanfile) def command(self, sln, targets=None): cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' @@ -52,9 +50,6 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) - if self.toolset: - cmd += f" /p:PlatformToolset=\"{self.toolset}\"" - props_paths = [] for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): props_path = os.path.join(self._conanfile.generators_folder, props_file) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index f3a0781789a..b98f6be4560 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -7,7 +7,7 @@ from conan.tools._check_build_profile import check_using_build_profile from conan.tools.build import build_jobs from conan.tools.intel.intel_cc import IntelCC -from conan.tools.microsoft.visual import msvs_toolset, VCVars +from conan.tools.microsoft.visual import VCVars, msvc_version_to_toolset_version from conans.errors import ConanException from conans.util.files import save, load @@ -54,7 +54,7 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.build_type self.runtime_library = self._runtime_library(conanfile.settings) self.cppstd = conanfile.settings.get_safe("compiler.cppstd") - self.toolset = msvs_toolset(conanfile) + self.toolset = self._msvs_toolset(conanfile) self.properties = {} check_using_build_profile(self._conanfile) @@ -82,6 +82,37 @@ def generate(self): else: VCVars(self._conanfile).generate() + @staticmethod + def _msvs_toolset(conanfile): + settings = conanfile.settings + compiler = settings.get_safe("compiler") + compiler_version = settings.get_safe("compiler.version") + if compiler == "msvc": + subs_toolset = settings.get_safe("compiler.toolset") + if subs_toolset: + return subs_toolset + return msvc_version_to_toolset_version(compiler_version) + if compiler == "intel": + compiler_version = compiler_version if "." in compiler_version else \ + "%s.0" % compiler_version + return "Intel C++ Compiler " + compiler_version + if compiler == "intel-cc": + return IntelCC(conanfile).ms_toolset + if compiler == "Visual Studio": + toolset = settings.get_safe("compiler.toolset") + if not toolset: + toolsets = {"17": "v143", + "16": "v142", + "15": "v141", + "14": "v140", + "12": "v120", + "11": "v110", + "10": "v100", + "9": "v90", + "8": "v80"} + toolset = toolsets.get(compiler_version) + return toolset or "" + @staticmethod def _runtime_library(settings): compiler = settings.compiler diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index 72dddfdb6ac..882b867e5d5 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -1,7 +1,6 @@ import os import textwrap -from conan.tools.intel.intel_cc import IntelCC from conans.client.tools import vs_installation_path from conans.client.tools.version import Version from conans.errors import ConanException, ConanInvalidConfiguration @@ -269,34 +268,3 @@ def is_msvc_static_runtime(conanfile): :return: True, if msvc + runtime MT. Otherwise, False """ return is_msvc(conanfile) and "MT" in msvc_runtime_flag(conanfile) - - -def msvs_toolset(conanfile): - settings = conanfile.settings - compiler = settings.get_safe("compiler") - compiler_version = settings.get_safe("compiler.version") - if compiler == "msvc": - subs_toolset = settings.get_safe("compiler.toolset") - if subs_toolset: - return subs_toolset - return msvc_version_to_toolset_version(compiler_version) - if compiler == "intel": - compiler_version = compiler_version if "." in compiler_version else \ - "%s.0" % compiler_version - return "Intel C++ Compiler " + compiler_version - if compiler == "intel-cc": - return IntelCC(conanfile).ms_toolset - if compiler == "Visual Studio": - toolset = settings.get_safe("compiler.toolset") - if not toolset: - toolsets = {"17": "v143", - "16": "v142", - "15": "v141", - "14": "v140", - "12": "v120", - "11": "v110", - "10": "v100", - "9": "v90", - "8": "v80"} - toolset = toolsets.get(compiler_version) - return toolset or "" diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 8cdee79e74f..d1f23b663bf 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -581,8 +581,7 @@ def test_toolchain_win_multi(self): ]) cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' f'"{vcvars_path}" x64 && msbuild "MyProject.sln" /p:Configuration={configuration} ' - f'/p:Platform={platform_arch} /p:PlatformToolset={self.toolset} ' - f'/p:ForceImportBeforeCppTargets="{props_paths}"') + f'/p:Platform={platform_arch} /p:ForceImportBeforeCppTargets="{props_paths}"') client.run_command(cmd) self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) From d3e48ba40c3e46fa34da1de445f108c2ae267452 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:43:45 +0100 Subject: [PATCH 10/31] Revert "adapt template & tests" This reverts commit 297677677df8ef440251056a7603003c181e09e6. --- conans/assets/templates/new_v2_msbuild.py | 13 +++++++--- .../toolchains/microsoft/test_msbuild.py | 14 ++++++----- .../toolchains/microsoft/test_msbuilddeps.py | 24 +++++++++++++++++-- .../microsoft/test_msbuilddeps_components.py | 9 ++++++- .../microsoft/test_msbuildtoolchain.py | 14 +++++++++++ 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/conans/assets/templates/new_v2_msbuild.py b/conans/assets/templates/new_v2_msbuild.py index 3baa3702845..e7f2cc6eef1 100644 --- a/conans/assets/templates/new_v2_msbuild.py +++ b/conans/assets/templates/new_v2_msbuild.py @@ -61,6 +61,10 @@ {{name}} + + + {{dependencies}} + {{type}} true @@ -395,12 +399,14 @@ def test(self): def get_msbuild_lib_files(name, version, package_name="Pkg"): - d = {"name": name, "version": version, "pkg_name": package_name, "type": "StaticLibrary"} + d = {"name": name, "version": version, "pkg_name": package_name, "type": "StaticLibrary", + "dependencies": ""} sln = Template(sln_file, keep_trailing_newline=True).render(d) vcp = Template(vcxproj, keep_trailing_newline=True).render(d) conanfile = Template(conanfile_sources_v2, keep_trailing_newline=True).render(d) test_d = {"name": "test_" + name, "version": version, "pkg_name": package_name, - "type": "Application"} + "type": "Application", + "dependencies": ''} test_sln = Template(sln_file, keep_trailing_newline=True).render(test_d) test_vcp = Template(vcxproj, keep_trailing_newline=True).render(test_d) test_conanfile = Template(test_conanfile_v2, keep_trailing_newline=True).render(test_d) @@ -490,7 +496,8 @@ def test(self): def get_msbuild_exe_files(name, version, package_name="Pkg"): - d = {"name": name, "version": version, "pkg_name": package_name, "type": "Application"} + d = {"name": name, "version": version, "pkg_name": package_name, "type": "Application", + "dependencies": ""} sln = Template(sln_file, keep_trailing_newline=True).render(d) vcp = Template(vcxproj, keep_trailing_newline=True).render(d) conanfile = Template(conanfile_exe, keep_trailing_newline=True).render(d) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index d1f23b663bf..aeb24a05c2b 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -132,6 +132,12 @@ true Unicode + + + + + @@ -575,13 +581,9 @@ def test_toolchain_win_multi(self): configuration = build_type # The "conan build" command is not good enough, cannot do the switch between configs - props_paths = ";".join([ - os.path.join(client.current_folder, "conan", "conantoolchain.props"), - os.path.join(client.current_folder, "conan", "conandeps.props"), - ]) cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' - f'"{vcvars_path}" x64 && msbuild "MyProject.sln" /p:Configuration={configuration} ' - f'/p:Platform={platform_arch} /p:ForceImportBeforeCppTargets="{props_paths}"') + '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' + '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py index 70554f3a6ee..f36d3bedea6 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py @@ -115,6 +115,9 @@ + + + + + + ' + new = old + ''.format(props=props) + files["MyProject/MyProject.vcxproj"] = files["MyProject/MyProject.vcxproj"].replace(old, new) client.save(files, clean_first=True) client.run('install . -s compiler="Visual Studio"' ' -s compiler.version={vs_version}'.format(vs_version=vs_version)) @@ -816,6 +828,10 @@ def build(self): main_cpp = gen_function_cpp(name="main", includes=["mydep_pkg_team"], calls=["mydep_pkg_team"]) files["MyProject/main.cpp"] = main_cpp files["conanfile.py"] = consumer + props = os.path.join(client.current_folder, "conandeps.props") + old = r'' + new = old + ''.format(props=props) + files["MyProject/MyProject.vcxproj"] = files["MyProject/MyProject.vcxproj"].replace(old, new) client.save(files, clean_first=True) client.run('install . -s compiler.version={vs_version}'.format(vs_version=vs_version)) client.run("build .") @@ -899,6 +915,10 @@ def build(self): + + + + diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py index ac58fb24a49..ae62297b99a 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps_components.py @@ -153,9 +153,16 @@ def package_info(self): 'requires="chat/1.0"\n' ' generators = "MSBuildDeps"\n' ' settings = ') + vcproj = client.load("greet.vcxproj") + vcproj2 = vcproj.replace(r'', + r""" + + """) + assert vcproj2 != vcproj client.save({"conanfile.py": conanfile, "src/greet.cpp": gen_function_cpp(name="main", includes=["chat"], - calls=["chat"])}) + calls=["chat"]), + "greet.vcxproj": vcproj2}) client.run("create .") assert "main: Release!" in client.out assert "core/1.0: Hello World Release!" in client.out diff --git a/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py b/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py index 2ae688e5981..c60a56fbae6 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuildtoolchain.py @@ -1,11 +1,22 @@ import platform import sys import textwrap +import os import pytest +try: + from unittest.mock import MagicMock +except: + from mock import MagicMock +from conan.tools.files import replace_in_file from conans.test.utils.tools import TestClient +toolchain_props = """ + + +""" + @pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2") @pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows") @@ -31,6 +42,9 @@ def test_msbuildtoolchain_props_with_extra_flags(): client.save({ "myprofile": profile }) + # Let's import manually the created conantoolchain_release_x64.props + replace_in_file(MagicMock(), os.path.join(client.current_folder, "hello.vcxproj"), + r' ', toolchain_props) client.run("create . -pr myprofile -tf None") assert "/analyze:quiet /doc src/hello.cpp" in client.out assert r"/VERBOSE:UNUSEDLIBS /PDB:mypdbfile x64\Release\hello.obj" in client.out From 24d75e5123ed457dd9c73eb452c6b4c45909fd25 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:55:38 +0100 Subject: [PATCH 11/31] add force_import_generated_files argument to MSBuild.build() this argument is disabled by default. When enabled, it automatically injects props files generated by MSBuildToolchain and MSBuildDeps. A new attribute configuration is added to MSBuild, because we have to extract properties from MSBuildToolchain for the configuration/platform. --- conan/tools/microsoft/msbuild.py | 98 +++++++++++++++++++++------- conan/tools/microsoft/msbuilddeps.py | 6 +- conan/tools/microsoft/toolchain.py | 8 +-- conan/tools/microsoft/visual.py | 11 ++++ 4 files changed, 90 insertions(+), 33 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index c7787ca7aa1..0e8964570f6 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -1,7 +1,9 @@ import os +import xml.etree.ElementTree as ET from conan.tools.microsoft.msbuilddeps import MSBuildDeps from conan.tools.microsoft.toolchain import MSBuildToolchain +from conan.tools.microsoft.visual import msbuild_arch from conans.errors import ConanException @@ -13,29 +15,22 @@ def msbuild_verbosity_cmd_line_arg(conanfile): return '/verbosity:{}'.format(verbosity) -def msbuild_arch(arch): - return {'x86': 'x86', - 'x86_64': 'x64', - 'armv7': 'ARM', - 'armv8': 'ARM64'}.get(str(arch)) - - class MSBuild(object): def __init__(self, conanfile): self._conanfile = conanfile self.build_type = conanfile.settings.get_safe("build_type") + self.configuration = conanfile.settings.get_safe("build_type") # if platforms: # msvc_arch.update(platforms) - arch = conanfile.settings.get_safe("arch") - msvc_arch = msbuild_arch(arch) - if conanfile.settings.get_safe("os") == "WindowsCE": - msvc_arch = conanfile.settings.get_safe("os.platform") - self.platform = msvc_arch + self.platform = msbuild_arch(conanfile) - def command(self, sln, targets=None): + def command(self, sln, targets=None, force_import_generated_files=False): cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' % (sln, self.build_type, self.platform)) + if force_import_generated_files: + cmd += f" {self._force_import_generated_files_cmd_line_arg()}" + verbosity = msbuild_verbosity_cmd_line_arg(self._conanfile) if verbosity: cmd += " {}".format(verbosity) @@ -50,22 +45,77 @@ def command(self, sln, targets=None): raise ConanException("targets argument should be a list") cmd += " /target:{}".format(";".join(targets)) - props_paths = [] - for props_file in (MSBuildToolchain.filename, MSBuildDeps.filename): - props_path = os.path.join(self._conanfile.generators_folder, props_file) - if os.path.exists(props_path): - props_paths.append(props_path) - if props_paths: - props_paths = ";".join(props_paths) - cmd += f" /p:ForceImportBeforeCppTargets=\"{props_paths}\"" - return cmd - def build(self, sln, targets=None): - cmd = self.command(sln, targets=targets) + def build(self, sln, targets=None, force_import_generated_files=False): + cmd = self.command(sln, targets=targets, force_import_generated_files=force_import_generated_files) self._conanfile.run(cmd) @staticmethod def get_version(_): return NotImplementedError("get_version() method is not supported in MSBuild " "toolchain helper") + + def _get_concrete_props_file(self, root_props_file): + concrete_props_file = "" + + root = ET.parse(root_props_file).getroot() + importgroup_element = root.find("ImportGroup") + if importgroup_element: + expected_condition = f"'$(Configuration)' == '{self.configuration}' And '$(Platform)' == '{self.platform}'" + for import_element in importgroup_element.iter("Import"): + condition = import_element.attrib.get("Condition") + if expected_condition == condition: + concrete_props_file = import_element.attrib.get("Project") + break + + if concrete_props_file: + concrete_props_file = os.path.join(self._conanfile.generators_folders, concrete_props_file) + + if not concrete_props_file or not os.path.exists(concrete_props_file): + raise ConanException( + f"MSBuildToolchain props file is missing for configuration={self.configuration} and " + f"platform={self.platform}. 'configuration' and 'platform' attributes must be the same " + "respectively in MSBuildToolchain and MSBuild." + ) + + return concrete_props_file + + def _get_msbuildtoolchain_properties(self, root_props_file): + properties = {} + + # Get properties from props file of configuration and platform + concrete_props_file = self._get_concrete_props_file(root_props_file) + root = ET.parse(concrete_props_file).getroot() + for propertygroup in root.iter("PropertyGroup"): + if propertygroup.attrib.get("Label") == "Configuration": + for child in propertygroup: + properties[child.tag] = child.text + return properties + + def _force_import_generated_files_cmd_line_arg(self): + cmd_args = [] + props_paths = [] + + # MSBuildToolchan must be in generators for this MSBuild mode + msbuildtoolchain_file = os.path.join(self._conanfile.generators_folder, MSBuildToolchain.filename) + if not os.path.exists(msbuildtoolchain_file): + raise ConanException("Missing MSBuildToolchain, it should be added to generators") + props_paths.append(msbuildtoolchain_file) + + # Properties of MSBuildToolchain must be extracted and passed manually through command line + # because they don't have precedence when props file is injected with /p:ForceImportBeforeCppTargets + properties = self._get_msbuildtoolchain_properties(msbuildtoolchain_file) + for k, v in properties.items(): + cmd_args.append(f"/p:{k}=\"{v}\"") + + # MSBuildDeps generator is optional + msbuilddeps_file = os.path.join(self._conanfile.generators_folder, MSBuildDeps.filename) + if os.path.exists(msbuilddeps_file): + props_paths.append(msbuilddeps_file) + + # Inject root props generated by MSBuildToolchain & MSBuildDeps + if props_paths: + cmd_args.append(f"/p:ForceImportBeforeCppTargets=\"{';'.join(props_paths)}\"") + + return " ".join(cmd_args) diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py index 99be49ad156..803a3000089 100644 --- a/conan/tools/microsoft/msbuilddeps.py +++ b/conan/tools/microsoft/msbuilddeps.py @@ -7,6 +7,7 @@ from jinja2 import Template from conan.tools._check_build_profile import check_using_build_profile +from conan.tools.microsoft.visual import msbuild_arch from conans.errors import ConanException from conans.util.files import load, save @@ -96,10 +97,7 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.build_type # TODO: This platform is not exactly the same as ``msbuild_arch``, because it differs # in x86=>Win32 - self.platform = {'x86': 'Win32', - 'x86_64': 'x64', - 'armv7': 'ARM', - 'armv8': 'ARM64'}.get(str(conanfile.settings.arch)) + self.platform = msbuild_arch(conanfile) ca_exclude = "tools.microsoft.msbuilddeps:exclude_code_analysis" self.exclude_code_analysis = self._conanfile.conf.get(ca_exclude, check_type=list) check_using_build_profile(self._conanfile) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index b98f6be4560..4d88ae673f5 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -7,7 +7,7 @@ from conan.tools._check_build_profile import check_using_build_profile from conan.tools.build import build_jobs from conan.tools.intel.intel_cc import IntelCC -from conan.tools.microsoft.visual import VCVars, msvc_version_to_toolset_version +from conan.tools.microsoft.visual import VCVars, msbuild_arch, msvc_version_to_toolset_version from conans.errors import ConanException from conans.util.files import save, load @@ -52,6 +52,7 @@ def __init__(self, conanfile): self.cflags = [] self.ldflags = [] self.configuration = conanfile.settings.build_type + self.platform = msbuild_arch(conanfile) self.runtime_library = self._runtime_library(conanfile.settings) self.cppstd = conanfile.settings.get_safe("compiler.cppstd") self.toolset = self._msvs_toolset(conanfile) @@ -62,10 +63,7 @@ def _name_condition(self, settings): props = [("Configuration", self.configuration), # TODO: refactor, put in common with MSBuildDeps. Beware this is != msbuild_arch # because of Win32 - ("Platform", {'x86': 'Win32', - 'x86_64': 'x64', - 'armv7': 'ARM', - 'armv8': 'ARM64'}.get(settings.get_safe("arch")))] + ("Platform", self.platform)] name = "".join("_%s" % v for _, v in props if v is not None) condition = " And ".join("'$(%s)' == '%s'" % (k, v) for k, v in props if v is not None) diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index 882b867e5d5..d84e5895d90 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -268,3 +268,14 @@ def is_msvc_static_runtime(conanfile): :return: True, if msvc + runtime MT. Otherwise, False """ return is_msvc(conanfile) and "MT" in msvc_runtime_flag(conanfile) + + +def msbuild_arch(conanfile): + if conanfile.settings.get_safe("os") == "WindowsCE": + return conanfile.settings.get_safe("os.platform") + return { + "x86": "x86", + "x86_64": "x64", + "armv7": "ARM", + "armv8": "ARM64", + }.get(str(conanfile.settings.get_safe("arch"))) From a42e46f60cb987971bd07d01d1f62ad4fde5063f Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 16:18:47 +0100 Subject: [PATCH 12/31] typo --- conan/tools/microsoft/msbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 0e8964570f6..419135716d5 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -70,7 +70,7 @@ def _get_concrete_props_file(self, root_props_file): break if concrete_props_file: - concrete_props_file = os.path.join(self._conanfile.generators_folders, concrete_props_file) + concrete_props_file = os.path.join(self._conanfile.generators_folder, concrete_props_file) if not concrete_props_file or not os.path.exists(concrete_props_file): raise ConanException( From f42f32c8bb83ba469c0c592cf7c98c199b68d96d Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 17:15:33 +0100 Subject: [PATCH 13/31] take into account namespace in props files --- conan/tools/microsoft/msbuild.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 419135716d5..66067aa8aa2 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -1,4 +1,5 @@ import os +import re import xml.etree.ElementTree as ET from conan.tools.microsoft.msbuilddeps import MSBuildDeps @@ -60,10 +61,12 @@ def _get_concrete_props_file(self, root_props_file): concrete_props_file = "" root = ET.parse(root_props_file).getroot() - importgroup_element = root.find("ImportGroup") + namespace = re.match('\{.*\}', root.tag) + namespace = namespace.group(0) if namespace else "" + importgroup_element = root.find(f"{namespace}ImportGroup") if importgroup_element: expected_condition = f"'$(Configuration)' == '{self.configuration}' And '$(Platform)' == '{self.platform}'" - for import_element in importgroup_element.iter("Import"): + for import_element in importgroup_element.iter(f"{namespace}Import"): condition = import_element.attrib.get("Condition") if expected_condition == condition: concrete_props_file = import_element.attrib.get("Project") @@ -87,10 +90,13 @@ def _get_msbuildtoolchain_properties(self, root_props_file): # Get properties from props file of configuration and platform concrete_props_file = self._get_concrete_props_file(root_props_file) root = ET.parse(concrete_props_file).getroot() - for propertygroup in root.iter("PropertyGroup"): + namespace = re.match('\{.*\}', root.tag) + namespace = namespace.group(0) if namespace else "" + for propertygroup in root.iter(f"{namespace}PropertyGroup"): if propertygroup.attrib.get("Label") == "Configuration": for child in propertygroup: - properties[child.tag] = child.text + propert_name = child.tag.replace(namespace, "") + properties[propert_name] = child.text return properties def _force_import_generated_files_cmd_line_arg(self): From 3d178a6dad12ed77c7bc4dfbd220bbfba3921eab Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 17:47:28 +0100 Subject: [PATCH 14/31] revert WindowsCE logic --- conan/tools/microsoft/msbuild.py | 5 ++++- conan/tools/microsoft/visual.py | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 66067aa8aa2..2996226e63d 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -23,7 +23,10 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.get_safe("build_type") # if platforms: # msvc_arch.update(platforms) - self.platform = msbuild_arch(conanfile) + msvc_arch = msbuild_arch(conanfile) + if conanfile.settings.get_safe("os") == "WindowsCE": + msvc_arch = conanfile.settings.get_safe("os.platform") + self.platform = msvc_arch def command(self, sln, targets=None, force_import_generated_files=False): cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s' diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index d84e5895d90..c155d2d25d7 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -271,8 +271,6 @@ def is_msvc_static_runtime(conanfile): def msbuild_arch(conanfile): - if conanfile.settings.get_safe("os") == "WindowsCE": - return conanfile.settings.get_safe("os.platform") return { "x86": "x86", "x86_64": "x64", From 68a2200af995d50536b9115b69be5b9135d9d458 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 18:11:04 +0100 Subject: [PATCH 15/31] restore difference between msbuild_arch injected by MSBuild and the one used for conditions in props file --- conan/tools/microsoft/msbuild.py | 24 +++++++++++++++++++----- conan/tools/microsoft/msbuilddeps.py | 6 ++++-- conan/tools/microsoft/toolchain.py | 11 +++++++---- conan/tools/microsoft/visual.py | 9 --------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 2996226e63d..73c8503ea31 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -4,7 +4,6 @@ from conan.tools.microsoft.msbuilddeps import MSBuildDeps from conan.tools.microsoft.toolchain import MSBuildToolchain -from conan.tools.microsoft.visual import msbuild_arch from conans.errors import ConanException @@ -16,6 +15,20 @@ def msbuild_verbosity_cmd_line_arg(conanfile): return '/verbosity:{}'.format(verbosity) +def msbuild_arch(arch): + return {'x86': 'x86', + 'x86_64': 'x64', + 'armv7': 'ARM', + 'armv8': 'ARM64'}.get(str(arch)) + + +def msbuild_arch_to_conf_arch(arch): + return {'x86': 'Win32', + 'x64': 'x64', + 'ARM': 'ARM', + 'ARM64': 'ARM64'}.get(str(arch)) + + class MSBuild(object): def __init__(self, conanfile): self._conanfile = conanfile @@ -23,7 +36,8 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.get_safe("build_type") # if platforms: # msvc_arch.update(platforms) - msvc_arch = msbuild_arch(conanfile) + arch = conanfile.settings.get_safe("arch") + msvc_arch = msbuild_arch(arch) if conanfile.settings.get_safe("os") == "WindowsCE": msvc_arch = conanfile.settings.get_safe("os.platform") self.platform = msvc_arch @@ -68,7 +82,8 @@ def _get_concrete_props_file(self, root_props_file): namespace = namespace.group(0) if namespace else "" importgroup_element = root.find(f"{namespace}ImportGroup") if importgroup_element: - expected_condition = f"'$(Configuration)' == '{self.configuration}' And '$(Platform)' == '{self.platform}'" + expected_condition = (f"'$(Configuration)' == '{self.configuration}' And " + f"$(Platform)' == '{msbuild_arch_to_conf_arch(self.platform)}'") for import_element in importgroup_element.iter(f"{namespace}Import"): condition = import_element.attrib.get("Condition") if expected_condition == condition: @@ -81,8 +96,7 @@ def _get_concrete_props_file(self, root_props_file): if not concrete_props_file or not os.path.exists(concrete_props_file): raise ConanException( f"MSBuildToolchain props file is missing for configuration={self.configuration} and " - f"platform={self.platform}. 'configuration' and 'platform' attributes must be the same " - "respectively in MSBuildToolchain and MSBuild." + f"platform={msbuild_arch_to_conf_arch(self.platform)}." ) return concrete_props_file diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py index 803a3000089..99be49ad156 100644 --- a/conan/tools/microsoft/msbuilddeps.py +++ b/conan/tools/microsoft/msbuilddeps.py @@ -7,7 +7,6 @@ from jinja2 import Template from conan.tools._check_build_profile import check_using_build_profile -from conan.tools.microsoft.visual import msbuild_arch from conans.errors import ConanException from conans.util.files import load, save @@ -97,7 +96,10 @@ def __init__(self, conanfile): self.configuration = conanfile.settings.build_type # TODO: This platform is not exactly the same as ``msbuild_arch``, because it differs # in x86=>Win32 - self.platform = msbuild_arch(conanfile) + self.platform = {'x86': 'Win32', + 'x86_64': 'x64', + 'armv7': 'ARM', + 'armv8': 'ARM64'}.get(str(conanfile.settings.arch)) ca_exclude = "tools.microsoft.msbuilddeps:exclude_code_analysis" self.exclude_code_analysis = self._conanfile.conf.get(ca_exclude, check_type=list) check_using_build_profile(self._conanfile) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index 4d88ae673f5..a091d736025 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -7,7 +7,7 @@ from conan.tools._check_build_profile import check_using_build_profile from conan.tools.build import build_jobs from conan.tools.intel.intel_cc import IntelCC -from conan.tools.microsoft.visual import VCVars, msbuild_arch, msvc_version_to_toolset_version +from conan.tools.microsoft.visual import VCVars, msvc_version_to_toolset_version from conans.errors import ConanException from conans.util.files import save, load @@ -52,7 +52,12 @@ def __init__(self, conanfile): self.cflags = [] self.ldflags = [] self.configuration = conanfile.settings.build_type - self.platform = msbuild_arch(conanfile) + # TODO: refactor, put in common with MSBuildDeps. Beware this is != msbuild_arch + # because of Win32 + self.platform = {'x86': 'Win32', + 'x86_64': 'x64', + 'armv7': 'ARM', + 'armv8': 'ARM64'}.get(str(conanfile.settings.arch)) self.runtime_library = self._runtime_library(conanfile.settings) self.cppstd = conanfile.settings.get_safe("compiler.cppstd") self.toolset = self._msvs_toolset(conanfile) @@ -61,8 +66,6 @@ def __init__(self, conanfile): def _name_condition(self, settings): props = [("Configuration", self.configuration), - # TODO: refactor, put in common with MSBuildDeps. Beware this is != msbuild_arch - # because of Win32 ("Platform", self.platform)] name = "".join("_%s" % v for _, v in props if v is not None) diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py index c155d2d25d7..882b867e5d5 100644 --- a/conan/tools/microsoft/visual.py +++ b/conan/tools/microsoft/visual.py @@ -268,12 +268,3 @@ def is_msvc_static_runtime(conanfile): :return: True, if msvc + runtime MT. Otherwise, False """ return is_msvc(conanfile) and "MT" in msvc_runtime_flag(conanfile) - - -def msbuild_arch(conanfile): - return { - "x86": "x86", - "x86_64": "x64", - "armv7": "ARM", - "armv8": "ARM64", - }.get(str(conanfile.settings.get_safe("arch"))) From 04e69cdcb48a485b792fd90a3f10a5d209f38933 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 19:21:48 +0100 Subject: [PATCH 16/31] typo --- conan/tools/microsoft/msbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 73c8503ea31..cad436afe51 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -83,7 +83,7 @@ def _get_concrete_props_file(self, root_props_file): importgroup_element = root.find(f"{namespace}ImportGroup") if importgroup_element: expected_condition = (f"'$(Configuration)' == '{self.configuration}' And " - f"$(Platform)' == '{msbuild_arch_to_conf_arch(self.platform)}'") + f"'$(Platform)' == '{msbuild_arch_to_conf_arch(self.platform)}'") for import_element in importgroup_element.iter(f"{namespace}Import"): condition = import_element.attrib.get("Condition") if expected_condition == condition: From ab5295c442f958503e7c36e5e790b9deb14b0131 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 19:40:07 +0100 Subject: [PATCH 17/31] handle platform overridden as Win32 in MSBuild --- conan/tools/microsoft/msbuild.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index cad436afe51..04b6c31b262 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -23,10 +23,13 @@ def msbuild_arch(arch): def msbuild_arch_to_conf_arch(arch): - return {'x86': 'Win32', - 'x64': 'x64', - 'ARM': 'ARM', - 'ARM64': 'ARM64'}.get(str(arch)) + return { + "Win32": "Win32", + "x86": "Win32", + "x64": "x64", + "ARM": "ARM", + "ARM64": "ARM64", + }.get(str(arch)) class MSBuild(object): From 88cf4c1d79d02dee9a6ed27f20c4754a52a4d82a Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Mon, 2 Jan 2023 23:30:04 +0100 Subject: [PATCH 18/31] improve robustness --- conan/tools/microsoft/msbuild.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py index 04b6c31b262..164f2ac9c60 100644 --- a/conan/tools/microsoft/msbuild.py +++ b/conan/tools/microsoft/msbuild.py @@ -85,13 +85,16 @@ def _get_concrete_props_file(self, root_props_file): namespace = namespace.group(0) if namespace else "" importgroup_element = root.find(f"{namespace}ImportGroup") if importgroup_element: - expected_condition = (f"'$(Configuration)' == '{self.configuration}' And " - f"'$(Platform)' == '{msbuild_arch_to_conf_arch(self.platform)}'") - for import_element in importgroup_element.iter(f"{namespace}Import"): - condition = import_element.attrib.get("Condition") - if expected_condition == condition: - concrete_props_file = import_element.attrib.get("Project") - break + import_elements = importgroup_element.findall(f"{namespace}Import") + if len(import_elements) == 1: + concrete_props_file = import_elements[0].attrib.get("Project") + else: + expected_condition = (f"'$(Configuration)' == '{self.configuration}' And " + f"'$(Platform)' == '{msbuild_arch_to_conf_arch(self.platform)}'") + for import_element in import_elements: + if expected_condition == import_element.attrib.get("Condition"): + concrete_props_file = import_element.attrib.get("Project") + break if concrete_props_file: concrete_props_file = os.path.join(self._conanfile.generators_folder, concrete_props_file) From 0941ed3d62742d8f8e4d58619827701023460def Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 11:00:00 +0100 Subject: [PATCH 19/31] test force_import_generated_files=True flavor --- .../toolchains/microsoft/test_msbuild.py | 143 ++++++++++-------- 1 file changed, 76 insertions(+), 67 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index aeb24a05c2b..5eff28e753d 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -55,8 +55,15 @@ EndGlobal """ +def myapp_vcxproj(force_import_generated_files=False): + intrusive_conan_integration = r""" + + + + +""" -myapp_vcxproj = r""" + return r""" @@ -87,7 +94,7 @@ 15.0 - {B58316C0-C78A-4E9B-AE8F-5D6368CE3840} + {{B58316C0-C78A-4E9B-AE8F-5D6368CE3840}} Win32Proj MyApp @@ -134,10 +141,7 @@ - - - - +{} @@ -302,7 +306,7 @@ -""" +""".format("" if force_import_generated_files else intrusive_conan_integration) @pytest.mark.tool_visual_studio(version='15') @@ -354,61 +358,64 @@ def generate(self): @pytest.mark.tool_visual_studio class WinTest(unittest.TestCase): - conanfile = textwrap.dedent(""" - from conans import ConanFile - from conan.tools.microsoft import MSBuildToolchain, MSBuild, MSBuildDeps - class App(ConanFile): - settings = "os", "arch", "compiler", "build_type" - requires = "hello/0.1" - options = {"shared": [True, False]} - default_options = {"shared": False} - - def layout(self): - self.folders.generators = "conan" - self.folders.build = "." - - def generate(self): - tc = MSBuildToolchain(self) - gen = MSBuildDeps(self) - if self.options["hello"].shared and self.settings.build_type == "Release": - tc.configuration = "ReleaseShared" - gen.configuration = "ReleaseShared" - - tc.preprocessor_definitions["DEFINITIONS_BOTH"] = '"True"' - tc.preprocessor_definitions["DEFINITIONS_BOTH2"] = 'DEFINITIONS_BOTH' - tc.preprocessor_definitions["DEFINITIONS_BOTH_INT"] = 123 - if self.settings.build_type == "Debug": - tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Debug"' - tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 234 - else: - tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Release"' - tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 456 - tc.preprocessor_definitions["DEFINITIONS_CONFIG2"] = 'DEFINITIONS_CONFIG' - - tc.generate() - gen.generate() - - def imports(self): - if self.options["hello"].shared and self.settings.build_type == "Release": - configuration = "ReleaseShared" - if self.settings.arch == "x86_64": - dst = "x64/%s" % configuration - else: - dst = configuration - else: - configuration = self.settings.build_type - dst = "%s/%s" % (self.settings.arch, configuration) - self.copy("*.dll", src="bin", dst=dst, keep_path=False) - - def build(self): - msbuild = MSBuild(self) - msbuild.build("MyProject.sln") - """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"], preprocessor=["DEFINITIONS_BOTH", "DEFINITIONS_BOTH2", "DEFINITIONS_BOTH_INT", "DEFINITIONS_CONFIG", "DEFINITIONS_CONFIG2", "DEFINITIONS_CONFIG_INT"]) + @staticmethod + def _conanfile(force_import_generated_files=False): + return textwrap.dedent(f""" + from conans import ConanFile + from conan.tools.microsoft import MSBuildToolchain, MSBuild, MSBuildDeps + class App(ConanFile): + settings = "os", "arch", "compiler", "build_type" + requires = "hello/0.1" + options = {"shared": [True, False]} + default_options = {"shared": False} + + def layout(self): + self.folders.generators = "conan" + self.folders.build = "." + + def generate(self): + tc = MSBuildToolchain(self) + gen = MSBuildDeps(self) + if self.options["hello"].shared and self.settings.build_type == "Release": + tc.configuration = "ReleaseShared" + gen.configuration = "ReleaseShared" + + tc.preprocessor_definitions["DEFINITIONS_BOTH"] = '"True"' + tc.preprocessor_definitions["DEFINITIONS_BOTH2"] = 'DEFINITIONS_BOTH' + tc.preprocessor_definitions["DEFINITIONS_BOTH_INT"] = 123 + if self.settings.build_type == "Debug": + tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Debug"' + tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 234 + else: + tc.preprocessor_definitions["DEFINITIONS_CONFIG"] = '"Release"' + tc.preprocessor_definitions["DEFINITIONS_CONFIG_INT"] = 456 + tc.preprocessor_definitions["DEFINITIONS_CONFIG2"] = 'DEFINITIONS_CONFIG' + + tc.generate() + gen.generate() + + def imports(self): + if self.options["hello"].shared and self.settings.build_type == "Release": + configuration = "ReleaseShared" + if self.settings.arch == "x86_64": + dst = "x64/%s" % configuration + else: + dst = configuration + else: + configuration = self.settings.build_type + dst = "%s/%s" % (self.settings.arch, configuration) + self.copy("*.dll", src="bin", dst=dst, keep_path=False) + + def build(self): + msbuild = MSBuild(self) + msbuild.build("MyProject.sln", force_import_generated_files={force_import_generated_files}) + """) + @staticmethod def _run_app(client, arch, build_type, shared=None): if build_type == "Release" and shared: @@ -422,16 +429,17 @@ def _run_app(client, arch, build_type, shared=None): command_str = "x64\\%s\\MyApp.exe" % configuration client.run_command(command_str) + @pytest.mark.parametrize("force_import_generated_files", [False, True]) @parameterized.expand([("Visual Studio", "15", "MT", "17"), ("msvc", "191", "static", "17"), ("msvc", "190", "static", "14")] ) @pytest.mark.tool_cmake - def test_toolchain_win_vs2017(self, compiler, version, runtime, cppstd): + def test_toolchain_win_vs2017(self, force_import_generated_files, compiler, version, runtime, cppstd): if self.vs_version != "15": pytest.skip("test for Visual Studio 2017") else: - self.check_toolchain_win(compiler, version, runtime, cppstd) + self.check_toolchain_win(force_import_generated_files, compiler, version, runtime, cppstd) @parameterized.expand([("Visual Studio", "17", "MT", "17"), ("msvc", "193", "static", "17")] @@ -442,7 +450,7 @@ def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd): else: self.check_toolchain_win(compiler, version, runtime, cppstd) - def check_toolchain_win(self, compiler, version, runtime, cppstd): + def check_toolchain_win(self, force_import_generated_files, compiler, version, runtime, cppstd): client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), ("compiler.version", version), @@ -466,9 +474,9 @@ def check_toolchain_win(self, compiler, version, runtime, cppstd): client.run("create . hello/0.1@ %s" % (settings, )) # Prepare the actual consumer package - client.save({"conanfile.py": self.conanfile, + client.save({"conanfile.py": self._conanfile(force_import_generated_files), "MyProject.sln": sln_file, - "MyApp/MyApp.vcxproj": myapp_vcxproj, + "MyApp/MyApp.vcxproj": myapp_vcxproj(force_import_generated_files), "MyApp/MyApp.cpp": self.app, "myprofile": profile}, clean_first=True) @@ -495,8 +503,9 @@ def check_toolchain_win(self, compiler, version, runtime, cppstd): check_vs_runtime("Release/MyApp.exe", client, self.vs_version, build_type="Release", static_runtime=static_runtime) + @pytest.mark.parametrize("force_import_generated_files", [False, True]) @pytest.mark.tool_cmake - def test_toolchain_win_debug(self): + def test_toolchain_win_debug(self, force_import_generated_files): client = TestClient(path_with_spaces=False) settings = [("compiler", "Visual Studio"), ("compiler.version", self.vs_version), @@ -512,9 +521,9 @@ def test_toolchain_win_debug(self): client.run("create . hello/0.1@ %s" % (settings,)) # Prepare the actual consumer package - client.save({"conanfile.py": self.conanfile, + client.save({"conanfile.py": self._conanfile(force_import_generated_files), "MyProject.sln": sln_file, - "MyApp/MyApp.vcxproj": myapp_vcxproj, + "MyApp/MyApp.vcxproj": myapp_vcxproj(force_import_generated_files), "MyApp/MyApp.cpp": self.app}, clean_first=True) @@ -558,9 +567,9 @@ def test_toolchain_win_multi(self): " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) # Prepare the actual consumer package - client.save({"conanfile.py": self.conanfile, + client.save({"conanfile.py": self._conanfile(), "MyProject.sln": sln_file, - "MyApp/MyApp.vcxproj": myapp_vcxproj, + "MyApp/MyApp.vcxproj": myapp_vcxproj(), "MyApp/MyApp.cpp": self.app}, clean_first=True) From b35577a0ce4244196c89dbe2053918e95c425b4c Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 11:59:23 +0100 Subject: [PATCH 20/31] fix tests --- .../toolchains/microsoft/test_msbuild.py | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 5eff28e753d..dce619b81bd 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -57,7 +57,7 @@ def myapp_vcxproj(force_import_generated_files=False): intrusive_conan_integration = r""" - + @@ -371,8 +371,8 @@ def _conanfile(force_import_generated_files=False): class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" - options = {"shared": [True, False]} - default_options = {"shared": False} + options = {{"shared": [True, False]}} + default_options = {{"shared": False}} def layout(self): self.folders.generators = "conan" @@ -429,28 +429,36 @@ def _run_app(client, arch, build_type, shared=None): command_str = "x64\\%s\\MyApp.exe" % configuration client.run_command(command_str) + @pytest.mark.parametrize( + "compiler,version,runtime,cppstd", + [ + ("Visual Studio", "15", "MT", "17"), + ("msvc", "191", "static", "17"), + ("msvc", "190", "static", "14"), + ] + ) @pytest.mark.parametrize("force_import_generated_files", [False, True]) - @parameterized.expand([("Visual Studio", "15", "MT", "17"), - ("msvc", "191", "static", "17"), - ("msvc", "190", "static", "14")] - ) @pytest.mark.tool_cmake - def test_toolchain_win_vs2017(self, force_import_generated_files, compiler, version, runtime, cppstd): + def test_toolchain_win_vs2017(self, compiler, version, runtime, cppstd, force_import_generated_files): if self.vs_version != "15": pytest.skip("test for Visual Studio 2017") else: - self.check_toolchain_win(force_import_generated_files, compiler, version, runtime, cppstd) - - @parameterized.expand([("Visual Studio", "17", "MT", "17"), - ("msvc", "193", "static", "17")] - ) - def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd): + self.check_toolchain_win(compiler, version, runtime, cppstd, force_import_generated_files) + + @pytest.mark.parametrize("compiler,version,runtime,cppstd", + [ + ("Visual Studio", "17", "MT", "17"), + ("msvc", "193", "static", "17"), + ] + ) + @pytest.mark.parametrize("force_import_generated_files", [False, True]) + def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd, force_import_generated_files): if self.vs_version != "17": pytest.skip("test for Visual Studio 2022") else: - self.check_toolchain_win(compiler, version, runtime, cppstd) + self.check_toolchain_win(compiler, version, runtime, cppstd, force_import_generated_files) - def check_toolchain_win(self, force_import_generated_files, compiler, version, runtime, cppstd): + def check_toolchain_win(self, compiler, version, runtime, cppstd, force_import_generated_files): client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), ("compiler.version", version), From 7b8e82ac59cfe0fed30717d6a9f6c774cbc29847 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 12:02:54 +0100 Subject: [PATCH 21/31] fix again --- conans/test/functional/toolchains/microsoft/test_msbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index dce619b81bd..9af80c050f8 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -438,7 +438,6 @@ def _run_app(client, arch, build_type, shared=None): ] ) @pytest.mark.parametrize("force_import_generated_files", [False, True]) - @pytest.mark.tool_cmake def test_toolchain_win_vs2017(self, compiler, version, runtime, cppstd, force_import_generated_files): if self.vs_version != "15": pytest.skip("test for Visual Studio 2017") @@ -458,6 +457,7 @@ def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd, force_im else: self.check_toolchain_win(compiler, version, runtime, cppstd, force_import_generated_files) + @pytest.mark.tool_cmake def check_toolchain_win(self, compiler, version, runtime, cppstd, force_import_generated_files): client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), From b4e08019d74fb9de4b1e0642226dc9b1ff981162 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:38:46 +0100 Subject: [PATCH 22/31] no mixup of unittest, parameterized and pytest --- .../toolchains/microsoft/test_msbuild.py | 199 ++++++++---------- 1 file changed, 89 insertions(+), 110 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 9af80c050f8..f54989c3897 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -1,13 +1,10 @@ import os import platform -import shutil import textwrap -import unittest import pytest -from parameterized import parameterized, parameterized_class -from conan.tools.microsoft.visual import vcvars_command +from conan.tools.microsoft.visual import msvc_version_to_vs_ide_version, vcvars_command from conans.client.tools import vs_installation_path from conans.test.assets.sources import gen_function_cpp from conans.test.conftest import tools_locations @@ -347,22 +344,47 @@ def generate(self): assert "MSVC FLAG=MD!!" in client.out -vs_versions = [{"vs_version": "15", "msvc_version": "191", "ide_year": "2017", "toolset": "v141"}] - -if "17" in tools_locations['visual_studio'] and not tools_locations['visual_studio']['17'].get('disabled', False): - vs_versions.append({"vs_version": "17", "msvc_version": "193", "ide_year": "2022", "toolset": "v143"}) - - -@parameterized_class(vs_versions) @pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows") @pytest.mark.tool_visual_studio -class WinTest(unittest.TestCase): +class TestMSBuild: app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"], preprocessor=["DEFINITIONS_BOTH", "DEFINITIONS_BOTH2", "DEFINITIONS_BOTH_INT", "DEFINITIONS_CONFIG", "DEFINITIONS_CONFIG2", "DEFINITIONS_CONFIG_INT"]) + _vs_versions = { + "11": { + "msvc_version": "170", + "ide_year": "2012", + }, + "12": { + "msvc_version": "180", + "ide_year": "2013", + }, + "14": { + "msvc_version": "190", + "ide_year": "2015", + }, + "15": { + "msvc_version": "191", + "ide_year": "2017", + }, + "16": { + "msvc_version": "192", + "ide_year": "2019", + }, + "17": { + "msvc_version": "193", + "ide_year": "2022", + }, + } + + @staticmethod + def _has_tool_vc(vs_version): + return vs_version in tools_locations["visual_studio"] and \ + not tools_locations["visual_studio"][vs_version].get("disabled", False) + @staticmethod def _conanfile(force_import_generated_files=False): return textwrap.dedent(f""" @@ -429,51 +451,40 @@ def _run_app(client, arch, build_type, shared=None): command_str = "x64\\%s\\MyApp.exe" % configuration client.run_command(command_str) - @pytest.mark.parametrize( - "compiler,version,runtime,cppstd", - [ - ("Visual Studio", "15", "MT", "17"), - ("msvc", "191", "static", "17"), - ("msvc", "190", "static", "14"), - ] - ) - @pytest.mark.parametrize("force_import_generated_files", [False, True]) - def test_toolchain_win_vs2017(self, compiler, version, runtime, cppstd, force_import_generated_files): - if self.vs_version != "15": - pytest.skip("test for Visual Studio 2017") - else: - self.check_toolchain_win(compiler, version, runtime, cppstd, force_import_generated_files) - - @pytest.mark.parametrize("compiler,version,runtime,cppstd", - [ - ("Visual Studio", "17", "MT", "17"), - ("msvc", "193", "static", "17"), - ] - ) + @pytest.mark.parametrize("arch", ["x86", "x86_64"]) + @pytest.mark.parametrize("compiler,version,runtime,cppstd", [("msvc", "190", "static", "14"), + ("Visual Studio", "15", "MT", "17"), + ("msvc", "191", "static", "17"), + ("Visual Studio", "17", "MT", "17"), + ("msvc", "193", "static", "17")]) + @pytest.mark.parametrize("build_type", ["Debug", "Release"]) @pytest.mark.parametrize("force_import_generated_files", [False, True]) - def test_toolchain_win_vs2022(self, compiler, version, runtime, cppstd, force_import_generated_files): - if self.vs_version != "17": - pytest.skip("test for Visual Studio 2022") - else: - self.check_toolchain_win(compiler, version, runtime, cppstd, force_import_generated_files) - @pytest.mark.tool_cmake - def check_toolchain_win(self, compiler, version, runtime, cppstd, force_import_generated_files): + def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_type, force_import_generated_files): + vs_version = msvc_version_to_vs_ide_version(version) if compiler == "msvc" else version + if not self._has_tool_vc(vs_version): + pytest.skip(f"Visual Studio {vs_version} not installed") + + if compiler == "Visual Studio" and build_type == "Debug": + runtime += "d" + client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), ("compiler.version", version), ("compiler.cppstd", cppstd), ("compiler.runtime", runtime), - ("build_type", "Release"), - ("arch", "x86")] + ("build_type", build_type), + ("arch", arch)] + if compiler == "msvc": + settings.append(("compiler.runtime_type"), "Debug" if build_type == "Debug" else "Release") - profile = textwrap.dedent(""" + profile = textwrap.dedent(f""" [settings] os=Windows [conf] tools.microsoft.msbuild:vs_version={vs_version} - """.format(vs_version=self.vs_version)) + """) client.save({"myprofile": profile}) # Build the profile according to the settings provided settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) @@ -491,75 +502,43 @@ def check_toolchain_win(self, compiler, version, runtime, cppstd, force_import_g # Run the configure corresponding to this test case client.run("install . %s -if=conan -pr=myprofile" % (settings, )) - self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_release_win32.props", - client.out) + props_arch = { + "x86": "Win32", + "x86_64": "x64", + "armv7": "ARM", + "armv8": "ARM64", + }[arch] + props_file = f"conantoolchain_{build_type.lower()}_{props_arch}.props" + self.assertIn(f"conanfile.py: MSBuildToolchain created {props_file}", client.out) client.run("build . -if=conan") - self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) - self.assertIn("[vcvarsall.bat] Environment initialized for: 'x86'", client.out) - - self._run_app(client, "x86", "Release") - self.assertIn("Hello World Release", client.out) - compiler_version = version if compiler == "msvc" else self.msvc_version - check_exe_run(client.out, "main", "msvc", compiler_version, "Release", "x86", cppstd, - {"DEFINITIONS_BOTH": 'True', + self.assertIn("Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]), client.out) + self.assertIn(f"[vcvarsall.bat] Environment initialized for: '{arch}'", client.out) + + self._run_app(client, arch, build_type) + self.assertIn(f"Hello World {build_type}", client.out) + compiler_version = self._vs_versions[vs_version]["msvc_version"] + check_exe_run(client.out, "main", "msvc", compiler_version, build_type, arch, cppstd, + {"DEFINITIONS_BOTH": "True", "DEFINITIONS_BOTH2": "True", "DEFINITIONS_BOTH_INT": "123", - "DEFINITIONS_CONFIG": 'Release', - "DEFINITIONS_CONFIG2": 'Release', - "DEFINITIONS_CONFIG_INT": "456"}) - static_runtime = True if runtime == "static" or "MT" in runtime else False - check_vs_runtime("Release/MyApp.exe", client, self.vs_version, build_type="Release", - static_runtime=static_runtime) - - @pytest.mark.parametrize("force_import_generated_files", [False, True]) + "DEFINITIONS_CONFIG": build_type, + "DEFINITIONS_CONFIG2": build_type, + "DEFINITIONS_CONFIG_INT": "234" if build_type == "Debug" else "456"}) + static_runtime = runtime == "static" or "MT" in runtime + check_vs_runtime("{}{}/MyApp.exe".format("" if arch == "x86" else f"{arch}/", build_type), client, + vs_version, build_type=build_type, static_runtime=static_runtime) + + @pytest.mark.parametrize("compiler,version,runtime,cppstd", [("Visual Studio", "15", "MT", "17")]) @pytest.mark.tool_cmake - def test_toolchain_win_debug(self, force_import_generated_files): - client = TestClient(path_with_spaces=False) - settings = [("compiler", "Visual Studio"), - ("compiler.version", self.vs_version), - ("compiler.toolset", "v140"), - ("compiler.runtime", "MDd"), - ("build_type", "Debug"), - ("arch", "x86_64")] - - # Build the profile according to the settings provided - settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) - - client.run("new hello/0.1 -s") - client.run("create . hello/0.1@ %s" % (settings,)) - - # Prepare the actual consumer package - client.save({"conanfile.py": self._conanfile(force_import_generated_files), - "MyProject.sln": sln_file, - "MyApp/MyApp.vcxproj": myapp_vcxproj(force_import_generated_files), - "MyApp/MyApp.cpp": self.app}, - clean_first=True) + def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): + if not self._has_tool_vc(version): + pytest.skip(f"Visual Studio {version} not installed") - # Run the configure corresponding to this test case - client.run("install . %s -if=conan" % (settings, )) - self.assertIn("conanfile.py: MSBuildToolchain created conantoolchain_debug_x64.props", - client.out) - client.run("build . -if=conan") - self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) - self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) - self._run_app(client, "x64", "Debug") - self.assertIn("Hello World Debug", client.out) - check_exe_run(client.out, "main", "msvc", "190", "Debug", "x86_64", "14", - {"DEFINITIONS_BOTH": 'True', - "DEFINITIONS_BOTH2": "True", - "DEFINITIONS_BOTH_INT": "123", - "DEFINITIONS_CONFIG": 'Debug', - "DEFINITIONS_CONFIG2": 'Debug', - "DEFINITIONS_CONFIG_INT": "234"}) - check_vs_runtime("x64/Debug/MyApp.exe", client, self.vs_version, build_type="Debug") - - @pytest.mark.tool_cmake - def test_toolchain_win_multi(self): client = TestClient(path_with_spaces=False) - settings = [("compiler", "Visual Studio"), - ("compiler.version", self.vs_version), - ("compiler.cppstd", "17")] + settings = [("compiler", compiler), + ("compiler.version", version), + ("compiler.cppstd", cppstd)] settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v) client.run("new hello/0.1 -m=cmake_lib") @@ -587,7 +566,7 @@ def test_toolchain_win_multi(self): client.run("install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) - vs_path = vs_installation_path(self.vs_version) + vs_path = vs_installation_path(version) vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch, shared in configs: @@ -602,11 +581,11 @@ def test_toolchain_win_multi(self): '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) - self.assertIn("Visual Studio {ide_year}".format(ide_year=self.ide_year), client.out) + self.assertIn("Visual Studio {ide_year}".format(self._vs_versions[version]["ide_year"]), client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, arch, build_type, shared) - check_exe_run(client.out, "main", "msvc", self.msvc_version, build_type, arch, "17", + check_exe_run(client.out, "main", "msvc", self._vs_versions[version]["msvc_version"], build_type, arch, cppstd, {"DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": build_type}) @@ -614,7 +593,7 @@ def test_toolchain_win_multi(self): command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration - vcvars = vcvars_command(version=self.vs_version, architecture="amd64") + vcvars = vcvars_command(version, architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, command_str)) client.run_command(cmd) if shared: From 97cc0fe58739b424346f5746ab497d321c0bf54e Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 19:31:47 +0100 Subject: [PATCH 23/31] more fix --- .../toolchains/microsoft/test_msbuild.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index f54989c3897..361146fa32d 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -476,7 +476,7 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ ("build_type", build_type), ("arch", arch)] if compiler == "msvc": - settings.append(("compiler.runtime_type"), "Debug" if build_type == "Debug" else "Release") + settings.append(("compiler.runtime_type", "Debug" if build_type == "Debug" else "Release")) profile = textwrap.dedent(f""" [settings] @@ -509,13 +509,13 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ "armv8": "ARM64", }[arch] props_file = f"conantoolchain_{build_type.lower()}_{props_arch}.props" - self.assertIn(f"conanfile.py: MSBuildToolchain created {props_file}", client.out) + assert f"conanfile.py: MSBuildToolchain created {props_file}" in client.out client.run("build . -if=conan") - self.assertIn("Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]), client.out) - self.assertIn(f"[vcvarsall.bat] Environment initialized for: '{arch}'", client.out) + assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]) in client.out + assert f"[vcvarsall.bat] Environment initialized for: '{arch}'" in client.out self._run_app(client, arch, build_type) - self.assertIn(f"Hello World {build_type}", client.out) + assert f"Hello World {build_type}" in client.out compiler_version = self._vs_versions[vs_version]["msvc_version"] check_exe_run(client.out, "main", "msvc", compiler_version, build_type, arch, cppstd, {"DEFINITIONS_BOTH": "True", @@ -581,8 +581,8 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) - self.assertIn("Visual Studio {ide_year}".format(self._vs_versions[version]["ide_year"]), client.out) - self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) + assert "Visual Studio {ide_year}".format(self._vs_versions[version]["ide_year"]) in client.out + assert "[vcvarsall.bat] Environment initialized for: 'x64'" in client.out self._run_app(client, arch, build_type, shared) check_exe_run(client.out, "main", "msvc", self._vs_versions[version]["msvc_version"], build_type, arch, cppstd, @@ -597,10 +597,10 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, command_str)) client.run_command(cmd) if shared: - self.assertIn("hello.dll", client.out) + assert "hello.dll" in client.out else: - self.assertNotIn("hello.dll", client.out) - self.assertIn("KERNEL32.dll", client.out) + assert "hello.dll" not in client.out + assert "KERNEL32.dll" in client.out def test_msvc_runtime_flag_common_usage(): From 501e2278800feec84d2ec4f3079fcad02114c81a Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 20:25:05 +0100 Subject: [PATCH 24/31] fix again --- .../toolchains/microsoft/test_msbuild.py | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 361146fa32d..66031a1e62e 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -344,6 +344,11 @@ def generate(self): assert "MSVC FLAG=MD!!" in client.out +def _has_tool_vc(vs_version): + return vs_version in tools_locations["visual_studio"] and \ + not tools_locations["visual_studio"][vs_version].get("disabled", False) + + @pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows") @pytest.mark.tool_visual_studio class TestMSBuild: @@ -380,11 +385,6 @@ class TestMSBuild: }, } - @staticmethod - def _has_tool_vc(vs_version): - return vs_version in tools_locations["visual_studio"] and \ - not tools_locations["visual_studio"][vs_version].get("disabled", False) - @staticmethod def _conanfile(force_import_generated_files=False): return textwrap.dedent(f""" @@ -452,18 +452,35 @@ def _run_app(client, arch, build_type, shared=None): client.run_command(command_str) @pytest.mark.parametrize("arch", ["x86", "x86_64"]) - @pytest.mark.parametrize("compiler,version,runtime,cppstd", [("msvc", "190", "static", "14"), - ("Visual Studio", "15", "MT", "17"), - ("msvc", "191", "static", "17"), - ("Visual Studio", "17", "MT", "17"), - ("msvc", "193", "static", "17")]) + @pytest.mark.parametrize( + "compiler,version,runtime,cppstd", + [ + pytest.param( + "msvc", "190", "static", "14", + marks=pytest.mark.skipif(not _has_tool_vc("14"), reason="Visual Studio 14 not installed"), + ), + pytest.param( + "Visual Studio", "15", "MT", "17", + marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), + ), + pytest.param( + "msvc", "191", "static", "17", + marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), + ), + pytest.param( + "Visual Studio", "17", "MT", "17", + marks=pytest.mark.skipif(not _has_tool_vc("17"), reason="Visual Studio 17 not installed"), + ), + pytest.param( + "msvc", "193", "static", "17", + marks=pytest.mark.skipif(not _has_tool_vc("17"), reason="Visual Studio 17 not installed"), + ), + ]) @pytest.mark.parametrize("build_type", ["Debug", "Release"]) @pytest.mark.parametrize("force_import_generated_files", [False, True]) @pytest.mark.tool_cmake def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_type, force_import_generated_files): vs_version = msvc_version_to_vs_ide_version(version) if compiler == "msvc" else version - if not self._has_tool_vc(vs_version): - pytest.skip(f"Visual Studio {vs_version} not installed") if compiler == "Visual Studio" and build_type == "Debug": runtime += "d" @@ -508,11 +525,11 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ "armv7": "ARM", "armv8": "ARM64", }[arch] - props_file = f"conantoolchain_{build_type.lower()}_{props_arch}.props" + props_file = f"conantoolchain_{build_type.lower()}_{props_arch.lower()}.props" assert f"conanfile.py: MSBuildToolchain created {props_file}" in client.out client.run("build . -if=conan") assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]) in client.out - assert f"[vcvarsall.bat] Environment initialized for: '{arch}'" in client.out + assert f"[vcvarsall.bat] Environment initialized for: '{props_arch}'" in client.out self._run_app(client, arch, build_type) assert f"Hello World {build_type}" in client.out @@ -525,15 +542,20 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ "DEFINITIONS_CONFIG2": build_type, "DEFINITIONS_CONFIG_INT": "234" if build_type == "Debug" else "456"}) static_runtime = runtime == "static" or "MT" in runtime - check_vs_runtime("{}{}/MyApp.exe".format("" if arch == "x86" else f"{arch}/", build_type), client, + check_vs_runtime("{}{}/MyApp.exe".format("" if arch == "x86" else f"{props_arch}/", build_type), client, vs_version, build_type=build_type, static_runtime=static_runtime) - @pytest.mark.parametrize("compiler,version,runtime,cppstd", [("Visual Studio", "15", "MT", "17")]) + @pytest.mark.parametrize( + "compiler,version,runtime,cppstd", + [ + pytest.param( + "Visual Studio", "15", "MT", "17", + marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), + ), + ] + ) @pytest.mark.tool_cmake def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): - if not self._has_tool_vc(version): - pytest.skip(f"Visual Studio {version} not installed") - client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), From c4f5a86b18942fe9b4a6a4491f1d53d4f22353e3 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 20:32:01 +0100 Subject: [PATCH 25/31] fix test again --- .../functional/toolchains/microsoft/test_msbuild.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 66031a1e62e..7afc7179c24 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -519,6 +519,12 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ # Run the configure corresponding to this test case client.run("install . %s -if=conan -pr=myprofile" % (settings, )) + msbuild_arch = { + "x86": "x86", + "x86_64": "x64", + "armv7": "ARM", + "armv8": "ARM64", + }[arch] props_arch = { "x86": "Win32", "x86_64": "x64", @@ -529,7 +535,7 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ assert f"conanfile.py: MSBuildToolchain created {props_file}" in client.out client.run("build . -if=conan") assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]) in client.out - assert f"[vcvarsall.bat] Environment initialized for: '{props_arch}'" in client.out + assert f"[vcvarsall.bat] Environment initialized for: '{msbuild_arch.lower()}'" in client.out self._run_app(client, arch, build_type) assert f"Hello World {build_type}" in client.out @@ -542,7 +548,7 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ "DEFINITIONS_CONFIG2": build_type, "DEFINITIONS_CONFIG_INT": "234" if build_type == "Debug" else "456"}) static_runtime = runtime == "static" or "MT" in runtime - check_vs_runtime("{}{}/MyApp.exe".format("" if arch == "x86" else f"{props_arch}/", build_type), client, + check_vs_runtime("{}{}/MyApp.exe".format("" if arch == "x86" else f"{msbuild_arch}/", build_type), client, vs_version, build_type=build_type, static_runtime=static_runtime) @pytest.mark.parametrize( From c4504490664ef127707bc44482a168fa3288d2b6 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 3 Jan 2023 20:57:49 +0100 Subject: [PATCH 26/31] minor change --- conans/test/functional/toolchains/microsoft/test_msbuild.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 7afc7179c24..d16aa0c86ac 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -609,7 +609,7 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) - assert "Visual Studio {ide_year}".format(self._vs_versions[version]["ide_year"]) in client.out + assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[version]["ide_year"]) in client.out assert "[vcvarsall.bat] Environment initialized for: 'x64'" in client.out self._run_app(client, arch, build_type, shared) @@ -621,7 +621,7 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration - vcvars = vcvars_command(version, architecture="amd64") + vcvars = vcvars_command(version=version, architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, command_str)) client.run_command(cmd) if shared: From 7753e04b9e1e7f759b1634e9a613e531461c668c Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Wed, 4 Jan 2023 00:06:06 +0100 Subject: [PATCH 27/31] simplify test_msbuild --- .../toolchains/microsoft/test_msbuild.py | 83 ++++++++++--------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index d16aa0c86ac..7e2fb8bc11d 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -344,7 +344,7 @@ def generate(self): assert "MSVC FLAG=MD!!" in client.out -def _has_tool_vc(vs_version): +def is_visual_studio_installed(vs_version): return vs_version in tools_locations["visual_studio"] and \ not tools_locations["visual_studio"][vs_version].get("disabled", False) @@ -455,32 +455,23 @@ def _run_app(client, arch, build_type, shared=None): @pytest.mark.parametrize( "compiler,version,runtime,cppstd", [ - pytest.param( - "msvc", "190", "static", "14", - marks=pytest.mark.skipif(not _has_tool_vc("14"), reason="Visual Studio 14 not installed"), - ), - pytest.param( - "Visual Studio", "15", "MT", "17", - marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), - ), - pytest.param( - "msvc", "191", "static", "17", - marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), - ), - pytest.param( - "Visual Studio", "17", "MT", "17", - marks=pytest.mark.skipif(not _has_tool_vc("17"), reason="Visual Studio 17 not installed"), - ), - pytest.param( - "msvc", "193", "static", "17", - marks=pytest.mark.skipif(not _has_tool_vc("17"), reason="Visual Studio 17 not installed"), - ), - ]) + ("Visual Studio", "14", "MT", "14"), + ("msvc", "190", "static", "14"), + ("Visual Studio", "15", "MT", "17"), + ("msvc", "191", "static", "17"), + ("Visual Studio", "16", "MT", "17"), + ("msvc", "192", "static", "17"), + ("Visual Studio", "17", "MT", "17"), + ("msvc", "193", "static", "17"), + ], + ) @pytest.mark.parametrize("build_type", ["Debug", "Release"]) @pytest.mark.parametrize("force_import_generated_files", [False, True]) @pytest.mark.tool_cmake def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_type, force_import_generated_files): vs_version = msvc_version_to_vs_ide_version(version) if compiler == "msvc" else version + if not is_visual_studio_installed(vs_version): + pytest.skip(f"Visual Studio {vs_version} not installed") if compiler == "Visual Studio" and build_type == "Debug": runtime += "d" @@ -554,14 +545,22 @@ def test_toolchain_win(self, arch, compiler, version, runtime, cppstd, build_typ @pytest.mark.parametrize( "compiler,version,runtime,cppstd", [ - pytest.param( - "Visual Studio", "15", "MT", "17", - marks=pytest.mark.skipif(not _has_tool_vc("15"), reason="Visual Studio 15 not installed"), - ), - ] + ("Visual Studio", "14", "MT", "14"), + ("msvc", "190", "static", "14"), + ("Visual Studio", "15", "MT", "17"), + ("msvc", "191", "static", "17"), + ("Visual Studio", "16", "MT", "17"), + ("msvc", "192", "static", "17"), + ("Visual Studio", "17", "MT", "17"), + ("msvc", "193", "static", "17"), + ], ) @pytest.mark.tool_cmake def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): + vs_version = msvc_version_to_vs_ide_version(version) if compiler == "msvc" else version + if not is_visual_studio_installed(vs_version): + pytest.skip(f"Visual Studio {vs_version} not installed") + client = TestClient(path_with_spaces=False) settings = [("compiler", compiler), @@ -577,9 +576,14 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): # TODO: It is a bit ugly to remove manually build_test_folder = os.path.join(client.current_folder, "test_package", "build") rmdir(build_test_folder) - runtime = "MT" if build_type == "Release" else "MTd" - client.run("create . hello/0.1@ %s -s build_type=%s -s arch=%s -s compiler.runtime=%s " - " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) + cmd = f"create . hello/0.1@ {settings} -s build_type={build_type} -s arch={arch} -o hello:shared={shared}" + if compiler == "Visual Studio": + runtime_suffix = "d" if build_type == "Debug" else "" + cmd += f" -s compiler.runtime={runtime}{runtime_suffix}" + else: + runtime_type = "Debug" if build_type == "Debug" else "Release" + cmd += f" -s compiler.runtime={runtime} -s compiler.runtime_type={runtime_type}" + client.run(cmd) # Prepare the actual consumer package client.save({"conanfile.py": self._conanfile(), @@ -590,11 +594,16 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): # Run the configure corresponding to this test case for build_type, arch, shared in configs: - runtime = "MT" if build_type == "Release" else "MTd" - client.run("install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" - " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) + cmd = f"install . {settings} -s build_type={build_type} -s arch={arch} -o hello:shared={shared}" + if compiler == "Visual Studio": + runtime_suffix = "d" if build_type == "Debug" else "" + cmd += f" -s compiler.runtime={runtime}{runtime_suffix}" + else: + runtime_type = "Debug" if build_type == "Debug" else "Release" + cmd += f" -s compiler.runtime={runtime} -s compiler.runtime_type={runtime_type}" + client.run(cmd) - vs_path = vs_installation_path(version) + vs_path = vs_installation_path(vs_version) vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch, shared in configs: @@ -609,11 +618,11 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) - assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[version]["ide_year"]) in client.out + assert "Visual Studio {ide_year}".format(ide_year=self._vs_versions[vs_version]["ide_year"]) in client.out assert "[vcvarsall.bat] Environment initialized for: 'x64'" in client.out self._run_app(client, arch, build_type, shared) - check_exe_run(client.out, "main", "msvc", self._vs_versions[version]["msvc_version"], build_type, arch, cppstd, + check_exe_run(client.out, "main", "msvc", self._vs_versions[vs_version]["msvc_version"], build_type, arch, cppstd, {"DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": build_type}) @@ -621,7 +630,7 @@ def test_toolchain_win_multi(self, compiler, version, runtime, cppstd): command_str = "%s\\MyApp.exe" % configuration else: command_str = "x64\\%s\\MyApp.exe" % configuration - vcvars = vcvars_command(version=version, architecture="amd64") + vcvars = vcvars_command(version=vs_version, architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, command_str)) client.run_command(cmd) if shared: From 730cede722466982c7127ccce648dfb97db0a200 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Wed, 4 Jan 2023 01:15:07 +0100 Subject: [PATCH 28/31] fix side effect in intel msbuild test --- conans/test/functional/toolchains/intel/test_using_msbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/test/functional/toolchains/intel/test_using_msbuild.py b/conans/test/functional/toolchains/intel/test_using_msbuild.py index e602ea5cffa..68e4163187e 100644 --- a/conans/test/functional/toolchains/intel/test_using_msbuild.py +++ b/conans/test/functional/toolchains/intel/test_using_msbuild.py @@ -44,7 +44,7 @@ def test_use_msbuild_toolchain(self): # Prepare the actual consumer package self.t.save({"conanfile.py": conanfile_py, "MyProject.sln": sln_file, - "MyApp/MyApp.vcxproj": myapp_vcxproj, + "MyApp/MyApp.vcxproj": myapp_vcxproj(), "MyApp/MyApp.cpp": app, 'profile': self.profile}, clean_first=True) From 008c5686121cb59f66f92ef79e43d5610fe14ec4 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Wed, 4 Jan 2023 12:29:18 +0100 Subject: [PATCH 29/31] in test_msbuild, change PlatformToolset in project file to an old one to really test that it can be overridden --- .../toolchains/microsoft/test_msbuild.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/conans/test/functional/toolchains/microsoft/test_msbuild.py b/conans/test/functional/toolchains/microsoft/test_msbuild.py index 7e2fb8bc11d..2514e950d66 100644 --- a/conans/test/functional/toolchains/microsoft/test_msbuild.py +++ b/conans/test/functional/toolchains/microsoft/test_msbuild.py @@ -15,8 +15,6 @@ sln_file = r""" Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.757 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyApp", "MyApp\MyApp.vcxproj", "{B58316C0-C78A-4E9B-AE8F-5D6368CE3840}" EndProject @@ -99,40 +97,40 @@ def myapp_vcxproj(force_import_generated_files=False): Application false - v141 + v120 true Unicode Application false - v141 + v120 true Unicode Application true - v141 + v120 Unicode Application false - v141 + v120 true Unicode Application true - v141 + v120 Unicode Application false - v141 + v120 true Unicode From ce846a50c9808aaaf4ff91110c03301c6bead6fa Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Thu, 5 Jan 2023 13:31:52 +0100 Subject: [PATCH 30/31] cleanup --- conan/tools/microsoft/toolchain.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index a091d736025..5c1a968686a 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -64,7 +64,7 @@ def __init__(self, conanfile): self.properties = {} check_using_build_profile(self._conanfile) - def _name_condition(self, settings): + def _name_condition(self): props = [("Configuration", self.configuration), ("Platform", self.platform)] @@ -73,7 +73,7 @@ def _name_condition(self, settings): return name.lower(), condition def generate(self): - name, condition = self._name_condition(self._conanfile.settings) + name, condition = self._name_condition() config_filename = "conantoolchain{}.props".format(name) # Writing the props files self._write_config_toolchain(config_filename) From def7edc1aa102877878ead6174bda7d055fc2c21 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Thu, 5 Jan 2023 13:43:07 +0100 Subject: [PATCH 31/31] factorize default platform computation in MSBuildToolchain & MSBuildDeps --- conan/tools/microsoft/msbuilddeps.py | 8 ++------ conan/tools/microsoft/toolchain.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py index 99be49ad156..9f7c8028564 100644 --- a/conan/tools/microsoft/msbuilddeps.py +++ b/conan/tools/microsoft/msbuilddeps.py @@ -7,6 +7,7 @@ from jinja2 import Template from conan.tools._check_build_profile import check_using_build_profile +from conan.tools.microsoft.toolchain import arch_to_vcproj_platform from conans.errors import ConanException from conans.util.files import load, save @@ -94,12 +95,7 @@ def __init__(self, conanfile): self._conanfile = conanfile self._conanfile.must_use_new_helpers = True # TODO: Remove 2.0 self.configuration = conanfile.settings.build_type - # TODO: This platform is not exactly the same as ``msbuild_arch``, because it differs - # in x86=>Win32 - self.platform = {'x86': 'Win32', - 'x86_64': 'x64', - 'armv7': 'ARM', - 'armv8': 'ARM64'}.get(str(conanfile.settings.arch)) + self.platform = arch_to_vcproj_platform(str(conanfile.settings.arch)) ca_exclude = "tools.microsoft.msbuilddeps:exclude_code_analysis" self.exclude_code_analysis = self._conanfile.conf.get(ca_exclude, check_type=list) check_using_build_profile(self._conanfile) diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py index 5c1a968686a..3d48474a4c1 100644 --- a/conan/tools/microsoft/toolchain.py +++ b/conan/tools/microsoft/toolchain.py @@ -12,6 +12,15 @@ from conans.util.files import save, load +def arch_to_vcproj_platform(arch): + return { + "x86": "Win32", + "x86_64": "x64", + "armv7": "ARM", + "armv8": "ARM64", + }.get(arch) + + class MSBuildToolchain(object): filename = "conantoolchain.props" @@ -52,12 +61,7 @@ def __init__(self, conanfile): self.cflags = [] self.ldflags = [] self.configuration = conanfile.settings.build_type - # TODO: refactor, put in common with MSBuildDeps. Beware this is != msbuild_arch - # because of Win32 - self.platform = {'x86': 'Win32', - 'x86_64': 'x64', - 'armv7': 'ARM', - 'armv8': 'ARM64'}.get(str(conanfile.settings.arch)) + self.platform = arch_to_vcproj_platform(str(conanfile.settings.arch)) self.runtime_library = self._runtime_library(conanfile.settings) self.cppstd = conanfile.settings.get_safe("compiler.cppstd") self.toolset = self._msvs_toolset(conanfile)