MantisBT - CMake
View Issue Details
0014737CMakeCMakepublic2014-02-05 10:492016-06-10 14:31
Alex Merry 
Kitware Robot 
normalfeaturealways
closedmoved 
GNULinux
CMake-2-8 
 
0014737: if(ENV{FOO}) should work like if(FOO) but for env vars
A script like
if($ENV{FOO})
  # do something
endif()
will never evaluate the statements in the if() branch, regardless of the value of the environment variable FOO.
Store the attached testenv.cmake somewhere, then run
FOO="" cmake -P testenv.cmake
As expected, the output is
-- $ENV{FOO} =
-- $ENV{FOO} evaluates to FALSE
-- ENV{FOO} evaluates to FALSE

Now try
FOO="bar" cmake -P testenv.cmake
The output is
-- $ENV{FOO} = bar
-- $ENV{FOO} evaluates to FALSE
-- ENV{FOO} evaluates to FALSE
when the expected output would be
-- $ENV{FOO} = bar
-- $ENV{FOO} evaluates to TRUE
-- ENV{FOO} evaluates to TRUE
Tested with cmake 2.8.12 and cmake 2.8.12.20140204-g5414b
No tags attached.
? testenv.cmake (303) 2014-02-05 10:49
https://public.kitware.com/Bug/file/5062/testenv.cmake
Issue History
2014-02-05 10:49Alex MerryNew Issue
2014-02-05 10:49Alex MerryFile Added: testenv.cmake
2014-02-05 12:39Brad KingNote Added: 0035040
2014-02-05 12:41Brad KingNote Added: 0035041
2014-02-05 12:45Alex MerryNote Added: 0035042
2014-02-06 07:29Alex MerryNote Added: 0035043
2014-02-06 08:52Brad KingNote Added: 0035044
2014-02-06 08:52Brad KingSeverityminor => feature
2014-02-06 08:52Brad KingStatusnew => backlog
2014-02-06 08:52Brad KingSummary$ENV{FOO} always evaluates to FALSE => if(ENV{FOO}) should work like if(FOO) but for env vars
2016-06-10 14:29Kitware RobotNote Added: 0042477
2016-06-10 14:29Kitware RobotStatusbacklog => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0035040)
Brad King   
2014-02-05 12:39   
The if command documentation:

 http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:if [^]

explains that the value it is given is first checked against a boolean constant and then treated as a variable name. Since you're evaluating "$ENV{FOO}" the CMake language expands the value of the environment variable before the if() command ever sees the reference. Therefore for value "bar" the if() command sees

 if(bar)

Since "bar" is not a boolean constant then if() looks for a variable called "bar" and since that is not defined the result is false. Using FOO=1 results in evaluation to true.

Prior to policy CMP0012, introduced in CMake 2.8.0, if() would consider variables before named constants like "TRUE" so one must add

  cmake_minimum_required(VERSION 2.8)

to ensure modern behavior.

A common idiom for this use case is:

 set(FOO "$ENV{FOO}")
 if(FOO)
  ...
 endif()
(0035041)
Brad King   
2014-02-05 12:41   
One may also use

 if(DEFINED ENV{FOO})
 endif()

to detect whether the environment variable is defined at all.
(0035042)
Alex Merry   
2014-02-05 12:45   
Maybe I shouldn't have used that particular construction in the title of the bug. What surprised me was that
if(ENV{FOO})
also did not work.
(0035043)
Alex Merry   
2014-02-06 07:29   
I'm happy for this to be considered a feature request, rather than a bug, BTW: it would be really convenient for
if(ENV{DESTDIR})
   # modify installation command
endif()
to work (in the context of install(CODE), of course).
(0035044)
Brad King   
2014-02-06 08:52   
The proper place in the code to make this work is at the bottom of GetBooleanValue in cmIfCommand.cxx:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmIfCommand.cxx;hb=v2.8.12.2#l263 [^]

That's where it falls back to looking for a variable definition. One could teach that step to recognize ENV{} syntax and check the environment value instead.
(0042477)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.