aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py19
-rw-r--r--mesonbuild/compilers/__init__.py3
-rw-r--r--mesonbuild/compilers/cs.py38
-rw-r--r--mesonbuild/environment.py35
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: