Why can't this work? add_custom_command, add_custom_target?

Can anyone tell me why the below does not work correctly?

I meant to do this:

If timer_cx.h is changed, then timer_cx.c should be recompiled and timer_cx.c.obj should be generated
Then, MY_Project should be re-built, because timer_cx.c.obj has changed

But when I execute “make all”:
timer_cx.c.obj is regenerated, but
MY_Project is not rebuilt, ie. MY_Project.exe is not re-generated ← Why?

add_executable(MY_Project ${SOURCE})

set(IF_f “${CMAKE_CURRENT_SOURCE_DIR}/timer/timer_cx.h”)

add_custom_command(
OUTPUT “${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MY_Project.dir/timer/src/timer_cx.c.obj”
COMMAND ${CMAKE_CXX_COMPILER} -subcommand=${COMPFILE} -debug -nofpu -output=obj=${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MY_Project.dir/timer/src/timer_cx.c.obj ${CMAKE_CURRENT_SOURCE_DIR}/timer/src/timer_cx.c
DEPENDS ${IF_f}
VERBATIM
)

add_custom_target(
what ALL
DEPENDS “${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MY_Project.dir/timer/src/timer_cx.c.obj”
VERBATIM
)

Why are you running the compiler manually in a custom command? What’s wrong with just adding timer_cx.c to the list of sources for your executable?

Either way, it doesn’t work because MY_Project has no idea that it is supposed to include the object file you’re creating here.

Dear Ben,

Either way, it doesn’t work because MY_Project has no idea that it is supposed to include the object file you’re creating here.

I also suspect the mistake is there, which means MY_Project is not ‘sensitive’ to changes in the object file

However, the custom target what has been added to ALL already:

add_custom_target(
what ALL
DEPENDS “${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MY_Project.dir/timer/src/timer_cx.c.obj”
VERBATIM
)

Doesn’t the above establish the dependency between the custom target and my executable target?
Unless my understanding of ALL target is wrong?

Or should it be like this:

add_custom_target(
what ${CMAKE_PROJECT_NAME}
DEPENDS “${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MY_Project.dir/timer/src/timer_cx.c.obj”
VERBATIM
)

ALL just means the custom target is run in the default set of targets when running the build without a specific list of targets given. It has zero relation to any other target in the project.

Again, why is listing timer_cx.c as a source of your executable not sufficient?

Dear Ben,

Again, why is listing timer_cx.c as a source of your executable not sufficient?

timer_cx.c in fact is listed as a source of the executable already, ${SOURCE} actually includes all *.c file

Either way, it doesn’t work because MY_Project has no idea that it is supposed to include the object file you’re creating here.

I managed to get it to work based on your comment above! I added add_dependencies:

add_custom_command(OUTPUT …)
add_custom_target(header-target …)
add_dependencies(${CMAKE_PROJECT_NAME} header-target)

Thanks for the clue!