We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
MSBuild should allow "do not adjust PlatformToolset" with an argument
Hey,

In https://github.com/conan-io/conan/pull/4250 the default behavior of VisualStudio's toolset selection was changed to compile the whole solution using the same toolset (the `/p:PlatformToolset` is always set - see discussion here https://github.com/conan-io/conan/pull/4250#pullrequestreview-193994771).

This change prevents using two different toolsets in the same solution. In my case building a driver using the `WindowsKernelModeDriver10.0` (which is not even a valid option right now) toolset and user mode library using the `v141` toolset.

I will be happy to write the code if this behavior change is accepted.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conans/client/build/msbuild.py`
Content:
```
1 import copy
2 import os
3 import re
4 import subprocess
5 
6 from conans.client import tools
7 from conans.client.build.visual_environment import (VisualStudioBuildEnvironment,
8                                                     vs_build_type_flags, vs_std_cpp)
9 from conans.client.tools.oss import cpu_count
10 from conans.client.tools.win import vcvars_command
11 from conans.errors import ConanException
12 from conans.model.conan_file import ConanFile
13 from conans.model.version import Version
14 from conans.tools import vcvars_command as tools_vcvars_command
15 from conans.util.env_reader import get_env
16 from conans.util.files import decode_text, save
17 
18 
19 class MSBuild(object):
20 
21     def __init__(self, conanfile):
22         if isinstance(conanfile, ConanFile):
23             self._conanfile = conanfile
24             self._settings = self._conanfile.settings
25             self._output = self._conanfile.output
26             self.build_env = VisualStudioBuildEnvironment(self._conanfile,
27                                                           with_build_type_flags=False)
28         else:  # backwards compatible with build_sln_command
29             self._settings = conanfile
30             self.build_env = None
31 
32     def build(self, project_file, targets=None, upgrade_project=True, build_type=None, arch=None,
33               parallel=True, force_vcvars=False, toolset=None, platforms=None, use_env=True,
34               vcvars_ver=None, winsdk_version=None, properties=None, output_binary_log=None,
35               property_file_name=None, verbosity=None, definitions=None):
36         """
37         :param project_file: Path to the .sln file.
38         :param targets: List of targets to build.
39         :param upgrade_project: Will call devenv to upgrade the solution to your current Visual Studio.
40         :param build_type: Use a custom build type name instead of the default settings.build_type one.
41         :param arch: Use a custom architecture name instead of the settings.arch one.
42         It will be used to build the /p:Configuration= parameter of MSBuild.
43         It can be used as the key of the platforms parameter. E.g. arch="x86", platforms={"x86": "i386"}
44         :param parallel: Will use the configured number of cores in the conan.conf file or tools.cpu_count():
45         In the solution: Building the solution with the projects in parallel. (/m: parameter).
46         CL compiler: Building the sources in parallel. (/MP: compiler flag)
47         :param force_vcvars: Will ignore if the environment is already set for a different Visual Studio version.
48         :param toolset: Specify a toolset. Will append a /p:PlatformToolset option.
49         :param platforms: Dictionary with the mapping of archs/platforms from Conan naming to another one.
50         It is useful for Visual Studio solutions that have a different naming in architectures.
51         Example: platforms={"x86":"Win32"} (Visual solution uses "Win32" instead of "x86").
52         This dictionary will update the default one:
53         msvc_arch = {'x86': 'x86', 'x86_64': 'x64', 'armv7': 'ARM', 'armv8': 'ARM64'}
54         :param use_env: Applies the argument /p:UseEnv=true to the MSBuild call.
55         :param vcvars_ver: Specifies the Visual Studio compiler toolset to use.
56         :param winsdk_version: Specifies the version of the Windows SDK to use.
57         :param properties: Dictionary with new properties, for each element in the dictionary {name: value}
58         it will append a /p:name="value" option.
59         :param output_binary_log: If set to True then MSBuild will output a binary log file called msbuild.binlog in
60         the working directory. It can also be used to set the name of log file like this
61         output_binary_log="my_log.binlog".
62         This parameter is only supported starting from MSBuild version 15.3 and onwards.
63         :param property_file_name: When None it will generate a file named conan_build.props.
64         You can specify a different name for the generated properties file.
65         :param verbosity: Specifies verbosity level (/verbosity: parameter)
66         :param definitions: Dictionary with additional compiler definitions to be applied during the build.
67         Use value of None to set compiler definition with no value.
68         :return: status code of the MSBuild command invocation
69         """
70 
71         property_file_name = property_file_name or "conan_build.props"
72         self.build_env.parallel = parallel
73 
74         with tools.environment_append(self.build_env.vars):
75             # Path for custom properties file
76             props_file_contents = self._get_props_file_contents(definitions)
77             property_file_name = os.path.abspath(property_file_name)
78             save(property_file_name, props_file_contents)
79             vcvars = vcvars_command(self._conanfile.settings, force=force_vcvars,
80                                     vcvars_ver=vcvars_ver, winsdk_version=winsdk_version,
81                                     output=self._output)
82             command = self.get_command(project_file, property_file_name,
83                                        targets=targets, upgrade_project=upgrade_project,
84                                        build_type=build_type, arch=arch, parallel=parallel,
85                                        toolset=toolset, platforms=platforms,
86                                        use_env=use_env, properties=properties,
87                                        output_binary_log=output_binary_log,
88                                        verbosity=verbosity)
89             command = "%s && %s" % (vcvars, command)
90             return self._conanfile.run(command)
91 
92     def get_command(self, project_file, props_file_path=None, targets=None, upgrade_project=True,
93                     build_type=None, arch=None, parallel=True, toolset=None, platforms=None,
94                     use_env=False, properties=None, output_binary_log=None, verbosity=None):
95 
96         targets = targets or []
97         properties = properties or {}
98         command = []
99 
100         if upgrade_project and not get_env("CONAN_SKIP_VS_PROJECTS_UPGRADE", False):
101             command.append('devenv "%s" /upgrade &&' % project_file)
102         else:
103             self._output.info("Skipped sln project upgrade")
104 
105         build_type = build_type or self._settings.get_safe("build_type")
106         arch = arch or self._settings.get_safe("arch")
107         toolset = toolset or tools.msvs_toolset(self._settings)
108         verbosity = os.getenv("CONAN_MSBUILD_VERBOSITY") or verbosity or "minimal"
109         if not build_type:
110             raise ConanException("Cannot build_sln_command, build_type not defined")
111         if not arch:
112             raise ConanException("Cannot build_sln_command, arch not defined")
113 
114         command.append('msbuild "%s" /p:Configuration="%s"' % (project_file, build_type))
115         msvc_arch = {'x86': 'x86',
116                      'x86_64': 'x64',
117                      'armv7': 'ARM',
118                      'armv8': 'ARM64'}
119         if platforms:
120             msvc_arch.update(platforms)
121         msvc_arch = msvc_arch.get(str(arch))
122         if self._settings.get_safe("os") == "WindowsCE":
123             msvc_arch = self._settings.get_safe("os.platform")
124         try:
125             sln = tools.load(project_file)
126             pattern = re.compile(r"GlobalSection\(SolutionConfigurationPlatforms\)"
127                                  r"(.*?)EndGlobalSection", re.DOTALL)
128             solution_global = pattern.search(sln).group(1)
129             lines = solution_global.splitlines()
130             lines = [s.split("=")[0].strip() for s in lines]
131         except Exception:
132             pass  # TODO: !!! what are we catching here? tools.load? .group(1)? .splitlines?
133         else:
134             config = "%s|%s" % (build_type, msvc_arch)
135             if config not in "".join(lines):
136                 self._output.warn("***** The configuration %s does not exist in this solution *****"
137                                   % config)
138                 self._output.warn("Use 'platforms' argument to define your architectures")
139 
140         if output_binary_log:
141             msbuild_version = MSBuild.get_version(self._settings)
142             if msbuild_version >= "15.3":  # http://msbuildlog.com/
143                 command.append('/bl' if isinstance(output_binary_log, bool)
144                                else '/bl:"%s"' % output_binary_log)
145             else:
146                 raise ConanException("MSBuild version detected (%s) does not support "
147                                      "'output_binary_log' ('/bl')" % msbuild_version)
148 
149         if use_env:
150             command.append('/p:UseEnv=true')
151 
152         if msvc_arch:
153             command.append('/p:Platform="%s"' % msvc_arch)
154 
155         if parallel:
156             command.append('/m:%s' % cpu_count(output=self._output))
157 
158         if targets:
159             command.append("/target:%s" % ";".join(targets))
160 
161         if toolset:
162             command.append('/p:PlatformToolset="%s"' % toolset)
163 
164         if verbosity:
165             command.append('/verbosity:%s' % verbosity)
166 
167         if props_file_path:
168             command.append('/p:ForceImportBeforeCppTargets="%s"'
169                            % os.path.abspath(props_file_path))
170 
171         for name, value in properties.items():
172             command.append('/p:%s="%s"' % (name, value))
173 
174         return " ".join(command)
175 
176     def _get_props_file_contents(self, definitions=None):
177 
178         def format_macro(name, value):
179             return "%s=%s" % (name, value) if value else name
180 
181         # how to specify runtime in command line:
182         # https://stackoverflow.com/questions/38840332/msbuild-overrides-properties-while-building-vc-project
183         runtime_library = {"MT": "MultiThreaded",
184                            "MTd": "MultiThreadedDebug",
185                            "MD": "MultiThreadedDLL",
186                            "MDd": "MultiThreadedDebugDLL"}.get(
187                                self._settings.get_safe("compiler.runtime"), "")
188 
189         if self.build_env:
190             # Take the flags from the build env, the user was able to alter them if needed
191             flags = copy.copy(self.build_env.flags)
192             flags.append(self.build_env.std)
193         else:  # To be removed when build_sln_command is deprecated
194             flags = vs_build_type_flags(self._settings, with_flags=False)
195             flags.append(vs_std_cpp(self._settings))
196 
197         if definitions:
198             definitions = ";".join([format_macro(name, definitions[name]) for name in definitions])
199 
200         flags_str = " ".join(list(filter(None, flags)))  # Removes empty and None elements
201         additional_node = "<AdditionalOptions>" \
202                           "{} %(AdditionalOptions)" \
203                           "</AdditionalOptions>".format(flags_str) if flags_str else ""
204         runtime_node = "<RuntimeLibrary>" \
205                        "{}" \
206                        "</RuntimeLibrary>".format(runtime_library) if runtime_library else ""
207         definitions_node = "<PreprocessorDefinitions>" \
208                            "{};%(PreprocessorDefinitions)" \
209                            "</PreprocessorDefinitions>".format(definitions) if definitions else ""
210         template = """<?xml version="1.0" encoding="utf-8"?>
211 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
212   <ItemDefinitionGroup>
213     <ClCompile>
214       {runtime_node}
215       {additional_node}
216       {definitions_node}
217     </ClCompile>
218   </ItemDefinitionGroup>
219 </Project>""".format(**{"runtime_node": runtime_node,
220                         "additional_node": additional_node,
221                         "definitions_node": definitions_node})
222         return template
223 
224     @staticmethod
225     def get_version(settings):
226         msbuild_cmd = "msbuild -version"
227         vcvars = tools_vcvars_command(settings)
228         command = "%s && %s" % (vcvars, msbuild_cmd)
229         try:
230             out, _ = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()
231             version_line = decode_text(out).split("\n")[-1]
232             prog = re.compile("(\d+\.){2,3}\d+")
233             result = prog.match(version_line).group()
234             return Version(result)
235         except Exception as e:
236             raise ConanException("Error retrieving MSBuild version: '{}'".format(e))
237
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/conans/client/build/msbuild.py b/conans/client/build/msbuild.py
--- a/conans/client/build/msbuild.py
+++ b/conans/client/build/msbuild.py
@@ -104,7 +104,8 @@
 
         build_type = build_type or self._settings.get_safe("build_type")
         arch = arch or self._settings.get_safe("arch")
