Skip to content

Commit

Permalink
install: Add --strip option
Browse files Browse the repository at this point in the history
  • Loading branch information
xclaesse committed Mar 9, 2022
1 parent 6ec6e0c commit eafb8a8
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 11 deletions.
5 changes: 5 additions & 0 deletions docs/markdown/snippets/strip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## `meson install --strip`

It is now possible to strip targets using `meson install --strip` even if
`-Dstrip=true` option was not set during configuration. This allows doing
stripped and not stripped installations without reconfiguring the build.
6 changes: 4 additions & 2 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class TargetInstallData:
subproject: str
optional: bool = False
tag: T.Optional[str] = None
can_strip: bool = False

def __post_init__(self, outdir_name: str) -> None:
self.out_name = os.path.join(outdir_name, os.path.basename(self.fname))
Expand Down Expand Up @@ -1573,7 +1574,8 @@ def generate_target_install(self, d: InstallData) -> None:
#
# TODO: Create GNUStrip/AppleStrip/etc. hierarchy for more
# fine-grained stripping of static archives.
should_strip = not isinstance(t, build.StaticLibrary) and self.get_option_for_target(OptionKey('strip'), t)
can_strip = not isinstance(t, build.StaticLibrary)
should_strip = can_strip and self.get_option_for_target(OptionKey('strip'), t)
assert isinstance(should_strip, bool), 'for mypy'
# Install primary build output (library/executable/jar, etc)
# Done separately because of strip/aliases/rpath
Expand All @@ -1584,7 +1586,7 @@ def generate_target_install(self, d: InstallData) -> None:
install_dir_name,
should_strip, mappings, t.rpath_dirs_to_remove,
t.install_rpath, install_mode, t.subproject,
tag=tag)
tag=tag, can_strip=can_strip)
d.targets.append(i)

for alias, to, tag in t.get_aliases():
Expand Down
23 changes: 14 additions & 9 deletions mesonbuild/minstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ArgumentType(Protocol):
dry_run: bool
skip_subprojects: str
tags: str
strip: bool


symlink_warning = '''Warning: trying to copy a symlink that points to a file. This will copy the file,
Expand Down Expand Up @@ -88,6 +89,8 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
help='Do not install files from given subprojects. (Since 0.58.0)')
parser.add_argument('--tags', default=None,
help='Install only targets having one of the given tags. (Since 0.60.0)')
parser.add_argument('--strip', action='store_true',
help='Strip targets even if strip option was not set during configure. (Since 0.62.0)')

class DirMaker:
def __init__(self, lf: T.TextIO, makedirs: T.Callable[..., None]):
Expand Down Expand Up @@ -564,6 +567,15 @@ def do_install(self, datafilename: str) -> None:
else:
raise

def do_strip(self, strip_bin: T.List[str], fname: str, outname: str) -> None:
self.log(f'Stripping target {fname!r}.')
returncode, stdo, stde = self.Popen_safe(strip_bin + [outname])
if returncode != 0:
print('Could not strip file.\n')
print(f'Stdout:\n{stdo}\n')
print(f'Stderr:\n{stde}\n')
sys.exit(1)

def install_subdirs(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None:
for i in d.install_subdirs:
if not self.should_install(i):
Expand Down Expand Up @@ -676,7 +688,7 @@ def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix
outdir = get_destdir_path(destdir, fullprefix, t.outdir)
outname = os.path.join(outdir, os.path.basename(fname))
final_path = os.path.join(d.prefix, t.outdir, os.path.basename(fname))
should_strip = t.strip
should_strip = t.strip or (t.can_strip and self.options.strip)
install_rpath = t.install_rpath
install_name_mappings = t.install_name_mappings
install_mode = t.install_mode
Expand All @@ -689,13 +701,7 @@ def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix
if fname.endswith('.jar'):
self.log('Not stripping jar target: {}'.format(os.path.basename(fname)))
continue
self.log('Stripping target {!r} using {}.'.format(fname, d.strip_bin[0]))
returncode, stdo, stde = self.Popen_safe(d.strip_bin + [outname])
if returncode != 0:
print('Could not strip file.\n')
print(f'Stdout:\n{stdo}\n')
print(f'Stderr:\n{stde}\n')
sys.exit(1)
self.do_strip(d.strip_bin, fname, outname)
if fname.endswith('.js'):
# Emscripten outputs js files and optionally a wasm file.
# If one was generated, install it as well.
Expand All @@ -721,7 +727,6 @@ def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix
else:
raise


def rebuild_all(wd: str) -> bool:
if not (Path(wd) / 'build.ninja').is_file():
print('Only ninja backend is supported to rebuild the project before installation.')
Expand Down
1 change: 1 addition & 0 deletions test cases/unit/104 strip/lib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void func(void){}
3 changes: 3 additions & 0 deletions test cases/unit/104 strip/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project('strip', 'c')

shared_library('a', 'lib.c', install: true)
20 changes: 20 additions & 0 deletions unittests/linuxliketests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1760,3 +1760,23 @@ def test_cmake_multilib(self):

# If so, we can test that cmake works with "gcc -m32"
self.do_one_test_with_nativefile('../cmake/1 basic', "['gcc', '-m32']")

@skipUnless(is_linux(), 'Test only applicable to Linux')
def test_install_strip(self):
testdir = os.path.join(self.unit_test_dir, '104 strip')
self.init(testdir)
self.build()

destdir = self.installdir + self.prefix
lib = os.path.join(destdir, self.libdir, 'liba.so')
install_cmd = self.meson_command + ['install', '--destdir', self.installdir]

# Check we have debug symbols by default
self._run(install_cmd, workdir=self.builddir)
stdout = self._run(['file', '-b', lib])
self.assertIn('not stripped', stdout)

# Check debug symbols got removed with --strip
self._run(install_cmd + ['--strip'], workdir=self.builddir)
stdout = self._run(['file', '-b', lib])
self.assertNotIn('not stripped', stdout)

0 comments on commit eafb8a8

Please sign in to comment.