[CMake] function and raise_scope commands

Ken Martin ken.martin at kitware.com
Mon Dec 3 14:07:27 EST 2007


I checked into CVS two new commands; function and raise_scope (well three
commands if you count endfunction)

The function command is very much like the macro command but it creates a
new scope for variables and its arguments are variables not string
replacements. Recall that a cmake macro is like a cpp macro and simply does
string replacements for its arguments. The new variable scope of a function
is the same as the new variable scope of a sub directory. Specifically:

1. It inherits all of the values from the parent scope at the time the new
scope is created 
2. Any changes or new variables are localized to the new scope and do not
change the parent scope
3. set CACHE can be used to set variables in the cache regardless of scope

I made functions work like new directories so that CMake would have one
consistent notion of how a new scope works. function and add_subdirectory
(and subdirs for that matter) both create new scopes and they do it exactly
the same way. I also added a command called raise_scope. This command will
take a list of local variables and push their values up to the parent scope.
This command can be used in both subdirectories and functions. For Tcl folks
this is much like the upvar command. Consider a toy example.

# test recursion and return via raise_scope
function (factorial argument result)
  if (argument LESS 2)
    set (${result} 1)
  else (argument LESS 2)
    math (EXPR temp "${argument} - 1")
    factorial (${temp} tresult)
    math (EXPR ${result} "${argument}*${tresult}")
  endif (argument LESS 2)
  raise_scope (${result})
endfunction (factorial)

factorial (5 fresult)
if (fresult EQUAL 120)
  message ("factorial worked")
else (fresult EQUAL 120)
  message ("factorial, computed ${fresult} instead of 120")
endif (fresult EQUAL 120)


It looks much like a macro but note that you can do "if (argument ..."
because argument is a real variable not just a string replacement. With a
macro this would not work. Next we do some recursion and finally at the end
we call raise_scope to return the value to the caller. We allow the user to
pass in the name of the result variable and use raise_scope to set that
variable, in the caller's scope, to the resulting value. ARGV, ARGC, ARGN,
and ARGV0, ARGV1, ... are all defined as well to support variable argument
lists. Note that in this example argument, result, temp, and tresult are all
"local" variables and do not impact the parent scope, nor do their values in
recursive calls to factorial impact the values in the parent calls.

Ken



Ken Martin PhD 
Kitware Inc.
28 Corporate Drive
Clifton Park NY 12065
518 371 3971 



More information about the CMake mailing list