Feature Request: Ability to set environment variables at build time

At my day job, I maintain a few custom toolchain files for cross-compiling. One of the problems I ran into when trying to add another one, is that the compiler requires several variables to be set. I’ve struggled to find any resources about setting environment variables at build time (only during the configuration step).

I can’t simply just add a custom target to modify the environment at build time, since the Ninja generator (which is one of the ones that I support) runs all of its commands in subshells.

The two workarounds I’ve come up with are:

  1. Create a script to configure the environment variables that a user can run pre-build. (I don’t like this since it would be easy for a user to forget to run it, and our build procedures can get pretty complicated for those unfamiliar with it)

  2. Create a wrapper script/program to use as the compiler. This would look something like:

REM compiler-wrapper.bat
SET VAR1=value
SET VAR2=other_value

%PATH_TO_COMPILER% %*

This doesn’t quite feel right as a solution.

I understand that not all build systems support setting environment variables out of the box, but it would definitely simplify this situation if CMake was able to handle this for me.

Summary

This text will be hidden

CMake generally assumes that the compiler is usable from the environment in which it is run. This is the case with MSVC, Intel, etc. I don’t think a mechanism to move environment settings to build time will be implemented because there’s no way to do something like that for make, ninja, or other generators anyways without requiring that one only use cmake --build . to do the build.

However, there are other potential solutions. If you do have such an environment script, you may be able to use it via CMAKE_<LANG>_COMPILER_LAUNCHER. This gets placed as the first argument for any compilation line (though maybe not linker?) for the compiler in the build. You’ll get the rest of the compilation line as arguments to the script (so that you don’t have to embed anything about compiler paths either). Note that rc.exe will still be unwrapped, so that won’t help you there if you need it.

In summary, the best solution available today is to just source vcvarsall.bat (or whatever you need) before you run cmake or the build.

Thanks for the quick reply, I’m gonna probably go forward with using the CMAKE_<LANG>_COMPILER_LAUNCHER since that seems to be the most idiomatic way to do what I want.

I do want to point out however, that some build systems do support setting environment variables:

For make you can apparently using the export keyword, and in .sln/.vcproj files like they do in this forum posting (which is a workaround using a custom task, so maybe not the best). ninja would be the only one that doesn’t support it at all (even though they do provide the ninja -t msvc -e command which sets the environment according to a file.

I think that this would definitely be a nice to have, if for nothing but setting up stuff like LD_LIBRARY_PATH, etc.

Use rpath settings and you won’t need LD_LIBRARY_PATH at all.

This looks like a GNU-ism. CMake generates POSIX-compatible makefiles.

You may be interested in an issue (that I can’t find right now) where I propose adding runtime usage requirements which would encompass things like @rpath usage on macOS and assist with PATH building on Windows.

Hi,

did you find the mentioned ticket? I also from time to time wished to be able to set variables; for example we have proprietary post build tools that need certain variables conditionally set. For these, we usually run them via …_command(“VAR=value /path/to/tool”). For some, we wrote wrapper scripts supporting command line options from what was used to be an environment setting (which I like because usage improves, but add complexity of course).

For compilers and ccache, we use a LAUNCHER, which is generated by cmake, for example to unset GCC_COLORS when using old compilers plus ccache (there are a lot of complex details).

Sorry, no, I can’t find it in my email. Maybe it was an in-person discussion? I’ll have to write it up some day anyways…I want to reference it at least every other week these days…