diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 19 | ||||
-rw-r--r-- | mesonbuild/compilers/__init__.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/cs.py | 38 | ||||
-rw-r--r-- | mesonbuild/environment.py | 35 |
4 files changed, 72 insertions, 23 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e8c8b39..8b616a6 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -103,7 +103,8 @@ class NinjaBuildElement: # This is the only way I could find to make this work on all # platforms including Windows command shell. Slash is a dir separator # on Windows, too, so all characters are unambiguous and, more importantly, - # do not require quoting. + # do not require quoting, unless explicitely specified, which is necessary for + # the csc compiler. line = line.replace('\\', '/') outfile.write(line) @@ -988,7 +989,7 @@ int dummy; outname_rel = os.path.join(self.get_target_dir(target), fname) src_list = target.get_sources() compiler = target.compilers['cs'] - rel_srcs = [s.rel_to_builddir(self.build_to_src) for s in src_list] + rel_srcs = [os.path.normpath(s.rel_to_builddir(self.build_to_src)) for s in src_list] deps = [] commands = CompilerArgs(compiler, target.extra_args.get('cs', [])) commands += compiler.get_buildtype_args(buildtype) @@ -1014,8 +1015,8 @@ int dummy; for rel_src in generated_sources.keys(): dirpart, fnamepart = os.path.split(rel_src) if rel_src.lower().endswith('.cs'): - rel_srcs.append(rel_src) - deps.append(rel_src) + rel_srcs.append(os.path.normpath(rel_src)) + deps.append(os.path.normpath(rel_src)) for dep in target.get_external_deps(): commands.extend_direct(dep.get_link_args()) @@ -1588,7 +1589,15 @@ int dummy; def generate_cs_compile_rule(self, compiler, outfile): rule = 'rule %s_COMPILER\n' % compiler.get_language() invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()]) - command = ' command = %s $ARGS $in\n' % invoc + + if mesonlib.is_windows(): + command = ''' command = {executable} @$out.rsp + rspfile = $out.rsp + rspfile_content = $ARGS $in +'''.format(executable=invoc) + else: + command = ' command = %s $ARGS $in\n' % invoc + description = ' description = Compiling C Sharp target $out.\n' outfile.write(rule) outfile.write(command) diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py index f09f252..84c87fb 100644 --- a/mesonbuild/compilers/__init__.py +++ b/mesonbuild/compilers/__init__.py @@ -67,6 +67,7 @@ __all__ = [ 'JavaCompiler', 'LLVMDCompiler', 'MonoCompiler', + 'VisualStudioCsCompiler', 'NAGFortranCompiler', 'ObjCCompiler', 'ObjCPPCompiler', @@ -127,7 +128,7 @@ from .cpp import ( IntelCPPCompiler, VisualStudioCPPCompiler, ) -from .cs import MonoCompiler +from .cs import MonoCompiler, VisualStudioCsCompiler from .d import ( DCompiler, DmdDCompiler, diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index dd7a433..6d4811b 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -15,15 +15,16 @@ import os.path, subprocess from ..mesonlib import EnvironmentException +from ..mesonlib import is_windows from .compilers import Compiler, mono_buildtype_args -class MonoCompiler(Compiler): - def __init__(self, exelist, version, **kwargs): +class CsCompiler(Compiler): + def __init__(self, exelist, version, id, runner=None): self.language = 'cs' - super().__init__(exelist, version, **kwargs) - self.id = 'mono' - self.monorunner = 'mono' + super().__init__(exelist, version) + self.id = id + self.runner = runner def get_display_language(self): return 'C sharp' @@ -96,7 +97,10 @@ class MonoCompiler(Compiler): pc.wait() if pc.returncode != 0: raise EnvironmentException('Mono compiler %s can not compile programs.' % self.name_string()) - cmdlist = [self.monorunner, obj] + if self.runner: + cmdlist = [self.runner, obj] + else: + cmdlist = [os.path.join(work_dir, obj)] pe = subprocess.Popen(cmdlist, cwd=work_dir) pe.wait() if pe.returncode != 0: @@ -107,3 +111,25 @@ class MonoCompiler(Compiler): def get_buildtype_args(self, buildtype): return mono_buildtype_args[buildtype] + + +class MonoCompiler(CsCompiler): + def __init__(self, exelist, version): + super().__init__(exelist, version, 'mono', + 'mono') + + +class VisualStudioCsCompiler(CsCompiler): + def __init__(self, exelist, version): + super().__init__(exelist, version, 'csc') + + def get_buildtype_args(self, buildtype): + res = mono_buildtype_args[buildtype] + if not is_windows(): + tmp = [] + for flag in res: + if flag == '-debug': + flag = '-debug:portable' + tmp.append(flag) + res = tmp + return res diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index e553423..ccd85d5 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -54,6 +54,7 @@ from .compilers import ( IntelFortranCompiler, JavaCompiler, MonoCompiler, + VisualStudioCsCompiler, NAGFortranCompiler, Open64FortranCompiler, PathScaleFortranCompiler, @@ -275,6 +276,10 @@ class Environment: else: self.default_c = ['cc', 'gcc', 'clang'] self.default_cpp = ['c++', 'g++', 'clang++'] + if mesonlib.is_windows(): + self.default_cs = ['csc', 'mcs'] + else: + self.default_cs = ['mcs', 'csc'] self.default_objc = ['cc'] self.default_objcpp = ['c++'] self.default_fortran = ['gfortran', 'g95', 'f95', 'f90', 'f77', 'ifort'] @@ -419,7 +424,7 @@ class Environment: def _get_compilers(self, lang, evar, want_cross): ''' The list of compilers is detected in the exact same way for - C, C++, ObjC, ObjC++, Fortran so consolidate it here. + C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here. ''' if self.is_cross_build() and want_cross: compilers = mesonlib.stringlistify(self.cross_info.config['binaries'][lang]) @@ -664,16 +669,24 @@ class Environment: raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') def detect_cs_compiler(self): - exelist = ['mcs'] - try: - p, out, err = Popen_safe(exelist + ['--version']) - except OSError: - raise EnvironmentException('Could not execute C# compiler "%s"' % ' '.join(exelist)) - version = search_version(out) - full_version = out.split('\n', 1)[0] - if 'Mono' in out: - return MonoCompiler(exelist, version, full_version=full_version) - raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + compilers, ccache, is_cross, exe_wrap = self._get_compilers('cs', 'CSC', False) + popen_exceptions = {} + for comp in compilers: + if not isinstance(comp, list): + comp = [comp] + try: + p, out, err = Popen_safe(comp + ['--version']) + except OSError as e: + popen_exceptions[' '.join(comp + ['--version'])] = e + continue + + version = search_version(out) + if 'Mono' in out: + return MonoCompiler(comp, version) + elif "Visual C#" in out: + return VisualStudioCsCompiler(comp, version) + + self._handle_exceptions(popen_exceptions, compilers) def detect_vala_compiler(self): if 'VALAC' in os.environ: |