48

I set an environment variable in my bash profile, so I can see it in the terminal just fine . .

blah/builds$ echo $THING

thingy

How do I display it in a cmake message and check if it is set? I have tried the following, but it just displays thing as blank and skips the body of the if statement

message("THING:" $ENV{THING})
if(DEFINED ENV{THING})
    message(STATUS "THING environment variable defined")
    # some more commands
endif()
3
  • 1
    Is that variable exported in the shell? What does declare -p THING say? Does running export THING before running cmake help? Commented Apr 17, 2015 at 0:17
  • It works fine if hardcoding to known env variable => message("THING:" $ENV{PATH}) prints the path, seems the typical problem with strings
    – drodri
    Commented Apr 17, 2015 at 0:27
  • 1
    Actually it works fine in Win7, I set THING=thingy in the console, then the scripts output what is expected. CMake 3.2.2
    – drodri
    Commented Apr 17, 2015 at 0:31

5 Answers 5

55

Knowing perfectly well what export does and how environment works in general, I've still got a mouthful of WTFs with this form:

IF(DEFINED $ENV{THING})

but it worked fine in this form:

IF(DEFINED ENV{THING})

Notice the $ omission.


N.B. you can quickly test this using cmake -P:

[~] cat > test-env.cmake << 'EOF'
IF(DEFINED ENV{FOOBAR})
    MESSAGE(STATUS "FOOBAR env seen: --[$ENV{FOOBAR}]--")
ELSE()
    MESSAGE(STATUS "WTF")
ENDIF()
EOF
[~]
[~] FOOBAR=test cmake -P test-env.cmake
-- FOOBAR env seen: --[test]--

The reason it behaves so weirdly, is legacy, as usual. IF used to do insane stuff in older CMake; they sort-of fixed this in CMake 3.1 — in a backward-compatible manner — with CMP0054, which you have to enable explicitly:

CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
PROJECT(...)

CMAKE_POLICY(SET CMP0054 NEW) #-- fixes IF() with quoted args
CMAKE_POLICY(SET CMP0057 NEW) #-- enables IF(.. IN_LIST ..)
3
  • 1
    Can I recommend - can you change your answer so that first would be correct answer, and later on incorrect. Because normally you just copy answer, and then you notice it did not work out. Commented Sep 17, 2019 at 15:33
  • 10
    @TarmoPikaro let me respectfully decline. If you ask me, I normally read answers and code within, and never directly copy-paste code (because that's seriously bad engineering). You're supposed to pay attention to what you read. You're supposed to be able to type out four words on your own.
    – ulidtko
    Commented Sep 19, 2019 at 17:16
  • @ulidtko while you do make sense, I also fell victim of copy paste :)
    – desertkun
    Commented Feb 3 at 23:23
15

Just to be clear: as https://cmake.org/cmake/help/latest/command/if.html says:

if (DEFINED ENV{THING})
  # do stuff
endif()

is the right syntax, no $ anywhere.

12

You CMake code is correct. The problem is most likely that you only set the environment variable in your shell but did not export it. Run the following before invoking cmake:

export THING
4

I did this but it doesn't work. CMake can't detect it.

export THING

But this one is works.

export THING=on

Maybe I should always give default value for environment variable.

By the way, you can check the environment string by following CMake code.

if( $ENV{THING} STREQUAL "on")
    message(STATUS "THING = " $ENV{THING})
endif()
1
  • 2
    Should be ENV{} not $ENV{}.
    – juzzlin
    Commented Oct 1, 2020 at 12:31
-13

Replace

if(DEFINED ENV{THING})

with

if(DEFINED $ENV{THING})

You missed a '$' before the variable.

2
  • 4
    This is not true: the if command evaluates its arguments
    – kynan
    Commented Jul 11, 2016 at 11:08
  • 3
    This answer is incorrect; however, it lead me to try IF(DEFINED ENV{THING}) without the $ and this actually worked. Paradoxically, this answer came as the single helpful answer in the whole thread.
    – ulidtko
    Commented Oct 16, 2018 at 10:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.