[CMake] Re: function and raise_scope commands (+ unset bug)

Ken Martin ken.martin at kitware.com
Mon Feb 18 10:10:42 EST 2008


> FUNCTION(SET_VAR1 varname)
>    SET(${varname} "There's science to do" PARENT_SCOPE)
> ENDFUNCTION(SET_VAR1)
> 
> FUNCTION(SET_VAR2 varname)
>    SET_VAR1(${varname})
> ENDFUNCTION(SET_VAR2)
> 
> SET_VAR2(foo)
> MESSAGE("${foo}")
> 
> Obviously foo is not set, since it is now set in SET_VAR2 scope. Bummer.
> So now I have to do things like this:
> 
> FUNCTION(SET_VAR2 varname)
>    SET_VAR1(varname_proxy)
>    SET(${varname} ${varname_proxy} PARENT_SCOPE)
> ENDFUNCTION(SET_VAR2)
> 
> Which I guess I could live with

And you should live with that. And like it dang it! :) A function should be
clear on what variables it is modifying in the parent scope without having
to look at every function it in turn calls. This does make for more code,
but the resulting code is more self documenting. Otherwise if SET_VAR1 were
in a different file, just by looking at SET_VAR2 you would not know it is
returning anything. 

> But wait, it gets weird. In my macros it's not unusual that  I
> *unset* variables (yes, I do), using SET(var). I was wondering if
> that would work. It kinda does, but not quite:
> 
> FUNCTION(SET_VAR1 varname)
>    SET(${varname} "" PARENT_SCOPE)
> ENDFUNCTION(SET_VAR1)
> 
> FUNCTION(SET_VAR2 varname)
>    SET_VAR1(varname_proxy)
>    SET(${varname} "${varname_proxy}" PARENT_SCOPE)
> ENDFUNCTION(SET_VAR2)
> 
> SET_VAR2(foo)
> IF(DEFINED foo)
>    MESSAGE("foo is defined")
> ELSE(DEFINED foo)
>    MESSAGE("foo is NOT defined")
> ENDIF(DEFINED foo)
> 
> This will display that foo is NOT defined, even though it should be
> defined, if you unroll all the functions into a simple script. Note
> that replacing  SET(${varname} "" PARENT_SCOPE) by  SET(${varname}
> PARENT_SCOPE) will also display that foo is not defined (which was
> the expected behavior). Also note that removing the quote around
> ${varname_proxy} doesn't make any difference here.

Sounds like a bug, set should work the same regardless of scope. Maybe the
fix is that the remove command needs a parent_scope argument as well? So
remove removes and set will set even if it is to an empty string. Sound
right to you Alex?

Ken





More information about the CMake mailing list