[CMake] function and raise_scope commands

Ken Martin ken.martin at kitware.com
Fri Dec 28 10:36:48 EST 2007


> > > 1. CMake crashes if I use the same variable name as the argument and
> > > raise the scope later. That is, for the following function:
> > >
> > > function(track_find_variable cache_variable is_changed)
> > >   raise_scope(${is_changed})
> > > endfunction(track_find_variable)
> > >
> > > I can't call it like:
> > >
> > > track_find_variable(testvar is_changed) # I had to mangle is_changed
> > > above, but that's ok
> > >
> > > I think it shouldn't crash. If its too much effort to have cmake
> > > support this, then I don't think it is worth it... just having a note
> > > that the argument can't be used as a variable name in the help and
> > > maybe try to detect the case and signal an error...
> 
> This still doesn't work. I don't know if you have done anything for this.

Actually the code above works for me. If you add a set command of the
variable before the raise scope then I see the problem you describe. The
variable that has the name of the variable in it (is_changed) gets
overridden because it has the same name as its value. 

Specifically

Variable  value
--------------------
is_changed  is_changed
  set(${is_changed} "some_result")
is_changed some_result
  raise_scope(${is_changed})

well this last line becomes raise_scope(some_result) and since there is no
local variable named some_result it yerks. I have fixed the crash and it now
prints a nice warning message (on my local copy of cmake, not checked in
yet) but I'm not sure that is all the solution. I think a safer fix may be
to change the raise scope command to look like the following:

raise_scope(var_name value var_name value ...)

with a convention that you do not set variables that are to be returned (aka
passed by reference). In this case that would be is_changed. You leave
is_changed alone and only use it in the raise scope command. So the
resulting code would look like.

function(track_find_variable cache_variable is_changed)
   set(changed "some_result")
   raise_scope(${is_changed} "${changed}")
endfunction(track_find_variable)

which is safer. But I am still want to think about it a bit before I commit
the change.


> 3. I'm having another issue. If you pass a variable to a function that
> hasn't been defined previously and that isn't defined in the function
> either, then it crashes when you do a raise_scope on it.
> 
> For instance, if you have the following function:

Pretty sure I have fixed this on my local copy of the code. I'll check it in
with the above fixes in a few days (still on vacation for a few more days)

Thanks
Ken




More information about the CMake mailing list