spotify / XCRemoteCache

Other
830 stars 53 forks source link

Patch PLATFORM_PREFERRED_ARCH to support native Apple Silicon builds #42

Closed polac24 closed 2 years ago

polac24 commented 2 years ago

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
Key Value
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
CURRENT_VARIANT=normal
PLATFORM_PREFERRED_ARCH=x86_64
LINK_FILE_LIST_normal_x86_64=DerivedData/Project/Build/Intermediates.noindex/Project.build/Debug-iphonesimulator/T.build/Objects-normal/x86_64/T.LinkFileList
Key Value
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