I am contributing a custom feature--say, MyFeature--to a project that uses CMake and has separate source and build directories. MyFeature consists of a single binary file. (MyFeature is in fact a custom Simulink library, so I have to invoke MATLAB to create it--the important thing here is that creating the object does not involve GCC or the other standard build tools that CMake uses by default.) So I have a special rule to build the object--let's say myRule. I want make to run myRule only if (a) MyFeature does not exist, or (b) the one source file on which MyFeature depends--say, MySource--is newer than the currently-existing MyFeature. A small added wrinkle is that I only really need MyFeature in the source tree, which is where myRule normally places it. How can I accomplish all this?
I cannot use either add_executable or add_library, as far as I can tell, because they are designed narrowly for objects that you build using the GCC (or otherwise already-configured) toolchain. I cannot use add_custom_target, because the resulting target is always out of date. So far, I have made some progress using a combination of add_custom_target and add_custom_command, as follows:
add_custom_target(fakeTarget
DEPENDS MyFeature)
add_custom_command(OUTPUT MyFeature
COMMAND myRule && touch ${CMAKE_CURRENT_BINARY_DIR}/MyFeature
DEPENDS mySource)
add_dependencies(targetThatAlwaysRuns fakeTarget)
The command to create an empty MyFeature file in the build tree seems sufficient to fake make into not rebuilding if the real MyFeature exists (in the source tree), which accomplishes one of my goals. However, once this fake file exists, even if I update MySource in the source tree, make does not rebuild MyFeature. This is where I am stuck. It seems especially puzzling because I can see in the CMakeFiles innards that there is a target for MyFeature that does indeed list MySource (with the correct path--in the source tree!) as a dependency. If I were to try to replicate this situation with a much simpler (toy) Makefile in a single directory, if I update one of the source files on which the target depends, even if the target output file already exists, make will do the right thing--it will rebuild the object from the updated source and then rebuild the overall target. So why is the build behavior in this situation different? And what can I do to accomplish goal (b) along with goal (a)? Thanks!