Note
AI Disclosure: Altivec Intelligence has been lovingly crafted for retro Apple devices by me. Also the writing in this README and associated blog post is 100% written by me. That said, the build system and makefiles are 100% AI generated.
Altivec Intelligence is a containerized cross-compile environment that is built for retro tech-enthusiasts that want to build software for their retro Mac and iOS device. It builds Mac apps that run on all Macs with 10.4 Tiger and up including PowerPC, Intel, and Apple Silicon Macs. The iPhone toolchain can build apps that run on iPhone 3GS with iOS 5.0 and later.
Why include AI? Building apps that target these old platforms requires using old Objective-C that does not have the syntactic sugar provided by Objective-C 2.0 or Swift. So the AI will help with that by ensuring you are only using old APIs, helping you solve warnings, and typing out the very verbose Objective-C with no Properties, Automatic Reference Counting, or Block Syntax.
In the end, I think everyone that is a fan of retro Macs has an app idea or two that would make their old Mac more useful to them. But because of lack of time or lack of desire to program old-school Objective-C, they have never gotten around to building it. I hope that Altivec Intelligence will empower this niche community to make our favorite retro-tech more useful in the modern world.
Below is a Quick Start Guide. For more detailed information about the project's origins, technical matrix, and safety considerations, please see the FAQ.
Use altivec-app templates to list offline Mac/iOS app, service and CLI/library
starters. For example:
altivec-app new --template cocoa-shared --name MyApp \
--bundle-id com.example.myapp --destination ./MyAppThis creates a root Makefile, Compose setup, release configuration, artwork and
layered test entry points.
Run make test-host in the generated project before SDK-dependent builds.
See generated projects for supported profiles and tests.
Altivec Intelligence ships as a prebuilt container image on GHCR. You
consume it by referencing the image in a compose.yml at the root of your own
app repository β no submodule, no clone, no local toolchain build. This keeps
your app code fully separate from the engine, and you update the engine by
simply pulling a newer image.
Altivec Intelligence is BYOSDK (Bring Your Own SDK) (reference) and does not contain or download Apple SDK's. You must provide them yourself. The provided template compose file provides a way to "install" them via Docker volumes. Please google for the following files with "Github" as a keyword to find them:
iPhoneOS8.4.sdk.tar.gzMacOSX10.5.sdk.tar.xzMacOSX11.3.sdk.tar.xz
The install script provided verifies the file checksums, so it will fail if you somehow found a different file with the same name.
1. Generate your app and its Compose setup
Run this from the parent directory where you want MyCoolApp created. The
image's generator works without SDKs or Git and refuses to overwrite a folder.
docker run --rm -v "$PWD:/repo/user" -w /repo/user \
ghcr.io/jeffreybergier/altivec-intelligence:latest \
"altivec-app new --template cocoa-shared --name MyCoolApp --bundle-id com.example.mycoolapp --destination ./MyCoolApp"
cd MyCoolAppUse mac-basic or ios-basic for a single-platform app; cocoa-shared includes
both frontends and a portable C model. The generated compose.yml is ready to use.
2. Check the project before installing SDKs
docker compose run --rm altivec "make test-host check-project"Website work, generation, and portable tests do not require Apple SDKs.
3. Prepare the SDK's
mkdir -p ~/.altivec/.altivec-sdk .altivec-sdk
touch .gitignore && echo '.altivec-sdk/' >> .gitignore
cp ~/Downloads/iPhoneOS8.4.sdk.tar.gz .altivec-sdk/
cp ~/Downloads/MacOSX10.5.sdk.tar.xz .altivec-sdk/
cp ~/Downloads/MacOSX11.3.sdk.tar.xz .altivec-sdk/Each archive is selected independently, in this order inside the container:
$HOME/.altivec-sdk(normally/root/.altivec-sdk).$PWD/.altivec-sdkin the mounted project workspace.ALTIVEC_SDK_ARCHIVE_DIR, if explicitly set to an accessible custom path.
Compose reuses ~/.altivec:/root and the project workspace mount. Shared
archives therefore belong in ~/.altivec/.altivec-sdk on the host, and
project archives belong in ./.altivec-sdk. No separate SDK archive mounts
are needed. The SDK-only service uses the same home, workspace and working
directory as the app services. The extracted SDK named volumes are unchanged.
Only missing archives fall back; an existing invalid file, directory, or
symlink is an error, even if a valid lower-priority copy exists.
A custom fallback is optional and must already be visible inside the container:
docker compose run --rm -e ALTIVEC_SDK_ARCHIVE_DIR=/repo/user/sdk-backup altivec-sdk preflightSetting that variable does not mount a host path. ALTIVEC_SDK_HOST_DIR remains
a legacy alias for the custom fallback when ALTIVEC_SDK_ARCHIVE_DIR is unset;
Compose no longer uses it to select bind mounts.
Direct host use of bin/altivec-sdk preflight searches the host's own
$HOME/.altivec-sdk, then $PWD/.altivec-sdk, then the optional custom path.
It requires Bash, jq, tar/xz, and SHA-256 tooling.
These Compose files require an image with home-first SDK discovery. Update the
image before using them. Archives previously stored in the host's sibling
~/.altivec-sdk must be moved into ~/.altivec/.altivec-sdk (or the project).
Installed SDKs remain in the existing named volumes and need no migration.
For Podman providers that require explicit profile activation, use
podman compose --profile tools run --rm altivec-sdk install.
4. Pull the Docker Image and Install the SDK's
docker compose pull
docker compose run --rm altivec-sdk install5. Build from the project root
docker compose run --rm altivec "make macOS-debug"
docker compose run --rm altivec "make iOS-debug"
docker compose run --rm altivec "make print-config"Choose the platform included in your template. Outputs live under
build/<platform>/debug/. Mac compiler floors are 10.4 for PPC/i386, 10.9 for
x86_64, and 11.0 for arm64; iOS floors are 5.0 for armv7 and 7.0 for arm64.
These are build targets, not evidence of testing every OS version.
The placeholders are white. Mac ICNS files include legacy RGB/mask entries and
256/512/1024px JPEG 2000 images, matching ENIL's format/size profile. iPhone
starters use portrait launch PNGs and matching plist point sizes, including
Default-568h@2x.png for the taller legacy iPhone screen. See the
artwork contract before changing these resources.
6. Use AI
Altivec Intelligence has built in AI tools which keeps them sandboxed. After running the following command you can choose which AI tool you want to use. Note if you want to try for free, use your Google account with Antigravity
docker compose run --rm altivec-intelligence
Hello, you are inside of a docker container that has a cross-compile
environment for building retro Mac and iPhone Apps. My app code is in
/repo/user. The Altivec engine and examples are in /altivec. The modern
cross-compiler toolchain is in /osxcross/modern and the Apple GCC/PowerPC
toolchain is in /osxcross/legacy/target. Please start by reading the README.md
in /altivec and my project AGENTS.md. App defaults are in
/altivec/templates/AGENTS.md. Please always create makefiles for my app using
the altivec_common_[mac|phone].mk files in /altivec so I can ensure my makefiles
are small and make apps compatible with many retro Apple devices. Make sure you
treat my repo (/repo/user) as the base location for your work on my app as
changes made outside of volumes mounted in the compose.yml file will be lost
when we finish this session.
I want to make my own app. My app will be called MyNewApp and I want you to use
the altivec-app generator with the cocoa-shared template. Generate into a new
./MyNewApp directory and run its test-host and check-project root targets.
After that please compile the app and ensure there are no warnings. I will
run it to make sure it works.
Note: you can change the example app as the source depending on if you want an iPhone app or Mac app. Also, if you want to do networking, you may consider using the CURLmac or CURLphone app as starting place because those have AltivecCore linked.
Use the manual deployment recipes to transfer and launch Mac bundles, install IPAs or rootful/rootless DEBs, collect logs and crash reports, and start or stop a test daemon. They use SSH/SCP or rsync and require no debugger. Each recipe describes prerequisites, staging, and cleanup.
Note on Deploying to iPhone This requires common jailbreak tools like:
- AppSync (Unified)
- appinst (App Installer)
- OpenSSH
- Core Utilities
Jailbreaking and using a jailbroken iPhone is beyond the scope of this tutorial, but I highly recommend checking out Legacy-iOS-Kit for help. Its an excellent utility that is THE EASIEST way to downgrade / jailbreak your retro iPhone. It can also be used to deploy the apps built with Altivec Intelligence to the iPhone via the USB cable.
Note on SSH Authentication: The deployment script is designed for automated use and requires SSH key authentication. If you do not have keys set up, the script will repeatedly prompt for your password and likely fail.
To connect to vintage hardware from a modern Mac, you often need to explicitly
allow older algorithms in your ~/.ssh/config file. Here is a recommended
configuration:
Host iphone5-ios6
HostName 192.168.0.93
User root
IdentityFile ~/.ssh/id_rsa
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
Host imacg4-tiger
HostName my-imac.local
User myuser
IdentityFile ~/.ssh/id_rsa
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
Sample source is included in the image, while tagged sample binaries live with the matching GitHub Release. With GitHub CLI installed on the host, download the newest CURLmac build without compiling it:
# 1. Download the latest matching release asset.
gh release download --repo jeffreybergier/AltivecIntelligence \
--pattern 'CURLmac-*.zip'
# 2. On your Mac, unzip and launch the app:
unzip CURLmac-*.zip
open CURLmac.appCURLmac.app is a Quad-Fat universal binary, so the same bundle runs on
PowerPC, 32-bit Intel, 64-bit Intel, and Apple Silicon Macs (10.4 Tiger and
newer). CURLmac links AltivecCore, so this app has modern TLS 1.2
networking, SQLite, and cJSON even on Mac OS X Tiger.
To make a fresh build instead, compile and copy it during the same disposable container run:
docker compose run --rm altivec \
"cd /altivec/apps/CURLmac && make release && cp build/macOS/release/CURLmac/CURLmac.zip /repo/user/"Swap CURLmac for SingleWindow to build the simpler, non-networking sample.
Each tagged release also carries AltivecCore/AltivecCocoa packages, the optional
iOS armv7 AltivecToolchain .deb, and SHA256SUMS. No arm64 device-toolchain
package is currently built.
apps: Sample projects and Makefilesaltivec_common_mac.mk: A "parent" Makefile with the general rules for compiling Mac appsaltivec_common_phone.mk: A "parent" Makefile with the general rules for compiling Phone appstemplates: Reusable templates for end users (compose + thin Makefiles for new app projects)templates/compose.yml: The compose file end users drop into their own app repo (prebuilt GHCR image, app mounted at/repo/user). This is the file most people want.templates/altivec-release.json: Optional release config for version bumps, tags, and staged release assets.templates/github-release.yml: Optional GitHub Actions workflow that builds and uploads configured release assets.toolchain: Optional toolchain package sources. The current release-extras workflow builds onlyiOS/armv7; shared iOS helpers live iniOS/common.compose.yml: The engine-development compose β clone-and-build the image locally and mount your live checkout at/repo/altivec. Only needed if you are customizing the engine itself.bin: Runtime scripts onPATHinside the image, includingaltivec-sdkfor verified SDK archive management.docs/deployment.md: Manual install, run, log collection, and cleanup recipes.AGENTS.md: guidance for maintaining AltivecIntelligence itself (also surfaced as CLAUDE.md / GEMINI.md via symlink in the image).templates/AGENTS.md: app-development defaults copied by the chooser only when the working directory has no AGENTS.md entry. Existing copies are preserved; customize them for the app.
New application Makefiles declare PRODUCTS, source groups, resources and
package policies, then include the existing common Makefile entry points.
The product API covers apps, daemons, CLI tools and
static libraries, configurable slices, signing and offline test conventions.
Root and child builds share build/<platform>/<debug|release>/ outputs.
Consumer Compose files default to ghcr.io/jeffreybergier/altivec-intelligence:latest.
Set ALTIVEC_IMAGE=altivec-intelligence:local to use a local build instead.
This repository keeps that separate local image for toolchain development.
Build it locally with mkdir -p ~/.altivec/.altivec-sdk .altivec-sdk followed by
docker compose build altivec. BuildKit requires both context directories to
exist, even if one is empty; runtime Compose mounts create missing folders,
but docker compose build does not. The build uses the same home-first
per-archive resolver and validation, with read-only build contexts scoped to
the SDK-dependent build step. Direct docker buildx build callers must supply both
--build-context altivec_sdk=/path/to/project-archives and
--build-context altivec_sdk_shared=/path/to/shared-archives (they may point to
the same folder).
The runtime module layer follows the expensive toolchain layer, so subsequent
module-only changes reuse the toolchain cache.
Use these thin templates in your app repo:
The following knobs apply to the legacy APP_NAME interface. The templates
above use the product API, including per-product
CORE, COCOA, PLIST, and resource inputs.
Optional AltivecCore knobs:
ALTIVECCORE_REQUIRED=1: enforce required Core artifacts at validate time.ALTIVECCORE_LINKAGE=dynamic|static: choose framework or static archives on macOS. Phone apps supportstaticonly.ALTIVECCORE_DIR=/path/to/altivec/libs/core/build-mac|build-phone: override autodetect.
For iPhone apps, AltivecCore is static-only because embedded frameworks require iOS 8+ at runtime and break the iOS 5-7 compatibility target.
Shared SQLite change feeds, read snapshots and bounded row collections are
documented in SQLite infrastructure. Database consumers opt
in with <Product>_SQLITE = 1 and explicit CORE/COCOA linkage.
Shared local notifications provide one Mac/iOS API for background-only alerts, permission requests, badges, and foreground cleanup.
Optional AltivecCocoa knobs:
ALTIVECCOCOA_REQUIRED=1: enforce required Cocoa artifacts at validate time.ALTIVECCOCOA_LINKAGE=dynamic|static: chooseAltivecCocoa.frameworkorlibAltivecCocoa.aon macOS. Phone apps supportstaticonly.ALTIVECCOCOA_DIR=/path/to/altivec/libs/cocoa/build-mac|build-phone: override autodetect.
AltivecCocoa contains reusable nibless AppKit controller classes such as
AIViewController, AICookieCutterWindowController, and AIWebViewController,
plus the cross-platform AIFontAwesome icon helper. Static AltivecCocoa apps
stage Font Awesome OTFs into the app bundle; macOS dynamic apps use the fonts
inside AltivecCocoa.framework.
The build downloads checksum-pinned Font Awesome Free OTFs from redundant
sources and verifies cached copies before use. Release outputs bundle those
fonts under SIL OFL 1.1 and copy their notice alongside them. Static-library
clients can also use +[AIFontAwesome fontAwesomeLicenseText] to present the
complete license in an About or Licenses screen without loading the notice as
a resource. Run make -C libs/cocoa fontawesome-fetch to prefill the ignored
cache without compiling the framework.
Bundle resource knobs:
RES_DIR=Resources: blind-copy ordinary resources into the bundle resource root. For iPhone this includes icon and launch image PNGs referenced byInfo.plist.INFO_PLIST=$(RES_DIR)/Info.plist: copied to the real bundle plist location.Info.plistis required to live underRES_DIRby default, and is skipped by the blind resource copy.MAC_ICON=AppIcon.icns: copy a Mac.icnsfile intoContents/Resources.BUNDLE_FONT_DIRS=../shared/Resources/Fonts: copy font directory contents into the bundle'sFonts/directory.BUNDLE_LOCALIZATION_DIRS=../shared/Resources: copy*.lprojdirectories. Mac builds transcode.stringsfiles to UTF-16 LE with BOM for Tiger and Leopard; iPhone builds copy UTF-8.stringsfiles verbatim.EXTRA_BUNDLE_STEPS=...: run app-specific bundle staging after common resource processing. Phone builds also supportPHONE_EXTRA_BUNDLE_STEPS.PHONE_LDID_SIGN=1orPHONE_LDID_ENTITLEMENTS=Entitlements.plist: opt in toldidpseudo-signing before IPA packaging.
altivec-release is a dependency-free Node CLI. Version preparation, builds and
artifact staging work in Docker without Git identity, SSH keys, tokens, remote
access, or a .git directory. Review and commit/tag on the host; publish only
with an explicit push.
Install on the host from this checkout (Node >=22):
npm pack ./packages/altivec-release
npm install -g ./altivec-release-1.0.0.tgzThe image installs this pinned package at build time. Copy
templates/altivec-release.json to
.altivec-release.json in your project and edit its paths and targets.
# Inside Docker, with your project mounted:
altivec-release doctor
altivec-release current
altivec-release prepare patch --dry-run
altivec-release prepare patch
altivec-release build --target iOS
altivec-release stage
# On the host, after reviewing git diff and build/release/plan.json:
altivec-release commit
# Only when you explicitly want publication:
altivec-release pushcommit reads the host's existing Git identity; --name and --email provide
per-invocation overrides without changing global settings. doctor reports
missing identity/credentials without blocking preparation. No ordinary
inspection or preparation command probes the network.
Existing YAML projects should run altivec-release migrate --config .altivec-release.yml once in the image, then review the JSON. Migration requires
Python/PyYAML; normal CLI commands do not. bump is now a deprecated alias for
local preparation and never implicitly commits or pushes, with or without
--no-push. Retry failed preparation/commit/push commands without bumping again.
set, check, ci-env, named build targets, custom workdirs, per-plist keys,
and multiple artifacts remain supported. New configurations stage artifacts
under build/release/artifacts; migrated configurations keep dist. Existing
CI can explicitly use stage --dist dist to preserve dist/* upload globs.
Copy templates/github-release.yml to an app's
.github/workflows/release.yml for tagged release builds.
See the release CLI guide for the config
contract, plain-text version sources, recovery steps, and optional runtime
SSH-agent/token authentication. Run dependency-free regressions with
node --test test/altivec-release.test.cjs; migration fixtures additionally need
Python/PyYAML, and the package installation test needs npm.
Everything above uses the prebuilt GHCR image and never requires a clone.
You only need this section if you want to modify the engine itself β change
build rules in altivec_common_*.mk, edit the bin/ scripts, add a new
library, or rebuild AltivecCore and its dependencies from source.
- Git (to clone the engine repo)
- Docker Desktop or an alternative
The from-source build compiles Apple GCC 4.2.1 and current OSXCross, so give Docker some headroom in its Settings β Resources tab:
- 6β8 GB RAM
- As many CPU cores as you can spare
- At least 50 GB of free Docker disk space (separate from free host disk space)
This builds the isolated legacy toolchain first, then the modern toolchain, and
is a heavyweight first-time build. Plan on 5+ hours, depending on the host
and the resources assigned to Docker; subsequent builds are much faster when
the expensive layers are cached. Build parallelism automatically matches the
CPU cores visible to Docker. To cap it, pass an explicit build argument, for
example docker compose build --build-arg JOBS=4.
git clone https://github.com/jeffreybergier/AltivecIntelligence.git
cd AltivecIntelligence
docker compose buildThe root compose.yml is wired for this workflow: it mounts
your live checkout at /repo/altivec (the working directory) while the baked
toolchain stays at /altivec.
/altivec is baked into the image at build time; your live
checkout is mounted separately at /repo/altivec. A build that includes
/altivec/altivec_common_mac.mk therefore uses the baked copy, not your
edits. To make engine changes take effect you must either:
- Rebuild the image with
docker compose build, or - Overlay your checkout by adding
- .:/altivecto the service'svolumesso your live files shadow the baked toolchain.
See the active roadmap for remaining work and priorities. Implementation history preserves completed work, earlier reviews, and validation evidence.
This was a small project for me so I could work on my own hobby apps for my iPhone 5 and my iMac G4. I am not a compiler, cmake, SDK, or build-system engineer. I would not have been able to do this without AI. That said, I also know AI has probably not produced the most efficient build files and scripts. So I am totally open to new ideas. How can we improve them, how can I learn more. If you know, I want to know. So please file an issue and let's talk about it β€οΈ
This project is built on top of OSXCross. You should check out this project because it could make it much easier and cheaper for you to automatically build and release your apps because it allows building in Linux containers instead of on expensive Mac runners.
This project is licensed under the MIT License. This is a permissive license that allows for free use, modification, and distribution. The SDK-free image and repository still use separately downloaded open-source and closed-source build inputs. Those inputs, including Apple SDKs, carry their own licenses and remain the user's responsibility.