How to modify environment variables passed to custom CMake target?
A portable way of setting environment variables for a custom target is to use CMake's command-line tool mode command env
:
env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...
Run command in a modified environment.
E.g.:
add_custom_target(newtarget ${CMAKE_COMMAND} -E env NAME=VALUE somecommand)
Also see Command Line Tool Mode.
You set environment variable at configuration step, but command specified for add_custom_target
is executed at build step. See also CMake FAQ: How can I get or set environment variables?
[...]
environment variablesSET
in the CMakeLists.txt only take effect for cmake itself (configure-time), so you cannot use this method to set an environment variable that a custom command might need (build-time). Barring environment variable support by various CMake commands (e.g.add_custom_command()
, currently not supported yet), an acceptable workaround may be to invoke shell scripts instead which wrap the commands to be executed.
Currently add_custom_target
(and others commands, which define actions for build step, e.g. add_custom_command
) doesn't support simple setting environment variables. As adviced in this bugreport, for set variable's value without spaces on Linux you may prepend command with "VAR=VAL" clauses. For general cases you may prepare wrapper script, which setups environment and run actual command:
On Windows:
wrapper.bat:
@ECHO OFF
set PATH=C:\\Some\\Path;%PATH%
%*
CMakeLists.txt:
add_custom_target(...
COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.bat <real_command> args...
)
On Linux:
wrapper.sh:
export "PATH=/Some/Path:$PATH"
eval "$*"
CMakeLists.txt:
add_custom_target(...
COMMAND /bin/sh ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.sh <real_command> args...
)
If value of variable depends on configuration, you may configure wrapper script with configure_file
.
UPDATE:
As noted by @sakra, env
tool mode of cmake
executable can be used as a wrapper script:
add_custom_target(...
COMMAND ${CMAKE_COMMAND} -E env "PATH=C:/Some/Path;$ENV{PATH}" <real_command> args...
)
This way is available since CMake 3.2.
A late answer to this, but perhaps it will help somebody. We use the && operator to do this in our cmake files on Windows.
set(MY_COMMAND set "PATH=C:\\some\\path\;%PATH%"&&
somecommand)
add_custom_target(TARGET newtarget COMMAND ${MY_COMMAND})
Note that you cannot have a space before the && (for reasons I don't understand completely). Also, spaces are a real pain to deal with here, so I don't know if I have it right if c:\some\path has spaces. It does work if your original path has spaces.