120

I know how to retrieve a normal machine wide environment variable in CMAKE using

$ENV{EnvironmentVariableName}

but I can not retrieve a user specific environment variable. Is it possible and how?

Andreas Haferburg
  • 5,189
  • 3
  • 37
  • 63
Lars Bilke
  • 4,940
  • 6
  • 45
  • 63
  • 13
    This is the first Google hit on how to retrieve environment vars in CMake. It might be a bit weird that the question already contains the answer, but it should not be deleted IMO. – Andreas Haferburg May 30 '14 at 13:34
  • 4
    @Ludwik because it answers the problem that user specific environment variables are not available in CMake scripts. – Robert Apr 05 '17 at 12:59
  • 3
    Part of the problem is that the split between "user specific environment variables" and "normal machine wide environment variable" is a concept that's very specific to Windows. Unix-like systems don't care where environment variables are set; they're all the same. – James Moore Apr 20 '18 at 16:34
  • Exemple: `message($ENV{WINDIR})` shows `C:\Windows` (note that it is not written %WINDIR%) – Gabriel Devillers May 07 '19 at 12:27

4 Answers4

104

Getting variables into your CMake script

You can pass a variable on the line with the cmake invocation:

FOO=1 cmake

or by exporting a variable in BASH:

export FOO=1

Then you can pick it up in a cmake script using:

$ENV{FOO}
Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
  • This was the best advice I've found so far but if you happen to be using powershell, it can be confusing. CMake is looking for variables set using $Env: `$Env:HOME = $HOME; cmake ...` – Lucian Thorr Jul 05 '22 at 19:15
18

You can also invoke itself to do this in a cross-platform way:

cmake -E env EnvironmentVariableName="Hello World" cmake ..

env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...

Run command in a modified environment.


Just be aware that this may only work the first time. If CMake re-configures with one of the consecutive builds (you just call e.g. make, one CMakeLists.txt was changed and CMake runs through the generation process again), the user defined environment variable may not be there anymore (in comparison to system wide environment variables).

So I transfer those user defined environment variables in my projects into a CMake cached variable:

cmake_minimum_required(VERSION 2.6)

project(PrintEnv NONE)

if (NOT "$ENV{EnvironmentVariableName}" STREQUAL "")
    set(EnvironmentVariableName "$ENV{EnvironmentVariableName}" CACHE INTERNAL "Copied from environment variable")
endif()

message("EnvironmentVariableName = ${EnvironmentVariableName}")

Reference

Florian
  • 39,996
  • 9
  • 133
  • 149
5

You need to have your variables exported. So for example in Linux:

export EnvironmentVariableName=foo

Unexported variables are empty in CMAKE.

sth
  • 222,467
  • 53
  • 283
  • 367
P51DAce
  • 69
  • 1
  • 3
  • 5
    You don't have to export them! Example: CMakeLists.txt ``IF($ENV{COVERAGE}) ... END()``, invocation: ``COVERAGE=1 cmake ..``. Granted, I don't check the contents, and I don't know if it would. But it certainly works for testing if it is defined or not! – Janus Troelsen Dec 10 '11 at 01:22
  • 2
    If you define variables on previous lines, then you do need the export. Only variables defined on the same line do not require the export, but the question we cannot infer whether you do it one way or the other. – Alexis Wilke Jul 04 '13 at 19:40
1

Environment variables (that you modify using the System Properties) are only propagated to subshells when you create a new subshell.

If you had a command line prompt (DOS or cygwin) open when you changed the User env vars, then they won't show up.

You need to open a new command line prompt after you change the user settings.

The equivalent in Unix/Linux is adding a line to your .bash_rc: you need to start a new shell to get the values.

Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
  • For Windows you can also run `SET var_name=var_value` to set the environment variable in the current DOS session, or `SETX var_name var_value` to set it permanently: see [set](https://ss64.com/nt/set.html) and [setx](https://ss64.com/nt/setx.html) . [set local](https://ss64.com/nt/setlocal.html) might also be interesting. – WillC Jun 04 '18 at 02:05
  • For Unix/Linux you can also generally run `source ~/.bashrc` to re-run the modified `.bashrc` file and get the new values into your current session. – WillC Jun 04 '18 at 02:14