I have a project where I hope to build a binary, named `final_exe`. The
build directory where `final_exe` ends up needs to contain a file called
`final_resource` in order for `final_exe` to be considered "built."

The file `final_resource` is generated by another binary, called
`generating_exe`, which I also build from source as part of my project.
Furthermore, for `generating_exe` to be considered "built" or "usable," a
file called `generating_resource` needs to be present in the directory
where `generating_exe` ends up. The file `generating_resource` is, say,
copied verbatim from the source tree.

There are many binaries in the project whose builds depend on
`generating_exe` (and, transitively, on `generating_resource`) in this
manner.

I can't think of a way to express this dependency graph cleanly in CMake.

First, the easiest thing to do is to add `POST_BUILD` custom commands to
the `final_exe` and `generating_exe` targets. I don't like this approach,
for a couple of reasons. If the copy of `generating_resource` located in
the source tree changes, without some extra work the `POST_BUILD` custom
commands won't get called. Developers would need to somehow convince the
build system to re-link `generating_exe`. (I am not even clear about how to
work around this from within my project's CMake scripts.) Then, even once
`generating_exe` is rebuilt, the developer _again_ has to convince the
build system to re-link `final_exe` (and any other executable, library,
etc., that depends on `final_resource`) in order to obtain a correctly
updated build.

(Suppose that `final_resource` is not a CPP file, etc., so it is not
natural to shove it into the list of sources of `final_exe`.)

(The above problem can be summed up by asking, how do you create a custom
command in the flavor of, e.g., a `POST_BUILD` command invoking
`${CMAKE_COMMAND} -E copy_if_different`, but which will be re-run if the
"source files" of the custom command are modified?)

A nice(r) solution to the above problems would be to create a custom
target, called `copy_generating_resource`, which invokes `${CMAKE_COMMAND}
-E copy_if_different`, and which would be run every build (because those
are the semantics of custom targets). This approach actually solves the
above issues in a reasonable way, except for the following problem:

A natural definition of `copy_generating_resource` involves the use of
`$<TARGET_FILE_DIR:generating_exe>` to specify the directory into which to
place `generating_resource`, which would make `copy_generating_resource` a
dependency of `generating_exe`. It is natural that `final_exe` depends on
`generating_exe`. However `generating_exe` is not actually usable until
`copy_generating_resource` is run. Furthermore, we cannot even awkwardly
declare `copy_generating_resource` to be a dependency of `generating_exe`,
because there is already a dependency between these two targets going in
the other direction.

It is very annoying to insist that the author of the `CMakeLists.txt` file
corresponding to `final_exe` must be aware that he needs to encode that
`final_exe` depends on `copy_generating_resource` manually. If he fails to
do so, he risks `generating_exe` being run (to generate `final_resource`)
before it is actually usable, in particular, before
`copy_generating_resource` is run.

Am I missing something?

Andrey Mishchenko
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to