mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Follow-up commit 1fa2ec1bbd (Xcode: Use deterministic object ids for
targets, 2024-04-04, v3.30.0-rc1~263^2). Each target's product
PBXFileReference (the libfoo.a / foo entries under the Products group)
was created with a random object id on every regeneration. When a
CMake-generated Xcode project is embedded in another Xcode project, that
parent keeps the product reference's id in its remoteGlobalIDString; a
random id means the reference no longer resolves and the link falls back
to a bare `-l` flag (e.g. `ld: library 'foo' not found`).
Derive the product PBXFileReference id from the target name and the
build-tree-relative product path, the same hashing path already used for
the target object id. The id is now stable across regenerations and
independent of the absolute build tree location.
50 lines
1.7 KiB
CMake
50 lines
1.7 KiB
CMake
# Collect "path -> object id" for every product PBXFileReference (those under
|
|
# BUILT_PRODUCTS_DIR) in a generated project.pbxproj.
|
|
function(read_product_ids pbxproj out_var)
|
|
if(NOT EXISTS "${pbxproj}")
|
|
set(RunCMake_TEST_FAILED "Project file does not exist:\n ${pbxproj}" PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
set(ids "")
|
|
file(STRINGS "${pbxproj}" lines)
|
|
foreach(line IN LISTS lines)
|
|
if(line MATCHES "isa = PBXFileReference;" AND line MATCHES "sourceTree = BUILT_PRODUCTS_DIR;")
|
|
string(REGEX MATCH "^[ \t]*([0-9A-F]+) " _ "${line}")
|
|
set(id "${CMAKE_MATCH_1}")
|
|
string(REGEX MATCH "path = ([^;]+);" _ "${line}")
|
|
set(path "${CMAKE_MATCH_1}")
|
|
list(APPEND ids "${path}=${id}")
|
|
endif()
|
|
endforeach()
|
|
list(SORT ids)
|
|
set(${out_var} "${ids}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
set(pbxproj "${RunCMake_TEST_BINARY_DIR}/DeterministicProductIds.xcodeproj/project.pbxproj")
|
|
read_product_ids("${pbxproj}" this_ids)
|
|
if(RunCMake_TEST_FAILED)
|
|
return()
|
|
endif()
|
|
|
|
if(NOT this_ids)
|
|
set(RunCMake_TEST_FAILED "No product PBXFileReference entries found in\n ${pbxproj}")
|
|
return()
|
|
endif()
|
|
|
|
# On the second generation, compare against the first build tree. The ids must
|
|
# be byte-identical even though the build tree path differs.
|
|
if(DEFINED DeterministicProductIds_FirstBinaryDir)
|
|
read_product_ids(
|
|
"${DeterministicProductIds_FirstBinaryDir}/DeterministicProductIds.xcodeproj/project.pbxproj"
|
|
first_ids)
|
|
if(RunCMake_TEST_FAILED)
|
|
return()
|
|
endif()
|
|
if(NOT this_ids STREQUAL first_ids)
|
|
string(REPLACE ";" "\n " a "${first_ids}")
|
|
string(REPLACE ";" "\n " b "${this_ids}")
|
|
set(RunCMake_TEST_FAILED
|
|
"Product PBXFileReference ids are not deterministic across build trees.\nFirst:\n ${a}\nSecond:\n ${b}")
|
|
endif()
|
|
endif()
|