aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/compilers.py81
-rw-r--r--mesonbuild/coredata.py1
-rw-r--r--mesonbuild/interpreter.py8
-rw-r--r--mesonbuild/mconf.py14
5 files changed, 108 insertions, 0 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index c4ed9de..f1a02c9 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -17,6 +17,7 @@ from .. import environment, mesonlib
from .. import build
from .. import mlog
from .. import dependencies
+from .. import compilers
from ..mesonlib import File
from .backends import InstallData
from ..build import InvalidArguments
@@ -1430,6 +1431,7 @@ rule FORTRAN_DEP_HACK
commands = []
# The first thing is implicit include directories: source, build and private.
commands += compiler.get_include_args(self.get_target_private_dir(target), False)
+ commands += compilers.get_base_compile_args(self.environment.coredata.base_options)
curdir = target.get_subdir()
tmppath = os.path.normpath(os.path.join(self.build_to_src, curdir))
commands += compiler.get_include_args(tmppath, False)
@@ -1637,6 +1639,8 @@ rule FORTRAN_DEP_HACK
abspath = os.path.join(self.environment.get_build_dir(), target.subdir)
commands = []
commands += linker.get_linker_always_args()
+ if not isinstance(target, build.StaticLibrary):
+ commands += compilers.get_base_link_args(self.environment.coredata.base_options)
commands += linker.get_buildtype_linker_args(self.environment.coredata.get_builtin_option('buildtype'))
commands += linker.get_option_link_args(self.environment.coredata.compiler_options)
if not(isinstance(target, build.StaticLibrary)):
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index f3ddf8d..4dcc256 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -66,6 +66,7 @@ msvc_buildtype_args = {'plain' : [],
gnulike_buildtype_linker_args = {}
+
if mesonlib.is_osx():
gnulike_buildtype_linker_args.update({'plain' : [],
'debug' : [],
@@ -111,6 +112,81 @@ msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib',
'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib',
'uuid.lib', 'comdlg32.lib', 'advapi32.lib']
+
+base_options = {'b_lto': coredata.UserBooleanOption('b_lto', 'Use link time optimization', False),
+ 'b_sanitize': coredata.UserComboOption('b_sanitize',
+ 'Code sanitizer to use',
+ ['none', 'address', 'thread', 'undefined', 'memory'],
+ 'none'),
+ 'b_lundef': coredata.UserBooleanOption('b_lundef', 'Use -Wl,--no-undefined when linking', True),
+ 'b_pgo': coredata.UserComboOption('b_pgo', 'Use profile guide optimization',
+ ['off', 'generate', 'use'],
+ 'off')
+ }
+
+def sanitizer_compile_args(value):
+ if value == 'none':
+ return []
+ args = ['-fsanitize=' + value]
+ if value == 'address':
+ args.append('-fno-omit-frame-pointer')
+ return args
+
+def sanitizer_link_args(value):
+ if value == 'none':
+ return []
+ args = ['-fsanitize=' + value]
+ return args
+
+def get_base_compile_args(options):
+ args = []
+ # FIXME, gcc/clang specific.
+ try:
+ if options['b_lto'].value:
+ args.append('-flto')
+ except KeyError:
+ pass
+ try:
+ args += sanitizer_compile_args(options['b_sanitize'].value)
+ except KeyError:
+ pass
+ try:
+ pgo_val = options['b_pgo'].value
+ if pgo_val == 'generate':
+ args.append('-fprofile-generate')
+ elif pgo_val == 'use':
+ args.append('-fprofile-use')
+ except KeyError:
+ pass
+ return args
+
+def get_base_link_args(options):
+ args = []
+ # FIXME, gcc/clang specific.
+ try:
+ if options['b_lto'].value:
+ args.append('-flto')
+ except KeyError:
+ pass
+ try:
+ args += sanitizer_link_args(options['b_sanitize'].value)
+ except KeyError:
+ pass
+ try:
+ pgo_val = options['b_pgo'].value
+ if pgo_val == 'generate':
+ args.append('-fprofile-generate')
+ elif pgo_val == 'use':
+ args.append('-fprofile-use')
+ except KeyError:
+ pass
+ try:
+ if options['b_lundef'].value:
+ args.append('-Wl,--no-undefined')
+ except KeyError:
+ pass
+ return args
+
def build_unix_rpath_args(build_dir, rpath_paths, install_rpath):
if len(rpath_paths) == 0 and len(install_rpath) == 0:
return []
@@ -147,6 +223,7 @@ class Compiler():
else:
raise TypeError('Unknown argument to Compiler')
self.version = version
+ self.base_options = []
def get_always_args(self):
return []
@@ -1293,6 +1370,7 @@ class GnuCCompiler(CCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
+ self.base_options = ['b_lto', 'b_pgo', 'b_sanitize', 'b_lundef']
def get_pic_args(self):
if self.gcc_type == GCC_MINGW:
@@ -1355,6 +1433,7 @@ class GnuObjCCompiler(ObjCCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
+ self.base_options = ['b_lto', 'b_pgo', 'b_sanitize', 'b_lundef']
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@@ -1380,6 +1459,7 @@ class GnuObjCPPCompiler(ObjCPPCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
+ self.base_options = ['b_lto', 'b_pgo', 'b_sanitize', 'b_lundef']
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@@ -1455,6 +1535,7 @@ class GnuCPPCompiler(CPPCompiler):
self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
+ self.base_options = ['b_lto', 'b_pgo', 'b_sanitize', 'b_lundef']
def get_always_args(self):
return ['-pipe']
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 2a73577..5dd8eb8 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -144,6 +144,7 @@ class CoreData():
self.init_builtins(options)
self.user_options = {}
self.compiler_options = {}
+ self.base_options = {}
self.external_args = {} # These are set from "the outside" with e.g. mesonconf
self.external_link_args = {}
if options.cross_file is not None:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 2ade18a..39546b5 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -19,6 +19,7 @@ from . import dependencies
from . import mlog
from . import build
from . import optinterpreter
+from . import compilers
from .wrap import wrap
from . import mesonlib
@@ -1523,8 +1524,15 @@ class Interpreter():
self.build.add_cross_compiler(cross_comp)
if self.environment.is_cross_build() and not need_cross_compiler:
self.build.add_cross_compiler(comp)
+ self.add_base_options(comp)
return success
+ def add_base_options(self, compiler):
+ for optname in compiler.base_options:
+ if optname in self.coredata.base_options:
+ continue
+ self.coredata.base_options[optname] = compilers.base_options[optname]
+
def func_find_program(self, node, args, kwargs):
self.validate_arguments(args, 1, [str])
required = kwargs.get('required', True)
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 03cbe55..7cbfa6b 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -94,6 +94,9 @@ class Conf:
elif k in self.coredata.compiler_options:
tgt = self.coredata.compiler_options[k]
tgt.set_value(v)
+ elif k in self.coredata.base_options:
+ tgt = self.coredata.base_options[k]
+ tgt.set_value(v)
elif k.endswith('linkargs'):
lang = k[:-8]
if not lang in self.coredata.external_link_args:
@@ -131,6 +134,17 @@ class Conf:
carr.append(['default_library', 'Default library type', self.coredata.get_builtin_option('default_library'), libtypelist])
self.print_aligned(carr)
print('')
+ print('Base options:')
+ okeys = sorted(self.coredata.base_options.keys())
+ if len(okeys) == 0:
+ print(' No base options\n')
+ else:
+ coarr = []
+ for k in okeys:
+ o = self.coredata.base_options[k]
+ coarr.append([k, o.description, o.value, ''])
+ self.print_aligned(coarr)
+ print('')
print('Compiler arguments:')
for (lang, args) in self.coredata.external_args.items():
print(' ' + lang + 'args', str(args))