Reputation: 28719
I am using distcc
to speed up building my C++ project.
I configure cmake
to use distcc
using the CMAKE_CXX_COMPILER_LAUNCHER
variable:
set(CMAKE_CXX_COMPILER_LAUNCHER "distcc")
At times, some of the hosts in the distcc
pool are not available, and thus, at build time, I want to use lsdistcc
to find which hosts are currently available.
Below are my attempts to generate an environment variable, DISTCC_HOSTS
, available at build time, of which distcc hosts are currently online.
I would like to do this in my cmake
scripts, so that colleagues who use IDE's to generate and run the Makefiles when building vs those who use a command line all benefit from getting an up-to-date list of build hosts.
This is what I have so far:
I have a cmake script, distcc_hosts.cmake
which finds the set of distcc hosts currently available, using lsdistcc
, and sets an environment variable with the result:
distcc_hosts.cmake
:
execute_process(
COMMAND
sh -c "lsdistcc $LSDISTCC_HOSTS | sed \"s/.*/&\\/8,lzo /g\" | tr -d '\n'"
OUTPUT_VARIABLE
DISTCC_HOSTS
)
set(ENV{DISTCC_HOSTS} ${DISTCC_HOSTS})
I have configured this to run at build time using add_custom_target
:
add_custom_target(distcc_hosts
ALL
COMMAND
{CMAKE_COMMAND} -P ${CMAKE_SCRIPTS_DIR}/distcc_hosts.cmake
)
and I've created a dependency link so that it is run before everything else:
add_dependencies(my_core_target distcc_hosts)
This all works fine, in that it creates a phony target, distcc_hosts
which runs my scripts etc:
generated Makfile
:
CMakeFiles/distcc_hosts:
/usr/bin/cmake -P /src/cmake/distcc_hosts.cmake
The problem that I'm having is that obviously the above command to run cmake
executes in a subshell, and the exported environment variable ${DISTCC_HOSTS}
exists only in that subshell.
So when the rest of the build commands run, ${DISTCC_HOSTS}
is not set.
Ideally I would be able to eval
a script, so that the parent environment is modified, or I could execute a command such as export DISTCC_HOSTS := $(shell lsdistcc ...)
.
Is there a way to run a command at build time, and set an environment variable made available to the rest of the build?
Upvotes: 1
Views: 1562
Reputation: 52429
You can't do this with set($ENV{FOO} BAR)
. As per the docs:
This command affects only the current CMake process, not the process from which CMake was called, nor the system environment at large, nor the environment of subsequent build or test processes.
But you can use the environment
field of a build preset. Here's a brief excerpt from the docs (please see the docs for full info):
An optional map of environment variables. The key is the variable name (which may not be an empty string), and the value is either null or a string representing the value of the variable.
To use a build preset, use the --preset
flag in your cmake --build
command invocation.
Upvotes: 1