View Issue Details [ Jump to Notes ] | [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0010719 | CMake | CMake | public | 2010-05-16 03:35 | 2010-11-09 22:57 | ||||
Reporter | Yevgen Muntyan | ||||||||
Assigned To | David Cole | ||||||||
Priority | normal | Severity | block | Reproducibility | always | ||||
Status | closed | Resolution | no change required | ||||||
Platform | OS | OS Version | |||||||
Product Version | CMake-2-8 | ||||||||
Target Version | Fixed in Version | CMake 2.8.3 | |||||||
Summary | 0010719: IF("foo" MATCHES "foo") broken | ||||||||
Description | The following script produces an error: SET(foo FALSE) IF(NOT "foo" MATCHES "foo") MESSAGE(FATAL_ERROR "oops") ENDIF(NOT "foo" MATCHES "foo") It treats "foo" as variable foo in this case (if you do SET(foo foo) in the beginning, the error goes away). There is no error if there is STREQUAL instead of MATCHES; no error if foo isn't set before. This is particularly bad because cmake does it: MACRO(CHECK_C_SOURCE_COMPILES SOURCE VAR) IF("${VAR}" MATCHES "^${VAR}$") ... | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | |||||||||
Relationships | |
Relationships |
Notes | |
(0022293) David Cole (manager) 2010-09-21 12:01 |
The behavior reported here is "by design." When CMake does a comparison like this: IF("${VAR}" MATCHES "^${VAR}$") ...it is equivalent to: IF(NOT DEFINED VAR) ...but it works with ancient CMake versions that existed before IF DEFINED was supported. Basically, the IF command takes a look at its args and tries to use variables of those names first, and then if the variable's not there, it uses it as a plain string value. It is confusing, but that's the way it works for now. We cannot change this without breaking backwards compatibility for lots of projects without a quite complicated CMake policy to govern the behavior of if(VARIABLE commands. |
(0022306) Yevgen Muntyan (reporter) 2010-09-21 16:14 |
(Reopening because I can't make a comment otherwise). Could you then document exact behavior of IF() and fix the bug caused by that particular IF() command in cmake code? |
(0022307) David Cole (manager) 2010-09-21 16:30 |
Please state what actually happens vs. what you expect to happen. Your original report was this: <original> The following script produces an error: SET(foo FALSE) IF(NOT "foo" MATCHES "foo") MESSAGE(FATAL_ERROR "oops") ENDIF(NOT "foo" MATCHES "foo") </original> There is no bug here. If you run this script, you will get a FATAL_ERROR. If you don't want a FATAL_ERROR, then change the script. The documentation for IF command is quite detailed, but you must read it all the way to the bottom and pay very close attention to the details at the end of that documentation to understand this behavior and the reasons for maintaining it as is. |
(0022308) David Cole (manager) 2010-09-21 16:30 |
Online docs for "IF" are here: http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:if [^] |
(0022314) Yevgen Muntyan (reporter) 2010-09-21 23:24 |
I see, I assumed that if you quote a string then it is going to be treated as a string (as opposed to maybe-variable-maybe-string), I thought docs said that somewhere. Documentation for IF() command doesn't mention quotes at all, so I suppose that means quotes don't matter. I still think it's FUBAR, since we have CMAKE_REQUIRE which could turn off strange compatibility quirks, but that's not so important. The bug I mentioned: CHECK_C_SOURCE_COMPILES(SOURCE VAR) macro (as well as _RUNS and their CXX buddies) assumes that variable VAR is unique, but it shouldn't. I should be able to do CHECK_C_SOURCE_COMPILES(some_source temp_bool_var) if(temp_bool_var) ... CHECK_C_SOURCE_COMPILES(some_other_source temp_bool_var) if(temp_bool_var) ... Now, I can see why these macros could assume uniqueness of the variable, but that's not documented, and combined with the IF() quirk I just assumed it was a bug caused by a bug in IF(). |
(0022316) David Cole (manager) 2010-09-22 07:01 |
In the case of: CHECK_C_SOURCE_COMPILES(some_source temp_bool_var) "temp_bool_var" is not temporary. It is a cache variable so that the try compile only has to occur once in any given build tree. That variable should be unique in your whole build tree. Same for any other try_compile result. I agree that the behavior of CMake IF is strange w.r.t. strings that happen to be variable names. Changing would be possible with a policy, but the differences are so subtle in some cases, it is definitely going to be a challenge... I'll resolve this again now. Perhaps bringing up something like this on the mailing list would get more people interested in the idea of changing the IF command to "something better"... |
Notes |
Issue History | |||
Date Modified | Username | Field | Change |
2010-05-16 03:35 | Yevgen Muntyan | New Issue | |
2010-09-21 11:56 | David Cole | Status | new => assigned |
2010-09-21 11:56 | David Cole | Assigned To | => David Cole |
2010-09-21 12:01 | David Cole | Note Added: 0022293 | |
2010-09-21 12:01 | David Cole | Status | assigned => resolved |
2010-09-21 12:01 | David Cole | Fixed in Version | => CMake 2.8.3 |
2010-09-21 12:01 | David Cole | Resolution | open => no change required |
2010-09-21 16:14 | Yevgen Muntyan | Note Added: 0022306 | |
2010-09-21 16:14 | Yevgen Muntyan | Status | resolved => feedback |
2010-09-21 16:14 | Yevgen Muntyan | Resolution | no change required => reopened |
2010-09-21 16:30 | David Cole | Note Added: 0022307 | |
2010-09-21 16:30 | David Cole | Note Added: 0022308 | |
2010-09-21 23:24 | Yevgen Muntyan | Note Added: 0022314 | |
2010-09-22 07:01 | David Cole | Note Added: 0022316 | |
2010-09-22 07:02 | David Cole | Status | feedback => resolved |
2010-09-22 07:02 | David Cole | Resolution | reopened => no change required |
2010-11-09 22:57 | Philip Lowman | Status | resolved => closed |
Issue History |
Copyright © 2000 - 2018 MantisBT Team |