8

I'm trying to print messages after building process done using CMake.

I just want to inform the user after make command is done without any error.

How can I do it? I tried add_custom_target() but I cannot choose when to run.

Also, I tried add_custom_command(), again it doesn't give me the right result.

Any idea?

Thank you for your idea in advance.

Genie
  • 185
  • 1
  • 8
  • You wish to print this message when all targets are completed...So this custom target depends on all other targets... Would it be a good idea to `add_dependencies()` ? – francis Aug 11 '14 at 14:43
  • Yes! You're very right! But, the project consists of numerous targets. Is there any way I can get the list of all the targets? – Genie Aug 11 '14 at 15:17

3 Answers3

9

You could, indeed, do the following:

add_custom_target( FinalMessage ALL
    ${CMAKE_COMMAND} -E cmake_echo_color --cyan "Compilation is over!"
    COMMENT "Final Message" )
add_dependencies( FinalMessage ${ALL_TARGETS} )

That custom target depending on the list of all the targets you previously defined, you make sure it will be run last.

xStan
  • 552
  • 4
  • 4
  • 1
    Thanks the reply. I tried just now only to fail. `${ALL_TARGETS}` was just empty. I'm using CMake 2.8.11.2. Is it implemented in CMake above 3.0? – Genie Aug 11 '14 at 16:28
  • Thanks. I tried that before with `Set(ALL_TARGETS ${ALL_TARGETS} "${LIBRARY_NAME}" PARENT_SCOPE)`. but some targets defined in subdirectories loaded by `add_subdirectory()` method don't exist in that list. – Genie Aug 11 '14 at 17:01
5

To print a message after building a specific target, e. g. make yourtarget, you can use

add_custom_command(TARGET yourtarget POST_BUILD
                   COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan
                   "Message after yourtarget has been built.")

Instead of POST_BUILD, you could also use PRE_BUILD or PRE_LINK for other purposes, see documentation.

(You specified in the comments, that you like to print a message after all targets, but the original question is less precise. So it might be of some value for people looking here.)

John
  • 1,472
  • 1
  • 19
  • 22
  • Just note that with this approach, documentation states "If the target is already built, the command will not execute." – sdbbs Oct 03 '22 at 18:13
3

I just resolved the issue with the help of smarquis. Thank you.

Here's the step by step procedure to do it. Since my source tree are connected complicatedly with add_subdirectory() method, this method can be applied everyone.

  1. Initialize ALL_TARGETS variable cached. Add the line in CMakeLists.txt right below the version checking command.

     Set(ALL_TARGETS "" CACHE INTERNAL "")
    
  2. Override Add_library() and Add_executable() methods. If there's any other target, override it as well. Add the lines below at the end of CMakeLists.txt file.

     function(Add_library NAME)
       Set(ALL_TARGETS ${ALL_TARGETS} "${ARGN}" CACHE INTERNAL "ALL_TARGETS")
       _add_library(${NAME} ${ARGN})
     endfunction()
    
     function(Add_executable NAME)
       Set(ALL_TARGETS ${ALL_TARGETS} "${ARGN}" CACHE INTERNAL "ALL_TARGETS")
       _add_executable(${NAME} ${ARGN})
     endfunction()
    
  3. Create custom target that will execute all the things you want to do after building. In this example I just print some information on screen. Add it followed by the above.

     add_custom_target(BUILD_SUCCESSFUL ALL
                       DEPENDS ${ALL_TARGETS}
                       COMMAND ${CMAKE_COMMAND} -E echo ""
                       COMMAND ${CMAKE_COMMAND} -E echo "====================="
                       COMMAND ${CMAKE_COMMAND} -E echo "  Compile complete!"
                       COMMAND ${CMAKE_COMMAND} -E echo "====================="
                       COMMAND ${CMAKE_COMMAND} -E echo ""
                      )
    
  4. Tada!

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
Genie
  • 185
  • 1
  • 8