Add 'b_pie' compiler option
On Android executables must be position independent, many distributions enable it by default too for security reasons.
This commit is contained in:
parent
3ad99d2769
commit
c453400d59
|
@ -82,6 +82,7 @@ platforms or with all compilers:
|
|||
| b_pgo | off | off, generate, use | Use profile guided optimization |
|
||||
| b_sanitize | none | see below | Code sanitizer to use |
|
||||
| b_staticpic | true | true, false | Build static libraries as position independent |
|
||||
| b_pie | false | true, false | Build position-independent executables (since 0.49.0)|
|
||||
|
||||
The value of `b_sanitize` can be one of: `none`, `address`, `thread`,
|
||||
`undefined`, `memory`, `address,undefined`.
|
||||
|
|
|
@ -552,6 +552,7 @@ be passed to [shared and static libraries](#library).
|
|||
- `d_unittest`, when set to true, the D modules are compiled in debug mode
|
||||
- `d_module_versions` list of module version identifiers set when compiling D sources
|
||||
- `d_debug` list of module debug identifiers set when compiling D sources
|
||||
- `pie` *(added 0.49.0)* build a position-independent executable
|
||||
|
||||
The list of `sources`, `objects`, and `dependencies` is always
|
||||
flattened, which means you can freely nest and add lists while
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
## Position-independent executables
|
||||
|
||||
When `b_pie` option, or `executable()`'s `pie` keyword argument is set to
|
||||
`true`, position-independent executables are built. All their objects are built
|
||||
with `-fPIE` and the executable is linked with `-pie`. Any static library they
|
||||
link must be built with `pic` set to `true` (see `b_staticpic` option).
|
|
@ -552,6 +552,8 @@ class Backend:
|
|||
# Set -fPIC for static libraries by default unless explicitly disabled
|
||||
if isinstance(target, build.StaticLibrary) and target.pic:
|
||||
commands += compiler.get_pic_args()
|
||||
if isinstance(target, build.Executable) and target.pie:
|
||||
commands += compiler.get_pie_args()
|
||||
# Add compile args needed to find external dependencies. Link args are
|
||||
# added while generating the link command.
|
||||
# NOTE: We must preserve the order in which external deps are
|
||||
|
|
|
@ -2245,6 +2245,8 @@ rule FORTRAN_DEP_HACK%s
|
|||
# If implib, and that's significant on this platform (i.e. Windows using either GCC or Visual Studio)
|
||||
if target.import_filename:
|
||||
commands += linker.gen_import_library_args(os.path.join(self.get_target_dir(target), target.import_filename))
|
||||
if target.pie:
|
||||
commands += linker.get_pie_link_args()
|
||||
elif isinstance(target, build.SharedLibrary):
|
||||
if isinstance(target, build.SharedModule):
|
||||
options = self.environment.coredata.base_options
|
||||
|
|
|
@ -84,7 +84,7 @@ known_build_target_kwargs = (
|
|||
rust_kwargs |
|
||||
cs_kwargs)
|
||||
|
||||
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic'}
|
||||
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie'}
|
||||
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'}
|
||||
known_shmod_kwargs = known_build_target_kwargs
|
||||
known_stlib_kwargs = known_build_target_kwargs | {'pic'}
|
||||
|
@ -414,6 +414,8 @@ class BuildTarget(Target):
|
|||
self.generated = []
|
||||
self.extra_files = []
|
||||
self.d_features = {}
|
||||
self.pic = False
|
||||
self.pie = False
|
||||
# Sources can be:
|
||||
# 1. Pre-existing source files in the source tree
|
||||
# 2. Pre-existing sources generated by configure_file in the build tree
|
||||
|
@ -869,13 +871,14 @@ This will become a hard error in a future Meson release.''')
|
|||
# since library loading is done differently)
|
||||
if for_darwin(self.is_cross, self.environment) or for_windows(self.is_cross, self.environment):
|
||||
self.pic = True
|
||||
elif '-fPIC' in clist + cpplist:
|
||||
mlog.warning("Use the 'pic' kwarg instead of passing -fPIC manually to static library {!r}".format(self.name))
|
||||
self.pic = True
|
||||
else:
|
||||
self.pic = kwargs.get('pic', False)
|
||||
if not isinstance(self.pic, bool):
|
||||
raise InvalidArguments('Argument pic to static library {!r} must be boolean'.format(self.name))
|
||||
self.pic = self._extract_pic_pie(kwargs, 'pic')
|
||||
if isinstance(self, Executable):
|
||||
# Executables must be PIE on Android
|
||||
if for_android(self.is_cross, self.environment):
|
||||
self.pie = True
|
||||
else:
|
||||
self.pie = self._extract_pic_pie(kwargs, 'pie')
|
||||
self.implicit_include_directories = kwargs.get('implicit_include_directories', True)
|
||||
if not isinstance(self.implicit_include_directories, bool):
|
||||
raise InvalidArguments('Implicit_include_directories must be a boolean.')
|
||||
|
@ -888,6 +891,18 @@ This will become a hard error in a future Meson release.''')
|
|||
raise InvalidArguments('GNU symbol visibility arg %s not one of: %s',
|
||||
self.symbol_visibility, ', '.join(permitted))
|
||||
|
||||
def _extract_pic_pie(self, kwargs, arg):
|
||||
# Check if we have -fPIC, -fpic, -fPIE, or -fpie in cflags
|
||||
all_flags = self.extra_args['c'] + self.extra_args['cpp']
|
||||
if '-f' + arg.lower() in all_flags or '-f' + arg.upper() in all_flags:
|
||||
mlog.warning("Use the '{}' kwarg instead of passing '{}' manually to {!r}".format(arg, '-f' + arg, self.name))
|
||||
return True
|
||||
|
||||
val = kwargs.get(arg, False)
|
||||
if not isinstance(val, bool):
|
||||
raise InvalidArguments('Argument {} to {!r} must be boolean'.format(arg, self.name))
|
||||
return val
|
||||
|
||||
def get_filename(self):
|
||||
return self.filename
|
||||
|
||||
|
@ -1307,6 +1322,8 @@ class Executable(BuildTarget):
|
|||
known_kwargs = known_exe_kwargs
|
||||
|
||||
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
|
||||
if 'pie' not in kwargs and 'b_pie' in environment.coredata.base_options:
|
||||
kwargs['pie'] = environment.coredata.base_options['b_pie'].value
|
||||
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
|
||||
# Unless overridden, executables have no suffix or prefix. Except on
|
||||
# Windows and with C#/Mono executables where the suffix is 'exe'
|
||||
|
|
|
@ -331,6 +331,9 @@ base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled he
|
|||
'b_staticpic': coredata.UserBooleanOption('b_staticpic',
|
||||
'Build static libraries as position independent',
|
||||
True),
|
||||
'b_pie': coredata.UserBooleanOption('b_pie',
|
||||
'Build executables as position independent',
|
||||
False),
|
||||
'b_bitcode': coredata.UserBooleanOption('b_bitcode',
|
||||
'Generate and embed bitcode (only macOS and iOS)',
|
||||
False),
|
||||
|
@ -1180,6 +1183,18 @@ class Compiler:
|
|||
raise EnvironmentException(
|
||||
'Language {} does not support function attributes.'.format(self.get_display_language()))
|
||||
|
||||
def get_pic_args(self):
|
||||
m = 'Language {} does not support position-independent code'
|
||||
raise EnvironmentException(m.format(self.get_display_language()))
|
||||
|
||||
def get_pie_args(self):
|
||||
m = 'Language {} does not support position-independent executable'
|
||||
raise EnvironmentException(m.format(self.get_display_language()))
|
||||
|
||||
def get_pie_link_args(self):
|
||||
m = 'Language {} does not support position-independent executable'
|
||||
raise EnvironmentException(m.format(self.get_display_language()))
|
||||
|
||||
|
||||
@enum.unique
|
||||
class CompilerType(enum.Enum):
|
||||
|
@ -1322,7 +1337,7 @@ class GnuLikeCompiler(abc.ABC):
|
|||
def __init__(self, compiler_type):
|
||||
self.compiler_type = compiler_type
|
||||
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
|
||||
'b_ndebug', 'b_staticpic']
|
||||
'b_ndebug', 'b_staticpic', 'b_pie']
|
||||
if not self.compiler_type.is_osx_compiler and not self.compiler_type.is_windows_compiler:
|
||||
self.base_options.append('b_lundef')
|
||||
if not self.compiler_type.is_windows_compiler:
|
||||
|
@ -1345,6 +1360,12 @@ class GnuLikeCompiler(abc.ABC):
|
|||
return [] # On Window and OS X, pic is always on.
|
||||
return ['-fPIC']
|
||||
|
||||
def get_pie_args(self):
|
||||
return ['-fPIE']
|
||||
|
||||
def get_pie_link_args(self):
|
||||
return ['-pie']
|
||||
|
||||
def get_buildtype_args(self, buildtype):
|
||||
return gnulike_buildtype_args[buildtype]
|
||||
|
||||
|
|
Loading…
Reference in New Issue