Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange function argument name behaviour

Tags:

cmake

I asked a questions about cmake and passing variables here. I can make it work, but only if I name my variable in the function differently than the variable in parent scope I call the function for. So in essence:

function(strange name)
   message(STATUS ${name})
   message(STATUS ${${name}})
endfunction()

set(name foo)
set(anothername foo)
strange(name)
strange(anothername)

Which results in:

-- name   (message(STATUS ${name}) for var "name")
-- name   (message(STATUS ${${name}}) for var "name")
-- anothername message(STATUS ${name}) for var "anothername")
-- foo    (message(STATUS ${${name}}) for var "anothername")

Isn't that a little weird? What's happening? I think the behaviour of a function should not depend on the naming of variable in the parent scope - should it?!

Any clarification is much appreciated!

like image 359
nandaloo Avatar asked Jan 18 '13 10:01

nandaloo


2 Answers

Unfortunately, the language of CMake is extremely primitive. In this case, the naming of local variables may interact with variables with the same name in outer scopes.

Concretely, in the two calls ${${name}} expands to ${name} and ${anothername}, respectively. In the former name is the name of a local variable whose value is used. In the latter, the anothername from the outer scope is used.

I don't know of any way around this, except using obfuscated variable names in function accept variable names as arguments.

Maybe we should petition for a ${name:PARENT_SCOPE} from the CMake team?

like image 79
Lindydancer Avatar answered Oct 13 '22 03:10

Lindydancer


If you want to avoid the local scoping issues described in @Lindydancer's concise answer, you can change your function to a macro

From the documentation of macro:

Note that the parameters to a macro and values such as ARGN are not variables in the usual CMake sense. They are string replacements much like the c preprocessor would do with a macro. If you want true CMake variables you should look at the function command.

If you change to use macro, your output becomes

-- name
-- foo
-- anothername
-- foo
like image 38
Fraser Avatar answered Oct 13 '22 04:10

Fraser