Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New builtin-option to support partial linking for shared libraries #5499

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/markdown/Builtin-options.md
Expand Up @@ -82,6 +82,7 @@ Using the option as-is with no prefix affects all machines. For example:
| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
| werror | false | Treat warnings as errors | no |
| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
| sharedlib_linkmodel {standard, partial} | standard | Shared library link model. standard linking or partial linking | no |

## Base options

Expand Down
5 changes: 3 additions & 2 deletions mesonbuild/backend/backends.py
Expand Up @@ -607,9 +607,10 @@ def generate_basic_compiler_args(self, target, compiler, no_warn_args=False):
# file. We want these to override all the defaults, but not the
# per-target compile args.
commands += self.environment.coredata.get_external_args(target.for_machine, compiler.get_language())
# Always set -fPIC for shared libraries
# Always set -fPIC for shared libraries unless partially linked
if isinstance(target, build.SharedLibrary):
commands += compiler.get_pic_args()
if self.get_option_for_target('sharedlib_linkmodel', target) != 'partial':
commands += compiler.get_pic_args()
# Set -fPIC for static libraries by default unless explicitly disabled
if isinstance(target, build.StaticLibrary) and target.pic:
commands += compiler.get_pic_args()
Expand Down
24 changes: 17 additions & 7 deletions mesonbuild/backend/ninjabackend.py
Expand Up @@ -2322,17 +2322,27 @@ def get_target_type_link_args(self, target, linker):
if target.pie:
commands += linker.get_pie_link_args()
elif isinstance(target, build.SharedLibrary):
is_linkmodel_partial = (self.get_option_for_target('sharedlib_linkmodel', target) == 'partial')
if isinstance(target, build.SharedModule):
options = self.environment.coredata.base_options
commands += linker.get_std_shared_module_link_args(options)
else:
commands += linker.get_std_shared_lib_link_args()
# All shared libraries are PIC
commands += linker.get_pic_args()
# Add -Wl,-soname arguments on Linux, -install_name on OS X
commands += linker.get_soname_args(target.prefix, target.name, target.suffix,
target.soversion, target.darwin_versions,
isinstance(target, build.SharedModule))
if is_linkmodel_partial:
if hasattr(linker, 'get_std_partial_lib_link_args'):
commands += linker.get_std_partial_lib_link_args()
else:
mlog.warning('The sharedlib_linkmodel option is set to partial, '
'but %s does not have support for '
'shared library partial linking' % linker.get_id())
else:
commands += linker.get_std_shared_lib_link_args()
if not is_linkmodel_partial:
# All shared libraries are PIC
commands += linker.get_pic_args()
# Add -Wl,-soname arguments on Linux, -install_name on OS X
commands += linker.get_soname_args(target.prefix, target.name, target.suffix,
target.soversion, target.darwin_versions,
isinstance(target, build.SharedModule))
# This is only visited when building for Windows using either GCC or Visual Studio
if target.vs_module_defs and hasattr(linker, 'gen_vs_module_defs_args'):
commands += linker.gen_vs_module_defs_args(target.vs_module_defs.rel_to_builddir(self.build_to_src))
Expand Down
10 changes: 9 additions & 1 deletion mesonbuild/compilers/compilers.py
Expand Up @@ -2037,6 +2037,9 @@ def get_pch_suffix(self) -> str:
def openmp_flags(self) -> List[str]:
return ['-fopenmp']

def get_std_partial_lib_link_args(self):
return ['-Wl,-r', '-nostdlib']


class PGICompiler:
def __init__(self, compiler_type):
Expand Down Expand Up @@ -2238,6 +2241,9 @@ def get_buildtype_linker_args(self, buildtype):
def get_std_shared_lib_link_args(self):
return []

def get_std_partial_lib_link_args(self):
return ['--partial']

def get_pch_suffix(self):
return 'gch'

Expand Down Expand Up @@ -2386,7 +2392,6 @@ def openmp_flags(self):


class ArmCompiler:
# Functionality that is common to all ARM family compilers.
def __init__(self, compiler_type):
if not self.is_cross:
raise EnvironmentException('armcc supports only cross-compilation.')
Expand Down Expand Up @@ -2425,6 +2430,9 @@ def get_dependency_gen_args(self, outtarget, outfile):
def get_std_shared_lib_link_args(self):
return []

def get_std_partial_lib_link_args(self):
return ['--partial']

def get_pch_use_args(self, pch_dir, header):
# FIXME: Add required arguments
# NOTE from armcc user guide:
Expand Down
1 change: 1 addition & 0 deletions mesonbuild/coredata.py
Expand Up @@ -945,6 +945,7 @@ def add_to_argparse(self, name: str, parser: argparse.ArgumentParser, prefix: st
('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False)),
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
('sharedlib_linkmodel', BuiltinOption(UserComboOption, 'Shared library link model', 'standard', choices=['standard', 'partial'])),
])

builtin_options_per_machine = OrderedDict([
Expand Down