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?
You can't do this with
set($ENV{FOO} BAR). As per the docs:But you can use the
environmentfield of a build preset. Here's a brief excerpt from the docs (please see the docs for full info):To use a build preset, use the
--presetflag in yourcmake --buildcommand invocation.