Perhaps this is impossible and I'm misreading the cmake 3.2 documentation, but I though creating a custom command would create a custom "target" in the Makefile so that I could build the target by invoking the name of the output file. The CMake docs says:
In makefile terms this creates a new target in the following form:
OUTPUT: MAIN_DEPENDENCY DEPENDS COMMAND
so I thought I could then run make OUTPUT
. Perhaps the documentation is confusing CMake targets with Makefile targets?
For example,
add_custom_command(OUTPUT foo_out
COMMAND post_process foo_in > foo_out
DEPENDS foo_in
)
I would like to do
make foo_out
and it will make foo_out
. However, if I do this, I get
make: **** No rule to make target `foo_out`. Stop.
and sure enough, the word "foo_out" doesn't exist anywhere in any file in the cmake binary output directory. If I change it to this
add_custom_target(bar DEPENDS foo_out)
add_custom_command(OUTPUT foo_out COMMAND post_process foo_in > foo_out)
Then I can do
make bar
and I can do
make foo_in
but I still can't do
make foo_out
The problem with make bar
is that it is unintuitive, as the actual file output is foo_out
not bar
.
How do I do this?
In my case, I need to run a special processing step to the standard executable target which inserts optional resources into the ELF file. I would like the ability to have both executables as Makefile targets, so I can build the naked ELF executable as well as the resource-injected ELF executable.
If I was writing a custom Makefile, this is trivial to do!
foo_in: foo.c
$(CC) $< -o $@
foo_out: foo_in
post_process $< > $@
And I can do make foo_in
and make foo_out
.
add_custom_command
does not create a new target. You have to define targets explicitly byadd_executable
,add_library
oradd_custom_target
in order to make them visible to make.If you have to fix things up for deployment, you could
1. use the
install
command (somewhere in your CMakeLists.txt) like this:to store commands which are executed only when you run
make install
in a separate .cmake file. Or if the install target is already reserved for other things or you have more complex stuff going on:2. manually define a deploy target. Once you got that, you can create a custom post-build command which is only executed when you explicitly run make on your deploy target. This allows you to execute commands through a separate target.
In your CMakeLists.txt this could look like:
Both approaches allow you to separate dev builds from expensive ready-to-deploy builds (if I understand correctly, that's the goal here). I would recommend option 1 since it's just cleaner.
Hope this helps!