mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 13:51:33 -06:00
cmake --build: Fix building multiple targets in Xcode workspace
Extend commit 844d79916a (cmake --build: Add support for driving Xcode
workspaces, 2025-06-02) to support multiple `--target` arguments.
`xcodebuild -scheme` cannot be repeated in a single call, so call it
multiple times instead.
Issue: #26958
Co-Authored-By: Craig Scott <craig.scott@crascit.com>
This commit is contained in:
committed by
Craig Scott
parent
b44bc8d1a5
commit
26869fb4ba
@@ -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()));
|
||||
|
||||
if (!projectName.empty()) {
|
||||
makeCommand.Add(projectFlag, projectPath);
|
||||
}
|
||||
if (cm::contains(targetNames, "clean")) {
|
||||
makeCommand.Add("clean");
|
||||
makeCommand.Add(targetFlag, "ALL_BUILD");
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<std::string> requiredArgs;
|
||||
|
||||
if (isWorkspace) {
|
||||
makeCommand.Add(
|
||||
"-destination",
|
||||
cmStrCat("generic/platform=", this->GetAppleSpecificPlatformName()));
|
||||
requiredArgs.insert(requiredArgs.end(), { "-workspace", workspacePath });
|
||||
} else {
|
||||
requiredArgs.insert(requiredArgs.end(), { "-project", projectPath });
|
||||
}
|
||||
|
||||
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 {
|
||||
requiredArgs.push_back("build");
|
||||
}
|
||||
|
||||
requiredArgs.insert(requiredArgs.end(),
|
||||
{ "-configuration", config.empty() ? "Debug" : config });
|
||||
|
||||
if (isWorkspace) {
|
||||
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) };
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 12)
|
||||
run_cmake(XcodeWorkspace)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(XcodeWorkspace-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(XcodeWorkspace-build2 ${CMAKE_COMMAND} --build . --config Debug --target custom1 custom2)
|
||||
endblock()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
xcodebuild -workspace XcodeWorkspace\.xcworkspace build -scheme ALL_BUILD -destination generic/platform=MacOS
|
||||
xcodebuild -workspace XcodeWorkspace\.xcworkspace build -configuration Debug -destination generic/platform=MacOS -parallelizeTargets -hideShellScriptEnvironment -scheme ALL_BUILD
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.*xcodebuild -workspace XcodeWorkspace\.xcworkspace build -configuration Debug -destination generic/platform=MacOS -parallelizeTargets -hideShellScriptEnvironment -scheme custom1[^
|
||||
]*
|
||||
.*xcodebuild -workspace XcodeWorkspace\.xcworkspace build -configuration Debug -destination generic/platform=MacOS -parallelizeTargets -hideShellScriptEnvironment -scheme custom2[^
|
||||
]*
|
||||
@@ -1,5 +1,7 @@
|
||||
enable_language(C)
|
||||
add_executable(main main.c)
|
||||
add_custom_target(custom1)
|
||||
add_custom_target(custom2)
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/XcodeWorkspace.xcworkspace/contents.xcworkspacedata" [[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace version = "1.0">
|
||||
|
||||
Reference in New Issue
Block a user