5

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!

2 Answers 2

8

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?

Sign up to request clarification or add additional context in comments.

1 Comment

+1 for a clear answer. Not sure I'd favour your petition though :-) If anything, I'd prefer an AUTHOR_WARNING type message, warning about the local variable hiding the parent one.
4

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

2 Comments

Thanks for that additional information. Though, I wonder what the advantage of a function over a macro is at all then...
I usually prefer a function as it doesn't "pollute" the parent namespace with variables used only in the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.