summaryrefslogtreecommitdiff
path: root/giscanner/msvccompiler.py
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2015-03-10 13:15:52 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2015-07-30 11:01:01 +0800
commitad8fc51441b331c7db573201dd283a423081c042 (patch)
treef54c33c452d90e3c1b814b366e9072563236069c /giscanner/msvccompiler.py
parent0638f9f130fe080f945d07cde5cc01835a80553a (diff)
downloadgobject-introspection-ad8fc51441b331c7db573201dd283a423081c042.tar.gz
sourcescanner.py: Use Distutils for Preprocessing
Add a preprocess() function in ccompiler.py so that it will call the preprocess() method of the distutils.ccompiler class, and make use of it from sourcescanner.py. As we would need to set up the options (include paths, macros, undefs) to pass into the preprocessor (and later for the compiler), we have a new private function that translates what we have from the rest of giscanner so that it could be passed to distutils.ccompiler in a way that it understands. Also, as the MSVCCompiler classes in distutils do not provide a preprocess() implementation, we provide our own so that we can use it when preprocessing, via distutils, through subclassing MSVCCompiler. https://bugzilla.gnome.org/show_bug.cgi?id=728313
Diffstat (limited to 'giscanner/msvccompiler.py')
-rw-r--r--giscanner/msvccompiler.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/giscanner/msvccompiler.py b/giscanner/msvccompiler.py
new file mode 100644
index 00000000..63248093
--- /dev/null
+++ b/giscanner/msvccompiler.py
@@ -0,0 +1,101 @@
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2014 Chun-wei Fan
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+import os
+import distutils
+
+from distutils.errors import (DistutilsExecError, CompileError, LibError,
+ LinkError, UnknownFileError)
+from distutils.ccompiler import CCompiler, gen_preprocess_options
+from distutils.dep_util import newer
+
+# Distutil's MSVCCompiler does not provide a preprocess()
+# Implementation, so do our own here.
+
+
+def get_msvc_compiler():
+ return MSVCCompiler()
+
+
+class MSVCCompiler(distutils.msvccompiler.MSVCCompiler):
+
+ def __init__(self, verbose=0, dry_run=0, force=0):
+ CCompiler.__init__(self, verbose, dry_run, force)
+ self.__paths = []
+ self.__arch = None # deprecated name
+ if os.name == 'nt':
+ if isinstance(self, distutils.msvc9compiler.MSVCCompiler):
+ self.__version = distutils.msvc9compiler.VERSION
+ self.initialized = False
+ self.preprocess_options = None
+
+ def preprocess(self,
+ source,
+ output_file=None,
+ macros=None,
+ include_dirs=None,
+ extra_preargs=None,
+ extra_postargs=None):
+ if self.initialized is False:
+ self.initialize()
+
+ (_, macros, include_dirs) = \
+ self._fix_compile_args(None, macros, include_dirs)
+ pp_opts = gen_preprocess_options(macros, include_dirs)
+ preprocess_options = ['-E']
+ source_basename = None
+
+ if output_file is not None:
+ preprocess_options.append('-P')
+ source_basename = self._get_file_basename(source)
+ cpp_args = self.cc.split()
+ if extra_preargs is not None:
+ cpp_args[:0] = extra_preargs
+ if extra_postargs is not None:
+ preprocess_options.extend(extra_postargs)
+ cpp_args.extend(preprocess_options)
+ cpp_args.extend(pp_opts)
+ cpp_args.append(source)
+
+ # We need to preprocess: either we're being forced to, or the
+ # source file is newer than the target (or the target doesn't
+ # exist).
+ if self.force or output_file is None or newer(source, output_file):
+ try:
+ self.spawn(cpp_args)
+ except DistutilsExecError, msg:
+ print msg
+ raise CompileError
+
+ # The /P option for the MSVC preprocessor will output the results
+ # of the preprocessor to a file, as <source_without_extension>.i,
+ # so in order to output the specified filename, we need to rename
+ # that file
+ if output_file is not None:
+ if output_file != source_basename + '.i':
+ os.rename(source_basename + '.i', output_file)
+
+ def _get_file_basename(self, filename):
+ if filename is None:
+ return None
+ if filename.rfind('.') == -1:
+ return filename[filename.rfind('\\') + 1:]
+ else:
+ return filename[filename.rfind('\\') + 1:filename.rfind('.')]