Merge pull request #6976 from davidhorstmann-arm/2.28-c-build-helper-improvements

[Backport 2.28] Minor improvements to `c_build_helper.py`
diff --git a/ChangeLog.d/c-build-helper-hostcc.txt b/ChangeLog.d/c-build-helper-hostcc.txt
new file mode 100644
index 0000000..86182c3
--- /dev/null
+++ b/ChangeLog.d/c-build-helper-hostcc.txt
@@ -0,0 +1,4 @@
+Features
+   * Use HOSTCC (if it is set) when compiling C code during generation of the
+     configuration-independent files. This allows them to be generated when
+     CC is set for cross compilation.
diff --git a/scripts/mbedtls_dev/c_build_helper.py b/scripts/mbedtls_dev/c_build_helper.py
index 5c587a1..d76b746 100644
--- a/scripts/mbedtls_dev/c_build_helper.py
+++ b/scripts/mbedtls_dev/c_build_helper.py
@@ -89,6 +89,37 @@
 }
 ''')
 
+def compile_c_file(c_filename, exe_filename, include_dirs):
+    """Compile a C source file with the host compiler.
+
+    * ``c_filename``: the name of the source file to compile.
+    * ``exe_filename``: the name for the executable to be created.
+    * ``include_dirs``: a list of paths to include directories to be passed
+      with the -I switch.
+    """
+    # Respect $HOSTCC if it is set
+    cc = os.getenv('HOSTCC', None)
+    if cc is None:
+        cc = os.getenv('CC', 'cc')
+    cmd = [cc]
+
+    proc = subprocess.Popen(cmd,
+                            stdout=subprocess.DEVNULL,
+                            stderr=subprocess.PIPE,
+                            universal_newlines=True)
+    cc_is_msvc = 'Microsoft (R) C/C++' in proc.communicate()[1]
+
+    cmd += ['-I' + dir for dir in include_dirs]
+    if cc_is_msvc:
+        # MSVC has deprecated using -o to specify the output file,
+        # and produces an object file in the working directory by default.
+        obj_filename = exe_filename[:-4] + '.obj'
+        cmd += ['-Fe' + exe_filename, '-Fo' + obj_filename]
+    else:
+        cmd += ['-o' + exe_filename]
+
+    subprocess.check_call(cmd + [c_filename])
+
 def get_c_expression_values(
         cast_to, printf_format,
         expressions,
@@ -123,10 +154,8 @@
                                                          expressions)
         )
         c_file.close()
-        cc = os.getenv('CC', 'cc')
-        subprocess.check_call([cc] +
-                              ['-I' + dir for dir in include_path] +
-                              ['-o', exe_name, c_name])
+
+        compile_c_file(c_name, exe_name, include_path)
         if keep_c:
             sys.stderr.write('List of {} tests kept at {}\n'
                              .format(caller, c_name))