Merged buildrpath branch.

pull/2104/head
Jussi Pakkanen 7 years ago
commit bff37a90fc
  1. 1
      docs/markdown/Reference-manual.md
  2. 13
      docs/markdown/Release-notes-for-0.42.0.md
  3. 2
      mesonbuild/backend/ninjabackend.py
  4. 8
      mesonbuild/build.py
  5. 6
      mesonbuild/compilers/c.py
  6. 7
      mesonbuild/compilers/compilers.py
  7. 2
      mesonbuild/compilers/cs.py
  8. 8
      mesonbuild/compilers/d.py
  9. 4
      mesonbuild/compilers/fortran.py
  10. 2
      mesonbuild/compilers/java.py
  11. 4
      mesonbuild/compilers/rust.py
  12. 1
      mesonbuild/interpreter.py
  13. 4
      mesonbuild/linkers.py
  14. 11
      run_unittests.py
  15. 14
      test cases/linuxlike/7 library versions/meson.build
  16. 9
      test cases/unit/11 build_rpath/meson.build
  17. 5
      test cases/unit/11 build_rpath/prog.c
  18. 1
      test cases/unit/11 build_rpath/sub/meson.build
  19. 3
      test cases/unit/11 build_rpath/sub/stuff.c

@ -243,6 +243,7 @@ Executable supports the following keyword arguments. Note that just like the pos
- `extra_files` are not used for the build itself but are shown as source files in IDEs that group files by targets (such as Visual Studio) - `extra_files` are not used for the build itself but are shown as source files in IDEs that group files by targets (such as Visual Studio)
- `install`, when set to true, this executable should be installed - `install`, when set to true, this executable should be installed
- `install_rpath` a string to set the target's rpath to after install (but *not* before that) - `install_rpath` a string to set the target's rpath to after install (but *not* before that)
- `build_rpath` a string to add to target's rpath definition in the build dir, but which will be removed on install
- `install_dir` override install directory for this file. The value is relative to the `prefix` specified. F.ex, if you want to install plugins into a subdir, you'd use something like this: `install_dir : get_option('libdir') + '/projectname-1.0'`. - `install_dir` override install directory for this file. The value is relative to the `prefix` specified. F.ex, if you want to install plugins into a subdir, you'd use something like this: `install_dir : get_option('libdir') + '/projectname-1.0'`.
- `objects` list of prebuilt object files (usually for third party products you don't have source to) that should be linked in this target, **never** use this for object files that you build yourself. - `objects` list of prebuilt object files (usually for third party products you don't have source to) that should be linked in this target, **never** use this for object files that you build yourself.
- `name_suffix` the string that will be used as the extension for the target by overriding the default. By default on Windows this is `exe` and on other platforms it is omitted. - `name_suffix` the string that will be used as the extension for the target by overriding the default. By default on Windows this is `exe` and on other platforms it is omitted.

@ -66,7 +66,20 @@ instruction sets and selecting the best one at runtime. This module
is unstable, meaning its API is subject to change in later releases. is unstable, meaning its API is subject to change in later releases.
It might also be removed altogether. It might also be removed altogether.
## Import libraries for executables on Windows ## Import libraries for executables on Windows
The new keyword `implib` to `executable()` allows generation of an import The new keyword `implib` to `executable()` allows generation of an import
library for the executable. library for the executable.
## Added build_rpath keyword argument
You can specify `build_rpath : '/foo/bar'` in build targets and the
given path will get added to the target's rpath in the build tree. It
is removed during the install step.
Meson will print a warning when the user tries to add an rpath linker
flag manually, e.g. via `link_args` to a target. This is not
recommended because having multiple rpath causes them to stomp on each
other. This warning will become a hard error in some future release.

@ -1214,6 +1214,7 @@ int dummy;
rpath_args = rustc.build_rpath_args(self.environment.get_build_dir(), rpath_args = rustc.build_rpath_args(self.environment.get_build_dir(),
target_slashname_workaround_dir, target_slashname_workaround_dir,
self.determine_rpath_dirs(target), self.determine_rpath_dirs(target),
target.build_rpath,
target.install_rpath) target.install_rpath)
# ... but then add rustc's sysroot to account for rustup # ... but then add rustc's sysroot to account for rustup
# installations # installations
@ -2393,6 +2394,7 @@ rule FORTRAN_DEP_HACK
commands += linker.build_rpath_args(self.environment.get_build_dir(), commands += linker.build_rpath_args(self.environment.get_build_dir(),
target_slashname_workaround_dir, target_slashname_workaround_dir,
self.determine_rpath_dirs(target), self.determine_rpath_dirs(target),
target.build_rpath,
target.install_rpath) target.install_rpath)
# Add libraries generated by custom targets # Add libraries generated by custom targets
custom_target_libraries = self.get_custom_target_provided_libraries(target) custom_target_libraries = self.get_custom_target_provided_libraries(target)

