Answer first
.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.
Likely explanation vs confirmed facts
Likely explanation
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.
Confirmed facts
- A value defined in a .xcconfig file and attached to a target’s Build Settings overrides the Xcode default, regardless of the host macOS or Xcode version.
- .xcconfig supports conditional definitions with
#if, #else, #endif (e.g., #if SDK_VERSION_MAX >= 14.0) to tailor settings per SDK range.
- The same .xcconfig can be referenced by multiple targets by selecting it in the Based on field of each target’s Build Settings.
- Running
xcodebuild -showBuildSettings displays the effective value and its source, letting you verify that the .xcconfig override is active.
Steps to keep .xcconfig portable
- Replace any absolute paths with Xcode variables:
$(SRCROOT), $(PROJECT_DIR), $(BUILT_PRODUCTS_DIR), $(CONFIGURATION_BUILD_DIR).
- Pin the SDK and deployment targets explicitly in the shared file, for example:
// Shared.xcconfig
MACOSX_DEPLOYMENT_TARGET = 13.0
SDKROOT = macosx
IPHONEOS_DEPLOYMENT_TARGET = 16.0
- Use conditionals only when you need different flags for specific SDK ranges:
#if SDK_VERSION_MAX >= 15.0
OTHER_SWIFT_FLAGS = -enable-upcoming-feature
#endif
- Attach the same .xcconfig to all targets (project‑wide or per‑target) via the Build Settings Based on field.
- Verify the override:
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 standardization
Derived data location is not a build setting, so it cannot be set in .xcconfig. To obtain repeatable paths:
- Local developers: Xcode → Settings → Locations → Derived Data → Relative to Workspace (or a fixed subfolder).
- CI / Xcode Cloud: invoke
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.