I try to run some basic commands for my CLion projects, but it just doesn't work. Here is my CMake setting.
cmake_minimum_required(VERSION 3.6)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(hello ${SOURCE_FILES})
add_custom_command(OUTPUT hello.out
COMMAND ls -l hello
DEPENDS hello)
add_custom_target(run_hello_out
DEPENDS hello.out)
I got the following error messages when running run_hello_out in CLion.
[100%] Generating hello.out
process_begin: CreateProcess(NULL, ls -l hello, ...) failed.
make (e=2): The system cannot find the file specified.
mingw32-make.exe[3]: *** [hello.out] Error 2
mingw32-make.exe[2]: *** [CMakeFiles/run_hello_out.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/run_hello_out.dir/rule] Error 2
mingw32-make.exe: *** [run_hello_out] Error 2
CMakeFiles\run_hello_out.dir\build.make:59: recipe for target 'hello.out' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/run_hello_out.dir/all' failed
CMakeFiles\Makefile2:73: recipe for target 'CMakeFiles/run_hello_out.dir/rule' failed
Makefile:117: recipe for target 'run_hello_out' failed
It is supposed to run "ls -l hello" and see the results in either build window or run window.
The Problem
CMake doesn't guaranty a shell context for its COMMAND
calls and it doesn't automatically search for the executable given with COMMAND
itself.
It mainly puts the given command into the generated build environment and depends on how it's handled there.
In your case I assume you/CLion is running cmake
and mingw32-make
in a MS Windows cmd
shell. In this case you would have had to use the dir
instead of the ls
command:
add_custom_target(
run_hello_out
COMMAND dir $<TARGET_FILE_NAME:hello>
DEPENDS hello
)
Possible Soltions
I see three possible solutions. Either
Provide a bash
shell context
include(FindUnixCommands)
if (BASH)
add_custom_target(
run_hello_out
COMMAND ${BASH} -c "ls -l hello"
DEPENDS hello
)
endif()
Use CMake's shell abstraction cmake -E
(only limited number of commands, e.g. no ls
equivalent)
add_custom_target(
run_hello_out
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_FILE:hello>
DEPENDS hello
)
Search for the executable with find_program()
.
find_program(LS ls)
if (LS)
add_custom_target(
run_hello_out
COMMAND ${LS} -l hello
DEPENDS hello
endif()
Reference
- How to use redirection in cmake add_test
Somehow ls
doesn't work even I set up the global path correctly. CMake needs full path. The following works and solves the issue.
add_custom_command(OUTPUT hello.out
COMMAND "C:\\FULL PATH HERE\\ls" -l hello
DEPENDS hello)