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


_______________________________________________
CMake mailing list
CMake@cmake.org
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to