diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-03-13 03:45:10 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2017-04-04 14:59:13 +0530 |
commit | 57cb1f9aad0928e167018ba886e2d8c06225b515 (patch) | |
tree | fd5a35a19ef7d4f384b3f14ea21494fd0a139aae /mesonbuild/backend/ninjabackend.py | |
parent | 99649e66908693c58fa0c015dbcce19ad8f55b19 (diff) | |
download | meson-57cb1f9aad0928e167018ba886e2d8c06225b515.zip meson-57cb1f9aad0928e167018ba886e2d8c06225b515.tar.gz meson-57cb1f9aad0928e167018ba886e2d8c06225b515.tar.bz2 |
Support multiple install dirs for built/custom targets
You can now pass a list of strings to the install_dir: kwarg to
build_target and custom_target.
Custom Targets:
===============
Allows you to specify the installation directory for each
corresponding output. For example:
custom_target('different-install-dirs',
output : ['first.file', 'second.file'],
...
install : true,
install_dir : ['somedir', 'otherdir])
This would install first.file to somedir and second.file to otherdir.
If only one install_dir is provided, all outputs are installed there
(same behaviour as before).
To only install some outputs, pass `false` for the outputs that you
don't want installed. For example:
custom_target('only-install-second',
output : ['first.file', 'second.file'],
...
install : true,
install_dir : [false, 'otherdir])
This would install second.file to otherdir and not install first.file.
Build Targets:
==============
With build_target() (which includes executable(), library(), etc),
usually there is only one primary output. However some types of
targets have multiple outputs.
For example, while generating Vala libraries, valac also generates
a header and a .vapi file both of which often need to be installed.
This allows you to specify installation directories for those too.
# This will only install the library (same as before)
shared_library('somevalalib', 'somesource.vala',
...
install : true)
# This will install the library, the header, and the vapi into the
# respective directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : ['libdir', 'incdir', 'vapidir'])
# This will install the library into the default libdir and
# everything else into the specified directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : [true, 'incdir', 'vapidir'])
# This will NOT install the library, and will install everything
# else into the specified directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : [false, 'incdir', 'vapidir'])
true/false can also be used for secondary outputs in the same way.
Valac can also generate a GIR file for libraries when the `vala_gir:`
keyword argument is passed to library(). In that case, `install_dir:`
must be given a list with four elements, one for each output.
Includes tests for all these.
Closes https://github.com/mesonbuild/meson/issues/705
Closes https://github.com/mesonbuild/meson/issues/891
Closes https://github.com/mesonbuild/meson/issues/892
Closes https://github.com/mesonbuild/meson/issues/1178
Closes https://github.com/mesonbuild/meson/issues/1193
Diffstat (limited to 'mesonbuild/backend/ninjabackend.py')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index bc51ace..77b2d1d 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -630,15 +630,17 @@ int dummy; for t in self.build.get_targets().values(): if t.should_install(): should_strip = self.get_option_for_target('strip', t) - # Find the installation directory. FIXME: Currently only one - # installation directory is supported for each target - outdir = t.get_custom_install_dir() - if outdir is not None: + # Find the installation directory. + outdirs = t.get_custom_install_dir() + if outdirs[0] is not None and outdirs[0] is not True: + # Either the value is set, or is set to False which means + # we want this specific output out of many outputs to not + # be installed. pass elif isinstance(t, build.SharedLibrary): - # For toolchains/platforms that need an import library for + # On toolchains/platforms that use an import library for # linking (separate from the shared library with all the - # code), we need to install the import library (dll.a/.lib) + # code), we need to install that too (dll.a/.lib). if t.get_import_filename(): # Install the import library. i = [self.get_target_filename_for_linking(t), @@ -647,22 +649,56 @@ int dummy; # doesn't have an install_rpath {}, False, ''] d.targets.append(i) - outdir = self.environment.get_shared_lib_dir() + outdirs[0] = self.environment.get_shared_lib_dir() elif isinstance(t, build.StaticLibrary): - outdir = self.environment.get_static_lib_dir() + outdirs[0] = self.environment.get_static_lib_dir() elif isinstance(t, build.Executable): - outdir = self.environment.get_bindir() + outdirs[0] = self.environment.get_bindir() else: + assert(isinstance(t, build.BuildTarget)) # XXX: Add BuildTarget-specific install dir cases here - outdir = self.environment.get_libdir() + outdirs[0] = self.environment.get_libdir() + # Sanity-check the outputs and install_dirs + num_outdirs, num_out = len(outdirs), len(t.get_outputs()) + if num_outdirs != 1 and num_outdirs != num_out: + raise MesonException('Target {!r} has {} outputs, but only ' + '{} "install_dir"s were specified' + ''.format(t.name, num_out, num_outdirs)) + # Install the target output(s) if isinstance(t, build.BuildTarget): - i = [self.get_target_filename(t), outdir, t.get_aliases(), - should_strip, t.install_rpath] - d.targets.append(i) + # Install primary build output (library/executable/jar, etc) + # Done separately because of strip/aliases/rpath + if outdirs[0] is not False: + i = [self.get_target_filename(t), outdirs[0], + t.get_aliases(), should_strip, t.install_rpath] + d.targets.append(i) + # Install secondary outputs. Only used for Vala right now. + if num_outdirs > 1: + for output, outdir in zip(t.get_outputs()[1:], outdirs[1:]): + # User requested that we not install this output + if outdir is False: + continue + f = os.path.join(self.get_target_dir(t), output) + d.targets.append([f, outdir, {}, False, None]) elif isinstance(t, build.CustomTarget): - for output in t.get_outputs(): - f = os.path.join(self.get_target_dir(t), output) - d.targets.append([f, outdir, {}, False, None]) + # If only one install_dir is specified, assume that all + # outputs will be installed into it. This is for + # backwards-compatibility and because it makes sense to + # avoid repetition since this is a common use-case. + # + # To selectively install only some outputs, pass `false` as + # the install_dir for the corresponding output by index + if num_outdirs == 1 and num_out > 1: + for output in t.get_outputs(): + f = os.path.join(self.get_target_dir(t), output) + d.targets.append([f, outdirs[0], {}, False, None]) + else: + for output, outdir in zip(t.get_outputs(), outdirs): + # User requested that we not install this output + if outdir is False: + continue + f = os.path.join(self.get_target_dir(t), output) + d.targets.append([f, outdir, {}, False, None]) def generate_custom_install_script(self, d): d.install_scripts = self.build.install_scripts @@ -1029,10 +1065,12 @@ int dummy; # Without this, it will write it inside c_out_dir args += ['--vapi', os.path.join('..', target.vala_vapi)] valac_outputs.append(vapiname) + target.outputs += [target.vala_header, target.vala_vapi] if isinstance(target.vala_gir, str): girname = os.path.join(self.get_target_dir(target), target.vala_gir) args += ['--gir', os.path.join('..', target.vala_gir)] valac_outputs.append(girname) + target.outputs.append(target.vala_gir) if self.get_option_for_target('werror', target): args += valac.get_werror_args() for d in target.get_external_deps(): |