[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