@ -49,6 +49,7 @@ known_basic_kwargs = {'install': True,
'gui_app': True, 'gui_app': True,
'extra_files': True, 'extra_files': True,
'install_rpath': True, 'install_rpath': True,
'build_rpath': True,
'resources': True, 'resources': True,
'sources': True, 'sources': True,
'objects': True, 'objects': True,
@ -672,6 +673,10 @@ class BuildTarget(Target):
for i in self.link_args: for i in self.link_args:
if not isinstance(i, str): if not isinstance(i, str):
raise InvalidArguments('Link_args arguments must be strings.') raise InvalidArguments('Link_args arguments must be strings.')
for l in self.link_args:
if '-Wl,-rpath' in l or l.startswith('-rpath'):
mlog.warning('''Please do not define rpath with a linker argument, use install_rpath or build_rpath properties instead.
This will become a hard error in a future Meson release.''')
self.process_link_depends(kwargs.get('link_depends', []), environment) self.process_link_depends(kwargs.get('link_depends', []), environment)
# Target-specific include dirs must be added BEFORE include dirs from # Target-specific include dirs must be added BEFORE include dirs from
# internal deps (added inside self.add_deps()) to override them. # internal deps (added inside self.add_deps()) to override them.
@ -710,6 +715,9 @@ class BuildTarget(Target):
self.install_rpath = kwargs.get('install_rpath', '') self.install_rpath = kwargs.get('install_rpath', '')
if not isinstance(self.install_rpath, str): if not isinstance(self.install_rpath, str):
raise InvalidArguments('Install_rpath is not a string.') raise InvalidArguments('Install_rpath is not a string.')
self.build_rpath = kwargs.get('build_rpath', '')
if not isinstance(self.build_rpath, str):
raise InvalidArguments('Build_rpath is not a string.')
resources = kwargs.get('resources', []) resources = kwargs.get('resources', [])
if not isinstance(resources, list): if not isinstance(resources, list):
resources = [resources] resources = [resources]

@ -87,8 +87,8 @@ class CCompiler(Compiler):
return None, fname return None, fname
# The default behavior is this, override in MSVC # The default behavior is this, override in MSVC
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath) return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
def get_dependency_gen_args(self, outtarget, outfile): def get_dependency_gen_args(self, outtarget, outfile):
return ['-MMD', '-MQ', outtarget, '-MF', outfile] return ['-MMD', '-MQ', outtarget, '-MF', outfile]
@ -909,7 +909,7 @@ class VisualStudioCCompiler(CCompiler):
"The name of the outputted import library" "The name of the outputted import library"
return ['/IMPLIB:' + implibname] return ['/IMPLIB:' + implibname]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return [] return []
# FIXME, no idea what these should be. # FIXME, no idea what these should be.

@ -798,8 +798,8 @@ class Compiler:
def get_instruction_set_args(self, instruction_set): def get_instruction_set_args(self, instruction_set):
return None return None
def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
if not rpath_paths and not install_rpath: if not rpath_paths and not install_rpath and not build_rpath:
return [] return []
# The rpaths we write must be relative, because otherwise # The rpaths we write must be relative, because otherwise
# they have different length depending on the build # they have different length depending on the build
@ -812,6 +812,9 @@ class Compiler:
relative = os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir)) relative = os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir))
rel_rpaths.append(relative) rel_rpaths.append(relative)
paths = ':'.join([os.path.join('$ORIGIN', p) for p in rel_rpaths]) paths = ':'.join([os.path.join('$ORIGIN', p) for p in rel_rpaths])
# Build_rpath is used as-is (it is usually absolute).
if build_rpath != '':
paths += ':' + build_rpath
if len(paths) < len(install_rpath): if len(paths) < len(install_rpath):
padding = 'X' * (len(install_rpath) - len(paths)) padding = 'X' * (len(install_rpath) - len(paths))
if not paths: if not paths:

@ -43,7 +43,7 @@ class MonoCompiler(Compiler):
def split_shlib_to_parts(self, fname): def split_shlib_to_parts(self, fname):
return None, fname return None, fname
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return [] return []
def get_dependency_gen_args(self, outtarget, outfile): def get_dependency_gen_args(self, outtarget, outfile):

@ -88,12 +88,14 @@ class DCompiler(Compiler):
def get_std_exe_link_args(self): def get_std_exe_link_args(self):
return [] return []
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
# This method is to be used by LDC and DMD. # This method is to be used by LDC and DMD.
# GDC can deal with the verbatim flags. # GDC can deal with the verbatim flags.
if not rpath_paths and not install_rpath: if not rpath_paths and not install_rpath:
return [] return []
paths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths]) paths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths])
if build_rpath != '':
paths += ':' + build_rpath
if len(paths) < len(install_rpath): if len(paths) < len(install_rpath):
padding = 'X' * (len(install_rpath) - len(paths)) padding = 'X' * (len(install_rpath) - len(paths))
if not paths: if not paths:
@ -212,8 +214,8 @@ class GnuDCompiler(DCompiler):
def get_buildtype_args(self, buildtype): def get_buildtype_args(self, buildtype):
return d_gdc_buildtype_args[buildtype] return d_gdc_buildtype_args[buildtype]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath) return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
def get_unittest_args(self): def get_unittest_args(self):
return ['-funittest'] return ['-funittest']

