Skip to content

Latest commit

 

History

History
216 lines (167 loc) · 10 KB

appendix-b-build-settings.md

File metadata and controls

216 lines (167 loc) · 10 KB

Build settings reference

Everything below is grounded in Spettro.xcodeproj/project.pbxproj and Local.xcconfig. The project has exactly one app target (Spettro), two configurations (Debug, Release), and no test targets.

Configuration layering

Build settings come from three places, in increasing order of precedence:

  1. Xcode defaults — anything not mentioned anywhere else.
  2. Project-level configurations — the XCBuildConfiguration blocks on the PBXProject "Spettro" object. These set MACOSX_DEPLOYMENT_TARGET = 26.5, compiler warnings, and optimization levels. No base xcconfig.
  3. Target-level configurations — the XCBuildConfiguration blocks on the PBXNativeTarget "Spettro" object. Both Debug and Release use Local.xcconfig as their base configuration (baseConfigurationReference), then override specific keys inline.

Local.xcconfig itself contains exactly one line of substance:

DEVELOPMENT_TEAM = <your-team-id>

It is gitignored on purpose (see .gitignore) — it's the dev's personal signing team and should never be committed. If you clone the repo fresh, create your own Local.xcconfig at the repo root with your team ID, or signing will fail at build time.

Deployment target

Where Value
Project-level Debug/Release 26.5
Target-level Debug/Release 26.0

The target-level value wins, so the effective MACOSX_DEPLOYMENT_TARGET is 26.0. The 26.5 on the project object is a leftover default and has no effect on the built product. (Doc 02 notes the same split.)

Product

Setting Value
PRODUCT_NAME $(TARGET_NAME) → Spettro
PRODUCT_BUNDLE_IDENTIFIER to.eyed.Spettro
MARKETING_VERSION 1.0
CURRENT_PROJECT_VERSION 1
Product type com.apple.product-type.application
Product reference Spettro.app in BUILT_PRODUCTS_DIR

The bundle id to.eyed.Spettro is what defaults write to.eyed.Spettro … targets when persisting the explicit CLI path (see doc 03).

Signing

Setting Value
CODE_SIGN_STYLE Automatic
CODE_SIGN_IDENTITY[sdk=macosx*] Apple Development
DEVELOPMENT_TEAM from Local.xcconfig
ENABLE_HARDENED_RUNTIME YES
ENABLE_APP_SANDBOX NO

Signing is fully automatic against an Apple Development identity; the only machine-specific input is the team ID injected via Local.xcconfig. The hardened runtime is on for both configurations.

The app is not sandboxed (ENABLE_APP_SANDBOX = NO). That's deliberate: it must spawn spettro as a subprocess, read/write ~/.spettro/config.json and ~/.spettro/memory.md outside its container, and run user shell commands in the terminal drawer. Sandboxing would forbid all of that.

Hardened-runtime exceptions

All six RUNTIME_EXCEPTION_* keys are set explicitly, five of them to NO (i.e. the entitlement is not granted):

Setting Value Meaning
RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES NO No DYLD_* env overrides
RUNTIME_EXCEPTION_ALLOW_JIT NO No JIT
RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY NO No unsigned executable memory
RUNTIME_EXCEPTION_DEBUGGING_TOOL YES Is a debugging tool (may attach)
RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION NO No rwx pages
RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION NO Library validation stays on

Only the debugging-tool exception is granted — consistent with an app that manages a long-lived child process and surfaces its logs.

Resource-access and automation toggles

Because the target is non-sandboxed, these are inert but recorded anyway: AUTOMATION_APPLE_EVENTS = NO, and every ENABLE_RESOURCE_ACCESS_* key (audio input, calendars, camera, contacts, location, photo library) is NO. ENABLE_USER_SELECTED_FILES = readonly grants read-only access to files the user picks in open/save panels.

Entitlements

There is no .entitlements file in the repo (CODE_SIGN_ENTITLEMENTS is never set). Every entitlement is generated by Xcode from the build settings above — primarily the hardened-runtime exceptions, the resource-access toggles, and REGISTER_APP_GROUPS = YES (which registers any app-group identifiers at signing time; the project defines none, so this is effectively a no-op placeholder).

