MantisBT - CMake |
View Issue Details |
|
ID | Project | Category | View Status | Date Submitted | Last Update |
0015335 | CMake | CMake | public | 2015-01-04 21:19 | 2015-06-01 08:38 |
|
Reporter | Brian Chojnowski | |
Assigned To | | |
Priority | normal | Severity | major | Reproducibility | always |
Status | closed | Resolution | no change required | |
Platform | Linux | OS | CentOS | OS Version | 7 |
Product Version | CMake 3.1 | |
Target Version | | Fixed in Version | | |
|
Summary | 0015335: if () evaluates to FALSE for quoted constants/variables where the contents are non-null and not defined constants |
Description | An if statement should evaluate to TRUE if the variable is not-null and is not a defined false constant.
From the documentation:
if(<constant>)
True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND. Named boolean constants are case-insensitive. If the argument is not one of these constants, it is treated as a variable.
if(<variable>)
True if the variable is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.) |
Steps To Reproduce | set(myvar "not a false constant")
message(STATUS "myvar=${myvar}")
if(myvar)
message(STATUS "un quoted variable name = TRUE")
endif()
if(${myvar})
message(STATUS "un quoted variable contents = TRUE")
endif()
if("${myvar}")
message(STATUS "quoted variable = TRUE")
endif()
Output:
Eclipse version is set to 4.4 (). Adjust CMAKE_ECLIPSE_VERSION if this is wrong.
myvar=test string
un quoted variable name = TRUE
Configuring done |
Additional Information | |
Tags | No tags attached. |
Relationships | |
Attached Files | |
|
Issue History |
Date Modified | Username | Field | Change |
2015-01-04 21:19 | Brian Chojnowski | New Issue | |
2015-01-08 12:14 | Brad King | Note Added: 0037633 | |
2015-01-08 12:14 | Brad King | Status | new => resolved |
2015-01-08 12:14 | Brad King | Resolution | open => no change required |
2015-01-08 12:18 | Brian Chojnowski | Note Added: 0037635 | |
2015-01-08 12:21 | Brian Chojnowski | Note Added: 0037636 | |
2015-01-08 12:29 | Brad King | Note Added: 0037638 | |
2015-01-08 12:45 | Brian Chojnowski | Note Added: 0037639 | |
2015-01-08 12:51 | Brad King | Note Added: 0037640 | |
2015-01-08 12:56 | Brian Chojnowski | Note Added: 0037641 | |
2015-01-08 12:58 | Brad King | Note Added: 0037642 | |
2015-01-08 13:03 | Brad King | Note Added: 0037643 | |
2015-01-08 13:04 | Brian Chojnowski | Note Added: 0037644 | |
2015-01-08 13:06 | Brian Chojnowski | Note Added: 0037645 | |
2015-01-08 13:14 | Brad King | Note Added: 0037646 | |
2015-01-08 13:26 | Brian Chojnowski | Note Added: 0037647 | |
2015-01-08 13:34 | Brad King | Note Added: 0037648 | |
2015-01-08 13:39 | Brian Chojnowski | Note Added: 0037649 | |
2015-01-08 13:43 | Brad King | Note Added: 0037650 | |
2015-01-08 13:45 | Brad King | Note Added: 0037651 | |
2015-01-08 13:50 | Brian Chojnowski | Note Added: 0037652 | |
2015-01-08 14:15 | Brad King | Note Added: 0037654 | |
2015-01-08 14:17 | Brian Chojnowski | Note Added: 0037655 | |
2015-06-01 08:38 | Robert Maynard | Note Added: 0038831 | |
2015-06-01 08:38 | Robert Maynard | Status | resolved => closed |
Notes |
|
(0037633)
|
Brad King
|
2015-01-08 12:14
|
|
The if(<variable>) case refers to when <variable> is the name of a variable, not a reference to a variable.
For
if(${myvar})
the if() command sees
if(not\ a\ false\ constant)
which is not a defined variable or a true constant.
For
if("${myvar}")
the if() command sees
if("not a false constant")
which is not a defined variable or a true constant. |
|
|
(0037635)
|
Brian Chojnowski
|
2015-01-08 12:18
|
|
However, from the documentation of the if(<constant>) case:
If the argument is not one of these constants, it is treated as a variable.
if(<variable>) |
|
|
(0037636)
|
Brian Chojnowski
|
2015-01-08 12:21
|
|
So am I reading your notes correctly in that there is no defined rule for if(<not a true constant>) and if(<not a true variable>) ??
If so, seems like we should define the behavior. in this case. |
|
|
(0037638)
|
Brad King
|
2015-01-08 12:29
|
|
Re 0015335:0037636: If it is not a defined constant or one of the later cases that involves a keyword then it is treated as the if(<variable>) case. That case defines the not-defined case as false (see text "False otherwise."). |
|
|
(0037639)
|
Brian Chojnowski
|
2015-01-08 12:45
|
|
if(<variable>)
True if the variable is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.)
This statement says that if the variable does not resolve to a false constant than the if() will evaluate true. The "False otherwise" sentence therefore applies to the case where the variable does resolve to a false constant.
Or said more plainly, anything that is not a false constant evaluates to TRUE. |
|
|
(0037640)
|
Brad King
|
2015-01-08 12:51
|
|
Re 0015335:0037639: "False otherwise" is a separate sentence, meaning that the result is false if the case described in the first sentence is not true. |
|
|
(0037641)
|
Brian Chojnowski
|
2015-01-08 12:56
|
|
I have been trying to get the FindIce.cmake module to work correctly (CentOS 7 environment). The module is failing because the variable that contains the result of a find_library statement...
foreach(component ${Ice_FIND_COMPONENTS})
string(TOUPPER "${component}" component_upcase)
set(component_cache "Ice_${component_upcase}_LIBRARY")
set(component_found "${component_upcase}_FOUND")
find_library("${component_cache}" "${component}"
HINTS ${ice_roots}
PATH_SUFFIXES ${ice_library_suffixes}
DOC "Ice ${component} library")
mark_as_advanced("${component_cache}")
if("${component_cache}")
The if test evaluates to FALSE, even though it contains a non-empty path to the library.
I built this from source, if that matters.
Strangely, removing the quotes and issuing make clean;make; make install then makes this if () test evaluate TRUE... even though the minimal example in this bug report fails (this code was not in a module, just in the CMakeLists.txt file) |
|
|
(0037642)
|
Brad King
|
2015-01-08 12:58
|
|
Re 0015335:0037640: Perhaps the wording can be clarified. How about
``if(<variable|string>)``
True if given a variable that is defined to a value that is not a false
constant. False otherwise. (Note macro arguments are not variables.) |
|
|
(0037643)
|
Brad King
|
2015-01-08 13:03
|
|
|
|
(0037644)
|
Brian Chojnowski
|
2015-01-08 13:04
|
|
I agree the definition needs clarification of some sort. I am still confused as to why if (<string>) where string is not one of the false constants is evaluating as false. |
|
|
(0037645)
|
Brian Chojnowski
|
2015-01-08 13:06
|
|
if ("not a false constant")
message(status "string is true")
endif()
This produces no output. |
|
|
(0037646)
|
Brad King
|
2015-01-08 13:14
|
|
Re 0015335:0037644: The behavior was defined that way for use cases like
if(COOL_OPTION)
message(STATUS "cool option enabled")
endif()
where the COOL_OPTION variable may or may not be defined. This is just like the C preprocessor where code like
#if COOL_OPTION
will be true only if the symbol is defined to a non-false value.
Does the wording proposed in 0015335:0037642 describe the behavior clearly? (It is not intended to describe the design choice or motivation, just the behavior.) |
|
|
(0037647)
|
Brian Chojnowski
|
2015-01-08 13:26
|
|
I think the clarification will help. But I still am struggling to see why this also does not work.
if ("not a false constant")
message(status "string is true")
endif()
This if evaluates to false. "not a false constant" is a defined string and not one of the false constants correct? so I believe this should evaluate to TRUE. |
|
|
(0037648)
|
Brad King
|
2015-01-08 13:34
|
|
Re 0015335:0037647: There is no
set("not a false constant" 1)
line so "not a false constant" is not the name of a defined variable. Therefore the string does not name a variable that is defined to a value that is not a false constant. |
|
|
(0037649)
|
Brian Chojnowski
|
2015-01-08 13:39
|
|
Are you implying that if ("some text here") is not of the form: if(<constant>) ??
If so I understand why I am confused. |
|
|
(0037650)
|
Brad King
|
2015-01-08 13:43
|
|
Re 0015335:0037649: The documentation of if(<constant>) says "If the argument is not one of these constants, it is treated as a variable". |
|
|
(0037651)
|
Brad King
|
2015-01-08 13:45
|
|
|
|
(0037652)
|
Brian Chojnowski
|
2015-01-08 13:50
|
|
Ok I see, so if ("sometext") is treated as if (sometext).
I think I found why FindIce.cmake worked in 2.8 and not 3.1. I will work with the FindIce developer to update the module.
this code placed in CMakeLists.txt (and not a module that might have the CMFoo54 policy set to NEW):
set(fooref "foo")
set ("${fooref}" "some string")
if ("${fooref}")
message(status "string is true")
endif()
produces this output:
CMake Warning (dev) at CMakeLists.txt:3 (if):
Policy CMP0054 is not set: Only interpret if() arguments as variables or
keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
Quoted variables like "foo" will no longer be dereferenced when the policy
is set to NEW. Since the policy is not set the OLD behavior will be used.
This warning is for project developers. Use -Wno-dev to suppress it.
statusstring is true |
|
|
(0037654)
|
Brad King
|
2015-01-08 14:15
|
|
|
|
(0037655)
|
Brian Chojnowski
|
2015-01-08 14:17
|
|
|
|
(0038831)
|
Robert Maynard
|
2015-06-01 08:38
|
|
Closing resolved issues that have not been updated in more than 4 months. |
|