@ -132,8 +132,8 @@ end program prog
def get_std_exe_link_args(self): def get_std_exe_link_args(self):
return [] return []
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath) return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
def module_name_to_filename(self, module_name): def module_name_to_filename(self, module_name):
return module_name.lower() + '.mod' return module_name.lower() + '.mod'

@ -34,7 +34,7 @@ class JavaCompiler(Compiler):
def split_shlib_to_parts(self, fname): def split_shlib_to_parts(self, fname):
return None, fname return None, fname
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return [] return []
def get_dependency_gen_args(self, outtarget, outfile): def get_dependency_gen_args(self, outtarget, outfile):

@ -50,8 +50,8 @@ class RustCompiler(Compiler):
def get_buildtype_args(self, buildtype): def get_buildtype_args(self, buildtype):
return rust_buildtype_args[buildtype] return rust_buildtype_args[buildtype]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath) return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
def get_sysroot(self): def get_sysroot(self):
cmd = self.exelist + ['--print', 'sysroot'] cmd = self.exelist + ['--print', 'sysroot']

@ -1241,6 +1241,7 @@ rust_kwargs = set(['rust_crate_type'])
cs_kwargs = set(['resources']) cs_kwargs = set(['resources'])
buildtarget_kwargs = set(['build_by_default', buildtarget_kwargs = set(['build_by_default',
'build_rpath',
'dependencies', 'dependencies',
'extra_files', 'extra_files',
'gui_app', 'gui_app',

@ -45,7 +45,7 @@ class VisualStudioLinker(StaticLinker):
def get_linker_always_args(self): def get_linker_always_args(self):
return VisualStudioLinker.always_args return VisualStudioLinker.always_args
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return [] return []
def thread_link_flags(self): def thread_link_flags(self):
@ -76,7 +76,7 @@ class ArLinker(StaticLinker):
else: else:
self.std_args = ['csr'] self.std_args = ['csr']
def build_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return [] return []
def get_exelist(self): def get_exelist(self):

@ -1850,6 +1850,17 @@ class LinuxlikeTests(BasePlatformTests):
self.assertTrue(glib_found) self.assertTrue(glib_found)
self.assertTrue(gobject_found) self.assertTrue(gobject_found)
def test_build_rpath(self):
testdir = os.path.join(self.unit_test_dir, '11 build_rpath')
self.init(testdir)
self.build()
build_rpath = get_rpath(os.path.join(self.builddir, 'prog'))
self.assertEqual(build_rpath, '$ORIGIN/sub:/foo/bar')
self.install()
install_rpath = get_rpath(os.path.join(self.installdir, 'usr/bin/prog'))
self.assertEqual(install_rpath, '/baz')
class LinuxArmCrossCompileTests(BasePlatformTests): class LinuxArmCrossCompileTests(BasePlatformTests):
''' '''
Tests that verify cross-compilation to Linux/ARM Tests that verify cross-compilation to Linux/ARM

@ -32,20 +32,24 @@ out = custom_target('library-dependency-hack',
# Need to add this manually because Meson can't add it automatically because # Need to add this manually because Meson can't add it automatically because
# it doesn't know that we are linking to libraries in the build directory. # it doesn't know that we are linking to libraries in the build directory.
rpath_arg = '-Wl,-rpath,' + meson.current_build_dir() rpath_dir = meson.current_build_dir()
# Manually test if the linker can find the above libraries # Manually test if the linker can find the above libraries
# i.e., whether they were generated with the right naming scheme # i.e., whether they were generated with the right naming scheme
test('manually linked 1', executable('manuallink1', out, test('manually linked 1', executable('manuallink1', out,
link_args : ['-L.', '-lsome', rpath_arg])) link_args : ['-L.', '-lsome'],
build_rpath : rpath_dir))
test('manually linked 2', executable('manuallink2', out, test('manually linked 2', executable('manuallink2', out,
link_args : ['-L.', '-lnoversion', rpath_arg])) link_args : ['-L.', '-lnoversion'],
build_rpath : rpath_dir))
test('manually linked 3', executable('manuallink3', out, test('manually linked 3', executable('manuallink3', out,
link_args : ['-L.', '-lonlyversion', rpath_arg])) link_args : ['-L.', '-lonlyversion'],
build_rpath : rpath_dir))
test('manually linked 4', executable('manuallink4', out, test('manually linked 4', executable('manuallink4', out,
link_args : ['-L.', '-lonlysoversion', rpath_arg])) link_args : ['-L.', '-lonlysoversion'],
build_rpath : rpath_dir))
shared_module('module', 'lib.c', install : true) shared_module('module', 'lib.c', install : true)

@ -0,0 +1,9 @@
project('build rpath', 'c')
subdir('sub')
executable('prog', 'prog.c',
link_with : l,
build_rpath : '/foo/bar',
install_rpath : '/baz',
install : true,
)

@ -0,0 +1,5 @@
int get_stuff();
int main(int argc, char **argv) {
return get_stuff();
}

@ -0,0 +1 @@
l = shared_library('stuff', 'stuff.c')

@ -0,0 +1,3 @@
int get_stuff() {
return 0;
}
Loading…
Cancel
Save