cmake: Teach --build to reject multiple --target options

Previously we did not clearly document that `--target` is only supported
to be specified once.  Even worse, specifying it multiple times would
silently ignore any previously specified targets and only build the last
target.

Update the documentation to specify this.  Update the implementation to
reject multiple `--target` options to prevent user errors.
This commit is contained in:
Sebastian Schuberth 2016-02-04 12:36:44 +01:00 committed by Brad King
parent 886acd80f0
commit 497cad7c88
7 changed files with 28 additions and 1 deletions

View File

@ -58,6 +58,7 @@ Options
<dir> = Project binary directory to be built. <dir> = Project binary directory to be built.
--target <tgt> = Build <tgt> instead of default targets. --target <tgt> = Build <tgt> instead of default targets.
May only be specified once.
--config <cfg> = For multi-configuration tools, choose <cfg>. --config <cfg> = For multi-configuration tools, choose <cfg>.
--clean-first = Build target 'clean' first, then build. --clean-first = Build target 'clean' first, then build.
(To clean only, use --target 'clean'.) (To clean only, use --target 'clean'.)

View File

@ -0,0 +1,6 @@
error-multiple-targets
----------------------
* The :manual:`cmake(1)` ``--build`` command-line tool now rejects multiple
``--target`` options with an error instead of silently ignoring all but the
last one.

View File

@ -60,6 +60,7 @@ static const char * cmDocumentationUsageNote[][2] =
#define CMAKE_BUILD_OPTIONS \ #define CMAKE_BUILD_OPTIONS \
" <dir> = Project binary directory to be built.\n" \ " <dir> = Project binary directory to be built.\n" \
" --target <tgt> = Build <tgt> instead of default targets.\n" \ " --target <tgt> = Build <tgt> instead of default targets.\n" \
" May only be specified once.\n" \
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
" --clean-first = Build target 'clean' first, then build.\n" \ " --clean-first = Build target 'clean' first, then build.\n" \
" (To clean only, use --target 'clean'.)\n" \ " (To clean only, use --target 'clean'.)\n" \
@ -386,6 +387,7 @@ static int do_build(int ac, char const* const* av)
std::string dir; std::string dir;
std::vector<std::string> nativeOptions; std::vector<std::string> nativeOptions;
bool clean = false; bool clean = false;
bool hasTarget = false;
enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative}; enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative};
Doing doing = DoingDir; Doing doing = DoingDir;
@ -397,7 +399,17 @@ static int do_build(int ac, char const* const* av)
} }
else if(strcmp(av[i], "--target") == 0) else if(strcmp(av[i], "--target") == 0)
{ {
doing = DoingTarget; if (!hasTarget)
{
doing = DoingTarget;
hasTarget = true;
}
else
{
std::cerr << "'--target' may not be specified more than once.\n\n";
dir = "";
break;
}
} }
else if(strcmp(av[i], "--config") == 0) else if(strcmp(av[i], "--config") == 0)
{ {

View File

@ -0,0 +1,3 @@
^'--target' may not be specified more than once\.
+
Usage: cmake --build <dir> \[options\] \[-- \[native-options\]\]

View File

@ -3,3 +3,5 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
) )
add_custom_target(CustomTarget ALL DEPENDS output.txt) add_custom_target(CustomTarget ALL DEPENDS output.txt)
add_custom_target(CustomTarget2 ALL DEPENDS output.txt)
add_custom_target(CustomTarget3 ALL DEPENDS output.txt)

View File

@ -51,6 +51,8 @@ function(run_BuildDir)
run_cmake(BuildDir) run_cmake(BuildDir)
run_cmake_command(BuildDir--build ${CMAKE_COMMAND} -E chdir .. run_cmake_command(BuildDir--build ${CMAKE_COMMAND} -E chdir ..
${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget) ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
run_cmake_command(BuildDir--build-multiple-targets ${CMAKE_COMMAND} -E chdir ..
${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget2 --target CustomTarget3)
endfunction() endfunction()
run_BuildDir() run_BuildDir()