diff options
-rw-r--r-- | Help/command/add_custom_command.rst | 6 | ||||
-rw-r--r-- | Source/cmGlobalBorlandMakefileGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 85 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmState.cxx | 10 | ||||
-rw-r--r-- | Source/cmState.h | 3 | ||||
-rw-r--r-- | Tests/CustomCommand/CMakeLists.txt | 9 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/BadByproduct.cmake | 4 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/BadOutput-stderr.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/BadOutput.cmake | 4 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_target/BadByproduct.cmake | 4 |
14 files changed, 93 insertions, 65 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index c184a96..77357c0 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -269,6 +269,8 @@ The options are: source tree is mentioned as an absolute source file path elsewhere in the current directory. + The output file path may not contain ``<`` or ``>`` characters. + .. versionadded:: 3.20 Arguments to ``OUTPUT`` may use a restricted set of :manual:`generator expressions <cmake-generator-expressions(7)>`. @@ -280,6 +282,10 @@ The options are: considered private unless they are listed in a non-private file set. See policy :policy:`CMP0154`. + .. versionchanged:: 3.30 + The output file path may now use ``#`` characters, except + when using the :generator:`Borland Makefiles` generator. + ``USES_TERMINAL`` .. versionadded:: 3.2 diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 2fd7f8a..6eabe9c 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -24,6 +24,7 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm) this->ToolSupportsColor = true; this->UseLinkScript = false; cm->GetState()->SetWindowsShell(true); + cm->GetState()->SetBorlandMake(true); this->IncludeDirective = "!include"; this->DefineWindowsNULL = true; this->PassMakeflags = true; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index bf66255..aa948a5 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -264,6 +264,27 @@ cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name, #endif } +namespace { +std::string ConvertToMakefilePath(std::string const& path) +{ + std::string result; + result.reserve(path.size()); + for (char c : path) { + switch (c) { + case '\\': + case ' ': + case '#': + result.push_back('\\'); + CM_FALLTHROUGH; + default: + result.push_back(c); + break; + } + } + return result; +} +} + bool cmGlobalXCodeGenerator::FindMakeProgram(cmMakefile* mf) { // The Xcode generator knows how to lookup its build tool @@ -653,7 +674,7 @@ void cmGlobalXCodeGenerator::AddExtraTargets( if (regenerate && isGenerateProject) { this->CreateReRunCMakeFile(root, gens); std::string file = - this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile); + cmSystemTools::ConvertToOutputPath(this->CurrentReRunCMakeMakefile); cmSystemTools::ReplaceString(file, "\\ ", " "); cc = cm::make_unique<cmCustomCommand>(); cc->SetCommandLines(cmMakeSingleCommandLine({ "make", "-f", file })); @@ -732,7 +753,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( for (const auto& lfile : lfiles) { makefileStream << "TARGETS += $(subst $(space),$(spaceplus),$(wildcard " - << this->ConvertToRelativeForMake(lfile) << "))\n"; + << ConvertToMakefilePath(lfile) << "))\n"; } makefileStream << '\n'; @@ -743,25 +764,25 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( makefileStream << ".NOTPARALLEL:\n\n" ".PHONY: all VERIFY_GLOBS\n\n" "all: VERIFY_GLOBS " - << this->ConvertToRelativeForMake(checkCache) + << ConvertToMakefilePath(checkCache) << "\n\n" "VERIFY_GLOBS:\n" "\t" - << this->ConvertToRelativeForMake( - cmSystemTools::GetCMakeCommand()) + << ConvertToMakefilePath(cmSystemTools::GetCMakeCommand()) << " -P " - << this->ConvertToRelativeForMake(cm->GetGlobVerifyScript()) + << ConvertToMakefilePath(cm->GetGlobVerifyScript()) << "\n\n"; } - makefileStream << this->ConvertToRelativeForMake(checkCache) - << ": $(TARGETS)\n"; - makefileStream - << '\t' << this->ConvertToRelativeForMake(cmSystemTools::GetCMakeCommand()) - << " -S" << this->ConvertToRelativeForMake(root->GetSourceDirectory()) - << " -B" << this->ConvertToRelativeForMake(root->GetBinaryDirectory()) - << (cm->GetIgnoreWarningAsError() ? " --compile-no-warning-as-error" : "") - << '\n'; + makefileStream << ConvertToMakefilePath(checkCache) << ": $(TARGETS)\n"; + makefileStream << '\t' + << ConvertToMakefilePath(cmSystemTools::GetCMakeCommand()) + << " -S" << ConvertToMakefilePath(root->GetSourceDirectory()) + << " -B" << ConvertToMakefilePath(root->GetBinaryDirectory()) + << (cm->GetIgnoreWarningAsError() + ? " --compile-no-warning-as-error" + : "") + << '\n'; } static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l, @@ -2199,11 +2220,10 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase( } std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory(); - cdir = this->ConvertToRelativeForMake(cdir); + cdir = cmSystemTools::ConvertToOutputPath(cdir); std::string makecmd = cmStrCat( - "make -C ", cdir, " -f ", - this->ConvertToRelativeForMake(cmStrCat(makefile, "$CONFIGURATION")), - " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all"); + "make -C ", cdir, " -f ", cmSystemTools::ConvertToOutputPath(makefile), + "$CONFIGURATION", " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all"); buildphase->AddAttribute("shellScript", this->CreateString(makecmd)); buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0")); } @@ -2237,7 +2257,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( const std::vector<std::string>& outputs = ccg.GetOutputs(); if (!outputs.empty()) { for (auto const& output : outputs) { - makefileStream << "\\\n\t" << this->ConvertToRelativeForMake(output); + makefileStream << "\\\n\t" << ConvertToMakefilePath(output); } } else { std::ostringstream str; @@ -2291,7 +2311,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( // There is at least one output, start the rule for it const char* sep = ""; for (auto const& output : outputs) { - makefileStream << sep << this->ConvertToRelativeForMake(output); + makefileStream << sep << ConvertToMakefilePath(output); sep = " "; } makefileStream << ": "; @@ -2300,7 +2320,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( makefileStream << tname[&ccg.GetCC()] << ": "; } for (auto const& dep : realDepends) { - makefileStream << "\\\n" << this->ConvertToRelativeForMake(dep); + makefileStream << "\\\n" << ConvertToMakefilePath(dep); } makefileStream << '\n'; @@ -2317,12 +2337,12 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( // Build the command line in a single string. std::string cmd2 = ccg.GetCommand(c); cmSystemTools::ReplaceString(cmd2, "/./", "/"); - cmd2 = this->ConvertToRelativeForMake(cmd2); + cmd2 = ConvertToMakefilePath(cmd2); std::string cmd; std::string wd = ccg.GetWorkingDirectory(); if (!wd.empty()) { cmd += "cd "; - cmd += this->ConvertToRelativeForMake(wd); + cmd += ConvertToMakefilePath(wd); cmd += " && "; } cmd += cmd2; @@ -2336,7 +2356,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( target->GetLocalGenerator()->GetMakefile()->GetSource( dep, cmSourceFileLocationKind::Known)) { if (dsf->GetPropertyAsBool("SYMBOLIC")) { - makefileStream << this->ConvertToRelativeForMake(dep) << ":\n"; + makefileStream << ConvertToMakefilePath(dep) << ":\n"; } } } @@ -4865,7 +4885,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( gt->GetType() == cmStateEnums::SHARED_LIBRARY || gt->GetType() == cmStateEnums::MODULE_LIBRARY) { std::string tfull = gt->GetFullPath(configName); - std::string trel = this->ConvertToRelativeForMake(tfull); + std::string trel = ConvertToMakefilePath(tfull); // Add this target to the post-build phases of its dependencies. auto const y = target->GetDependTargets().find(configName); @@ -4891,7 +4911,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( auto const x = target->GetDependLibraries().find(configName); if (x != target->GetDependLibraries().end()) { for (auto const& deplib : x->second) { - std::string file = this->ConvertToRelativeForMake(deplib); + std::string file = ConvertToMakefilePath(deplib); makefileStream << "\\\n\t" << file; dummyRules.insert(file); } @@ -4903,7 +4923,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( std::string d = cmStrCat(this->GetTargetTempDir(gt, configName), "/lib", objLibName, ".a"); - std::string dependency = this->ConvertToRelativeForMake(d); + std::string dependency = ConvertToMakefilePath(d); makefileStream << "\\\n\t" << dependency; dummyRules.insert(dependency); } @@ -4911,7 +4931,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( // Write the action to remove the target if it is out of date. makefileStream << "\n" "\t/bin/rm -f " - << this->ConvertToRelativeForMake(tfull) << '\n'; + << ConvertToMakefilePath(tfull) << '\n'; // if building for more than one architecture // then remove those executables as well if (this->Architectures.size() > 1) { @@ -4921,8 +4941,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( std::string universalFile = cmStrCat(universal, architecture, '/', gt->GetFullName(configName)); makefileStream << "\t/bin/rm -f " - << this->ConvertToRelativeForMake(universalFile) - << '\n'; + << ConvertToMakefilePath(universalFile) << '\n'; } } makefileStream << "\n\n"; @@ -5123,12 +5142,6 @@ cmDocumentationEntry cmGlobalXCodeGenerator::GetDocumentation() "Generate Xcode project files." }; } -std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake( - std::string const& p) -{ - return cmSystemTools::ConvertToOutputPath(p); -} - std::string cmGlobalXCodeGenerator::RelativeToSource(const std::string& p) { std::string const& rootSrc = diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 2375e95..14e9308 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -163,7 +163,6 @@ private: std::string RelativeToSource(const std::string& p); std::string RelativeToRootBinary(const std::string& p); std::string RelativeToBinary(const std::string& p); - std::string ConvertToRelativeForMake(std::string const& p); void CreateCustomCommands( cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 22daa0e..1440771 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4403,7 +4403,12 @@ void CreateGeneratedSource(cmLocalGenerator& lg, const std::string& output, } // Make sure the output file name has no invalid characters. - std::string::size_type pos = output.find_first_of("#<>"); + const bool hashNotAllowed = lg.GetState()->UseBorlandMake(); + std::string::size_type pos = output.find_first_of("<>"); + if (pos == std::string::npos && hashNotAllowed) { + pos = output.find_first_of('#'); + } + if (pos != std::string::npos) { lg.GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 72eeb9d..e05eb10 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -716,6 +716,16 @@ bool cmState::UseGhsMultiIDE() const return this->GhsMultiIDE; } +void cmState::SetBorlandMake(bool borlandMake) +{ + this->BorlandMake = borlandMake; +} + +bool cmState::UseBorlandMake() const +{ + return this->BorlandMake; +} + void cmState::SetWatcomWMake(bool watcomWMake) { this->WatcomWMake = watcomWMake; diff --git a/Source/cmState.h b/Source/cmState.h index 5aceb6a..4dc982f 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -213,6 +213,8 @@ public: bool UseWindowsVSIDE() const; void SetGhsMultiIDE(bool ghsMultiIDE); bool UseGhsMultiIDE() const; + void SetBorlandMake(bool borlandMake); + bool UseBorlandMake() const; void SetWatcomWMake(bool watcomWMake); bool UseWatcomWMake() const; void SetMinGWMake(bool minGWMake); @@ -294,6 +296,7 @@ private: bool WindowsShell = false; bool WindowsVSIDE = false; bool GhsMultiIDE = false; + bool BorlandMake = false; bool WatcomWMake = false; bool MinGWMake = false; bool NMake = false; diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index d46ee08..c145907 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -588,3 +588,12 @@ add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt) # Test empty COMMANDs are omitted add_executable(empty_command empty_command.cxx) add_custom_command(TARGET empty_command POST_BUILD COMMAND $<0:date>) + +# Test OUTPUT allows filenames containing "#" on generators that support this +if(NOT CMAKE_GENERATOR MATCHES "Borland Makefiles") + add_custom_target(file_with_hash ALL DEPENDS "${PROJECT_BINARY_DIR}/hash#in#name.txt") + add_custom_command( + OUTPUT "${PROJECT_BINARY_DIR}/hash#in#name.txt" + COMMAND ${CMAKE_COMMAND} -E touch "${PROJECT_BINARY_DIR}/hash#in#name.txt" + ) +endif() diff --git a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt index 547fb1c..5741ae5 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadByproduct-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadByproduct.cmake:2 \(add_custom_command\): - BYPRODUCTS containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadByproduct.cmake:3 \(add_custom_command\): BYPRODUCTS containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadByproduct.cmake:5 \(add_custom_command\): - BYPRODUCTS containing a "#" is not allowed. + BYPRODUCTS containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/BadByproduct.cmake b/Tests/RunCMake/add_custom_command/BadByproduct.cmake index cf00f5b..4fe0b82 100644 --- a/Tests/RunCMake/add_custom_command/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_command/BadByproduct.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_command(OUTPUT a BYPRODUCTS "a#") + add_custom_command(OUTPUT b BYPRODUCTS "a<") add_custom_command(OUTPUT c BYPRODUCTS "a>") -add_custom_command(OUTPUT d BYPRODUCTS "$<CONFIG>/#") +add_custom_command(OUTPUT d BYPRODUCTS "$<CONFIG>/$<ANGLE-R>") add_custom_command(OUTPUT e BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/f) add_custom_command(OUTPUT f BYPRODUCTS "$<TARGET_PROPERTY:prop>") add_custom_command(OUTPUT h BYPRODUCTS "$<OUTPUT_CONFIG:h>") diff --git a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt index 2e43568..9d25949 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt +++ b/Tests/RunCMake/add_custom_command/BadOutput-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadOutput.cmake:2 \(add_custom_command\): - OUTPUT containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadOutput.cmake:3 \(add_custom_command\): OUTPUT containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadOutput.cmake:5 \(add_custom_command\): - OUTPUT containing a "#" is not allowed. + OUTPUT containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/BadOutput.cmake b/Tests/RunCMake/add_custom_command/BadOutput.cmake index f04bdd1..0f6bd07 100644 --- a/Tests/RunCMake/add_custom_command/BadOutput.cmake +++ b/Tests/RunCMake/add_custom_command/BadOutput.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_command(OUTPUT "a#" COMMAND a) + add_custom_command(OUTPUT "a<" COMMAND b) add_custom_command(OUTPUT "a>" COMMAND c) -add_custom_command(OUTPUT "$<CONFIG>/#" COMMAND d) +add_custom_command(OUTPUT "$<CONFIG>/$<ANGLE-R>" COMMAND d) add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/e COMMAND f) add_custom_command(OUTPUT "$<TARGET_PROPERTY:prop>" COMMAND g) add_custom_command(OUTPUT "$<OUTPUT_CONFIG:h>" COMMAND h) diff --git a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt index da9af49..b734ddd 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt +++ b/Tests/RunCMake/add_custom_target/BadByproduct-stderr.txt @@ -1,9 +1,3 @@ -CMake Error at BadByproduct.cmake:2 \(add_custom_target\): - BYPRODUCTS containing a "#" is not allowed. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) - - CMake Error at BadByproduct.cmake:3 \(add_custom_target\): BYPRODUCTS containing a "<" is not allowed. Call Stack \(most recent call first\): @@ -17,7 +11,7 @@ Call Stack \(most recent call first\): ( CMake Error at BadByproduct.cmake:5 \(add_custom_target\): - BYPRODUCTS containing a "#" is not allowed. + BYPRODUCTS containing a ">" is not allowed. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/BadByproduct.cmake b/Tests/RunCMake/add_custom_target/BadByproduct.cmake index c317b83..d29c02f 100644 --- a/Tests/RunCMake/add_custom_target/BadByproduct.cmake +++ b/Tests/RunCMake/add_custom_target/BadByproduct.cmake @@ -1,8 +1,8 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON) -add_custom_target(a BYPRODUCTS "a#" COMMAND b) + add_custom_target(c BYPRODUCTS "a<" COMMAND d) add_custom_target(e BYPRODUCTS "a>" COMMAND f) -add_custom_target(g BYPRODUCTS "$<CONFIG>/#" COMMAND h) +add_custom_target(g BYPRODUCTS "$<CONFIG>/$<ANGLE-R>" COMMAND h) add_custom_target(i BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/j COMMAND k) add_custom_target(l BYPRODUCTS "$<TARGET_PROPERTY:prop>" COMMAND m) add_custom_target(n BYPRODUCTS "$<OUTPUT_CONFIG:n>" COMMAND o) |