[CMake] Fwd: [CMake 0012398]: "IF" infamous <variable/string> functionality fails to work with macro arguments

Albert Meltzer bulsara at gmail.com
Mon Aug 15 15:23:37 EDT 2011


On Mon, Aug 15, 2011 at 3:26 PM, David Cole <david.cole at kitware.com> wrote:

> 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
>

Umm... once again, doesn't this case look perfect for using a policy?

If cmake knew the difference between identifiers and strings (foo vs.
"bar"), I wouldn't mind having IF recognize foo as a variable - and only a
variable (if undefined, it shouldn't be treated as "foo") - and "bar" (or
"${HAVE_${foo}}") as a string, and behave accordingly.

Otherwise, IF(var) instead of IF(${var}) isn't much of a benefit to me,
given the drawbacks. The unpredictable and inconsistent treatment of its
arguments by IF() is something I'd consider a major drawback.

Every mode of IF() has its own set of variable-vs-string rules. Why does
STREQUAL expect variables on both side and MATCHES doesn't? How should I
remember that? Does EXISTS allow specifying a variable - or only a string
will do? How should I remember that? What if I define SET(YES NO); how do I
remember what IF(YES) will do?

Maybe the esteemed colleagues would suggest another good and reliable way to
handle situations such as this:

IF (lang STREQUAL "perl") ...
ELSEIF(lang STREQUAL "python") ...
ELSEIF(....)
...
ENDIF ()

without having to SET(perl perl) (and all the other cases in this switch)
myself (just in case), but still being afraid that somebody, somewhere else,
would SET(perl 5.10.0), and without resorting to IF (lang MATCHES "^perl$")?

On Sat, Aug 13, 2011 at 3:39 AM, Michael Wild <themiwi at gmail.com> wrote:
> > For most users, macros should be a taboo anyways. They are much better
>

If MACRO is taboo, deprecate it. Having an active command exhibit peculiar
and hard-to-debug behaviour in conjunction with another active command is
hardly a way to deter people from using it. However...

> served by functions, IMHO. In all of my projects I had only one case
> > where I actually needed a macro. That was when I wrapped a function
> > that set some variables in the PARENT_SCOPE and I had to propagate them
> > outside of the wrapping macro without knowing their name.
>

... bingo. It is possible that we are relatively light users, but our use
case involves thousands of directories, half of them libraries with complex
dependency chains, 5k+ lines of specialized cmake code (not counting the
per-directory CMakeLists.txt); I have tried to use functions as much as
possible, and this "don't know what variables are being set and how deep my
call stack is" is effectively ruling it out in most cases.

Maybe having an easier way to work with properties would help, so that they
can behave like variables. Something like this, for instance:

${dir:var} - property for directory "dir"
${:var} - property for current directory
${::var} - global property

or

${#GLB:var}
${#DIR:dir:var}
${#SRC:src:var}
${#TGT:tgt:var}
${#TST:tst:var}
${#CCH:entry:var}

with all the requisite DEFINED etc. tests.

> Perhaps it would be enough to just properly document the quirky
> > behaviour of macro arguments in the docs and mention that one should
> > normally prefer functions over macros unless there is a real reason
> > that requires a macro?
>

Properly documenting everything would be nice in general. Emphasizing
stumbling blocks such as these would be nice. Having a separate section on
"here is what you should pay attention to" would also be nice. Documenting
what happens when a command fails would be nice, too (STRING(REGEX MATCH) if
no match, FILE(READ) if no file etc.) Explaining how to use STRING(FIND)
with STRING(SUBSTRING), if that is even possible, and whether any sort of
arithmetic is available would be good.

Maybe I missed it, but the documentation page below appeared not mention
such basic stuff as how to expand a variable (the ${} syntax is kind of
implied):

http://www.cmake.org/cmake/help/cmake-2-8-docs.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20110815/0ed5a816/attachment.htm>


More information about the CMake mailing list