Xcode: Fix target-name embedding overriding code-sign attributes

Multiple targets embedding the same internal framework dependency with
different code-signing attributes should not overwrite each other in the
generated `PBXBuildFile`.  Extend commit 0282429c5a (Xcode: Fix
XCODE_EMBED_FRAMEWORKS when settings differ across targets, 2024-12-02,
v4.0.0-rc1~358^2) to cover target names.

Remove `FileRefToEmbedBuildFileMap` entirely, forcing CMake to
instantiate a brand-new `PBXBuildFile` reference object with a unique
ref value for every separate target embedding action, matching Xcode's
native multi-target configuration behavior.

Fixes: #27850
This commit is contained in:
halx99
2026-05-27 11:56:16 -04:00
committed by Brad King
parent 442f2f49ac
commit 5ff6ac07e8
6 changed files with 54 additions and 21 deletions
+3 -9
View File
@@ -930,7 +930,6 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
this->FileRefs.clear();
this->ExternalLibRefs.clear();
this->FileRefToBuildFileMap.clear();
this->FileRefToEmbedBuildFileMap.clear();
this->CommandsVisited.clear();
}
@@ -4428,14 +4427,9 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
" is missing product reference"));
continue;
}
auto it = this->FileRefToEmbedBuildFileMap.find(fileRefObject);
if (it == this->FileRefToEmbedBuildFileMap.end()) {
buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
buildFile->AddAttribute("fileRef", fileRefObject);
this->FileRefToEmbedBuildFileMap[fileRefObject] = buildFile;
} else {
buildFile = it->second;
}
buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
buildFile->SetComment(xcTarget->GetComment());
buildFile->AddAttribute("fileRef", fileRefObject);
} else if (cmSystemTools::IsPathToFramework(relFile) ||
cmSystemTools::IsPathToMacOSSharedLibrary(relFile) ||
cmSystemTools::FileIsDirectory(filePath)) {
-1
View File
@@ -381,7 +381,6 @@ private:
std::map<std::string, cmXCodeObject*> ExternalLibRefs;
std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
std::map<cmXCodeObject*, cmXCodeObject*> FileRefToEmbedBuildFileMap;
std::vector<std::string> Architectures;
std::string ObjectDirArchDefault;
std::string ObjectDirArch;
@@ -0,0 +1,3 @@
include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake)
findAttribute(${test} "CodeSignOnCopy" TRUE 2)
@@ -0,0 +1,20 @@
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
add_library(MTestLib SHARED TestLib/TestLib.c TestLib/TestLib.h)
set_target_properties(MTestLib PROPERTIES
FRAMEWORK 1
PUBLIC_HEADER TestLib/TestLib.h
)
add_executable(mapp1 MACOSX_BUNDLE main.m)
add_executable(mapp2 MACOSX_BUNDLE main.m)
set_target_properties(mapp1 PROPERTIES
XCODE_EMBED_FRAMEWORKS MTestLib
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
)
set_target_properties(mapp2 PROPERTIES
XCODE_EMBED_FRAMEWORKS MTestLib
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
)
@@ -57,6 +57,19 @@ block()
)
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/EmbedFrameworksMultiTargets-build)
run_cmake(EmbedFrameworksMultiTargets)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(EmbedFrameworksMultiTargets-build
${CMAKE_COMMAND} --build .
--config Debug
--target MTestLib
--target mapp1
--target mapp2
)
endblock()
function(TestAppExtension platform)
set(testName EmbedAppExtensions-${platform})
if(NOT platform STREQUAL "macOS")
@@ -1,19 +1,23 @@
cmake_policy(VERSION 3.1...3.20)
function(findAttribute project attr expectPresent)
set(expectCount ${ARGV3})
if(NOT expectPresent)
set(expectCount 0)
endif()
execute_process(
COMMAND grep ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj
OUTPUT_VARIABLE output_var
RESULT_VARIABLE result_var
COMMAND grep -c ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj
OUTPUT_VARIABLE actualCount
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(${expectPresent})
if(result_var)
set(RunCMake_TEST_FAILED "${attr} attribute is not set" PARENT_SCOPE)
endif()
else()
if(NOT result_var)
set(RunCMake_TEST_FAILED "${attr} attribute is set" PARENT_SCOPE)
endif()
if(NOT actualCount MATCHES "^[0-9]+$")
set(actualCount 0)
endif()
if(NOT ("${expectCount}" STREQUAL "") AND NOT (actualCount EQUAL expectCount))
set(RunCMake_TEST_FAILED "${attr} expected ${expectCount} matches, but found ${actualCount}" PARENT_SCOPE)
endif()
endfunction()