I have seen How to print messages after make done with cmake? which in principle should answer my question, but it does not - so here is an example I prepared.
Say I have these two files in /tmp/cmake_test3
:
main.c
:
#include <stdio.h>
const char greeting[] = "hello world";
int main() {
printf("%s!\n", greeting);
return 0;
}
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.7)
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
project(my_project)
message("PROJECT_NAME is '${PROJECT_NAME}'")
# change the behavior by setting variable here to TRUE or FALSE
set(USE_CUSTOM_COMMAND TRUE)
add_executable(my_executable
main.c
)
target_compile_options(my_executable PRIVATE
-Wall
-std=c99
)
if(USE_CUSTOM_COMMAND)
message("Using custom command")
add_custom_command(TARGET my_executable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan
"Executable: $<TARGET_FILE_DIR:my_executable>"
COMMENT "print out executable path"
)
else()
message("Using custom target")
add_custom_target(printout ALL
${CMAKE_COMMAND} -E cmake_echo_color --cyan "PC Executable: $<TARGET_FILE:my_executable>"
COMMENT "print out executable path"
VERBATIM
)
add_dependencies(printout my_executable)
endif()
So, in /tmp/cmake_test3
I do:
mkdir build && cd build
cmake ../ -DCMAKE_BUILD_TYPE=Debug
For the CMakeLists.txt
posted as is, I get the following:
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
PROJECT_NAME is 'my_project'
Using custom command
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake_test3/build
# `make` first time - outputs message printout
$ make
Scanning dependencies of target my_executable
[ 50%] Building C object CMakeFiles/my_executable.dir/main.c.o
[100%] Linking C executable my_executable
print out executable path
Executable: /tmp/cmake_test3/build
[100%] Built target my_executable
# `make` second time - no message printout
$ make
[100%] Built target my_executable
# make clean; then `make my_executable` first time - outputs message printout
$ make clean
$ make my_executable
[ 50%] Building C object CMakeFiles/my_executable.dir/main.c.o
[100%] Linking C executable my_executable
print out executable path
Executable: /tmp/cmake_test3/build
[100%] Built target my_executable
# `make my_executable` second time - no message printout
$ make my_executable
[100%] Built target my_executable
Ok, so now, change the set(USE_CUSTOM_COMMAND TRUE)
to set(USE_CUSTOM_COMMAND FALSE)
in the CmakeLists.txt
, and let's repeat the process - still in the build/ subdirectory:
$ rm -rf *
$ cmake ../ -DCMAKE_BUILD_TYPE=Debug
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
PROJECT_NAME is 'my_project'
Using custom target
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake_test3/build
# `make` first time - outputs message printout
$ make
Scanning dependencies of target my_executable
[ 33%] Building C object CMakeFiles/my_executable.dir/main.c.o
[ 66%] Linking C executable my_executable
[ 66%] Built target my_executable
Scanning dependencies of target printout
[100%] print out executable path
PC Executable: /tmp/cmake_test3/build/my_executable
[100%] Built target printout
# `make` second time - outputs message printout
$ make
[ 66%] Built target my_executable
[100%] print out executable path
PC Executable: /tmp/cmake_test3/build/my_executable
[100%] Built target printout
# make clean; then `make my_executable` first time - no message printout
$ make clean
$ make my_executable
[ 50%] Building C object CMakeFiles/my_executable.dir/main.c.o
[100%] Linking C executable my_executable
[100%] Built target my_executable
# `make my_executable` second time - no message printout
$ make my_executable
[100%] Built target my_executable
So, how do I get a message - specified at CMake level - to print something at end of make
always - that is, regardless of:
- if a binary is built or not,
- whether I call
make
ormake all
ormake my_executable
?