Ensuring build setting consistency across macOS versions using .xcconfig
0 reputation · 11 Mar 2023, 02:41 UTC
0 reputation · 11 Mar 2023, 02:41 UTC
To establish a repeatable development environment in Xcode, teams often move environment-specific variables out of the .xcodeproj file and into .xcconfig files. This approach aims to decouple the project configuration from the local machine state.
While Swift Package Manager (SPM) handles dependency resolution consistently, there is uncertainty regarding how Xcode manages derived data paths and cached build artifacts when a project is migrated between different macOS versions or runtime images, such as those used in Xcode Cloud.
Which mechanisms are available to ensure that .xcconfig definitions remain portable and do not inadvertently inherit machine-specific absolute paths during the build process? Does Xcode provide a native way to standardize the derived data location across disparate macOS environments to prevent cache inconsistencies?
32775 reputation · 11 Mar 2023, 03:44 UTC
.xcconfig stays portable when it uses Xcode build variables instead of absolute paths and when SDK and deployment targets are explicitly set. Derived-data location cannot be forced via .xcconfig; it must be controlled with xcodebuild -derivedDataPath or Xcode's Locations preference.
When the active macOS SDK changes, Xcode’s default values for SDKROOT, MACOSX_DEPLOYMENT_TARGET, and related flags shift. If those values are not overridden in a .xcconfig, the build picks up the host‑specific defaults, making the configuration appear to inherit machine state.
#if, #else, #endif (e.g., #if SDK_VERSION_MAX >= 14.0) to tailor settings per SDK range.xcodebuild -showBuildSettings displays the effective value and its source, letting you verify that the .xcconfig override is active.$(SRCROOT), $(PROJECT_DIR), $(BUILT_PRODUCTS_DIR), $(CONFIGURATION_BUILD_DIR).// Shared.xcconfig
MACOSX_DEPLOYMENT_TARGET = 13.0
SDKROOT = macosx
IPHONEOS_DEPLOYMENT_TARGET = 16.0
#if SDK_VERSION_MAX >= 15.0
OTHER_SWIFT_FLAGS = -enable-upcoming-feature
#endif
xcodebuild -project MyApp.xcodeproj -target MyApp -showBuildSettings | grep -E 'MACOSX_DEPLOYMENT_TARGET|SDKROOT'
If the output shows values that differ from those in the .xcconfig, check that the file is correctly listed in the target’s Build Settings and that no later configuration file is overriding it.
Derived data location is not a build setting, so it cannot be set in .xcconfig. To obtain repeatable paths:
xcodebuild with a explicit -derivedDataPath argument, e.g.:xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -derivedDataPath '$PWD/build/DerivedData' clean build
When migrating between macOS versions, clean the derived data folder or use a fresh path per SDK to avoid cache incompatibilities.
Assumption: you need consistent build settings, not sharing of compiled artifacts. Overriding SDKROOT or MACOSX_DEPLOYMENT_TARGET can break compatibility on older hosts; verify the effective values with xcodebuild -showBuildSettings on each host before changing them.
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 11 Mar 2023, 13:13 UTC
To keep intermediate products predictable, you can define BUILD_DIR, OBJROOT and SYMROOT in a shared .xcconfig using Xcode variables like $(SRCROOT). These settings control where the compiler places object files and linked products, but they do not affect the DerivedData folder that Xcode uses for indexing, logs and caches.
In addition, the build setting INDEX_DATA_STORE_PATH can be pointed to a relative location under $(BUILD_DIR) (e.g., $(BUILD_DIR)/Index/DataStore) via .xcconfig. This redirects the index store out of the default per‑machine DerivedData location, making the overall build more uniform when the derived data path is overridden externally with xcodebuild -derivedDataPath or Xcode’s Locations preference.