Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using subshells or pipes in cmake commands?

I want to add a CMake target which, when made, will trigger the following:

rm $(find "${CMAKE_SOURCE_DIR}" -name "*.rej" -or -name "*.orig")

I tried this:

add_custom_target(pclean
    COMMAND bash -c "rm $(find \"${CMAKE_SOURCE_DIR}\" -name \"*.rej\" -or -name \"*.orig\")")

and this:

 add_custom_target(pclean
     COMMAND bash -c "find "${CMAKE_SOURCE_DIR}" -name \"*.rej\" -or -name \"*.orig\" | xargs rm")

but neither works. How should I do this right? Am I supposed to use something like add_custom_command?

Note: The issue here is not the quotes. Thus if I use:

 add_custom_target(pclean
     COMMAND bash -c "find "${CMAKE_SOURCE_DIR}" -name \"*.rej\" -or -name \"*.orig\"")

I get the list of *.orig and *.rej files.

like image 709
einpoklum Avatar asked Oct 18 '25 18:10

einpoklum


1 Answers

Turning my comment into an answer

I could reproduce your problem and adding the VERBATIM keyword to your add_custom_target() did fix it.

The following did work:

cmake_minimum_required(VERSION 2.6)

project(SubShell NONE)

add_custom_target(
    pclean
    COMMAND bash -c "rm $(find \"${CMAKE_SOURCE_DIR}\" -name \"*.rej\" -or -name \"*.orig\")"
    VERBATIM
)

If you start "escaping" things in your custom command, it's a hint you should use VERBATIM:

All arguments to the commands will be escaped properly for the build tool so that the invoked command receives each argument unchanged. Note that one level of escapes is still used by the CMake language processor before add_custom_target even sees the arguments.

An extract of the generated makefile without VERBATIM:

CMakeFiles/pclean:
    bash -c rm\ $(find\ "/mnt/c/temp/StackOverflow/SubShell"\ -name\ "*.rej"\ -or\ -name\ "*.orig")

and with VERBATIM:

CMakeFiles/pclean:
    bash -c "rm \$$(find \"/mnt/c/temp/StackOverflow/SubShell\" -name \"*.rej\" -or -name \"*.orig\")"

References

  • cmake: when to quote variables?
like image 94
Florian Avatar answered Oct 21 '25 03:10

Florian