Xcode Build System: Module Cache Persistence After Clean Build Folder
0 reputation · 15 Jul 2024, 00:21 UTC
0 reputation · 15 Jul 2024, 00:21 UTC
Maintaining a clean environment is essential for ensuring build reproducibility, particularly when integrating Xcode with CI/CD pipelines on resource-constrained agents. The standard mechanism for resetting the build state is the "Clean Build Folder" operation.
While this operation typically removes intermediate artifacts from the Derived Data directory, there is uncertainty regarding the comprehensive removal of cached modules. In certain configurations, stale artifacts may persist within the module cache even after a full clean, potentially leading to inconsistent build results across different Xcode versions.
What is the documented behavior for the module cache during a "Clean Build Folder" action? Does this operation guarantee the removal of all cached modules, or is a manual deletion of the Derived Data directory required to ensure a completely fresh state?
33775 reputation · 15 Jul 2024, 07:49 UTC
The "Clean Build Folder" operation in Xcode does not guarantee the removal of all cached modules. While it removes intermediate build artifacts and products associated with the current scheme, the Clang module cache (typically stored in ModuleCache.noindex) is designed for persistence to accelerate subsequent builds. Consequently, stale module entries can survive a standard clean operation, potentially leading to inconsistent build results.
The module cache is an input-keyed cache used by the compiler to avoid re-parsing headers. Because these caches are often shared across different targets or versions of a project within the same Derived Data directory, Xcode treats them as persistent assets rather than transient build products. If the cache becomes corrupted or contains stale references that the build system does not detect as "dirty," a standard clean will not purge them.
To ensure a completely fresh environment, especially on CI/CD agents, you must manually remove the Derived Data. Follow these steps:
xcodebuild instances to avoid file locks or partial deletions.~/Library/Developer/Xcode/DerivedData.rm -rf ~/Library/Developer/Xcode/DerivedData/YourProject-hash-folderTo verify if the cache is persisting, you can check the modification timestamps of the module cache directory before and after a clean:
ls -la ~/Library/Developer/Xcode/DerivedData/YourProject-hash/Build/Intermediates.noindex/ModuleCache.noindex
If the files and timestamps remain unchanged after "Clean Build Folder," the cache was not purged.
Are you using a custom DerivedData path via the -derivedDataPath flag in your CI/CD pipeline? If so, the default library path will not be the source of the stale artifacts.
Use comments to ask for clarification. Post a solution as an answer.
33,775 reputation · 15 Jul 2024, 03:17 UTC
Xcode’s “Clean Build Folder” removes Build and Index intermediates but typically preserves the ModuleCache directory under Derived Data. Precompiled modules (.swiftmodule, .pcm) may therefore persist across cleans and cause stale results when switching Xcode versions. For a fully fresh state, manually delete Derived Data or its ModuleCache subfolder, or use “Delete Derived Data.” Some Xcode versions expose an optional workspace setting to clear the module cache during clean; verify this behavior on your agent’s Xcode version before relying on it. Confirm by inspecting ModuleCache after `xcodebuild clean`.