Fixing a path to the xcpostbuild output file location for build for simulator on M1 machines.
Context
When building on Intel machines, PLATFORM_PREFERRED_ARCH correctly resolves to the "main" architecture of the build. Simulator - x86_64, Hardware iPhone - arm64, hardware AppleWatch - arm64_32 etc.
However, when building on M1 for a native simulator, it resolves to x86_64, even a build compiles only for arm64. This apparently is a bug (filed FB9824531) which could potentially lead to incorrectly skipped xcpostbuild build step (Xcode would look for a non-existing file in the x86_64 directory, which doesn't exist as relevant files will be placed in arm64 directory).
The workaround
The fix for the producer side has been merged in #39 - instead of relying on PLATFORM_PREFERRED_ARCH, the first architecture in ARCHS is used.
On the consumer side that Build Setting is used also to define xcpostbuild output files. The list of Build Settings operations is very limited so the fix had to use complex settings operations. For more details about available operations, see WWDC 2021 session.
Patching PLATFORM_PREFERRED_ARCH
In essence, we need to replace PLATFORM_PREFERRED_ARCH to arm64 when building for simulator on Apple Silicon machines. I found that for such case LINK_FILE_LIST_normal_$(PLATFORM_PREFERRED_ARCH) is empty (not defined).
The idea is to check if there is a build setting LINK_FILE_LIST_normal_{expected_arch}. If not, we are in a scenario with a bug so have to fallback to arm64.
LINK_FILE_LIST_normal_{ARCH} env has a path to the LinkFileList file which is placed in a dir {ARCH} so the trick is to extract that value for the non-buggy scenario (see the example below).
M1 machine example
CURRENT_VARIANT=normal
PLATFORM_PREFERRED_ARCH=x86_64
LINK_FILE_LIST_normal_arm64=DerivedData/Project/Build/Intermediates.noindex/Project.build/Debug-iphonesimulator/T.build/Objects-normal/arm64/T.LinkFileList
LINK_FILE_LIST_normal_x86_64= ## empty as not defined
Fixing a path to the xcpostbuild output file location for build for simulator on M1 machines.
Context
When building on Intel machines, PLATFORM_PREFERRED_ARCH correctly resolves to the "main" architecture of the build. Simulator -
x86_64
, Hardware iPhone -arm64
, hardware AppleWatch -arm64_32
etc. However, when building on M1 for a native simulator, it resolves tox86_64
, even a build compiles only forarm64
. This apparently is a bug (filed FB9824531) which could potentially lead to incorrectly skippedxcpostbuild
build step (Xcode would look for a non-existing file in thex86_64
directory, which doesn't exist as relevant files will be placed inarm64
directory).The workaround
The fix for the producer side has been merged in #39 - instead of relying on
PLATFORM_PREFERRED_ARCH
, the first architecture inARCHS
is used. On the consumer side that Build Setting is used also to definexcpostbuild
output files. The list of Build Settings operations is very limited so the fix had to use complex settings operations. For more details about available operations, see WWDC 2021 session.Patching
PLATFORM_PREFERRED_ARCH
In essence, we need to replace
PLATFORM_PREFERRED_ARCH
toarm64
when building for simulator on Apple Silicon machines. I found that for such caseLINK_FILE_LIST_normal_$(PLATFORM_PREFERRED_ARCH)
is empty (not defined). The idea is to check if there is a build settingLINK_FILE_LIST_normal_{expected_arch}
. If not, we are in a scenario with a bug so have to fallback toarm64
.LINK_FILE_LIST_normal_{ARCH}
env has a path to theLinkFileList
file which is placed in a dir{ARCH}
so the trick is to extract that value for the non-buggy scenario (see the example below).M1 machine example
LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH)
LINK_FILE_LIST_normal_x86_64
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH))
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir)
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath)
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath:file)
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath:file:default=arm64)
arm64
Intel machine example
LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH)
LINK_FILE_LIST_normal_x86_64
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH))
DerivedData/Project/Build/Intermediates.noindex/Project.build/Debug-iphonesimulator/T.build/Objects-normal/x86_64/T.LinkFileList
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir)
DerivedData/Project/Build/Intermediates.noindex/Project.build/Debug-iphonesimulator/T.build/Objects-normal/x86_64/
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath)
DerivedData/Project/Build/Intermediates.noindex/Project.build/Debug-iphonesimulator/T.build/Objects-normal/x86_64
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath:file)
x86_64
$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(PLATFORM_PREFERRED_ARCH):dir:standardizepath:file:default=arm64)
x86_64