diff options
-rw-r--r-- | Help/command/add_custom_command.rst | 10 | ||||
-rw-r--r-- | Source/cmLocalVisualStudioGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 12 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/RemoveEmptyCommands-check.cmake | 63 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/RemoveEmptyCommands.cmake | 22 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/RunCMakeTest.cmake | 4 |
6 files changed, 113 insertions, 8 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index d038406..1b0aa14 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -225,3 +225,13 @@ of the following is specified: :command:`add_custom_target` command. ``POST_BUILD`` Run after all other rules within the target have been executed. + +.. note:: + Because generator expressions can be used in custom commands, + it is possible to define ``COMMAND`` lines or whole custom commands + which evaluate to empty strings for certain configurations. + For **Visual Studio 2010 (and newer)** generators these command + lines or custom commands will be omitted for the specific + configuration and no "empty-string-command" will be added. + + This allows to add individual build events for every configuration. diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 41025af..d772d95 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -191,13 +191,17 @@ std::string cmLocalVisualStudioGenerator::ConstructScript( // Write each command on a single line. for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { + // Add this command line. + std::string cmd = ccg.GetCommand(c); + + if (cmd.empty()) { + continue; + } + // Start a new line. script += newline; newline = newline_text; - // Add this command line. - std::string cmd = ccg.GetCommand(c); - // Use "call " before any invocations of .bat or .cmd files // invoked as custom commands. // diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 86099eb..2b3d40f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3536,11 +3536,13 @@ void cmVisualStudio10TargetGenerator::WriteEvent( for (std::vector<cmCustomCommand>::const_iterator i = commands.begin(); i != commands.end(); ++i) { cmCustomCommandGenerator ccg(*i, configName, this->LocalGenerator); - comment += pre; - comment += lg->ConstructComment(ccg); - script += pre; - pre = "\n"; - script += cmVS10EscapeXML(lg->ConstructScript(ccg)); + if (!ccg.HasOnlyEmptyCommandLines()) { + comment += pre; + comment += lg->ConstructComment(ccg); + script += pre; + pre = "\n"; + script += cmVS10EscapeXML(lg->ConstructScript(ccg)); + } } comment = cmVS10EscapeComment(comment); if (this->ProjectType != csproj) { diff --git a/Tests/RunCMake/add_custom_command/RemoveEmptyCommands-check.cmake b/Tests/RunCMake/add_custom_command/RemoveEmptyCommands-check.cmake new file mode 100644 index 0000000..b297044 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/RemoveEmptyCommands-check.cmake @@ -0,0 +1,63 @@ +set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/exe.vcxproj") +if(NOT EXISTS "${vcProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.") + return() +endif() + +set(inGroup FALSE) +set(inCommand FALSE) + +set(expected_Debug + "cmd_1 cmd_1_arg" + "cmd_1_dbg cmd_1_dbg_arg" + "cmd_2_dbg cmd_2_dbg_arg" + "cmd_3_dbg cmd_3_dbg_arg") + +set(expected_Release + "cmd_1 cmd_1_arg" + "cmd_3_rel cmd_3_rel_arg") + +# extract build events +file(STRINGS "${vcProjectFile}" lines) +foreach(line IN LISTS lines) + if(line MATCHES "^ *<ItemDefinitionGroup Condition=.*Configuration.*Platform.*>$") + set(inGroup TRUE) + string(REGEX MATCH "=='(.*)\\|(.*)'" out ${line}) + set(config ${CMAKE_MATCH_1}) + elseif(line MATCHES "^ *</ItemDefinitionGroup>$") + set(inGroup FALSE) + elseif(inGroup) + if(line MATCHES "^ *<Command>.*$") + set(inCommand TRUE) + string(REGEX MATCH "<Command>(.*)" cmd ${line}) + set(currentCommand ${CMAKE_MATCH_1}) + elseif(line MATCHES "^(.*)</Command>$") + string(REGEX MATCH "(.*)</Command>" cmd ${line}) + list(APPEND currentCommand ${CMAKE_MATCH_1}) + set(command_${config} ${currentCommand}) + set(inCommand FALSE) + elseif(inCommand) + list(APPEND currentCommand ${line}) + endif() + endif() +endforeach() + +foreach(config "Debug" "Release") + set(currentName command_${config}) + set(expectedName expected_${config}) + set(strippedCommand "") + if(DEFINED ${currentName}) + foreach(v ${${currentName}}) + if(${v} MATCHES "cmd_") + list(APPEND strippedCommand ${v}) + endif() + endforeach() + if(NOT "${strippedCommand}" STREQUAL + "${${expectedName}}") + message(" - ${strippedCommand}") + message(" + ${${expectedName}}") + set(RunCMake_TEST_FAILED "build event command does not match") + return() + endif() + endif() +endforeach() diff --git a/Tests/RunCMake/add_custom_command/RemoveEmptyCommands.cmake b/Tests/RunCMake/add_custom_command/RemoveEmptyCommands.cmake new file mode 100644 index 0000000..eb190cc --- /dev/null +++ b/Tests/RunCMake/add_custom_command/RemoveEmptyCommands.cmake @@ -0,0 +1,22 @@ +enable_language(CXX) + +# reduce number of configuration types +set(CMAKE_CONFIGURATION_TYPES "Debug" "Release") + +set(main_file "${CMAKE_BINARY_DIR}/main.cpp") +file(WRITE "${main_file}" "test") +add_executable(exe "${main_file}") + +# add one command for all and one for debug only +add_custom_command(TARGET exe + COMMAND "cmd_1" "cmd_1_arg" + COMMAND $<$<CONFIG:Debug>:cmd_1_dbg> $<$<CONFIG:Debug>:cmd_1_dbg_arg>) + +# add command for debug only +add_custom_command(TARGET exe + COMMAND $<$<CONFIG:Debug>:cmd_2_dbg> $<$<CONFIG:Debug>:cmd_2_dbg_arg>) + +# add separate commands for configurations +add_custom_command(TARGET exe + COMMAND $<$<CONFIG:Debug>:cmd_3_dbg> $<$<CONFIG:Debug>:cmd_3_dbg_arg> + COMMAND $<$<CONFIG:Release>:cmd_3_rel> $<$<CONFIG:Release>:cmd_3_rel_arg>) diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake index 397c63d..c12e5aa 100644 --- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake @@ -10,3 +10,7 @@ run_cmake(SourceByproducts) run_cmake(SourceUsesTerminal) run_cmake(TargetImported) run_cmake(TargetNotInDir) + +if(${RunCMake_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") + run_cmake(RemoveEmptyCommands) +endif() |