diff --git a/compilers.py b/compilers.py index 10579eada..bb32069e3 100644 --- a/compilers.py +++ b/compilers.py @@ -91,6 +91,13 @@ mono_buildtype_args = {'plain' : [], 'debugoptimized': ['-debug', '-optimize+'], 'release' : ['-optimize+']} +gnu_winlibs = ['-lkernel32', '-luser32', '-lgdi32', '-lwinspool', '-lshell32', + '-lole32', '-loleaut32', '-luuid', '-lcomdlg32', '-ladvapi32'] + +msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib', + 'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', + 'uuid.lib', 'comdlg32.lib', 'advapi32.lib'] + def build_unix_rpath_args(build_dir, rpath_paths, install_rpath): if len(rpath_paths) == 0 and len(install_rpath) == 0: return [] @@ -901,6 +908,7 @@ class VisualStudioCCompiler(CCompiler): vs2010_always_args = ['/nologo', '/showIncludes'] vs2013_always_args = ['/nologo', '/showIncludes', '/FS'] + def __init__(self, exelist, version, is_cross, exe_wrap): CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) self.id = 'msvc' @@ -993,6 +1001,15 @@ class VisualStudioCCompiler(CCompiler): def thread_link_flags(self): return [] + def get_options(self): + return {'c_winlibs' : mesonlib.UserStringArrayOption('c_winlibs', + 'Windows libs to link against.', + msvc_winlibs) + } + + def get_option_link_args(self, options): + return options['c_winlibs'].value + class VisualStudioCPPCompiler(VisualStudioCCompiler): def __init__(self, exelist, version, is_cross, exe_wrap): VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap) @@ -1027,7 +1044,11 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler): return {'cpp_eh' : mesonlib.UserComboOption('cpp_eh', 'C++ exception handling type.', ['none', 'a', 's', 'sc'], - 'sc')} + 'sc'), + 'cpp_winlibs' : mesonlib.UserStringArrayOption('cpp_winlibs', + 'Windows libs to link against.', + msvc_winlibs) + } def get_option_compile_args(self, options): args = [] @@ -1037,7 +1058,7 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler): return args def get_option_link_args(self, options): - return [] + return options['cpp_winlibs'].value GCC_STANDARD = 0 GCC_OSX = 1 @@ -1056,6 +1077,7 @@ def get_gcc_soname_args(gcc_type, shlib_name, path, soversion): else: raise RuntimeError('Not implemented yet.') + class GnuCCompiler(CCompiler): def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) @@ -1092,9 +1114,15 @@ class GnuCCompiler(CCompiler): return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Gcc can do asm, too. def get_options(self): - return {'c_std' : mesonlib.UserComboOption('c_std', 'C language standard to use', + opts = {'c_std' : mesonlib.UserComboOption('c_std', 'C language standard to use', ['none', 'c89', 'c99', 'c11', 'gnu89', 'gnu99', 'gnu11'], 'c11')} + if self.gcc_type == GCC_MINGW: + opts.update({ + 'c_winlibs': mesonlib.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', + gnu_winlibs), + }) + return opts def get_option_compile_args(self, options): args = [] @@ -1104,6 +1132,8 @@ class GnuCCompiler(CCompiler): return args def get_option_link_args(self, options): + if self.gcc_type == GCC_MINGW: + return options['c_winlibs'].value return [] class GnuObjCCompiler(ObjCCompiler): @@ -1207,6 +1237,8 @@ class ClangCCompiler(CCompiler): return args def get_option_link_args(self, options): + if self.gcc_type == GCC_MINGW: + return options['c_winlibs'].value return [] class GnuCPPCompiler(CPPCompiler): @@ -1237,9 +1269,15 @@ class GnuCPPCompiler(CPPCompiler): return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion) def get_options(self): - return {'cpp_std' : mesonlib.UserComboOption('cpp_std', 'C language standard to use', - ['none', 'c++03', 'c++11', 'c++1y'], - 'c++11')} + opts = {'cpp_std' : mesonlib.UserComboOption('cpp_std', 'C language standard to use', + ['none', 'c++03', 'c++11', 'c++1y'], + 'c++11')} + if self.gcc_type == GCC_MINGW: + opts.update({ + 'cpp_winlibs': mesonlib.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against', + gnu_winlibs), + }) + return opts def get_option_compile_args(self, options): args = [] @@ -1249,6 +1287,8 @@ class GnuCPPCompiler(CPPCompiler): return args def get_option_link_args(self, options): + if self.gcc_type == GCC_MINGW: + return options['cpp_winlibs'].value return [] class ClangCPPCompiler(CPPCompiler): diff --git a/mesonintrospect.py b/mesonintrospect.py index 238d1528d..3ef2ab586 100755 --- a/mesonintrospect.py +++ b/mesonintrospect.py @@ -126,6 +126,8 @@ def add_keys(optlist, options): elif isinstance(opt, mesonlib.UserComboOption): optdict['choices'] = opt.choices typestr = 'combo' + elif isinstance(opt, mesonlib.UserStringArrayOption): + typestr = 'stringarray' else: raise RuntimeError("Unknown option type") optdict['type'] = typestr diff --git a/mesonlib.py b/mesonlib.py index 0e31ef118..0c7c3080d 100644 --- a/mesonlib.py +++ b/mesonlib.py @@ -314,3 +314,20 @@ class UserComboOption(UserOption): optionsstring = ', '.join(['"%s"' % (item,) for item in self.choices]) raise MesonException('Value "%s" for combo option "%s" is not one of the choices. Possible choices are: %s.' % (newvalue, self.name, optionsstring)) self.value = newvalue + +class UserStringArrayOption(UserOption): + def __init__(self, name, description, value): + super().__init__(name, description) + self.set_value(value) + + def set_value(self, newvalue): + if isinstance(newvalue, str): + if not newvalue.startswith('['): + raise MesonException('Valuestring does not define an array: ' + newvalue) + newvalue = eval(newvalue, {}, {}) # Yes, it is unsafe. + if not isinstance(newvalue, list): + raise MesonException('String array value is not an array.') + for i in newvalue: + if not isinstance(i, str): + raise MesonException('String array element not a string.') + self.value = newvalue