Joel
Joel

Reputation: 2035

cmake: variable has appended strings from SET contents, can't use for args in add_custom_command

I have an external file named images.list with following contents:

find "file1.png" add "file2.png"

In my cmake script I grab the file contents with this:

file(READ "images.list" FILE_CONTENTS)

And I create a list or arguments with this:

set(CMD_ARGS --raw --build-list ${FILE_CONTENTS} > "${CMAKE_BINARY_DIR}/image.h")

Later I use CMD_ARGS:

add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/image.h"
    MAIN_DEPENDENCY "${PROJECT_SOURCE_DIR}/images.list"
    WORKING_DIRECTORY ${DATADIR}
    COMMAND gdk-pixbuf-csource
    ARGS ${CMD_ARGS}
    COMMENT "Compilando GLIB resources..."
)

This code works as expected in my Windows 7, but not on Linux: a blank image.h file is created. I debug CMD_ARGS and I see the strings are appended and also cmake include some \ but not in Windows:

--raw--build-listfind \ "file1.png"

Which I expect like this for CMD_ARGS:

--raw --build-list find "file1.png" add "file2.png" > "/a/nice/path/image.h"

So, whay would be the proper way to grab external file contents and use it as arguments? Any one can help on this?

Updated: We must use something like this:

file(READ ${GRESOURCE_FILE_SRC} FILE_CONTENTS)
# Visit: https://stackoverflow.com/a/72735157/2030219
separate_arguments(FILE_CONTENTS_PROCESSED NATIVE_COMMAND ${FILE_CONTENTS})
set(CMD_ARGS --raw --build-list ${FILE_CONTENTS_PROCESSED} > "${CMAKE_BINARY_DIR}/images.h")

in order to get platform-independent file contents as command arguments.

Upvotes: 0

Views: 30

Answers (1)

fabian
fabian

Reputation: 82451

You can use the separate_arguments command to make sure the file contents are converted to a list variable:

file(READ "images.list" FILE_CONTENTS)

message("FILE_CONTENTS:")
set(CMD_ARGS --raw --build-list ${FILE_CONTENTS} > "${CMAKE_BINARY_DIR}/image.h")
foreach(ELEMENT IN LISTS CMD_ARGS)
    message("${ELEMENT}")
endforeach()

separate_arguments(FILE_CONTENTS_PROCESSED UNIX_COMMAND ${FILE_CONTENTS})

message("FILE_CONTENTS_PROCESSED:")
set(CMD_ARGS --raw --build-list ${FILE_CONTENTS_PROCESSED} > "${CMAKE_BINARY_DIR}/image.h")
foreach(ELEMENT IN LISTS CMD_ARGS)
    message("${ELEMENT}")
endforeach()

Output

FILE_CONTENTS:
--raw
--build-list
find "file1.png" add "file2.png"
>
.../image.h
FILE_CONTENTS_PROCESSED:
--raw
--build-list
find
file1.png
add
file2.png
>
.../image.h

You can see that the file contents are no longer treated as a single string after applying separate_arguments so it should work properly for passing multiple arguments to add_custom_command.

Upvotes: 1

Related Questions