mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 13:20:47 -06:00
Xcode: Fix POST_BUILD order in bundle targets on Xcode 16+
XCode 16+ no longer delays our POST_BUILD phase until after bundle files like `Info.plist` are generated. Teach the Xcode generator to add explicit dependencies to the POST_BUILD phase in bundle targets to ensure the files are created before it runs. Fixes: #26656
This commit is contained in:
committed by
Brad King
parent
b18513105c
commit
2dc8c1d45f
@@ -1814,9 +1814,37 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
|
||||
// create prelink phase
|
||||
preLinkPhase =
|
||||
this->CreateRunScriptBuildPhase("CMake PreLink Rules", gtgt, prelink);
|
||||
|
||||
std::vector<std::string> depends;
|
||||
if (gtgt->IsBundleOnApple()) {
|
||||
// In Xcode 16+ the POST_BUILD phase needs explicit dependencies to
|
||||
// ensure it runs after certain bundle files are generated.
|
||||
depends = {
|
||||
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/"
|
||||
"Contents/Resources/DWARF/${PRODUCT_NAME}",
|
||||
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/"
|
||||
"Contents/Info.plist",
|
||||
"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
|
||||
"$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)",
|
||||
};
|
||||
if (resourceBuildPhase) {
|
||||
auto resourceFiles = resourceBuildPhase->GetAttribute("files");
|
||||
for (auto xsf : resourceFiles->GetObjectList()) {
|
||||
auto fileRef = xsf->GetAttribute("fileRef");
|
||||
auto fileObj = fileRef->GetObject();
|
||||
auto path = fileObj->GetAttribute("path");
|
||||
auto fileName = cmSystemTools::GetFilenameName(path->GetString());
|
||||
if (cmSystemTools::GetFilenameLastExtension(fileName) == ".plist") {
|
||||
depends.push_back(
|
||||
"$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/" +
|
||||
fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// create postbuild phase
|
||||
postBuildPhase = this->CreateRunScriptBuildPhase("CMake PostBuild Rules",
|
||||
gtgt, postbuild);
|
||||
gtgt, postbuild, depends);
|
||||
} else {
|
||||
std::vector<cmSourceFile*> classes;
|
||||
if (!gtgt->GetConfigCommonSourceFilesForXcode(classes)) {
|
||||
@@ -2030,7 +2058,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
std::string const& name, cmGeneratorTarget const* gt,
|
||||
std::vector<cmCustomCommand> const& commands)
|
||||
std::vector<cmCustomCommand> const& commands,
|
||||
std::vector<std::string> const& depends)
|
||||
{
|
||||
if (commands.empty()) {
|
||||
return nullptr;
|
||||
@@ -2065,6 +2094,13 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
buildPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
|
||||
buildPhase->AddAttribute("shellScript", this->CreateString(shellScript));
|
||||
buildPhase->AddAttribute("showEnvVarsInLog", this->CreateString("0"));
|
||||
{
|
||||
cmXCodeObject* inputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
for (std::string const& s : depends) {
|
||||
inputPaths->AddUniqueObject(this->CreateString(s));
|
||||
}
|
||||
buildPhase->AddAttribute("inputPaths", inputPaths);
|
||||
}
|
||||
{
|
||||
cmXCodeObject* outputPaths =
|
||||
this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
|
||||
@@ -296,7 +296,8 @@ private:
|
||||
cmCustomCommand const& cc);
|
||||
cmXCodeObject* CreateRunScriptBuildPhase(
|
||||
std::string const& name, cmGeneratorTarget const* gt,
|
||||
std::vector<cmCustomCommand> const& commands);
|
||||
std::vector<cmCustomCommand> const& commands,
|
||||
std::vector<std::string> const& depends = {});
|
||||
std::string ConstructScript(cmCustomCommandGenerator const& ccg);
|
||||
void CreateReRunCMakeFile(cmLocalGenerator* root,
|
||||
std::vector<cmLocalGenerator*> const& gens);
|
||||
|
||||
15
Tests/RunCMake/XcodeProject/BundlePostBuild.cmake
Normal file
15
Tests/RunCMake/XcodeProject/BundlePostBuild.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
enable_language(CXX)
|
||||
add_executable(app MACOSX_BUNDLE app.cxx)
|
||||
add_library(fw SHARED fw.cxx)
|
||||
set_property(TARGET fw PROPERTY FRAMEWORK 1)
|
||||
foreach(target IN ITEMS app fw)
|
||||
set_property(TARGET ${target} PROPERTY XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
|
||||
add_custom_command(
|
||||
TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E sha256sum
|
||||
[["$DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME/Contents/Resources/DWARF/$PRODUCT_NAME"]]
|
||||
[["$DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME/Contents/Info.plist"]]
|
||||
[["$TARGET_BUILD_DIR/$EXECUTABLE_PATH"]]
|
||||
[["$TARGET_BUILD_DIR/$INFOPLIST_PATH"]]
|
||||
)
|
||||
endforeach()
|
||||
@@ -91,6 +91,13 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 12)
|
||||
|
||||
XcodeObjectLibsInTwoProjectsMacOS()
|
||||
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BundlePostBuild-build)
|
||||
run_cmake(BundlePostBuild)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(BundlePostBuild-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
endblock()
|
||||
|
||||
endif()
|
||||
|
||||
function(XcodeSchemaGeneration)
|
||||
|
||||
4
Tests/RunCMake/XcodeProject/app.cxx
Normal file
4
Tests/RunCMake/XcodeProject/app.cxx
Normal file
@@ -0,0 +1,4 @@
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
4
Tests/RunCMake/XcodeProject/fw.cxx
Normal file
4
Tests/RunCMake/XcodeProject/fw.cxx
Normal file
@@ -0,0 +1,4 @@
|
||||
int fw()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user