MCPcopy Create free account
hub / github.com/Kitware/CMake / BuildCommandLine

Method BuildCommandLine

Source/cmLocalNinjaGenerator.cxx:499–571  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

497#endif
498
499std::string cmLocalNinjaGenerator::BuildCommandLine(
500 std::vector<std::string> const& cmdLines, std::string const& outputConfig,
501 std::string const& commandConfig, std::string const& customStep,
502 cmGeneratorTarget const* target) const
503{
504 // If we have no commands but we need to build a command anyway, use noop.
505 // This happens when building a POST_BUILD value for link targets that
506 // don't use POST_BUILD.
507 if (cmdLines.empty()) {
508 return cmGlobalNinjaGenerator::SHELL_NOOP;
509 }
510
511 // If this is a custom step then we will have no '$VAR' ninja placeholders.
512 // This means we can deal with long command sequences by writing to a script.
513 // Do this if the command lines are on the scale of the OS limit.
514 if (!customStep.empty()) {
515 size_t cmdLinesTotal = 0;
516 for (std::string const& cmd : cmdLines) {
517 cmdLinesTotal += cmd.length() + 6;
518 }
519 if (cmdLinesTotal > cmSystemTools::CalculateCommandLineLengthLimit() / 2) {
520 std::string const scriptPath = this->WriteCommandScript(
521 cmdLines, outputConfig, commandConfig, customStep, target);
522 std::string cmd
523#ifndef _WIN32
524 = "/bin/sh "
525#endif
526 ;
527 cmd += this->ConvertToOutputFormat(
528 this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(scriptPath),
529 cmOutputConverter::SHELL);
530
531 // Add an unused argument based on script content so that Ninja
532 // knows when the command lines change.
533 cmd += " ";
534 cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
535 cmd += hash.HashFile(scriptPath).substr(0, 16);
536 return cmd;
537 }
538 }
539
540 std::ostringstream cmd;
541#ifdef _WIN32
542 cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator();
543 bool const needCMD =
544 cmdLines.size() > 1 || (customStep.empty() && RuleNeedsCMD(cmdLines[0]));
545 for (auto li = cmdLines.begin(); li != cmdLines.end(); ++li) {
546 if (li != cmdLines.begin()) {
547 cmd << " && ";
548 } else if (needCMD) {
549 cmd << gg->GetComspec() << " /C \"";
550 }
551 // Put current cmdLine in brackets if it contains "||" because it has
552 // higher precedence than "&&" in cmd.exe
553 if (li->find("||") != std::string::npos) {
554 cmd << "( " << *li << " )";
555 } else {
556 cmd << *li;

Callers 10

GetScanRuleFunction · 0.80
WriteCompileRuleMethod · 0.80
WriteDeviceLinkRulesMethod · 0.80
WriteLinkRuleMethod · 0.80
WriteLinkStatementMethod · 0.80

Calls 14

WriteCommandScriptMethod · 0.95
RuleNeedsCMDFunction · 0.85
lengthMethod · 0.80
HashFileMethod · 0.80
GetComspecMethod · 0.80
strMethod · 0.80
emptyMethod · 0.45
ConvertToOutputFormatMethod · 0.45
substrMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected