diff options
author | Chun-wei Fan <fanchunwei@src.gnome.org> | 2015-03-10 12:19:24 +0800 |
---|---|---|
committer | Chun-wei Fan <fanchunwei@src.gnome.org> | 2015-07-30 10:52:57 +0800 |
commit | 639841e46bc32ad92d1f040bc0de3150ffd3b603 (patch) | |
tree | 3e876c3e7b1d34edf9b0bb0dcdb2f2ae05e2c07e /giscanner | |
parent | e1d4c8413bf3f2ed5e877ef472eca8a05f8152bd (diff) | |
download | gobject-introspection-639841e46bc32ad92d1f040bc0de3150ffd3b603.tar.gz |
giscanner/sourcescanner.py: Use Tempfiles For Parsing
As we attempt to move giscanner to use distutils for preprocessing and
building the introspection dumper program, we need to update _parse(),
where the preprocessor is called, to not use stdin and stdout for the
preprocessor input and output, as distutils do not accept such usage.
The added bonus for this change is that MSVC builds can be done without
using MinGW/GCC as a helper, as the '-' flag for preprocessing from stdin
was the hindrance to that.
https://bugzilla.gnome.org/show_bug.cgi?id=728313
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/sourcescanner.py | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/giscanner/sourcescanner.py b/giscanner/sourcescanner.py index 15ced3f5..9310cff2 100644 --- a/giscanner/sourcescanner.py +++ b/giscanner/sourcescanner.py @@ -281,18 +281,36 @@ class SourceScanner(object): defines = ['__GI_SCANNER__'] undefs = [] + + tmp_fd_cpp, tmp_name_cpp = tempfile.mkstemp(prefix='g-ir-cpp-', suffix='.c') + fp_cpp = os.fdopen(tmp_fd_cpp, 'w') + self._write_preprocess_src(fp_cpp, defines, undefs, filenames) + fp_cpp.close() + + tmpfile_basename = os.path.basename(os.path.splitext(tmp_name_cpp)[0]) + + # Output file name of the preprocessor, only really used on non-MSVC, + # so we want the name to match the output file name of the MSVC preprocessor + tmpfile_output = tmpfile_basename + '.i' + cpp_args = os.environ.get('CC', 'cc').split() # support CC="ccache gcc" - if 'cl' in cpp_args: - # The Microsoft compiler/preprocessor (cl) does not accept - # source input from stdin (the '-' flag), so we need - # some help from gcc from MinGW/Cygwin or so. - # Note that the generated dumper program is - # still built and linked by Visual C++. - cpp_args = ['gcc'] - cpp_args += os.environ.get('CPPFLAGS', '').split() - cpp_args += os.environ.get('CFLAGS', '').split() - cpp_args += ['-E', '-C', '-I.', '-'] + + cpp_args += ['-E', '-C', '-I.'] + + # MSVC: The '-P' option makes the preprocessor output to a file, but we + # can't specify directly the name of the output file, so we use the + # MSVC-style preprocessor output file name for all builds for simplicity + # Define the following macros to silence many, many warnings + # in using the MSVC preprocessor during the parsing stage... + if 'cl.exe' in cpp_args or 'cl' in cpp_args: + cpp_args += ('-P', + '-D_USE_DECLSPECS_FOR_SAL', + '-D_CRT_SECURE_NO_WARNINGS', + '-D_CRT_NONSTDC_NO_WARNINGS', + '-DSAL_NO_ATTRIBUTE_DECLARATIONS') + cpp_args += self._cpp_options + cpp_args += [tmp_name_cpp] # We expect the preprocessor to remove macros. If debugging is turned # up high enough that won't happen, so strip these out. Bug #720504 @@ -306,32 +324,30 @@ class SourceScanner(object): stdin=subprocess.PIPE, stdout=subprocess.PIPE) - for define in defines: - proc.stdin.write('#ifndef %s\n' % (define, )) - proc.stdin.write('# define %s\n' % (define, )) - proc.stdin.write('#endif\n') - for undef in undefs: - proc.stdin.write('#undef %s\n' % (undef, )) - for filename in filenames: - proc.stdin.write('#include <%s>\n' % (filename, )) - proc.stdin.close() - - tmp_fd, tmp_name = tempfile.mkstemp() - fp = os.fdopen(tmp_fd, 'w+b') - while True: - data = proc.stdout.read(4096) - if data is None: - break - fp.write(data) - if len(data) < 4096: - break - fp.seek(0, 0) + if 'cl.exe' not in cpp_args and'cl' not in cpp_args: + cpp_args += ['-o', tmpfile_output] + + proc = subprocess.Popen(cpp_args) assert proc, 'Proc was none' proc.wait() if proc.returncode != 0: raise SystemExit('Error while processing the source.') + os.unlink(tmp_name_cpp) + fp = open(tmpfile_output, 'r') + self._scanner.parse_file(fp.fileno()) fp.close() - os.unlink(tmp_name) + os.unlink(tmpfile_output) + + def _write_preprocess_src(self, fp, defines, undefs, filenames): + # Write to the temp file for feeding into the preprocessor + for define in defines: + fp.write('#ifndef %s\n' % (define, )) + fp.write('# define %s\n' % (define, )) + fp.write('#endif\n') + for undef in undefs: + fp.write('#undef %s\n' % (undef, )) + for filename in filenames: + fp.write('#include <%s>\n' % (filename, )) |