[CMake] Strangeness with ARGVn variables
Zachary Pincus
zpincus at stanford.edu
Thu Jan 26 13:41:45 EST 2006
On Jan 26, 2006, at 8:43 AM, Brad King wrote:
> Zachary Pincus wrote:
>> I'm having some strange issues using the ARGVn variables in
>> macros. Specifically, even when one of those variables has a
>> value, they seem to fail IF tests (and similar).
>> Perhaps this is best illustrated with an example:
>> #----------
>> MACRO(foo)
>> IF(ARGV0)
>> MESSAGE("ONE ARGUMENT")
>> ELSE(ARGV0)
>> MESSAGE("NO ARGUMENTS")
>> ENDIF(ARGV0)
>> ENDMACRO(foo)
>
> The ARGV* variables in macros are handled differently from other
> variables. When the macro is invoked "${ARGV0}" is replaced by the
> argument passed to the macro. The resulting macro body is then
> executed. Try this:
>
> MACRO(foo)
> IF("${ARGV0}")
> MESSAGE("ONE ARGUMENT")
> ELSE("${ARGV0}")
> MESSAGE("NO ARGUMENTS")
> ENDIF("${ARGV0}")
> ENDMACRO(foo)
I had tried that construction too: it also doesn't work. The output
of defining the macro this way and then calling
foo()
foo(a)
is
NO ARGUMENTS
NO ARGUMENTS
On further testing, it looks like this is the case for even explicit
macro arguments. For example:
MACRO(foo a)
IF("${a}")
MESSAGE("ONE ARGUMENT")
ELSE("${a}")
MESSAGE("NO ARGUMENTS")
ENDIF("${a}")
ENDMACRO(foo)
foo("")
foo("m")
gives the same results. However, if I have a SET(m "foobar") command
in the CMakeLists, then things work.
I think I now have the issue figured out:
Both explicit macro parameters and ARGx parameters are never "defined
as variable names" -- they're expanded during macro processing to the
correct values. This is as per the documentation, of course. This
means that by the time the IF statement is evaluated, it looks like
IF("") or IF("m"), as in my last example.
However (also as per the documentation), this form of IF statement is
only valid for determining the contents of variables, not strings, so
the quotes are dropped, and a variable is sought with that name. In
the case above, where I specifically defined such a variable, the IF
statement works.
The upshot of all of this is that IF statements of the form:
IF("${var}") or IF(${var}) are fairly counterintuitive beasts because
they aren't testing for the truth of 'var', they're testing the truth
of a variable named by the contents of 'var'.
The result of this is that without some changes -- which might not be
a good idea, since they would change how CMake files are interpreted
-- an IF test of a macro parameter can never succeed unless that
macro parameter is first stored in a "real" variable, and not a
"fake" macro parameter variable.
Zach
More information about the CMake
mailing list