Repository: conan-io/conan

Issue:
VisualStudioBuildEnvironment uses semicolon as a delimiter
`SET CL=-MDd;%CL%`

And this is what cl.exe does not like:

```
cl : Command line warning D9002 :
ignoring unknown option '-MDd;'
```

delimiter should be a space instead of a semicolon as documented here: https://msdn.microsoft.com/en-us/library/kezkeayy.aspx

https://github.com/conan-io/conan/blob/d62ac20f21d73b1d681c3d138034a0d70b9a513e/conans/client/build/visual_environment.py#L55

cc/ @db4




Discussion:
The underlying problem seems to be `VirtualEnvGenerator` (parent of VirtualBuildEnvGenerator)

Resolving patch:
diff --git a/conans/client/build/visual_environment.py b/conans/client/build/visual_environment.py
--- a/conans/client/build/visual_environment.py
+++ b/conans/client/build/visual_environment.py
@@ -94,7 +94,7 @@ def vars_dict(self):
         return ret
 
     def _std_cpp(self):
-       return vs_std_cpp(self._settings)
+        return vs_std_cpp(self._settings)
 
 
 def vs_build_type_flags(settings):
diff --git a/conans/client/generators/virtualenv.py b/conans/client/generators/virtualenv.py
--- a/conans/client/generators/virtualenv.py
+++ b/conans/client/generators/virtualenv.py
@@ -37,21 +37,22 @@ def format_values(self, flavor, variables):
         :return:
         """
         variables = variables or self.env.items()
-        path_sep, quote_elements, quote_full_value, enable_space_path_sep = ":", True, False, True
-        if flavor in ["cmd", "ps1"]:
-            path_sep, quote_elements, enable_space_path_sep = ";", False, False
-        if flavor in ["ps1"]:
-            quote_full_value = True
+        if flavor == "cmd":
+            path_sep, quote_elements, quote_full_value = ";", False, False
+        elif flavor == "ps1":
+            path_sep, quote_elements, quote_full_value = ";", False, True
+        elif flavor == "sh":
+            path_sep, quote_elements, quote_full_value = ":", True, False
 
         ret = []
         for name, value in variables:
             # activate values
             if isinstance(value, list):
                 placeholder = self._variable_placeholder(flavor, name)
-                if enable_space_path_sep and name in self.append_with_spaces:
+                if name in self.append_with_spaces:
                     # Variables joined with spaces look like: CPPFLAGS="one two three"
                     value = " ".join(value+[placeholder])
-                    value = "\"%s\"" % value if value else ""
+                    value = "\"%s\"" % value if quote_elements else value
                 else:
                     # Quoted variables joined with pathset may look like:
                     # PATH="one path":"two paths"
@@ -104,12 +105,13 @@ def _cmd_lines(self):
     def _ps1_lines(self):
         activate_lines = ['function global:_old_conan_prompt {""}']
         activate_lines.append('$function:_old_conan_prompt = $function:prompt')
-        activate_lines.append('function global:prompt { write-host "(%s) " -nonewline; & $function:_old_conan_prompt }' % self.venv_name)
+        activate_lines.append('function global:prompt { write-host "(%s) " -nonewline; '
+                              '& $function:_old_conan_prompt }' % self.venv_name)
         deactivate_lines = ['$function:prompt = $function:_old_conan_prompt']
         deactivate_lines.append('remove-item function:_old_conan_prompt')
         for name, activate, deactivate in self.format_values("ps1", self.env.items()):
-            activate_lines.append('$env:%s = %s' % (name,activate))
-            deactivate_lines.append('$env:%s = %s' % (name,deactivate))
+            activate_lines.append('$env:%s = %s' % (name, activate))
+            deactivate_lines.append('$env:%s = %s' % (name, deactivate))
         activate_lines.append('')
         return activate_lines, deactivate_lines
 


Test patch:
diff --git a/conans/test/generators/virtualbuildenv_test.py b/conans/test/generators/virtualbuildenv_test.py
--- a/conans/test/generators/virtualbuildenv_test.py
+++ b/conans/test/generators/virtualbuildenv_test.py
@@ -9,6 +9,20 @@
 
 class VirtualBuildEnvTest(unittest.TestCase):
 
+    @unittest.skipUnless(platform.system() == "Windows", "needs Windows")
+    def test_delimiter_error(self):
+        # https://github.com/conan-io/conan/issues/3080
+        conanfile = """from conans import ConanFile
+class TestConan(ConanFile):
+    settings = "os", "compiler", "arch", "build_type"
+"""
+        client = TestClient()
+        client.save({"conanfile.py": conanfile})
+        client.run('install . -g virtualbuildenv -s os=Windows -s compiler="Visual Studio"'
+                   ' -s compiler.runtime=MD -s compiler.version=15')
+        bat = load(os.path.join(client.current_folder, "activate_build.bat"))
+        self.assertIn('SET CL=-MD -DNDEBUG -O2 -Ob2 %CL%', bat)
+
     def environment_deactivate_test(self):
 
         in_windows = platform.system() == "Windows"
diff --git a/conans/test/generators/virtualenv_test.py b/conans/test/generators/virtualenv_test.py
--- a/conans/test/generators/virtualenv_test.py
+++ b/conans/test/generators/virtualenv_test.py
@@ -5,6 +5,7 @@
 from conans.tools import os_info, get_env
 from conans.util.files import load
 
+
 class VirtualEnvGeneratorTest(unittest.TestCase):
 
     def basic_test(self, posix_empty_vars=True):
@@ -61,7 +62,7 @@ def package_info(self):
             self.assertIn('SET PROMPT=(conanenv) %PROMPT%', activate)
             self.assertIn('SET BASE_LIST=dummyValue1;dummyValue2;baseValue1;baseValue2;%BASE_LIST%', activate)
             self.assertIn('SET BASE_VAR=baseValue', activate)
-            self.assertIn('SET CPPFLAGS=-flag1;-flag2;-baseFlag1;-baseFlag2;%CPPFLAGS%', activate)
+            self.assertIn('SET CPPFLAGS=-flag1 -flag2 -baseFlag1 -baseFlag2 %CPPFLAGS%', activate)
             self.assertIn('SET LD_LIBRARY_PATH=dummydir\\lib;basedir\\lib;%LD_LIBRARY_PATH%', activate)
             self.assertIn('SET PATH=dummydir\\bin;basedir\\bin;samebin;%PATH%', activate)
             self.assertIn('SET SPECIAL_VAR=dummyValue', activate)
@@ -69,7 +70,7 @@ def package_info(self):
             activate = load(os.path.join(client.current_folder, "activate.ps1"))
             self.assertIn('$env:BASE_LIST = "dummyValue1;dummyValue2;baseValue1;baseValue2;$env:BASE_LIST"', activate)
             self.assertIn('$env:BASE_VAR = "baseValue"', activate)
-            self.assertIn('$env:CPPFLAGS = "-flag1;-flag2;-baseFlag1;-baseFlag2;$env:CPPFLAGS"', activate)
+            self.assertIn('$env:CPPFLAGS = "-flag1 -flag2 -baseFlag1 -baseFlag2 $env:CPPFLAGS"', activate)
             self.assertIn('$env:LD_LIBRARY_PATH = "dummydir\\lib;basedir\\lib;$env:LD_LIBRARY_PATH"', activate)
             self.assertIn('$env:PATH = "dummydir\\bin;basedir\\bin;samebin;$env:PATH"', activate)
             self.assertIn('$env:SPECIAL_VAR = "dummyValue"', activate)