diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-08-18 20:39:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-18 20:39:47 +0300 |
commit | d83f77109a7ac22da53acfad8f7ff078d929cd9d (patch) | |
tree | ba2dc20e3a91379008d6c7c841a4f503d50b5bd8 | |
parent | 8277d94e24d4382d49289c07ef20ea78d95443e1 (diff) | |
download | meson-d83f77109a7ac22da53acfad8f7ff078d929cd9d.tar.gz |
Convert buildtype to optimization and debug options (#3489)
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | docs/markdown/Builtin-options.md | 1 | ||||
-rw-r--r-- | docs/markdown/snippets/buildtype_toggles.md | 21 | ||||
-rw-r--r-- | mesonbuild/backend/backends.py | 2 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 7 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 27 | ||||
-rw-r--r-- | mesonbuild/compilers/c.py | 39 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 102 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/cs.py | 13 | ||||
-rw-r--r-- | mesonbuild/compilers/d.py | 28 | ||||
-rw-r--r-- | mesonbuild/compilers/fortran.py | 57 | ||||
-rw-r--r-- | mesonbuild/compilers/rust.py | 16 | ||||
-rw-r--r-- | mesonbuild/compilers/swift.py | 16 | ||||
-rw-r--r-- | mesonbuild/compilers/vala.py | 6 | ||||
-rw-r--r-- | mesonbuild/coredata.py | 52 | ||||
-rwxr-xr-x | run_unittests.py | 35 | ||||
-rw-r--r-- | test cases/common/126 llvm ir and assembly/meson.build | 2 |
18 files changed, 381 insertions, 46 deletions
diff --git a/.gitignore b/.gitignore index 0221a0584..fc090822a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /.settings /.cproject /.idea +/.vscode __pycache__ .coverage diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index b23cc9460..05578c70b 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -74,6 +74,7 @@ platforms or with all compilers: | b_bitcode | false | true, false | Embed Apple bitcode, see below | | b_colorout | always | auto, always, never | Use colored output | | b_coverage | false | true, false | Enable coverage tracking | +| b_vscrt | from_buildtype| none, md, mdd, mt, mtd, from_buildtype | VS runtime library to use (since 0.48.0) | | b_lundef | true | true, false | Don't allow undefined symbols when linking | | b_lto | false | true, false | Use link time optimization | | b_ndebug | false | true, false, if-release | Disable asserts | diff --git a/docs/markdown/snippets/buildtype_toggles.md b/docs/markdown/snippets/buildtype_toggles.md new file mode 100644 index 000000000..e6ae53d22 --- /dev/null +++ b/docs/markdown/snippets/buildtype_toggles.md @@ -0,0 +1,21 @@ +## Toggles for build type, optimization and vcrt type + +Since the very beginning Meson has provided different project types to +use, such as *debug* and *minsize*. There is also a *plain* type that +adds nothing by default but instead makes it the user's responsibility +to add everything by hand. This works but is a bit tedious. + +In this release we have added new new options to manually toggle +e.g. optimization levels and debug info so those can be changed +independently of other options. For example by default the debug +buildtype has no optmization enabled at all. If you wish to use GCC's +`-Og` instead, you could set it with the following command: + +``` +meson configure -Doptimization=g +``` + +Similarly we have added a toggle option to select the version of +Visual Studio C runtime to use. By default it uses the debug runtime +DLL debug builds and release DLL for release builds but this can be +manually changed with the new base option `b_vscrt`. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 730684859..7ed97b2bb 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -532,6 +532,8 @@ class Backend: commands += compiler.get_option_compile_args(copt_proxy) # Add buildtype args: optimization level, debugging, etc. commands += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target)) + commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target)) + commands += compiler.get_debug_args(self.get_option_for_target('debug', target)) # Add compile args added using add_project_arguments() commands += self.build.get_project_args(compiler, target.subproject) # Add compile args added using add_global_arguments() diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 9b718942f..ace069338 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -32,7 +32,7 @@ from ..compilers import CompilerArgs, CCompiler from ..linkers import ArLinker from ..mesonlib import File, MesonException, OrderedSet from ..mesonlib import get_compiler_for_source, has_path_sep -from .backends import CleanTrees, InstallData, TargetInstallData +from .backends import CleanTrees from ..build import InvalidArguments if mesonlib.is_windows(): @@ -826,6 +826,8 @@ int dummy; deps = [] commands = CompilerArgs(compiler, target.extra_args.get('cs', [])) commands += compiler.get_buildtype_args(buildtype) + commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target)) + commands += compiler.get_debug_args(self.get_option_for_target('debug', target)) if isinstance(target, build.Executable): commands.append('-target:exe') elif isinstance(target, build.SharedLibrary): @@ -1117,6 +1119,7 @@ int dummy; args.append(cratetype) args += ['--crate-name', target.name] args += rustc.get_buildtype_args(self.get_option_for_target('buildtype', target)) + args += rustc.get_debug_args(self.get_option_for_target('debug', target)) depfile = os.path.join(target.subdir, target.name + '.d') args += ['--emit', 'dep-info={}'.format(depfile), '--emit', 'link'] args += target.get_extra_args('rust') @@ -1241,6 +1244,8 @@ int dummy; raise InvalidArguments('Swift target %s contains a non-swift source file.' % target.get_basename()) os.makedirs(self.get_target_private_dir_abs(target), exist_ok=True) compile_args = swiftc.get_compile_only_args() + compile_args += swiftc.get_optimization_args(self.get_option_for_target('optimization', target)) + compile_args += swiftc.get_debug_args(self.get_option_for_target('debug', target)) compile_args += swiftc.get_module_args(module_name) compile_args += self.build.get_project_args(swiftc, target.subproject) compile_args += self.build.get_global_args(swiftc) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index acbb12ddf..4c799d03e 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -534,9 +534,17 @@ class Vs2010Backend(backends.Backend): pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang + def is_argument_with_msbuild_xml_entry(self, entry): + # Remove arguments that have a top level XML entry so + # they are not used twice. + # FIXME add args as needed. + return entry[1:].startswith('M') + def add_additional_options(self, lang, parent_node, file_args): args = [] for arg in file_args[lang].to_native(): + if self.is_argument_with_msbuild_xml_entry(arg): + continue if arg == '%(AdditionalOptions)': args.append(arg) else: @@ -677,6 +685,7 @@ class Vs2010Backend(backends.Backend): compiler = self._get_cl_compiler(target) buildtype_args = compiler.get_buildtype_args(self.buildtype) buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype) + vscrt_type = self.environment.coredata.base_options['b_vscrt'] project_name = target.name target_name = target.name root = ET.Element('Project', {'DefaultTargets': "Build", @@ -730,9 +739,24 @@ class Vs2010Backend(backends.Backend): if '/INCREMENTAL:NO' in buildtype_link_args: ET.SubElement(type_config, 'LinkIncremental').text = 'false' # CRT type; debug or release - if '/MDd' in buildtype_args: + if vscrt_type.value == 'from_buildtype': + if self.buildtype == 'debug' or self.buildtype == 'debugoptimized': + ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' + ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' + else: + ET.SubElement(type_config, 'UseDebugLibraries').text = 'false' + ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreaded' + elif vscrt_type.value == 'mdd': ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' + elif vscrt_type.value == 'mt': + # FIXME, wrong + ET.SubElement(type_config, 'UseDebugLibraries').text = 'false' + ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreaded' + elif vscrt_type.value == 'mtd': + # FIXME, wrong + ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' + ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDebug' else: ET.SubElement(type_config, 'UseDebugLibraries').text = 'false' ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDLL' @@ -800,6 +824,7 @@ class Vs2010Backend(backends.Backend): if l in file_args: file_args[l] += compilers.get_base_compile_args(self.get_base_options_for_target(target), comp) file_args[l] += comp.get_option_compile_args(self.environment.coredata.compiler_options) + # Add compile args added using add_project_arguments() for l, args in self.build.projects_args.get(target.subproject, {}).items(): if l in file_args: diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 1a0d6b25a..c7092b8c5 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -30,8 +30,6 @@ from .compilers import ( GCC_MINGW, get_largefile_args, gnu_winlibs, - msvc_buildtype_args, - msvc_buildtype_linker_args, msvc_winlibs, vs32_instruction_set_args, vs64_instruction_set_args, @@ -1197,6 +1195,13 @@ class VisualStudioCCompiler(CCompiler): ignore_libs = gnu_compiler_internal_libs internal_libs = () + crt_args = {'none': [], + 'md': ['/MD'], + 'mdd': ['/MDd'], + 'mt': ['/MT'], + 'mtd': ['/MTd'], + } + def __init__(self, exelist, version, is_cross, exe_wrap, is_64): CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) self.id = 'msvc' @@ -1206,7 +1211,7 @@ class VisualStudioCCompiler(CCompiler): self.warn_args = {'1': ['/W2'], '2': ['/W3'], '3': ['/W4']} - self.base_options = ['b_pch', 'b_ndebug'] # FIXME add lto, pgo and the like + self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like self.is_64 = is_64 # Override CCompiler.get_always_args @@ -1225,10 +1230,10 @@ class VisualStudioCCompiler(CCompiler): return ['/MDd'] def get_buildtype_args(self, buildtype): - return msvc_buildtype_args[buildtype] + return compilers.msvc_buildtype_args[buildtype] def get_buildtype_linker_args(self, buildtype): - return msvc_buildtype_linker_args[buildtype] + return compilers.msvc_buildtype_linker_args[buildtype] def get_pch_suffix(self): return 'pch' @@ -1258,6 +1263,12 @@ class VisualStudioCCompiler(CCompiler): return ['/Fe' + target] return ['/Fo' + target] + def get_optimization_args(self, optimization_level): + return compilers.msvc_optimization_args[optimization_level] + + def get_debug_args(self, is_debug): + return compilers.msvc_debug_args[is_debug] + def get_dependency_gen_args(self, outtarget, outfile): return [] @@ -1440,6 +1451,24 @@ class VisualStudioCCompiler(CCompiler): return [] return os.environ['INCLUDE'].split(os.pathsep) + def get_crt_compile_args(self, crt_val, buildtype): + if crt_val in self.crt_args: + return self.crt_args[crt_val] + assert(crt_val == 'from_buildtype') + # Match what build type flags used to do. + if buildtype == 'plain': + return [] + elif buildtype == 'debug': + return self.crt_args['mdd'] + elif buildtype == 'debugoptimized': + return self.crt_args['md'] + elif buildtype == 'release': + return self.crt_args['md'] + elif buildtype == 'minsize': + return self.crt_args['md'] + else: + assert(buildtype == 'custom') + raise EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".') class ArmCCompiler(ArmCompiler, CCompiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs): diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 97cca4779..b8ae399ae 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -124,12 +124,10 @@ def is_library(fname): return suffix in lib_suffixes gnulike_buildtype_args = {'plain': [], - # -O0 is passed for improved debugging information with gcc - # See https://github.com/mesonbuild/meson/pull/509 - 'debug': ['-O0', '-g'], - 'debugoptimized': ['-O2', '-g'], - 'release': ['-O3'], - 'minsize': ['-Os', '-g']} + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': []} armclang_buildtype_args = {'plain': [], 'debug': ['-O0', '-g'], @@ -145,10 +143,10 @@ arm_buildtype_args = {'plain': [], } msvc_buildtype_args = {'plain': [], - 'debug': ["/MDd", "/ZI", "/Ob0", "/Od", "/RTC1"], - 'debugoptimized': ["/MD", "/Zi", "/O2", "/Ob1"], - 'release': ["/MD", "/O2", "/Ob2"], - 'minsize': ["/MD", "/Zi", "/Os", "/Ob1"], + 'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"], + 'debugoptimized': ["/Zi", "/Ob1"], + 'release': ["/Ob2"], + 'minsize': ["/Zi", "/Ob1"], } apple_buildtype_linker_args = {'plain': [], @@ -190,44 +188,44 @@ java_buildtype_args = {'plain': [], } rust_buildtype_args = {'plain': [], - 'debug': ['-C', 'debuginfo=2'], - 'debugoptimized': ['-C', 'debuginfo=2', '-C', 'opt-level=2'], - 'release': ['-C', 'opt-level=3'], - 'minsize': [], # In a future release: ['-C', 'opt-level=s'], + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': [], } d_gdc_buildtype_args = {'plain': [], - 'debug': ['-g', '-O0'], - 'debugoptimized': ['-g', '-O'], + 'debug': [], + 'debugoptimized': ['-O'], 'release': ['-O3', '-frelease'], 'minsize': [], } d_ldc_buildtype_args = {'plain': [], - 'debug': ['-g', '-O0'], - 'debugoptimized': ['-g', '-O'], + 'debug': [], + 'debugoptimized': ['-O'], 'release': ['-O3', '-release'], 'minsize': [], } d_dmd_buildtype_args = {'plain': [], - 'debug': ['-g'], - 'debugoptimized': ['-g', '-O'], + 'debug': [], + 'debugoptimized': ['-O'], 'release': ['-O', '-release'], 'minsize': [], } mono_buildtype_args = {'plain': [], - 'debug': ['-debug'], - 'debugoptimized': ['-debug', '-optimize+'], + 'debug': [], + 'debugoptimized': ['-optimize+'], 'release': ['-optimize+'], 'minsize': [], } swift_buildtype_args = {'plain': [], - 'debug': ['-g'], - 'debugoptimized': ['-g', '-O'], - 'release': ['-O'], + 'debug': [], + 'debugoptimized': [], + 'release': [], 'minsize': [], } @@ -248,6 +246,36 @@ clang_color_args = {'auto': ['-Xclang', '-fcolor-diagnostics'], 'never': ['-Xclang', '-fno-color-diagnostics'], } +clike_optimization_args = {'0': [], + 'g': [], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'], + } + +gnu_optimization_args = {'0': [], + 'g': ['-Og'], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'], + } + +msvc_optimization_args = {'0': [], + 'g': ['/O0'], + '1': ['/O1'], + '2': ['/O2'], + '3': ['/O3'], + 's': ['/Os'], + } + +clike_debug_args = {False: [], + True: ['-g']} + +msvc_debug_args = {False: [], + True: []} # Fixme! + base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled headers', True), 'b_lto': coredata.UserBooleanOption('b_lto', 'Use link time optimization', False), 'b_sanitize': coredata.UserComboOption('b_sanitize', @@ -273,6 +301,9 @@ base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled he 'b_bitcode': coredata.UserBooleanOption('b_bitcode', 'Generate and embed bitcode (only macOS and iOS)', False), + 'b_vscrt': coredata.UserComboOption('b_vscrt', 'VS run-time library type to use.', + ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype'], + 'from_buildtype'), } gnulike_instruction_set_args = {'mmx': ['-mmmx'], @@ -380,6 +411,15 @@ def get_base_compile_args(options, compiler): # This does not need a try...except if option_enabled(compiler.base_options, options, 'b_bitcode'): args.append('-fembed-bitcode') + try: + crt_val = options['b_vscrt'].value + buildtype = options['buildtype'].value + try: + args += compiler.get_crt_compile_args(crt_val, buildtype) + except AttributeError: + pass + except KeyError: + pass return args def get_base_link_args(options, linker, is_shared_module): @@ -1250,6 +1290,12 @@ class GnuCompiler: def get_buildtype_args(self, buildtype): return gnulike_buildtype_args[buildtype] + def get_optimization_args(self, optimization_level): + return gnu_optimization_args[optimization_level] + + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] + def get_buildtype_linker_args(self, buildtype): if self.gcc_type == GCC_OSX: return apple_buildtype_linker_args[buildtype] @@ -1371,6 +1417,12 @@ class ClangCompiler: return apple_buildtype_linker_args[buildtype] return gnulike_buildtype_linker_args[buildtype] + def get_optimization_args(self, optimization_level): + return clike_optimization_args[optimization_level] + + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] + def get_pch_suffix(self): return 'pch' diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 2280f46bd..6483e54e4 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -242,7 +242,7 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler): def __init__(self, exelist, version, is_cross, exe_wrap, is_64): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, is_64) - self.base_options = ['b_pch'] # FIXME add lto, pgo and the like + self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like def get_options(self): opts = CPPCompiler.get_options(self) diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index e17cd4ed4..a6c74d260 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -19,6 +19,14 @@ from ..mesonlib import is_windows from .compilers import Compiler, mono_buildtype_args +cs_optimization_args = {'0': [], + 'g': [], + '1': ['-optimize+'], + '2': ['-optimize+'], + '3': ['-optimize+'], + 's': ['-optimize+'], + } + class CsCompiler(Compiler): def __init__(self, exelist, version, id, runner=None): self.language = 'cs' @@ -118,6 +126,11 @@ class CsCompiler(Compiler): def get_buildtype_args(self, buildtype): return mono_buildtype_args[buildtype] + def get_debug_args(self, is_debug): + return ['-debug'] if is_debug else [] + + def get_optimization_args(self, optimization_level): + return cs_optimization_args[optimization_level] class MonoCompiler(CsCompiler): def __init__(self, exelist, version): diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index f0f3d54b0..93dca0e35 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -23,6 +23,8 @@ from .compilers import ( d_ldc_buildtype_args, get_gcc_soname_args, gnu_color_args, + gnu_optimization_args, + clike_debug_args, Compiler, CompilerArgs, ) @@ -41,6 +43,22 @@ d_feature_args = {'gcc': {'unittest': '-funittest', } } +ldc_optimization_args = {'0': [], + 'g': [], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'], + } + +dmd_optimization_args = {'0': [], + 'g': [], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'], + } + class DCompiler(Compiler): def __init__(self, exelist, version, is_cross, **kwargs): self.language = 'd' @@ -238,6 +256,8 @@ class DCompiler(Compiler): return dcargs + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] class GnuDCompiler(DCompiler): def __init__(self, exelist, version, is_cross, **kwargs): @@ -288,6 +308,8 @@ class GnuDCompiler(DCompiler): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath): return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath) + def get_optimization_args(self, optimization_level): + return gnu_optimization_args[optimization_level] class LLVMDCompiler(DCompiler): def __init__(self, exelist, version, is_cross, **kwargs): @@ -342,6 +364,9 @@ class LLVMDCompiler(DCompiler): def unix_args_to_native(cls, args): return cls.translate_args_to_nongnu(args) + def get_optimization_args(self, optimization_level): + return ldc_optimization_args[optimization_level] + class DmdDCompiler(DCompiler): def __init__(self, exelist, version, is_cross, **kwargs): @@ -392,3 +417,6 @@ class DmdDCompiler(DCompiler): @classmethod def unix_args_to_native(cls, args): return cls.translate_args_to_nongnu(args) + + def get_optimization_args(self, optimization_level): + return dmd_optimization_args[optimization_level] diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index d6e41e3bd..5648a6f46 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -15,12 +15,20 @@ from .c import CCompiler from .compilers import ( ICC_STANDARD, + apple_buildtype_linker_args, + gnulike_buildtype_args, + gnulike_buildtype_linker_args, + gnu_optimization_args, + clike_debug_args, Compiler, GnuCompiler, ElbrusCompiler, IntelCompiler, ) +from mesonbuild.mesonlib import EnvironmentException, is_osx +import subprocess, os + class FortranCompiler(Compiler): library_dirs_cache = CCompiler.library_dirs_cache program_dirs_cache = CCompiler.library_dirs_cache @@ -61,6 +69,48 @@ class FortranCompiler(Compiler): def get_soname_args(self, *args): return CCompiler.get_soname_args(self, *args) + def sanity_check(self, work_dir, environment): + source_name = os.path.join(work_dir, 'sanitycheckf.f90') + binary_name = os.path.join(work_dir, 'sanitycheckf') + with open(source_name, 'w') as ofile: + ofile.write('''program prog + print *, "Fortran compilation is working." +end program prog +''') + extra_flags = self.get_cross_extra_flags(environment, link=True) + pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) + pc.wait() + if pc.returncode != 0: + raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string()) + if self.is_cross: + if self.exe_wrapper is None: + # Can't check if the binaries run so we have to assume they do + return + cmdlist = self.exe_wrapper + [binary_name] + else: + cmdlist = [binary_name] + pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + pe.wait() + if pe.returncode != 0: + raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string()) + + def get_std_warn_args(self, level): + return FortranCompiler.std_warn_args + + def get_buildtype_args(self, buildtype): + return gnulike_buildtype_args[buildtype] + + def get_optimization_args(self, optimization_level): + return gnu_optimization_args[optimization_level] + + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] + + def get_buildtype_linker_args(self, buildtype): + if is_osx(): + return apple_buildtype_linker_args[buildtype] + return gnulike_buildtype_linker_args[buildtype] + def split_shlib_to_parts(self, fname): return CCompiler.split_shlib_to_parts(self, fname) @@ -151,13 +201,6 @@ class FortranCompiler(Compiler): def gen_import_library_args(self, implibname): return CCompiler.gen_import_library_args(self, implibname) - def sanity_check(self, work_dir, environment): - code = '''program main - integer :: ret = 0 - call exit(ret) - end program main''' - return CCompiler.sanity_check_impl(self, work_dir, environment, 'sanitycheckf.f90', code) - def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'): return CCompiler._get_compiler_check_args(self, env, extra_args, dependencies, mode='compile') diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index d1a05ed21..93c291786 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -16,7 +16,15 @@ import subprocess, os.path from ..mesonlib import EnvironmentException, Popen_safe -from .compilers import Compiler, rust_buildtype_args +from .compilers import Compiler, rust_buildtype_args, clike_debug_args + +rust_optimization_args = {'0': [], + 'g': ['-C', '--opt-level=0'], + '1': ['-C', '--opt-level=1'], + '2': ['-C', '--opt-level=2'], + '3': ['-C', '--opt-level=3'], + 's': ['-C', '--opt-level=s'], + } class RustCompiler(Compiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None): @@ -68,3 +76,9 @@ class RustCompiler(Compiler): cmd = self.exelist + ['--print', 'sysroot'] p, stdo, stde = Popen_safe(cmd) return stdo.split('\n')[0] + + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] + + def get_optimization_args(self, optimization_level): + return rust_optimization_args[optimization_level] diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index 59997d6a2..4d5dd0cfe 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -16,7 +16,15 @@ import subprocess, os.path from ..mesonlib import EnvironmentException -from .compilers import Compiler, swift_buildtype_args +from .compilers import Compiler, swift_buildtype_args, clike_debug_args + +swift_optimization_args = {'0': [], + 'g': [], + '1': ['-O'], + '2': ['-O'], + '3': ['-O'], + 's': ['-O'], + } class SwiftCompiler(Compiler): def __init__(self, exelist, version): @@ -97,3 +105,9 @@ class SwiftCompiler(Compiler): raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string()) if subprocess.call(output_name) != 0: raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string()) + + def get_debug_args(self, is_debug): + return clike_debug_args[is_debug] + + def get_optimization_args(self, optimization_level): + return swift_optimization_args[optimization_level] diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index 6194d1aed..46bb210e9 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -34,6 +34,12 @@ class ValaCompiler(Compiler): def needs_static_linker(self): return False # Because compiles into C. + def get_optimization_args(self, optimization_level): + return [] + + def get_debug_args(self, is_debug): + return ['--debug'] + def get_output_args(self, target): return [] # Because compiles into C. diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 4c24dbde9..7520e06a3 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -349,6 +349,51 @@ class CoreData: raise RuntimeError('Tried to set unknown builtin option %s.' % optname) self.builtins[optname].set_value(value) + # Make sure that buildtype matches other settings. + if optname == 'buildtype': + self.set_others_from_buildtype(value) + else: + self.set_buildtype_from_others() + + def set_others_from_buildtype(self, value): + if value == 'plain': + opt = '0' + debug = False + elif value == 'debug': + opt = '0' + debug = True + elif value == 'debugoptimized': + opt = '2' + debug = True + elif value == 'release': + opt = '3' + debug = False + elif value == 'minsize': + opt = 's' + debug = True + else: + assert(value == 'custom') + return + self.builtins['optimization'].set_value(opt) + self.builtins['debug'].set_value(debug) + + def set_buildtype_from_others(self): + opt = self.builtins['optimization'].value + debug = self.builtins['debug'].value + if opt == '0' and not debug: + mode = 'plain' + elif opt == '0' and debug: + mode = 'debug' + elif opt == '2' and debug: + mode = 'debugoptimized' + elif opt == '3' and not debug: + mode = 'release' + elif opt == 's' and debug: + mode = 'minsize' + else: + mode = 'custom' + self.builtins['buildtype'].set_value(mode) + def validate_option_value(self, option_name, override_value): for opts in (self.builtins, self.base_options, self.compiler_options, self.user_options): if option_name in opts: @@ -389,8 +434,7 @@ class CoreData: if k == 'prefix': pass elif k in self.builtins: - tgt = self.builtins[k] - tgt.set_value(self.sanitize_dir_option_value(prefix, k, v)) + self.set_builtin_option(k, v) elif k in self.backend_options: tgt = self.backend_options[k] tgt.set_value(v) @@ -544,7 +588,7 @@ def parse_cmd_line_options(args): delattr(args, name) builtin_options = { - 'buildtype': [UserComboOption, 'Build type to use.', ['plain', 'debug', 'debugoptimized', 'release', 'minsize'], 'debug'], + 'buildtype': [UserComboOption, 'Build type to use.', ['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'], 'debug'], 'strip': [UserBooleanOption, 'Strip targets on install.', False], 'unity': [UserComboOption, 'Unity build.', ['on', 'off', 'subprojects'], 'off'], 'prefix': [UserStringOption, 'Installation prefix.', default_prefix()], @@ -569,6 +613,8 @@ builtin_options = { 'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True], 'install_umask': [UserUmaskOption, 'Default umask to apply on permissions of installed files.', '022'], 'auto_features': [UserFeatureOption, "Override value of all 'auto' features.", 'auto'], + 'optimization': [UserComboOption, 'Optimization level', ['0', 'g', '1', '2', '3', 's'], '0'], + 'debug': [UserBooleanOption, 'Debug', True] } # Special prefix-dependent defaults for installation directories that reside in diff --git a/run_unittests.py b/run_unittests.py index ab5d4b774..ab718823b 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -2552,6 +2552,41 @@ recommended as it is not supported on some platforms''') stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + def get_opts_as_dict(self): + result = {} + for i in self.introspect('--buildoptions'): + result[i['name']] = i['value'] + return result + + def test_buildtype_setting(self): + testdir = os.path.join(self.common_test_dir, '1 trivial') + self.init(testdir) + opts = self.get_opts_as_dict() + self.assertEqual(opts['buildtype'], 'debug') + self.assertEqual(opts['debug'], True) + self.setconf('-Ddebug=false') + opts = self.get_opts_as_dict() + self.assertEqual(opts['debug'], False) + self.assertEqual(opts['buildtype'], 'plain') + self.assertEqual(opts['optimization'], '0') + + # Setting optimizations to 3 should cause buildtype + # to go to release mode. + self.setconf('-Doptimization=3') + opts = self.get_opts_as_dict() + self.assertEqual(opts['buildtype'], 'release') + self.assertEqual(opts['debug'], False) + self.assertEqual(opts['optimization'], '3') + + # Going to debug build type should reset debugging + # and optimization + self.setconf('-Dbuildtype=debug') + opts = self.get_opts_as_dict() + self.assertEqual(opts['buildtype'], 'debug') + self.assertEqual(opts['debug'], True) + self.assertEqual(opts['optimization'], '0') + + class FailureTests(BasePlatformTests): ''' Tests that test failure conditions. Build files here should be dynamically diff --git a/test cases/common/126 llvm ir and assembly/meson.build b/test cases/common/126 llvm ir and assembly/meson.build index acff93f77..51321fb4a 100644 --- a/test cases/common/126 llvm ir and assembly/meson.build +++ b/test cases/common/126 llvm ir and assembly/meson.build @@ -47,7 +47,7 @@ foreach lang : ['c', 'cpp'] square_impl = custom_target(lang + square_impl, input : square_preproc, output : lang + square_base + '.obj', - command : [ml, '/Fo', '@OUTPUT@', '/c', '@INPUT@']) + command : [ml, '/safeseh', '/Fo', '@OUTPUT@', '/c', '@INPUT@']) endif if supported_cpus.contains(cpu) e = executable('square_asm_' + lang, square_impl, 'main.' + lang, |