|
|
@@ -548,62 +548,92 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
|
|
|
int jobs, bool /*verbose*/, cmBuildOptions const& /*buildOptions*/,
|
|
|
std::vector<std::string> const& makeOptions)
|
|
|
{
|
|
|
+ std::string const xcodebuild =
|
|
|
+ this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand());
|
|
|
+
|
|
|
+ std::string const workspacePath = cmStrCat(projectName, ".xcworkspace");
|
|
|
+ std::string const projectPath = cmStrCat(projectName, ".xcodeproj");
|
|
|
+
|
|
|
// If an external tool created a workspace then build it instead.
|
|
|
- std::string projectPath = cmStrCat(projectName, ".xcworkspace");
|
|
|
- bool const isWorkspace = cmSystemTools::FileIsDirectory(projectPath);
|
|
|
- if (!isWorkspace) {
|
|
|
- projectPath = cmStrCat(projectName, ".xcodeproj");
|
|
|
- }
|
|
|
+ bool const isWorkspace = cmSystemTools::FileIsDirectory(workspacePath);
|
|
|
|
|
|
std::string const targetFlag = isWorkspace ? "-scheme" : "-target";
|
|
|
- std::string const projectFlag = isWorkspace ? "-workspace" : "-project";
|
|
|
|
|
|
- GeneratedMakeCommand makeCommand;
|
|
|
- // now build the test
|
|
|
- makeCommand.Add(
|
|
|
- this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand()));
|
|
|
+ std::vector<std::string> requiredArgs;
|
|
|
|
|
|
- if (!projectName.empty()) {
|
|
|
- makeCommand.Add(projectFlag, projectPath);
|
|
|
+ if (isWorkspace) {
|
|
|
+ requiredArgs.insert(requiredArgs.end(), { "-workspace", workspacePath });
|
|
|
+ } else {
|
|
|
+ requiredArgs.insert(requiredArgs.end(), { "-project", projectPath });
|
|
|
}
|
|
|
- if (cm::contains(targetNames, "clean")) {
|
|
|
- makeCommand.Add("clean");
|
|
|
- makeCommand.Add(targetFlag, "ALL_BUILD");
|
|
|
+
|
|
|
+ bool const isCleanBuild = cm::contains(targetNames, "clean");
|
|
|
+ bool const isTargetEmpty = targetNames.empty() ||
|
|
|
+ ((targetNames.size() == 1) && targetNames.front().empty());
|
|
|
+
|
|
|
+ if (isCleanBuild) {
|
|
|
+ requiredArgs.push_back("clean");
|
|
|
} else {
|
|
|
- makeCommand.Add("build");
|
|
|
- if (targetNames.empty() ||
|
|
|
- ((targetNames.size() == 1) && targetNames.front().empty())) {
|
|
|
- makeCommand.Add(targetFlag, "ALL_BUILD");
|
|
|
- } else {
|
|
|
- for (auto const& tname : targetNames) {
|
|
|
- if (!tname.empty()) {
|
|
|
- makeCommand.Add(targetFlag, tname);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ requiredArgs.push_back("build");
|
|
|
}
|
|
|
|
|
|
+ requiredArgs.insert(requiredArgs.end(),
|
|
|
+ { "-configuration", config.empty() ? "Debug" : config });
|
|
|
+
|
|
|
if (isWorkspace) {
|
|
|
- makeCommand.Add(
|
|
|
- "-destination",
|
|
|
- cmStrCat("generic/platform=", this->GetAppleSpecificPlatformName()));
|
|
|
+ requiredArgs.insert(
|
|
|
+ requiredArgs.end(),
|
|
|
+ { "-destination",
|
|
|
+ cmStrCat("generic/platform=", this->GetAppleSpecificPlatformName()) });
|
|
|
}
|
|
|
|
|
|
if ((this->XcodeBuildSystem >= BuildSystem::Twelve) ||
|
|
|
(jobs != cmake::NO_BUILD_PARALLEL_LEVEL)) {
|
|
|
- makeCommand.Add("-parallelizeTargets");
|
|
|
+ requiredArgs.push_back("-parallelizeTargets");
|
|
|
}
|
|
|
- makeCommand.Add("-configuration", (config.empty() ? "Debug" : config));
|
|
|
|
|
|
if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
|
|
|
(jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
|
|
|
- makeCommand.Add("-jobs", std::to_string(jobs));
|
|
|
+ requiredArgs.insert(requiredArgs.end(), { "-jobs", std::to_string(jobs) });
|
|
|
}
|
|
|
|
|
|
if (this->XcodeVersion >= 70) {
|
|
|
- makeCommand.Add("-hideShellScriptEnvironment");
|
|
|
+ requiredArgs.push_back("-hideShellScriptEnvironment");
|
|
|
}
|
|
|
- makeCommand.Add(makeOptions.begin(), makeOptions.end());
|
|
|
+
|
|
|
+ requiredArgs.insert(requiredArgs.end(), makeOptions.begin(),
|
|
|
+ makeOptions.end());
|
|
|
+
|
|
|
+ if (isWorkspace && !isCleanBuild && targetNames.size() > 1) {
|
|
|
+ // For workspaces we need a separate command for each target,
|
|
|
+ // because xcodebuild can pass only one -scheme arg
|
|
|
+ std::vector<GeneratedMakeCommand> makeCommands;
|
|
|
+ for (auto const& target : targetNames) {
|
|
|
+ if (target.empty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ GeneratedMakeCommand makeCommand;
|
|
|
+ makeCommand.Add(xcodebuild);
|
|
|
+ makeCommand.Add(requiredArgs.cbegin(), requiredArgs.cend());
|
|
|
+ makeCommand.Add(targetFlag, target);
|
|
|
+ makeCommands.emplace_back(std::move(makeCommand));
|
|
|
+ }
|
|
|
+ return makeCommands;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isTargetEmpty || isCleanBuild) {
|
|
|
+ requiredArgs.insert(requiredArgs.end(), { targetFlag, "ALL_BUILD" });
|
|
|
+ } else {
|
|
|
+ for (auto const& target : targetNames) {
|
|
|
+ if (target.empty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ requiredArgs.insert(requiredArgs.end(), { targetFlag, target });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GeneratedMakeCommand makeCommand;
|
|
|
+ makeCommand.Add(xcodebuild);
|
|
|
+ makeCommand.Add(requiredArgs.cbegin(), requiredArgs.cend());
|
|
|
return { std::move(makeCommand) };
|
|
|
}
|
|
|
|