Convert buildtype to optimization and debug options (#3489)

pull/3980/head
Jussi Pakkanen 7 years ago committed by GitHub
parent 8277d94e24
commit d83f77109a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 1
      docs/markdown/Builtin-options.md
  3. 21
      docs/markdown/snippets/buildtype_toggles.md
  4. 2
      mesonbuild/backend/backends.py
  5. 7
      mesonbuild/backend/ninjabackend.py
  6. 27
      mesonbuild/backend/vs2010backend.py
  7. 39
      mesonbuild/compilers/c.py
  8. 102
      mesonbuild/compilers/compilers.py
  9. 2
      mesonbuild/compilers/cpp.py
  10. 13
      mesonbuild/compilers/cs.py
  11. 28
      mesonbuild/compilers/d.py
  12. 57
      mesonbuild/compilers/fortran.py
  13. 16
      mesonbuild/compilers/rust.py
  14. 16
      mesonbuild/compilers/swift.py
  15. 6
      mesonbuild/compilers/vala.py
  16. 52
      mesonbuild/coredata.py
  17. 35
      run_unittests.py
  18. 2
      test cases/common/126 llvm ir and assembly/meson.build

1
.gitignore vendored

@ -3,6 +3,7 @@
/.settings /.settings
/.cproject /.cproject
/.idea /.idea
/.vscode
__pycache__ __pycache__
.coverage .coverage

@ -74,6 +74,7 @@ platforms or with all compilers:
| b_bitcode | false | true, false | Embed Apple bitcode, see below | | b_bitcode | false | true, false | Embed Apple bitcode, see below |
| b_colorout | always | auto, always, never | Use colored output | | b_colorout | always | auto, always, never | Use colored output |
| b_coverage | false | true, false | Enable coverage tracking | | 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_lundef | true | true, false | Don't allow undefined symbols when linking |
| b_lto | false | true, false | Use link time optimization | | b_lto | false | true, false | Use link time optimization |
| b_ndebug | false | true, false, if-release | Disable asserts | | b_ndebug | false | true, false, if-release | Disable asserts |

@ -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`.

@ -532,6 +532,8 @@ class Backend:
commands += compiler.get_option_compile_args(copt_proxy) commands += compiler.get_option_compile_args(copt_proxy)
# Add buildtype args: optimization level, debugging, etc. # Add buildtype args: optimization level, debugging, etc.
commands += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target)) 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() # Add compile args added using add_project_arguments()
commands += self.build.get_project_args(compiler, target.subproject) commands += self.build.get_project_args(compiler, target.subproject)
# Add compile args added using add_global_arguments() # Add compile args added using add_global_arguments()

@ -32,7 +32,7 @@ from ..compilers import CompilerArgs, CCompiler
from ..linkers import ArLinker from ..linkers import ArLinker
from ..mesonlib import File, MesonException, OrderedSet from ..mesonlib import File, MesonException, OrderedSet
from ..mesonlib import get_compiler_for_source, has_path_sep from ..mesonlib import get_compiler_for_source, has_path_sep
from .backends import CleanTrees, InstallData, TargetInstallData from .backends import CleanTrees
from ..build import InvalidArguments from ..build import InvalidArguments
if mesonlib.is_windows(): if mesonlib.is_windows():
@ -826,6 +826,8 @@ int dummy;
deps = [] deps = []
commands = CompilerArgs(compiler, target.extra_args.get('cs', [])) commands = CompilerArgs(compiler, target.extra_args.get('cs', []))
commands += compiler.get_buildtype_args(buildtype) 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): if isinstance(target, build.Executable):
commands.append('-target:exe') commands.append('-target:exe')
elif isinstance(target, build.SharedLibrary): elif isinstance(target, build.SharedLibrary):
@ -1117,6 +1119,7 @@ int dummy;
args.append(cratetype) args.append(cratetype)
args += ['--crate-name', target.name] args += ['--crate-name', target.name]
args += rustc.get_buildtype_args(self.get_option_for_target('buildtype', target)) 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') depfile = os.path.join(target.subdir, target.name + '.d')
args += ['--emit', 'dep-info={}'.format(depfile), '--emit', 'link'] args += ['--emit', 'dep-info={}'.format(depfile), '--emit', 'link']
args += target.get_extra_args('rust') 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()) 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) os.makedirs(self.get_target_private_dir_abs(target), exist_ok=True)
compile_args = swiftc.get_compile_only_args() 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 += swiftc.get_module_args(module_name)
compile_args += self.build.get_project_args(swiftc, target.subproject) compile_args += self.build.get_project_args(swiftc, target.subproject)
compile_args += self.build.get_global_args(swiftc) compile_args += self.build.get_global_args(swiftc)

@ -534,9 +534,17 @@ class Vs2010Backend(backends.Backend):
pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang 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): def add_additional_options(self, lang, parent_node, file_args):
args = [] args = []
for arg in file_args[lang].to_native(): for arg in file_args[lang].to_native():
if self.is_argument_with_msbuild_xml_entry(arg):
continue
if arg == '%(AdditionalOptions)': if arg == '%(AdditionalOptions)':
args.append(arg) args.append(arg)
else: else:
@ -677,6 +685,7 @@ class Vs2010Backend(backends.Backend):
compiler = self._get_cl_compiler(target) compiler = self._get_cl_compiler(target)
buildtype_args = compiler.get_buildtype_args(self.buildtype) buildtype_args = compiler.get_buildtype_args(self.buildtype)
buildtype_link_args = compiler.get_buildtype_linker_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 project_name = target.name
target_name = target.name target_name = target.name
root = ET.Element('Project', {'DefaultTargets': "Build", root = ET.Element('Project', {'DefaultTargets': "Build",
@ -730,9 +739,24 @@ class Vs2010Backend(backends.Backend):
if '/INCREMENTAL:NO' in buildtype_link_args: if '/INCREMENTAL:NO' in buildtype_link_args:
ET.SubElement(type_config, 'LinkIncremental').text = 'false' ET.SubElement(type_config, 'LinkIncremental').text = 'false'
# CRT type; debug or release # 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, 'UseDebugLibraries').text = 'true'
ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' 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: else:
ET.SubElement(type_config, 'UseDebugLibraries').text = 'false' ET.SubElement(type_config, 'UseDebugLibraries').text = 'false'
ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDLL' ET.SubElement(type_config, 'RuntimeLibrary').text = 'MultiThreadedDLL'
@ -800,6 +824,7 @@ class Vs2010Backend(backends.Backend):
if l in file_args: if l in file_args:
file_args[l] += compilers.get_base_compile_args(self.get_base_options_for_target(target), comp) 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) file_args[l] += comp.get_option_compile_args(self.environment.coredata.compiler_options)
# Add compile args added using add_project_arguments() # Add compile args added using add_project_arguments()
for l, args in self.build.projects_args.get(target.subproject, {}).items(): for l, args in self.build.projects_args.get(target.subproject, {}).items():
if l in file_args: if l in file_args:

@ -30,8 +30,6 @@ from .compilers import (
GCC_MINGW, GCC_MINGW,
get_largefile_args, get_largefile_args,
gnu_winlibs, gnu_winlibs,
msvc_buildtype_args,
msvc_buildtype_linker_args,
msvc_winlibs, msvc_winlibs,
vs32_instruction_set_args, vs32_instruction_set_args,
vs64_instruction_set_args, vs64_instruction_set_args,
@ -1197,6 +1195,13 @@ class VisualStudioCCompiler(CCompiler):
ignore_libs = gnu_compiler_internal_libs ignore_libs = gnu_compiler_internal_libs
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): def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.id = 'msvc' self.id = 'msvc'
@ -1206,7 +1211,7 @@ class VisualStudioCCompiler(CCompiler):
self.warn_args = {'1': ['/W2'], self.warn_args = {'1': ['/W2'],
'2': ['/W3'], '2': ['/W3'],
'3': ['/W4']} '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 self.is_64 = is_64
# Override CCompiler.get_always_args # Override CCompiler.get_always_args
@ -1225,10 +1230,10 @@ class VisualStudioCCompiler(CCompiler):
return ['/MDd'] return ['/MDd']
def get_buildtype_args(self, buildtype): def get_buildtype_args(self, buildtype):
return msvc_buildtype_args[buildtype] return compilers.msvc_buildtype_args[buildtype]
def get_buildtype_linker_args(self, 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): def get_pch_suffix(self):
return 'pch' return 'pch'
@ -1258,6 +1263,12 @@ class VisualStudioCCompiler(CCompiler):
return ['/Fe' + target] return ['/Fe' + target]
return ['/Fo' + 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): def get_dependency_gen_args(self, outtarget, outfile):
return [] return []
@ -1440,6 +1451,24 @@ class VisualStudioCCompiler(CCompiler):
return [] return []
return os.environ['INCLUDE'].split(os.pathsep) 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): class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs): def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):

@ -124,12 +124,10 @@ def is_library(fname):
return suffix in lib_suffixes return suffix in lib_suffixes
gnulike_buildtype_args = {'plain': [], gnulike_buildtype_args = {'plain': [],
# -O0 is passed for improved debugging information with gcc 'debug': [],
# See https://github.com/mesonbuild/meson/pull/509 'debugoptimized': [],
'debug': ['-O0', '-g'], 'release': [],
'debugoptimized': ['-O2', '-g'], 'minsize': []}
'release': ['-O3'],
'minsize': ['-Os', '-g']}
armclang_buildtype_args = {'plain': [], armclang_buildtype_args = {'plain': [],
'debug': ['-O0', '-g'], 'debug': ['-O0', '-g'],
@ -145,10 +143,10 @@ arm_buildtype_args = {'plain': [],
} }
msvc_buildtype_args = {'plain': [], msvc_buildtype_args = {'plain': [],
'debug': ["/MDd", "/ZI", "/Ob0", "/Od", "/RTC1"], 'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
'debugoptimized': ["/MD", "/Zi", "/O2", "/Ob1"], 'debugoptimized': ["/Zi", "/Ob1"],
'release': ["/MD", "/O2", "/Ob2"], 'release': ["/Ob2"],
'minsize': ["/MD", "/Zi", "/Os", "/Ob1"], 'minsize': ["/Zi", "/Ob1"],
} }
apple_buildtype_linker_args = {'plain': [], apple_buildtype_linker_args = {'plain': [],
@ -190,44 +188,44 @@ java_buildtype_args = {'plain': [],
} }
rust_buildtype_args = {'plain': [], rust_buildtype_args = {'plain': [],
'debug': ['-C', 'debuginfo=2'], 'debug': [],
'debugoptimized': ['-C', 'debuginfo=2', '-C', 'opt-level=2'], 'debugoptimized': [],
'release': ['-C', 'opt-level=3'], 'release': [],
'minsize': [], # In a future release: ['-C', 'opt-level=s'], 'minsize': [],
} }
d_gdc_buildtype_args = {'plain': [], d_gdc_buildtype_args = {'plain': [],
'debug': ['-g', '-O0'], 'debug': [],
'debugoptimized': ['-g', '-O'], 'debugoptimized': ['-O'],
'release': ['-O3', '-frelease'], 'release': ['-O3', '-frelease'],
'minsize': [], 'minsize': [],
} }
d_ldc_buildtype_args = {'plain': [], d_ldc_buildtype_args = {'plain': [],
'debug': ['-g', '-O0'], 'debug': [],
'debugoptimized': ['-g', '-O'], 'debugoptimized': ['-O'],
'release': ['-O3', '-release'], 'release': ['-O3', '-release'],
'minsize': [], 'minsize': [],
} }
d_dmd_buildtype_args = {'plain': [], d_dmd_buildtype_args = {'plain': [],
'debug': ['-g'], 'debug': [],
'debugoptimized': ['-g', '-O'], 'debugoptimized': ['-O'],
'release': ['-O', '-release'], 'release': ['-O', '-release'],
'minsize': [], 'minsize': [],
} }
mono_buildtype_args = {'plain': [], mono_buildtype_args = {'plain': [],
'debug': ['-debug'], 'debug': [],
'debugoptimized': ['-debug', '-optimize+'], 'debugoptimized': ['-optimize+'],
'release': ['-optimize+'], 'release': ['-optimize+'],
'minsize': [], 'minsize': [],
} }
swift_buildtype_args = {'plain': [], swift_buildtype_args = {'plain': [],
'debug': ['-g'], 'debug': [],
'debugoptimized': ['-g', '-O'], 'debugoptimized': [],
'release': ['-O'], 'release': [],
'minsize': [], 'minsize': [],
} }
@ -248,6 +246,36 @@ clang_color_args = {'auto': ['-Xclang', '-fcolor-diagnostics'],
'never': ['-Xclang', '-fno-color-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), base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled headers', True),
'b_lto': coredata.UserBooleanOption('b_lto', 'Use link time optimization', False), 'b_lto': coredata.UserBooleanOption('b_lto', 'Use link time optimization', False),
'b_sanitize': coredata.UserComboOption('b_sanitize', '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', 'b_bitcode': coredata.UserBooleanOption('b_bitcode',
'Generate and embed bitcode (only macOS and iOS)', 'Generate and embed bitcode (only macOS and iOS)',
False), 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'], gnulike_instruction_set_args = {'mmx': ['-mmmx'],
@ -380,6 +411,15 @@ def get_base_compile_args(options, compiler):
# This does not need a try...except # This does not need a try...except
if option_enabled(compiler.base_options, options, 'b_bitcode'): if option_enabled(compiler.base_options, options, 'b_bitcode'):
args.append('-fembed-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 return args
def get_base_link_args(options, linker, is_shared_module): def get_base_link_args(options, linker, is_shared_module):
@ -1250,6 +1290,12 @@ class GnuCompiler:
def get_buildtype_args(self, buildtype): def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[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): def get_buildtype_linker_args(self, buildtype):
if self.gcc_type == GCC_OSX: if self.gcc_type == GCC_OSX:
return apple_buildtype_linker_args[buildtype] return apple_buildtype_linker_args[buildtype]
@ -1371,6 +1417,12 @@ class ClangCompiler:
return apple_buildtype_linker_args[buildtype] return apple_buildtype_linker_args[buildtype]
return gnulike_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): def get_pch_suffix(self):
return 'pch' return 'pch'

@ -242,7 +242,7 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, is_64): def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, is_64) 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): def get_options(self):
opts = CPPCompiler.get_options(self) opts = CPPCompiler.get_options(self)

@ -19,6 +19,14 @@ from ..mesonlib import is_windows
from .compilers import Compiler, mono_buildtype_args from .compilers import Compiler, mono_buildtype_args
cs_optimization_args = {'0': [],
'g': [],
'1': ['-optimize+'],
'2': ['-optimize+'],
'3': ['-optimize+'],
's': ['-optimize+'],
}
class CsCompiler(Compiler): class CsCompiler(Compiler):
def __init__(self, exelist, version, id, runner=None): def __init__(self, exelist, version, id, runner=None):
self.language = 'cs' self.language = 'cs'
@ -118,6 +126,11 @@ class CsCompiler(Compiler):
def get_buildtype_args(self, buildtype): def get_buildtype_args(self, buildtype):
return mono_buildtype_args[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): class MonoCompiler(CsCompiler):
def __init__(self, exelist, version): def __init__(self, exelist, version):

@ -23,6 +23,8 @@ from .compilers import (
d_ldc_buildtype_args, d_ldc_buildtype_args,
get_gcc_soname_args, get_gcc_soname_args,
gnu_color_args, gnu_color_args,
gnu_optimization_args,
clike_debug_args,
Compiler, Compiler,
CompilerArgs, 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): class DCompiler(Compiler):
def __init__(self, exelist, version, is_cross, **kwargs): def __init__(self, exelist, version, is_cross, **kwargs):
self.language = 'd' self.language = 'd'
@ -238,6 +256,8 @@ class DCompiler(Compiler):
return dcargs return dcargs
def get_debug_args(self, is_debug):
return clike_debug_args[is_debug]
class GnuDCompiler(DCompiler): class GnuDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, **kwargs): 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): 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) 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): class LLVMDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, **kwargs): def __init__(self, exelist, version, is_cross, **kwargs):
@ -342,6 +364,9 @@ class LLVMDCompiler(DCompiler):
def unix_args_to_native(cls, args): def unix_args_to_native(cls, args):
return cls.translate_args_to_nongnu(args) return cls.translate_args_to_nongnu(args)
def get_optimization_args(self, optimization_level):
return ldc_optimization_args[optimization_level]
class DmdDCompiler(DCompiler): class DmdDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, **kwargs): def __init__(self, exelist, version, is_cross, **kwargs):
@ -392,3 +417,6 @@ class DmdDCompiler(DCompiler):
@classmethod @classmethod
def unix_args_to_native(cls, args): def unix_args_to_native(cls, args):
return cls.translate_args_to_nongnu(args) return cls.translate_args_to_nongnu(args)
def get_optimization_args(self, optimization_level):
return dmd_optimization_args[optimization_level]

@ -15,12 +15,20 @@
from .c import CCompiler from .c import CCompiler
from .compilers import ( from .compilers import (
ICC_STANDARD, ICC_STANDARD,
apple_buildtype_linker_args,
gnulike_buildtype_args,
gnulike_buildtype_linker_args,
gnu_optimization_args,
clike_debug_args,
Compiler, Compiler,
GnuCompiler, GnuCompiler,
ElbrusCompiler, ElbrusCompiler,
IntelCompiler, IntelCompiler,
) )
from mesonbuild.mesonlib import EnvironmentException, is_osx
import subprocess, os
class FortranCompiler(Compiler): class FortranCompiler(Compiler):
library_dirs_cache = CCompiler.library_dirs_cache library_dirs_cache = CCompiler.library_dirs_cache
program_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): def get_soname_args(self, *args):
return CCompiler.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): def split_shlib_to_parts(self, fname):
return CCompiler.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): def gen_import_library_args(self, implibname):
return CCompiler.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'): 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') return CCompiler._get_compiler_check_args(self, env, extra_args, dependencies, mode='compile')

@ -16,7 +16,15 @@ import subprocess, os.path
from ..mesonlib import EnvironmentException, Popen_safe 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): class RustCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None): def __init__(self, exelist, version, is_cross, exe_wrapper=None):
@ -68,3 +76,9 @@ class RustCompiler(Compiler):
cmd = self.exelist + ['--print', 'sysroot'] cmd = self.exelist + ['--print', 'sysroot']
p, stdo, stde = Popen_safe(cmd) p, stdo, stde = Popen_safe(cmd)
return stdo.split('\n')[0] 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]

@ -16,7 +16,15 @@ import subprocess, os.path
from ..mesonlib import EnvironmentException 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): class SwiftCompiler(Compiler):
def __init__(self, exelist, version): def __init__(self, exelist, version):
@ -97,3 +105,9 @@ class SwiftCompiler(Compiler):
raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string()) raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string())
if subprocess.call(output_name) != 0: if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string()) 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]

@ -34,6 +34,12 @@ class ValaCompiler(Compiler):
def needs_static_linker(self): def needs_static_linker(self):
return False # Because compiles into C. 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): def get_output_args(self, target):
return [] # Because compiles into C. return [] # Because compiles into C.

@ -349,6 +349,51 @@ class CoreData:
raise RuntimeError('Tried to set unknown builtin option %s.' % optname) raise RuntimeError('Tried to set unknown builtin option %s.' % optname)
self.builtins[optname].set_value(value) 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): def validate_option_value(self, option_name, override_value):
for opts in (self.builtins, self.base_options, self.compiler_options, self.user_options): for opts in (self.builtins, self.base_options, self.compiler_options, self.user_options):
if option_name in opts: if option_name in opts:
@ -389,8 +434,7 @@ class CoreData:
if k == 'prefix': if k == 'prefix':
pass pass
elif k in self.builtins: elif k in self.builtins:
tgt = self.builtins[k] self.set_builtin_option(k, v)
tgt.set_value(self.sanitize_dir_option_value(prefix, k, v))
elif k in self.backend_options: elif k in self.backend_options:
tgt = self.backend_options[k] tgt = self.backend_options[k]
tgt.set_value(v) tgt.set_value(v)
@ -544,7 +588,7 @@ def parse_cmd_line_options(args):
delattr(args, name) delattr(args, name)
builtin_options = { 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], 'strip': [UserBooleanOption, 'Strip targets on install.', False],
'unity': [UserComboOption, 'Unity build.', ['on', 'off', 'subprojects'], 'off'], 'unity': [UserComboOption, 'Unity build.', ['on', 'off', 'subprojects'], 'off'],
'prefix': [UserStringOption, 'Installation prefix.', default_prefix()], 'prefix': [UserStringOption, 'Installation prefix.', default_prefix()],
@ -569,6 +613,8 @@ builtin_options = {
'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True], 'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True],
'install_umask': [UserUmaskOption, 'Default umask to apply on permissions of installed files.', '022'], 'install_umask': [UserUmaskOption, 'Default umask to apply on permissions of installed files.', '022'],
'auto_features': [UserFeatureOption, "Override value of all 'auto' features.", 'auto'], '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 # Special prefix-dependent defaults for installation directories that reside in

@ -2552,6 +2552,41 @@ recommended as it is not supported on some platforms''')
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=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): class FailureTests(BasePlatformTests):
''' '''
Tests that test failure conditions. Build files here should be dynamically Tests that test failure conditions. Build files here should be dynamically

@ -47,7 +47,7 @@ foreach lang : ['c', 'cpp']
square_impl = custom_target(lang + square_impl, square_impl = custom_target(lang + square_impl,
input : square_preproc, input : square_preproc,
output : lang + square_base + '.obj', output : lang + square_base + '.obj',
command : [ml, '/Fo', '@OUTPUT@', '/c', '@INPUT@']) command : [ml, '/safeseh', '/Fo', '@OUTPUT@', '/c', '@INPUT@'])
endif endif
if supported_cpus.contains(cpu) if supported_cpus.contains(cpu)
e = executable('square_asm_' + lang, square_impl, 'main.' + lang, e = executable('square_asm_' + lang, square_impl, 'main.' + lang,

Loading…
Cancel
Save