-        toolset = toolset or tools.msvs_toolset(self._settings)
+        if toolset is None:  # False value to skip adjusting
+            toolset = tools.msvs_toolset(self._settings)
         verbosity = os.getenv("CONAN_MSBUILD_VERBOSITY") or verbosity or "minimal"
         if not build_type:
             raise ConanException("Cannot build_sln_command, build_type not defined")

{"golden_diff": "diff --git a/conans/client/build/msbuild.py b/conans/client/build/msbuild.py\n--- a/conans/client/build/msbuild.py\n+++ b/conans/client/build/msbuild.py\n@@ -104,7 +104,8 @@\n \n         build_type = build_type or self._settings.get_safe(\"build_type\")\n         arch = arch or self._settings.get_safe(\"arch\")\n-        toolset = toolset or tools.msvs_toolset(self._settings)\n+        if toolset is None:  # False value to skip adjusting\n+            toolset = tools.msvs_toolset(self._settings)\n         verbosity = os.getenv(\"CONAN_MSBUILD_VERBOSITY\") or verbosity or \"minimal\"\n         if not build_type:\n             raise ConanException(\"Cannot build_sln_command, build_type not defined\")\n", "issue": "MSBuild should allow \"do not adjust PlatformToolset\" with an argument\nHey,\r\n\r\nIn https://github.com/conan-io/conan/pull/4250 the default behavior of VisualStudio's toolset selection was changed to compile the whole solution using the same toolset (the `/p:PlatformToolset` is always set - see discussion here https://github.com/conan-io/conan/pull/4250#pullrequestreview-193994771).\r\n\r\nThis change prevents using two different toolsets in the same solution. In my case building a driver using the `WindowsKernelModeDriver10.0` (which is not even a valid option right now) toolset and user mode library using the `v141` toolset.\r\n\r\nI will be happy to write the code if this behavior change is accepted.\n", "before_files": [{"content": "import copy\nimport os\nimport re\nimport subprocess\n\nfrom conans.client import tools\nfrom conans.client.build.visual_environment import (VisualStudioBuildEnvironment,\n                                                    vs_build_type_flags, vs_std_cpp)\nfrom conans.client.tools.oss import cpu_count\nfrom conans.client.tools.win import vcvars_command\nfrom conans.errors import ConanException\nfrom conans.model.conan_file import ConanFile\nfrom conans.model.version import Version\nfrom conans.tools import vcvars_command as tools_vcvars_command\nfrom conans.util.env_reader import get_env\nfrom conans.util.files import decode_text, save\n\n\nclass MSBuild(object):\n\n    def __init__(self, conanfile):\n        if isinstance(conanfile, ConanFile):\n            self._conanfile = conanfile\n            self._settings = self._conanfile.settings\n            self._output = self._conanfile.output\n            self.build_env = VisualStudioBuildEnvironment(self._conanfile,\n                                                          with_build_type_flags=False)\n        else:  # backwards compatible with build_sln_command\n            self._settings = conanfile\n            self.build_env = None\n\n    def build(self, project_file, targets=None, upgrade_project=True, build_type=None, arch=None,\n              parallel=True, force_vcvars=False, toolset=None, platforms=None, use_env=True,\n              vcvars_ver=None, winsdk_version=None, properties=None, output_binary_log=None,\n              property_file_name=None, verbosity=None, definitions=None):\n        \"\"\"\n        :param project_file: Path to the .sln file.\n        :param targets: List of targets to build.\n        :param upgrade_project: Will call devenv to upgrade the solution to your current Visual Studio.\n        :param build_type: Use a custom build type name instead of the default settings.build_type one.\n        :param arch: Use a custom architecture name instead of the settings.arch one.\n        It will be used to build the /p:Configuration= parameter of MSBuild.\n        It can be used as the key of the platforms parameter. E.g. arch=\"x86\", platforms={\"x86\": \"i386\"}\n        :param parallel: Will use the configured number of cores in the conan.conf file or tools.cpu_count():\n        In the solution: Building the solution with the projects in parallel. (/m: parameter).\n        CL compiler: Building the sources in parallel. (/MP: compiler flag)\n        :param force_vcvars: Will ignore if the environment is already set for a different Visual Studio version.\n        :param toolset: Specify a toolset. Will append a /p:PlatformToolset option.\n        :param platforms: Dictionary with the mapping of archs/platforms from Conan naming to another one.\n        It is useful for Visual Studio solutions that have a different naming in architectures.\n        Example: platforms={\"x86\":\"Win32\"} (Visual solution uses \"Win32\" instead of \"x86\").\n        This dictionary will update the default one:\n        msvc_arch = {'x86': 'x86', 'x86_64': 'x64', 'armv7': 'ARM', 'armv8': 'ARM64'}\n        :param use_env: Applies the argument /p:UseEnv=true to the MSBuild call.\n        :param vcvars_ver: Specifies the Visual Studio compiler toolset to use.\n        :param winsdk_version: Specifies the version of the Windows SDK to use.\n        :param properties: Dictionary with new properties, for each element in the dictionary {name: value}\n        it will append a /p:name=\"value\" option.\n        :param output_binary_log: If set to True then MSBuild will output a binary log file called msbuild.binlog in\n        the working directory. It can also be used to set the name of log file like this\n        output_binary_log=\"my_log.binlog\".\n        This parameter is only supported starting from MSBuild version 15.3 and onwards.\n        :param property_file_name: When None it will generate a file named conan_build.props.\n        You can specify a different name for the generated properties file.\n        :param verbosity: Specifies verbosity level (/verbosity: parameter)\n        :param definitions: Dictionary with additional compiler definitions to be applied during the build.\n        Use value of None to set compiler definition with no value.\n        :return: status code of the MSBuild command invocation\n        \"\"\"\n\n        property_file_name = property_file_name or \"conan_build.props\"\n        self.build_env.parallel = parallel\n\n        with tools.environment_append(self.build_env.vars):\n            # Path for custom properties file\n            props_file_contents = self._get_props_file_contents(definitions)\n            property_file_name = os.path.abspath(property_file_name)\n            save(property_file_name, props_file_contents)\n            vcvars = vcvars_command(self._conanfile.settings, force=force_vcvars,\n                                    vcvars_ver=vcvars_ver, winsdk_version=winsdk_version,\n                                    output=self._output)\n            command = self.get_command(project_file, property_file_name,\n                                       targets=targets, upgrade_project=upgrade_project,\n                                       build_type=build_type, arch=arch, parallel=parallel,\n                                       toolset=toolset, platforms=platforms,\n                                       use_env=use_env, properties=properties,\n                                       output_binary_log=output_binary_log,\n                                       verbosity=verbosity)\n            command = \"%s && %s\" % (vcvars, command)\n            return self._conanfile.run(command)\n\n    def get_command(self, project_file, props_file_path=None, targets=None, upgrade_project=True,\n                    build_type=None, arch=None, parallel=True, toolset=None, platforms=None,\n                    use_env=False, properties=None, output_binary_log=None, verbosity=None):\n\n        targets = targets or []\n        properties = properties or {}\n        command = []\n\n        if upgrade_project and not get_env(\"CONAN_SKIP_VS_PROJECTS_UPGRADE\", False):\n            command.append('devenv \"%s\" /upgrade &&' % project_file)\n        else:\n            self._output.info(\"Skipped sln project upgrade\")\n\n        build_type = build_type or self._settings.get_safe(\"build_type\")\n        arch = arch or self._settings.get_safe(\"arch\")\n        toolset = toolset or tools.msvs_toolset(self._settings)\n        verbosity = os.getenv(\"CONAN_MSBUILD_VERBOSITY\") or verbosity or \"minimal\"\n        if not build_type:\n            raise ConanException(\"Cannot build_sln_command, build_type not defined\")\n        if not arch:\n            raise ConanException(\"Cannot build_sln_command, arch not defined\")\n\n        command.append('msbuild \"%s\" /p:Configuration=\"%s\"' % (project_file, build_type))\n        msvc_arch = {'x86': 'x86',\n                     'x86_64': 'x64',\n                     'armv7': 'ARM',\n                     'armv8': 'ARM64'}\n        if platforms:\n            msvc_arch.update(platforms)\n        msvc_arch = msvc_arch.get(str(arch))\n        if self._settings.get_safe(\"os\") == \"WindowsCE\":\n            msvc_arch = self._settings.get_safe(\"os.platform\")\n        try:\n            sln = tools.load(project_file)\n            pattern = re.compile(r\"GlobalSection\\(SolutionConfigurationPlatforms\\)\"\n                                 r\"(.*?)EndGlobalSection\", re.DOTALL)\n            solution_global = pattern.search(sln).group(1)\n            lines = solution_global.splitlines()\n            lines = [s.split(\"=\")[0].strip() for s in lines]\n        except Exception:\n            pass  # TODO: !!! what are we catching here? tools.load? .group(1)? .splitlines?\n        else:\n            config = \"%s|%s\" % (build_type, msvc_arch)\n            if config not in \"\".join(lines):\n                self._output.warn(\"***** The configuration %s does not exist in this solution *****\"\n                                  % config)\n                self._output.warn(\"Use 'platforms' argument to define your architectures\")\n\n        if output_binary_log:\n            msbuild_version = MSBuild.get_version(self._settings)\n            if msbuild_version >= \"15.3\":  # http://msbuildlog.com/\n                command.append('/bl' if isinstance(output_binary_log, bool)\n                               else '/bl:\"%s\"' % output_binary_log)\n            else:\n                raise ConanException(\"MSBuild version detected (%s) does not support \"\n                                     \"'output_binary_log' ('/bl')\" % msbuild_version)\n\n        if use_env:\n            command.append('/p:UseEnv=true')\n\n        if msvc_arch:\n            command.append('/p:Platform=\"%s\"' % msvc_arch)\n\n        if parallel:\n            command.append('/m:%s' % cpu_count(output=self._output))\n\n        if targets:\n            command.append(\"/target:%s\" % \";\".join(targets))\n\n        if toolset:\n            command.append('/p:PlatformToolset=\"%s\"' % toolset)\n\n        if verbosity:\n            command.append('/verbosity:%s' % verbosity)\n\n        if props_file_path:\n            command.append('/p:ForceImportBeforeCppTargets=\"%s\"'\n                           % os.path.abspath(props_file_path))\n\n        for name, value in properties.items():\n            command.append('/p:%s=\"%s\"' % (name, value))\n\n        return \" \".join(command)\n\n    def _get_props_file_contents(self, definitions=None):\n\n        def format_macro(name, value):\n            return \"%s=%s\" % (name, value) if value else name\n\n        # how to specify runtime in command line:\n        # https://stackoverflow.com/questions/38840332/msbuild-overrides-properties-while-building-vc-project\n        runtime_library = {\"MT\": \"MultiThreaded\",\n                           \"MTd\": \"MultiThreadedDebug\",\n                           \"MD\": \"MultiThreadedDLL\",\n                           \"MDd\": \"MultiThreadedDebugDLL\"}.get(\n                               self._settings.get_safe(\"compiler.runtime\"), \"\")\n\n        if self.build_env:\n            # Take the flags from the build env, the user was able to alter them if needed\n            flags = copy.copy(self.build_env.flags)\n            flags.append(self.build_env.std)\n        else:  # To be removed when build_sln_command is deprecated\n            flags = vs_build_type_flags(self._settings, with_flags=False)\n            flags.append(vs_std_cpp(self._settings))\n\n        if definitions:\n            definitions = \";\".join([format_macro(name, definitions[name]) for name in definitions])\n\n        flags_str = \" \".join(list(filter(None, flags)))  # Removes empty and None elements\n        additional_node = \"<AdditionalOptions>\" \\\n                          \"{} %(AdditionalOptions)\" \\\n                          \"</AdditionalOptions>\".format(flags_str) if flags_str else \"\"\n        runtime_node = \"<RuntimeLibrary>\" \\\n                       \"{}\" \\\n                       \"</RuntimeLibrary>\".format(runtime_library) if runtime_library else \"\"\n        definitions_node = \"<PreprocessorDefinitions>\" \\\n                           \"{};%(PreprocessorDefinitions)\" \\\n                           \"</PreprocessorDefinitions>\".format(definitions) if definitions else \"\"\n        template = \"\"\"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemDefinitionGroup>\n    <ClCompile>\n      {runtime_node}\n      {additional_node}\n      {definitions_node}\n    </ClCompile>\n  </ItemDefinitionGroup>\n</Project>\"\"\".format(**{\"runtime_node\": runtime_node,\n                        \"additional_node\": additional_node,\n                        \"definitions_node\": definitions_node})\n        return template\n\n    @staticmethod\n    def get_version(settings):\n        msbuild_cmd = \"msbuild -version\"\n        vcvars = tools_vcvars_command(settings)\n        command = \"%s && %s\" % (vcvars, msbuild_cmd)\n        try:\n            out, _ = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()\n            version_line = decode_text(out).split(\"\\n\")[-1]\n            prog = re.compile(\"(\\d+\\.){2,3}\\d+\")\n            result = prog.match(version_line).group()\n            return Version(result)\n        except Exception as e:\n            raise ConanException(\"Error retrieving MSBuild version: '{}'\".format(e))\n", "path": "conans/client/build/msbuild.py"}], "after_files": [{"content": "import copy\nimport os\nimport re\nimport subprocess\n\nfrom conans.client import tools\nfrom conans.client.build.visual_environment import (VisualStudioBuildEnvironment,\n                                                    vs_build_type_flags, vs_std_cpp)\nfrom conans.client.tools.oss import cpu_count\nfrom conans.client.tools.win import vcvars_command\nfrom conans.errors import ConanException\nfrom conans.model.conan_file import ConanFile\nfrom conans.model.version import Version\nfrom conans.tools import vcvars_command as tools_vcvars_command\nfrom conans.util.env_reader import get_env\nfrom conans.util.files import decode_text, save\n\n\nclass MSBuild(object):\n\n    def __init__(self, conanfile):\n        if isinstance(conanfile, ConanFile):\n            self._conanfile = conanfile\n            self._settings = self._conanfile.settings\n            self._output = self._conanfile.output\n            self.build_env = VisualStudioBuildEnvironment(self._conanfile,\n                                                          with_build_type_flags=False)\n        else:  # backwards compatible with build_sln_command\n            self._settings = conanfile\n            self.build_env = None\n\n    def build(self, project_file, targets=None, upgrade_project=True, build_type=None, arch=None,\n              parallel=True, force_vcvars=False, toolset=None, platforms=None, use_env=True,\n              vcvars_ver=None, winsdk_version=None, properties=None, output_binary_log=None,\n              property_file_name=None, verbosity=None, definitions=None):\n        \"\"\"\n        :param project_file: Path to the .sln file.\n        :param targets: List of targets to build.\n        :param upgrade_project: Will call devenv to upgrade the solution to your current Visual Studio.\n        :param build_type: Use a custom build type name instead of the default settings.build_type one.\n        :param arch: Use a custom architecture name instead of the settings.arch one.\n        It will be used to build the /p:Configuration= parameter of MSBuild.\n        It can be used as the key of the platforms parameter. E.g. arch=\"x86\", platforms={\"x86\": \"i386\"}\n        :param parallel: Will use the configured number of cores in the conan.conf file or tools.cpu_count():\n        In the solution: Building the solution with the projects in parallel. (/m: parameter).\n        CL compiler: Building the sources in parallel. (/MP: compiler flag)\n        :param force_vcvars: Will ignore if the environment is already set for a different Visual Studio version.\n        :param toolset: Specify a toolset. Will append a /p:PlatformToolset option.\n        :param platforms: Dictionary with the mapping of archs/platforms from Conan naming to another one.\n        It is useful for Visual Studio solutions that have a different naming in architectures.\n        Example: platforms={\"x86\":\"Win32\"} (Visual solution uses \"Win32\" instead of \"x86\").\n        This dictionary will update the default one:\n        msvc_arch = {'x86': 'x86', 'x86_64': 'x64', 'armv7': 'ARM', 'armv8': 'ARM64'}\n        :param use_env: Applies the argument /p:UseEnv=true to the MSBuild call.\n        :param vcvars_ver: Specifies the Visual Studio compiler toolset to use.\n        :param winsdk_version: Specifies the version of the Windows SDK to use.\n        :param properties: Dictionary with new properties, for each element in the dictionary {name: value}\n        it will append a /p:name=\"value\" option.\n        :param output_binary_log: If set to True then MSBuild will output a binary log file called msbuild.binlog in\n        the working directory. It can also be used to set the name of log file like this\n        output_binary_log=\"my_log.binlog\".\n        This parameter is only supported starting from MSBuild version 15.3 and onwards.\n        :param property_file_name: When None it will generate a file named conan_build.props.\n        You can specify a different name for the generated properties file.\n        :param verbosity: Specifies verbosity level (/verbosity: parameter)\n        :param definitions: Dictionary with additional compiler definitions to be applied during the build.\n        Use value of None to set compiler definition with no value.\n        :return: status code of the MSBuild command invocation\n        \"\"\"\n\n        property_file_name = property_file_name or \"conan_build.props\"\n        self.build_env.parallel = parallel\n\n        with tools.environment_append(self.build_env.vars):\n            # Path for custom properties file\n            props_file_contents = self._get_props_file_contents(definitions)\n            property_file_name = os.path.abspath(property_file_name)\n            save(property_file_name, props_file_contents)\n            vcvars = vcvars_command(self._conanfile.settings, force=force_vcvars,\n                                    vcvars_ver=vcvars_ver, winsdk_version=winsdk_version,\n                                    output=self._output)\n            command = self.get_command(project_file, property_file_name,\n                                       targets=targets, upgrade_project=upgrade_project,\n                                       build_type=build_type, arch=arch, parallel=parallel,\n                                       toolset=toolset, platforms=platforms,\n                                       use_env=use_env, properties=properties,\n                                       output_binary_log=output_binary_log,\n                                       verbosity=verbosity)\n            command = \"%s && %s\" % (vcvars, command)\n            return self._conanfile.run(command)\n\n    def get_command(self, project_file, props_file_path=None, targets=None, upgrade_project=True,\n                    build_type=None, arch=None, parallel=True, toolset=None, platforms=None,\n                    use_env=False, properties=None, output_binary_log=None, verbosity=None):\n\n        targets = targets or []\n        properties = properties or {}\n        command = []\n\n        if upgrade_project and not get_env(\"CONAN_SKIP_VS_PROJECTS_UPGRADE\", False):\n            command.append('devenv \"%s\" /upgrade &&' % project_file)\n        else:\n            self._output.info(\"Skipped sln project upgrade\")\n\n        build_type = build_type or self._settings.get_safe(\"build_type\")\n        arch = arch or self._settings.get_safe(\"arch\")\n        if toolset is None:  # False value to skip adjusting\n            toolset = tools.msvs_toolset(self._settings)\n        verbosity = os.getenv(\"CONAN_MSBUILD_VERBOSITY\") or verbosity or \"minimal\"\n        if not build_type:\n            raise ConanException(\"Cannot build_sln_command, build_type not defined\")\n        if not arch:\n            raise ConanException(\"Cannot build_sln_command, arch not defined\")\n\n        command.append('msbuild \"%s\" /p:Configuration=\"%s\"' % (project_file, build_type))\n        msvc_arch = {'x86': 'x86',\n                     'x86_64': 'x64',\n                     'armv7': 'ARM',\n                     'armv8': 'ARM64'}\n        if platforms:\n            msvc_arch.update(platforms)\n        msvc_arch = msvc_arch.get(str(arch))\n        if self._settings.get_safe(\"os\") == \"WindowsCE\":\n            msvc_arch = self._settings.get_safe(\"os.platform\")\n        try:\n            sln = tools.load(project_file)\n            pattern = re.compile(r\"GlobalSection\\(SolutionConfigurationPlatforms\\)\"\n                                 r\"(.*?)EndGlobalSection\", re.DOTALL)\n            solution_global = pattern.search(sln).group(1)\n            lines = solution_global.splitlines()\n            lines = [s.split(\"=\")[0].strip() for s in lines]\n        except Exception:\n            pass  # TODO: !!! what are we catching here? tools.load? .group(1)? .splitlines?\n        else:\n            config = \"%s|%s\" % (build_type, msvc_arch)\n            if config not in \"\".join(lines):\n                self._output.warn(\"***** The configuration %s does not exist in this solution *****\"\n                                  % config)\n                self._output.warn(\"Use 'platforms' argument to define your architectures\")\n\n        if output_binary_log:\n            msbuild_version = MSBuild.get_version(self._settings)\n            if msbuild_version >= \"15.3\":  # http://msbuildlog.com/\n                command.append('/bl' if isinstance(output_binary_log, bool)\n                               else '/bl:\"%s\"' % output_binary_log)\n            else:\n                raise ConanException(\"MSBuild version detected (%s) does not support \"\n                                     \"'output_binary_log' ('/bl')\" % msbuild_version)\n\n        if use_env:\n            command.append('/p:UseEnv=true')\n\n        if msvc_arch:\n            command.append('/p:Platform=\"%s\"' % msvc_arch)\n\n        if parallel:\n            command.append('/m:%s' % cpu_count(output=self._output))\n\n        if targets:\n            command.append(\"/target:%s\" % \";\".join(targets))\n\n        if toolset:\n            command.append('/p:PlatformToolset=\"%s\"' % toolset)\n\n        if verbosity:\n            command.append('/verbosity:%s' % verbosity)\n\n        if props_file_path:\n            command.append('/p:ForceImportBeforeCppTargets=\"%s\"'\n                           % os.path.abspath(props_file_path))\n\n        for name, value in properties.items():\n            command.append('/p:%s=\"%s\"' % (name, value))\n\n        return \" \".join(command)\n\n    def _get_props_file_contents(self, definitions=None):\n\n        def format_macro(name, value):\n            return \"%s=%s\" % (name, value) if value else name\n\n        # how to specify runtime in command line:\n        # https://stackoverflow.com/questions/38840332/msbuild-overrides-properties-while-building-vc-project\n        runtime_library = {\"MT\": \"MultiThreaded\",\n                           \"MTd\": \"MultiThreadedDebug\",\n                           \"MD\": \"MultiThreadedDLL\",\n                           \"MDd\": \"MultiThreadedDebugDLL\"}.get(\n                               self._settings.get_safe(\"compiler.runtime\"), \"\")\n\n        if self.build_env:\n            # Take the flags from the build env, the user was able to alter them if needed\n            flags = copy.copy(self.build_env.flags)\n            flags.append(self.build_env.std)\n        else:  # To be removed when build_sln_command is deprecated\n            flags = vs_build_type_flags(self._settings, with_flags=False)\n            flags.append(vs_std_cpp(self._settings))\n\n        if definitions:\n            definitions = \";\".join([format_macro(name, definitions[name]) for name in definitions])\n\n        flags_str = \" \".join(list(filter(None, flags)))  # Removes empty and None elements\n        additional_node = \"<AdditionalOptions>\" \\\n                          \"{} %(AdditionalOptions)\" \\\n                          \"</AdditionalOptions>\".format(flags_str) if flags_str else \"\"\n        runtime_node = \"<RuntimeLibrary>\" \\\n                       \"{}\" \\\n                       \"</RuntimeLibrary>\".format(runtime_library) if runtime_library else \"\"\n        definitions_node = \"<PreprocessorDefinitions>\" \\\n                           \"{};%(PreprocessorDefinitions)\" \\\n                           \"</PreprocessorDefinitions>\".format(definitions) if definitions else \"\"\n        template = \"\"\"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemDefinitionGroup>\n    <ClCompile>\n      {runtime_node}\n      {additional_node}\n      {definitions_node}\n    </ClCompile>\n  </ItemDefinitionGroup>\n</Project>\"\"\".format(**{\"runtime_node\": runtime_node,\n                        \"additional_node\": additional_node,\n                        \"definitions_node\": definitions_node})\n        return template\n\n    @staticmethod\n    def get_version(settings):\n        msbuild_cmd = \"msbuild -version\"\n        vcvars = tools_vcvars_command(settings)\n        command = \"%s && %s\" % (vcvars, msbuild_cmd)\n        try:\n            out, _ = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()\n            version_line = decode_text(out).split(\"\\n\")[-1]\n            prog = re.compile(\"(\\d+\\.){2,3}\\d+\")\n            result = prog.match(version_line).group()\n            return Version(result)\n        except Exception as e:\n            raise ConanException(\"Error retrieving MSBuild version: '{}'\".format(e))\n", "path": "conans/client/build/msbuild.py"}]}