Reputation: 21831
I have a CMake build with a bunch of different targets A
, B
, C
, etc.
An external application is tasked with building, and currently does so by calling
cmake --build .
However, this builds all targets, and sometimes I only want to build a subset, like A
and B
but not C
.
The --target
flag can only be given once, and only accepts a single target.
I guess I could let CMake generate the appropriate Makefile, and then call make A B
explicitly, but that takes away the nice thing about cmake --build
being build system agnostic.
Is there a nice way to solve this?
Upvotes: 22
Views: 31108
Reputation: 9703
I don't know of a built-in way, but this does it:
$ BUILD_DIR=./cmake-build-debug; cmake --build $BUILD_DIR --target help | awk -F ':' '{print $1}' | grep $YOUR_FILTER | xargs cmake --build $BUILD_DIR --target
That is, take cmake --build $BUILD_DIR --target help
, strip off the trailing :...
stuff from the lines, filter it, then call cmake --build $BUILD_DIR $THAT
(possibly splitting up $THAT
to multiple calls as xargs
sees fit).
Or if you'd rather,
$ BUILD_DIR=./cmake-build-debug; cmake --build $BUILD_DIR --target $(cmake --build $BUILD_DIR --target help | awk -F ':' '{print $1}' | grep $YOUR_FILTER | paste -sd " " -)
which collects your target into one space-separated line with paste -sd " " -
and then calls cmake --build $BUILD_DIR --target $THOSE_SPACE_DELIMITED_TARGETS
.
Upvotes: 0
Reputation: 54589
CMake version 3.15 added support for this feature. Simply list all targets on the command line as follows:
cmake --build . --target Library1 Library2
Upvotes: 38
Reputation:
Maybe not the "nicest" way, but definitely a solution would be to introduce a custom top-level target and make the needed targets depend on it. For example:
cmake_minimum_required(VERSION 3.9) # can be lower
project(demo LANGUAGES C)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/a.c"
[[
#include <stdio.h>
int main(void) { printf("a\n"); return 0; }
]])
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/b.c"
[[
#include <stdio.h>
int main(void) { printf("b\n"); return 0; }
]])
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/c.c"
[[
#include <stdio.h>
int main(void) { printf("c\n"); return 0; }
]])
add_executable(A "${CMAKE_CURRENT_BINARY_DIR}/a.c")
add_executable(B "${CMAKE_CURRENT_BINARY_DIR}/b.c")
add_executable(C "${CMAKE_CURRENT_BINARY_DIR}/c.c")
set(DEMO_ENABLE_TARGETS "" CACHE
STRING "Targets to be built in demo simultaneously (default: none)")
if(NOT "${DEMO_ENABLE_TARGETS}" STREQUAL "")
add_custom_target(enabled_targets)
foreach(target IN LISTS DEMO_ENABLE_TARGETS)
add_dependencies(enabled_targets ${target})
endforeach()
endif()
Then invoke
$ cmake -H. -Bbuild -DDEMO_ENABLE_TARGETS="B;C"
$ cmake --build build --target enabled_targets
and only B
and C
will be built.
Note that you have to specify DEMO_ENABLE_TARGETS
's contents as a list, otherwise it'll break.
Upvotes: 4