Discussion:
[CMake] FOREACH loop control variable scope bug
Bradley Lowekamp
2005-06-22 17:07:54 UTC
Permalink
hi all,

This behavior I think is a bug. This is another problem I have
encounter in CMake with my apparent abuse while I am trying to get my
project to work easily. Consider the following simplified example:


# top level CMakeLists.txt
SET(var "this is var")
FOREACH(LCV one)
MESSAGE("var: ${var} LCV: ${LCV}")
ADD_SUBDIRECTORY(foo)
ENDFOREACH(LCV one two three)


# foo dir CMakeLists.txt
MESSAGE("In Directory var: ${var} LCV: ${LCV}")

This produces the following output:

var: this is var LCV: one
In Directory var: this is var LCV:

I expected LCV to be defined in the subdirectory just like any other
variable would have been. I realize this is can only happen with the
new immediate execution of the ADD_SUBDIRECTORY command. It appear that
there is some scoping issues with this variable.

Thanks,
Brad



========================================================
Bradley Lowekamp
Management Systems Designers Contractor for
Office of High Performance Computing and Communications
National Library of Medicine
'***@mail.nih.gov
Ken Martin
2005-06-22 17:16:58 UTC
Permalink
Currently FOREACH and MACRO do not actually use variables in their
implementation. They do their own string replacement on the "variable" prior
to passing the command to the main parser. (this was because they tend to
use nested variables ${FU${BAR}} which wasn't supported in CMake 2.0 or
earlier). With CMake 2.2 the parser fully supports nested variables so we
can convert these commands to use variables instead. In fact Andy added an
item on my whiteboard to do just that a couple weeks ago. I'll put that on
my todo list. Having said that a quick workaround is to just add a set
command

# top level CMakeLists.txt
SET(var "this is var")
FOREACH(LCV one two three)
MESSAGE("var: ${var} LCV: ${LCV}")
SET(LCV_SUB ${LCV})
ADD_SUBDIRECTORY(foo)
ENDFOREACH(LCV)


# foo dir CMakeLists.txt
MESSAGE("In Directory var: ${var} LCV: ${LCV_SUB}")


Thanks
Ken
Brad King
2005-06-22 17:21:58 UTC
Permalink
Post by Bradley Lowekamp
# top level CMakeLists.txt
SET(var "this is var")
FOREACH(LCV one)
MESSAGE("var: ${var} LCV: ${LCV}")
ADD_SUBDIRECTORY(foo)
ENDFOREACH(LCV one two three)
# foo dir CMakeLists.txt
MESSAGE("In Directory var: ${var} LCV: ${LCV}")
var: this is var LCV: one
I expected LCV to be defined in the subdirectory just like any other
variable would have been. I realize this is can only happen with the new
immediate execution of the ADD_SUBDIRECTORY command. It appear that
there is some scoping issues with this variable.
The FOREACH "control variable" is not really a variable. It is never
actually set and has no scope. The arguments of the commands inside the
loop just have the text "${LCV}" replaced with each iteration's value.
If you want to get its value from inside another command (like INCLUDE
or ADD_SUBDIRECTORY) then you have to set it explicitly:

FOREACH(LCV one two three)
SET(LCV "${LCV}")
ADD_SUBDIRECTORY(foo)
ENDFOREACH(LCV)

-Brad

Loading...