1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 | int cmGlobalGenerator::Build(
int jobs, const std::string& /*unused*/, const std::string& bindir,
const std::string& projectName, const std::vector<std::string>& targets,
std::ostream& ostr, const std::string& makeCommandCSTR,
const std::string& config, const cmBuildOptions& buildOptions, bool verbose,
cmDuration timeout, cmSystemTools::OutputOption outputflag,
std::vector<std::string> const& nativeOptions)
{
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
/**
* Run an executable command and put the stdout in output.
*/
cmWorkingDirectory workdir(bindir);
ostr << "Change Dir: '" << bindir << '\'' << std::endl;
if (workdir.Failed()) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
std::string err = cmStrCat("Failed to change directory: ",
std::strerror(workdir.GetLastResult()));
cmSystemTools::Error(err);
ostr << err << std::endl;
return 1;
}
std::string realConfig = config;
if (realConfig.empty()) {
realConfig = this->GetDefaultBuildConfig();
}
int retVal = 0;
cmSystemTools::SetRunCommandHideConsole(true);
std::string outputBuffer;
std::string* outputPtr = &outputBuffer;
std::vector<GeneratedMakeCommand> makeCommand = this->GenerateBuildCommand(
makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose,
buildOptions, nativeOptions);
// Workaround to convince some commands to produce output.
if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
makeCommand.back().RequiresOutputForward) {
outputflag = cmSystemTools::OUTPUT_FORWARD;
}
// should we do a clean first?
if (buildOptions.Clean) {
std::vector<GeneratedMakeCommand> cleanCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
{ "clean" }, realConfig, jobs, verbose,
buildOptions);
ostr << "\nRun Clean Command: " << cleanCommand.front().QuotedPrintable()
<< std::endl;
if (cleanCommand.size() != 1) {
this->GetCMakeInstance()->IssueMessage(MessageType::INTERNAL_ERROR,
"The generator did not produce "
"exactly one command for the "
"'clean' target");
return 1;
}
if (!cmSystemTools::RunSingleCommand(cleanCommand.front().PrimaryCommand,
outputPtr, outputPtr, &retVal,
nullptr, outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
ostr << *outputPtr << "\nGenerator: execution of make clean failed."
<< std::endl;
return 1;
}
ostr << *outputPtr;
}
// now build
std::string makeCommandStr;
std::string outputMakeCommandStr;
bool isWatcomWMake = this->CMakeInstance->GetState()->UseWatcomWMake();
bool needBuildOutput = isWatcomWMake;
std::string buildOutput;
ostr << "\nRun Build Command(s): ";
retVal = 0;
for (auto command = makeCommand.begin();
command != makeCommand.end() && retVal == 0; ++command) {
makeCommandStr = command->Printable();
outputMakeCommandStr = command->QuotedPrintable();
if ((command + 1) != makeCommand.end()) {
makeCommandStr += " && ";
outputMakeCommandStr += " && ";
}
ostr << outputMakeCommandStr << std::endl;
if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr,
outputPtr, &retVal, nullptr,
outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error(
cmStrCat("Generator: execution of make failed. Make command was: ",
makeCommandStr));
ostr << *outputPtr
<< "\nGenerator: execution of make failed. Make command was: "
<< outputMakeCommandStr << std::endl;
return 1;
}
ostr << *outputPtr << std::flush;
if (needBuildOutput) {
buildOutput += *outputPtr;
}
}
ostr << std::endl;
cmSystemTools::SetRunCommandHideConsole(hideconsole);
// The OpenWatcom tools do not return an error code when a link
// library is not found!
if (isWatcomWMake && retVal == 0 &&
buildOutput.find("W1008: cannot open") != std::string::npos) {
retVal = 1;
}
return retVal;
}
|