Info.plist

There is no checked-in Info.plist: GENERATE_INFOPLIST_FILE = YES makes Xcode synthesize one at build time. Values come from INFOPLIST_KEY_* build settings:

Build setting Generated key Value
INFOPLIST_KEY_CFBundleDisplayName CFBundleDisplayName Spettro
INFOPLIST_KEY_LSApplicationCategoryType LSApplicationCategory public.app-category.developer-tools
INFOPLIST_KEY_NSHumanReadableCopyright NSHumanReadableCopyright (empty string)

Everything else in the generated plist (CFBundleName, CFBundleShortVersionString from MARKETING_VERSION, CFBundleVersion from CURRENT_PROJECT_VERSION, etc.) is Xcode's standard synthesis.

Asset catalog

Setting Value
ASSETCATALOG_COMPILER_APPICON_NAME AppIcon
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME AccentColor
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS YES

Swift language settings

Setting Value
SWIFT_VERSION 5.0
SWIFT_DEFAULT_ACTOR_ISOLATION MainActor
SWIFT_APPROACHABLE_CONCURRENCY YES
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY YES
SWIFT_ACTIVE_COMPILATION_CONDITIONS (Debug) DEBUG $(inherited)
SWIFT_OPTIMIZATION_LEVEL (Debug) -Onone
SWIFT_COMPILATION_MODE (Release) wholemodule
ENABLE_PREVIEWS YES

Two of these shape the whole codebase:

  • SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor — every type is MainActor-isolated unless explicitly opted out, which is why the model layer can touch UI state freely (see doc 06 on AppModel).
  • SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG in Debug builds — this is what gates the mock data in PreviewSupport.swift behind #if DEBUG.

ENABLE_TESTABILITY = YES in Debug only (project level), as usual.

Linking and runpaths

LD_RUNPATH_SEARCH_PATHS = (
    "$(inherited)",
    "@executable_path/../Frameworks",
);

Standard for an app embedding SwiftPM frameworks. The two package products (SwiftTerm, Textual) are linked in the target's Frameworks phase — see SwiftPM dependencies.

Debug vs Release, the actual differences

Everything in the target-level configuration is identical between Debug and Release. All variation lives at the project level:

Setting Debug Release
GCC_OPTIMIZATION_LEVEL 0 (default -s)
SWIFT_OPTIMIZATION_LEVEL -Onone (default -O)
SWIFT_COMPILATION_MODE (incremental) wholemodule
DEBUG_INFORMATION_FORMAT dwarf dwarf-with-dsym
ENABLE_TESTABILITY YES (absent)
ENABLE_NS_ASSERTIONS (default on) NO
ONLY_ACTIVE_ARCH YES (absent)
MTL_ENABLE_DEBUG_INFO INCLUDE_SOURCE NO
GCC_PREPROCESSOR_DEFINITIONS DEBUG=1 (absent)

The default configuration for command-line builds (xcodebuild without -configuration) is Release — both XCConfigurationList blocks set defaultConfigurationName = Release.

Project metadata

From the PBXProject attributes block:

  • LastSwiftUpdateCheck / LastUpgradeCheck = 2660
  • Target created with Xcode 26.6 (CreatedOnToolsVersion = 26.6)
  • developmentRegion = en; known regions en, Base
  • objectVersion = 77 (the Xcode 16+ format that supports PBXFileSystemSynchronizedRootGroup — which is why the Spettro/ source folder has no per-file references in the pbxproj)
  • BuildIndependentTargetsInParallel = 1

Reproducing a fresh clone's setup

git clone <repo> && cd Spettro
echo 'DEVELOPMENT_TEAM = <your-team-id>' > Local.xcconfig
xcodebuild -project Spettro.xcodeproj -scheme Spettro \
  -configuration Debug build

That, plus a spettro CLI binary (see Building and running), is the entire setup. There are no other secrets, scripts, or generated files involved.