[CMake] Why are blank-delimited strings in commands escaped on Linux?

Claudio Bley b_l_e_y at ml1.net
Fri Oct 2 11:20:16 EDT 2009


Hendrik Sattler <post at hendrik-sattler.de>
writes:

> Zitat von Claudio Bley <b_l_e_y at ml1.net>:
>>> But I think that his example is wrong, it should be:
>>> set(a "-Lfoo -lbar")
>>> message(STATUS "a = ${a}")
>>> set(a_list ${a})
>>> message(STATUS "a_list = ${a_list}")
>>>
>>> Then the result should be
>>>  -- a = -Lfoo -lbar
>>>  -- a_list = -Lfoo;-lbar
>>
>> No, should it not. How should that be possible? ${a} is not a list, it's
>> a string (ie. it does not contain semi colons).
>>
>> The output is:
>>
>> ,----
>> | -- a = -Lfoo -lbar
>> | -- a_list = -Lfoo -lbar
>> `----
>
> Then explain the detailed difference between the following three:
>   set(a_list -Lfoo -lbar) -> creates a list with "-Lfoo" and "-lbar"

Correct, you could've used

,----
| set(a_list -Lfoo;-lbar)
`----

which is the same.

>   set(a_list ${a}) -> ???

This looks like a single argument to the set macro. But, ${a} is
exploded (I don't know how to better call it) - ie. if ${a} (ie. the
value of the variable a) is a list with a length greater than 1, the
macro is given several arguments, instead of one or none.

>   set(a_list "${a}") -> ???

Double quoting prevents exploding the value of ${a} into multiple
arguments - hence, the macro is given a single argument: a string.

To illustrate:

,----[ test.cmake ]
| function(first arg)
|   message("${arg}")
| endfunction(first)
| 
| set(a_list a b c)
| 
| first(${a_list})
| first("${a_list}")
`----

,----[ cmake -P test.cmake ]
| a
| a;b;c
`----

At the end, set(<var> <z>) will never set <var> to a list, if <z> itself
is no list - no matter whether <z> was quoted or not.

Regards,
Claudio



More information about the CMake mailing list