[CMake] Tricky problem with variable, whitespace, quotes and shell

Alexander Neundorf a.neundorf-work at gmx.net
Fri Sep 4 13:34:41 EDT 2009


On Thursday 06 August 2009, Asmodehn Shade wrote:
> Hi everyone,
>
> Sorry if this has been answered before, but google doesnt give me anything
> useful...
>
> Lets say I have a list of source files : SOURCES holds : filea.c;fileb.c
> I want to pass them to an external program ( Astyle for example ) so I need
> to have a whitespace separated list
>
> there fore I use the trick here which gives me the correct solution :
> http://www.vtk.org/Wiki/CMake_FAQ#How_to_convert_a_semicolon_separated_list
>_to_a_whitespace_separated_string.3F
>
> So now SPACES_SOURCES holds : "filea.c fileb.c"

Yes, this is now one argument and cmake correctly escapes the space.
But this is not necessary.
Put the following in a CMakeLists.txt and it works:

--------------

cmake_minimum_required(VERSION 2.6)

set(files CMakeLists.txt CMakeLists.txt)

add_custom_target(foo COMMAND cat ${files} )

-------------

By just listing whitespace separated words as arguments cmake considers these 
separate arguments.
I.e. 
add_custom_target(foo COMMAND cat CMakeLists.txt CMakeLists.txt )
is considered 5 arguments to add_custom_target(), i.e. it's a list of 
arguments.
If you just put 
add_custom_target(foo COMMAND cat ${files} )

files is expanded to <begin>CMakeLists.txt CMakeLists.txt<end>
i.e. it results in the same.

Converting a variable which holds a list to a string gives you the semicolons, 
i.e. the following results in only 4 arguments for add_custom_target():
add_custom_target(foo COMMAND cat "${files}" )
Here files "${files}" is expanded to:
<begin>CMakeLists.txt;CMakeLists.txt<end>
this gives:
add_custom_target(foo COMMAND cat CMakeLists.txt;CMakeLists.txt )

That's not what you want.
Now you had set files to just one string, which happened to contain 
whitespace, as in here:
set(files "CMakeLists.txt CMakeLists.txt")
If you then do
add_custom_target(foo COMMAND cat ${files} )
files is expanded to <begin>"CMakeLists.txt CMakeLists.txt"<end>
in order to preserve the whitespace. (That's also not what you want, just use 
what I showed at the top of the mail).

Alex


More information about the CMake mailing list