aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2021-01-21 13:12:21 -0500
committerXavier Claessens <xclaesse@gmail.com>2021-01-27 09:00:54 -0500
commit633264984b4b2278491476a0997193ff4996b3a6 (patch)
tree3859bec183f89046511cb6d5aca75411cc0e1440
parente4137ae3eca0c73e8c19ea84d9a203ddb065f0d8 (diff)
downloadmeson-633264984b4b2278491476a0997193ff4996b3a6.zip
meson-633264984b4b2278491476a0997193ff4996b3a6.tar.gz
meson-633264984b4b2278491476a0997193ff4996b3a6.tar.bz2
custom_target: Add env kwarg
-rw-r--r--docs/markdown/Reference-manual.md4
-rw-r--r--docs/markdown/snippets/customtarget_env.md11
-rw-r--r--mesonbuild/backend/backends.py13
-rw-r--r--mesonbuild/backend/ninjabackend.py3
-rw-r--r--mesonbuild/backend/vs2010backend.py3
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/interpreter.py5
-rw-r--r--mesonbuild/scripts/meson_exe.py3
-rw-r--r--test cases/common/50 custom target/meson.build1
-rwxr-xr-xtest cases/common/50 custom target/my_compiler.py1
10 files changed, 37 insertions, 9 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 4a1e759..f758e71 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -374,6 +374,10 @@ following.
- `install_mode` *(since 0.47.0)*: the file mode and optionally the
owner/uid and group/gid
- `output`: list of output files
+- `env` *(since 0.57.0)*: environment variables to set, such as
+ `{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`,
+ or an [`environment()` object](#environment-object) which allows more
+ sophisticated environment juggling.
The list of strings passed to the `command` keyword argument accept
the following special string substitutions:
diff --git a/docs/markdown/snippets/customtarget_env.md b/docs/markdown/snippets/customtarget_env.md
new file mode 100644
index 0000000..93687ab
--- /dev/null
+++ b/docs/markdown/snippets/customtarget_env.md
@@ -0,0 +1,11 @@
+## custom_target() now accepts `env` keyword argument
+
+Environment variables can now be passed to `custom_target()` command.
+
+```meson
+env = environment()
+env.append('PATH', '/foo')
+custom_target(..., env: env)
+custom_target(..., env: {'MY_ENV': 'value'})
+custom_target(..., env: ['MY_ENV=value'])
+```
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 8143941..b5e5cdf 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -125,10 +125,10 @@ class TargetInstallData:
self.optional = optional
class ExecutableSerialisation:
- def __init__(self, cmd_args, env=None, exe_wrapper=None,
+ def __init__(self, cmd_args, env: T.Optional[build.EnvironmentVariables] = None, exe_wrapper=None,
workdir=None, extra_paths=None, capture=None) -> None:
self.cmd_args = cmd_args
- self.env = env or {}
+ self.env = env
if exe_wrapper is not None:
assert(isinstance(exe_wrapper, dependencies.ExternalProgram))
self.exe_runner = exe_wrapper
@@ -378,7 +378,8 @@ class Backend:
return obj_list
def as_meson_exe_cmdline(self, tname, exe, cmd_args, workdir=None,
- extra_bdeps=None, capture=None, force_serialize=False):
+ extra_bdeps=None, capture=None, force_serialize=False,
+ env: T.Optional[build.EnvironmentVariables] = None):
'''
Serialize an executable for running with a generator or a custom target
'''
@@ -427,6 +428,9 @@ class Backend:
if any('\n' in c for c in cmd_args):
reasons.append('because command contains newlines')
+ if env and env.varnames:
+ reasons.append('to set env')
+
force_serialize = force_serialize or bool(reasons)
if capture:
@@ -440,7 +444,6 @@ class Backend:
', '.join(reasons))
workdir = workdir or self.environment.get_build_dir()
- env = {}
if isinstance(exe, (dependencies.ExternalProgram,
build.BuildTarget, build.CustomTarget)):
basename = exe.name
@@ -451,7 +454,7 @@ class Backend:
# Take a digest of the cmd args, env, workdir, and capture. This avoids
# collisions and also makes the name deterministic over regenerations
# which avoids a rebuild by Ninja because the cmdline stays the same.
- data = bytes(str(sorted(env.items())) + str(cmd_args) + str(workdir) + str(capture),
+ data = bytes(str(env) + str(cmd_args) + str(workdir) + str(capture),
encoding='utf-8')
digest = hashlib.sha1(data).hexdigest()
scratch_file = 'meson_exe_{0}_{1}.dat'.format(basename, digest)
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index dd70ae0..36f1fd2 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -960,7 +960,8 @@ int dummy;
meson_exe_cmd, reason = self.as_meson_exe_cmdline(target.name, target.command[0], cmd[1:],
extra_bdeps=target.get_transitive_build_target_deps(),
- capture=ofilenames[0] if target.capture else None)
+ capture=ofilenames[0] if target.capture else None,
+ env=target.env)
if meson_exe_cmd:
cmd = meson_exe_cmd
cmd_type = ' (wrapped by meson {})'.format(reason)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index e4886ba..c47fb4a 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -576,7 +576,8 @@ class Vs2010Backend(backends.Backend):
workdir=tdir_abs,
extra_bdeps=extra_bdeps,
capture=ofilenames[0] if target.capture else None,
- force_serialize=True)
+ force_serialize=True,
+ env=target.env)
if target.build_always_stale:
# Use a nonexistent file to always consider the target out-of-date.
ofilenames += [self.nonexistent_file(os.path.join(self.environment.get_scratch_dir(),
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 13783d1..7b15bfe 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -2153,6 +2153,7 @@ class CustomTarget(Target):
'build_by_default',
'override_options',
'console',
+ 'env',
])
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False, backend=None):
@@ -2325,6 +2326,7 @@ class CustomTarget(Target):
else:
mlog.debug(i)
raise InvalidArguments('Unknown type {!r} in depend_files.'.format(type(i).__name__))
+ self.env = kwargs.get('env')
def get_dependencies(self):
return self.dependencies
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index f317652..be0309e 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2315,7 +2315,8 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'depfile',
'build_by_default',
'build_always_stale',
- 'console'},
+ 'console',
+ 'env'},
'dependency': {'default_options',
'embed',
'fallback',
@@ -3997,6 +3998,7 @@ external dependencies (including libraries) must go to "dependencies".''')
raise SubdirDoneRequest()
@stringArgs
+ @FeatureNewKwargs('custom_target', '0.57.0', ['env'])
@FeatureNewKwargs('custom_target', '0.48.0', ['console'])
@FeatureNewKwargs('custom_target', '0.47.0', ['install_mode', 'build_always_stale'])
@FeatureNewKwargs('custom_target', '0.40.0', ['build_by_default'])
@@ -4018,6 +4020,7 @@ external dependencies (including libraries) must go to "dependencies".''')
except mesonlib.MesonException:
mlog.warning('''Custom target input \'%s\' can\'t be converted to File object(s).
This will become a hard error in the future.''' % kwargs['input'], location=self.current_node)
+ kwargs['env'] = self.unpack_env_kwarg(kwargs)
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs, backend=self.backend), self)
self.add_target(name, tg.held_object)
return tg
diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py
index 50ad2f5..751d39b 100644
--- a/mesonbuild/scripts/meson_exe.py
+++ b/mesonbuild/scripts/meson_exe.py
@@ -39,7 +39,8 @@ def run_exe(exe: ExecutableSerialisation) -> int:
else:
cmd_args = exe.cmd_args
child_env = os.environ.copy()
- child_env.update(exe.env)
+ if exe.env:
+ child_env = exe.env.get_env(child_env)
if exe.extra_paths:
child_env['PATH'] = (os.pathsep.join(exe.extra_paths + ['']) +
child_env['PATH'])
diff --git a/test cases/common/50 custom target/meson.build b/test cases/common/50 custom target/meson.build
index 5c7cfae..52e8630 100644
--- a/test cases/common/50 custom target/meson.build
+++ b/test cases/common/50 custom target/meson.build
@@ -15,6 +15,7 @@ mytarget = custom_target('bindat',
output : 'data.dat',
input : 'data_source.txt',
command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@', useless],
+env: {'MY_COMPILER_ENV': 'value'},
install : true,
install_dir : 'subdir'
)
diff --git a/test cases/common/50 custom target/my_compiler.py b/test cases/common/50 custom target/my_compiler.py
index f46d23a..9869111 100755
--- a/test cases/common/50 custom target/my_compiler.py
+++ b/test cases/common/50 custom target/my_compiler.py
@@ -8,6 +8,7 @@ assert(os.path.exists(sys.argv[3]))
args = sys.argv[:-1]
if __name__ == '__main__':
+ assert os.environ['MY_COMPILER_ENV'] == 'value'
if len(args) != 3 or not args[1].startswith('--input') or \
not args[2].startswith('--output'):
print(args[0], '--input=input_file --output=output_file')