MantisBT - CMake
View Issue Details
0012398CMakeCMakepublic2011-08-12 08:132012-03-06 08:37
freddie 
David Cole 
normalmajoralways
closedno change required 
CMake 2.8.5 
CMake 2.8.6 
0012398: "IF" infamous <variable/string> functionality fails to work with macro arguments
There is a problem with the "IF" command when it is used directly with macro arguments. Apparently, they are not considered variables and are used directly as strings.

However, if their contents can be construed as variables themselves (even though it is not desired), we have a problem when the only way to perform the test is to create another explicit variable assigning it to what the macro argument contains.

The problem doesn't appear to pertain to functions.
Please use the attached CMakeLists.txt file with "cmake -Wno-dev .".
It would really be a good idea to create a version of if/elseif/else/endif which does NOT attempt to treat its arguments as variables, either by creating a new name for the command or, better yet, by adding a new policy (possibly not associated with a version yet).

Otherwise, when trying to compare things which might be variables but should not be treated as such for the purposes of the comparison, one runs into subtle problems (when checks "randomly" fail) or has to create a level of indirection, by setting a new variable just for that.

I am sure you've heard this all before.
No tags attached.
duplicate of 0009590closed David Cole IF(VARIABLE) doesn't work inside Makro 
txt CMakeLists.txt (850) 2011-08-12 08:13
https://public.kitware.com/Bug/file/4002/CMakeLists.txt
Issue History
2011-08-12 08:13freddieNew Issue
2011-08-12 08:13freddieFile Added: CMakeLists.txt
2011-08-12 10:30David ColeAssigned To => David Cole
2011-08-12 10:30David ColeStatusnew => assigned
2011-08-12 10:36David ColeNote Added: 0027198
2011-08-12 10:36David ColeRelationship addedduplicate of 0009590
2011-08-12 10:36David ColeStatusassigned => resolved
2011-08-12 10:36David ColeFixed in Version => CMake 2.8.6
2011-08-12 10:36David ColeResolutionopen => duplicate
2011-08-12 14:49freddieNote Added: 0027199
2011-08-12 14:49freddieStatusresolved => feedback
2011-08-12 14:49freddieResolutionduplicate => reopened
2011-08-12 15:30David ColeNote Added: 0027200
2011-08-15 11:27David ColeNote Added: 0027204
2011-10-03 11:00David ColeNote Added: 0027515
2011-10-03 11:00David ColeStatusfeedback => resolved
2011-10-03 11:00David ColeResolutionreopened => no change required
2012-03-06 08:37David ColeNote Added: 0028817
2012-03-06 08:37David ColeStatusresolved => closed

Notes
(0027198)
David Cole   
2011-08-12 10:36   
You're right... we've heard it before. :-)

It would be possible to change this via a cmake policy, but I'm not sure it's worth the effort.

Think of CMake macro expansion as analogous to C preprocessor #define macro expansion. The "arguments" to:

  #define m(x, y, z) ((x) < (y)) ? (z) : 0

are not C "variables", but that does not mean that such a construct is useless...

Similarly with CMake macros: the macro arguments are not "variables" but they are still useful to eliminate duplication when used appropriately.

As you've noted functions do have "real variables" as their arguments.

Use function if you need variables. If you must use a macro, and you must have CMake variables, then you must make the CMake variables with set, as you've noted...
(0027199)
freddie   
2011-08-12 14:49   
Your comparison of macro with preprocessor macros makes sense. If only it worked that way. In cmake language, ${foo} expands a variable; if ARGV0 is not a variable, then you must either substitute ARGV0 for what was specified in the parameter list for the macro, or use a different expansion {#{ARGV0}, for instance); otherwise, people who can't be called stupid will keep running into these problems.

However, the analogy stops there; FUNCTION is not equivalent to functions or methods in C/C++ in the sense that variables are automatically local to the function, and setting a variable in a different scope is problematic. If I have a directory-specific variable that I set and append to in multiple places (I'd call it namespace-specific), I can't use it here because it's hard to say how many parent-scope levels up it is. So we end up using macros.

And about IF: I am not sure about this "worth the effort" statement. This behaviour is quite unusual (I don't know of any other language that does this) and, as it turns out, extremely inconvenient; forget that, after reading the manual on IF and MACRO (and the IF epilogue) several times, I still ran into problems as described in this bug. What about making it impossible to use the macro arguments with IF completely and calling it a feature? Making it easy to work with cmake and avoid peculiar bugs is probably more important.
(0027200)
David Cole   
2011-08-12 15:30   
I've posted a quick note on the CMake mailing list just now to ask others to chime in with their opinions here... Thanks.
(0027204)
David Cole   
2011-08-15 11:27   
Me, on the mailing list:

"I'll give this another week or so here on the mailing list (and in the
bug tracker) to gather feedback.

If I don't hear anything else, I'll consider changing some
documentation to clarify the existing situation, but I don't see a
reasonable way to accommodate this feature request *and* maintain
backwards compatibility with existing real world uses of macro and if
commands."

http://www.cmake.org/pipermail/cmake/2011-August/045884.html [^]
(0027515)
David Cole   
2011-10-03 11:00   
After giving sufficient time for feedback, resolving as "no change required" -- learning the idiosyncracies of CMake IF and MACRO is not as easy as it could be, but it is do-able.
(0028817)
David Cole   
2012-03-06 08:37   
Closing resolved issues that have not been updated in more than 4 months.