Skip to content

Commit

Permalink
build: use PIE objects for static libraries if b_staticpic=false but …
Browse files Browse the repository at this point in the history
…b_pie=true

If static_library is used as a convenience library (e.g. for link_whole)
it should in principle not need position independent code.
However, if the executables that the libraries is linked to are PIE,
the non-PIC objects in the static library will cause linker errors.
To avoid this, obey b_pie for static libraries if either b_staticpic=false
or they use "pic: false".

Without this patch, QEMU cannot use b_staticpic, which causes a slowdown
on some QEMU benchmarks up to 20%.
  • Loading branch information
bonzini committed Sep 19, 2020
1 parent 007ece4 commit 6bdec78
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
2 changes: 1 addition & 1 deletion mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ def generate_basic_compiler_args(self, target, compiler, no_warn_args=False):
# 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:
elif isinstance(target, (build.StaticLibrary, 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.
Expand Down
18 changes: 11 additions & 7 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -982,13 +982,13 @@ def process_kwargs(self, kwargs, environment):
if m.is_darwin() or m.is_windows():
self.pic = True
else:
self.pic = self._extract_pic_pie(kwargs, 'pic')
if isinstance(self, Executable):
self.pic = self._extract_pic_pie(kwargs, 'pic', environment, 'b_staticpic')
if isinstance(self, Executable) or (isinstance(self, StaticLibrary) and not self.pic):
# Executables must be PIE on Android
if self.environment.machines[self.for_machine].is_android():
self.pie = True
else:
self.pie = self._extract_pic_pie(kwargs, 'pie')
self.pie = self._extract_pic_pie(kwargs, 'pie', environment, 'b_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.')
Expand All @@ -1000,14 +1000,20 @@ def process_kwargs(self, kwargs, environment):
if self.gnu_symbol_visibility not in permitted:
raise InvalidArguments('GNU symbol visibility arg {} not one of: {}'.format(self.symbol_visibility, ', '.join(permitted)))

def _extract_pic_pie(self, kwargs, arg):
def _extract_pic_pie(self, kwargs, arg, environment, option):
# 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 arg in kwargs:
val = kwargs[arg]
elif option in environment.coredata.base_options:
val = environment.coredata.base_options[option].value
else:
val = False

if not isinstance(val, bool):
raise InvalidArguments('Argument {} to {!r} must be boolean'.format(arg, self.name))
return val
Expand Down Expand Up @@ -1614,8 +1620,6 @@ class StaticLibrary(BuildTarget):

def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
self.typename = 'static library'
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
kwargs['pic'] = environment.coredata.base_options['b_staticpic'].value
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
if 'cs' in self.compilers:
raise InvalidArguments('Static libraries not supported for C#.')
Expand Down

0 comments on commit 6bdec78

Please sign in to comment.