Compare commits

...

3 Commits

Author SHA1 Message Date
387c2c40aa docs: add CLAUDE.md for project guidance
- Introduced CLAUDE.md to provide comprehensive guidance on the macOS Emacs building system, including project overview, common commands, architecture details, and testing instructions.
2026-01-14 18:56:25 +00:00
527f855fbf chore(deps): add macOS SDK version 26
- Added support for macOS SDK version 26 to the list of supported SDKs.
- Reformatted flake.nix with nixfmt.
2026-01-14 18:53:56 +00:00
aafac57b1d chore(deps): update flake.lock and flake.pkgs for dependency versions
- Updated nixpkgs revision and narHash in flake.lock.
- Upgraded expat to version 2.7.3 and openssl to version 3.4.3 in flake.pkgs.
- Modified flake-package-versions command in Makefile for improved output.
2026-01-14 18:50:55 +00:00
5 changed files with 176 additions and 80 deletions

80
CLAUDE.md Normal file
View File

@@ -0,0 +1,80 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with
code in this repository.
## Project Overview
macOS Emacs building system with Ruby and Go components:
- **Ruby script** (`build-emacs-for-macos`): Main build script for creating
self-contained Emacs.app bundles
- **Go CLI tool** (`emacs-builder`): Packaging, signing, notarization, and
release management
- **Dual dependency management**: Nix (preferred) or Homebrew
## Common Commands
```bash
# Environment setup (Nix preferred)
nix develop # Default macOS 11 SDK
nix develop .#macos{11-15,26} # Target specific SDK version
# Go development
make build # Build emacs-builder CLI
make test # Run tests with race detection
make lint # Run golangci-lint
make format # Format with gofumpt
# Ruby development
bundle exec rubocop # Lint (with development group)
# Build Emacs
./build-emacs-for-macos # Build from master
./build-emacs-for-macos emacs-29.4
```
## Architecture
### Ruby Build Script (`build-emacs-for-macos`)
Single-file Ruby script (~2500 lines) that:
- Downloads source tarballs from emacs-mirror/emacs on GitHub
- Configures and compiles Emacs with native-comp, tree-sitter support
- Creates self-contained .app bundles by embedding/relinking dependencies
- Uses `ruby-macho` gem for Mach-O binary manipulation (RPATH handling)
### Go CLI (`cmd/emacs-builder/`)
Uses `urfave/cli/v2` framework. Key packages in `pkg/`:
- `cli/`: Commands (plan, sign, sign-files, notarize, package, release, cask)
- `sign/`: macOS code signing via `codesign`
- `notarize/`: Apple notarization workflow via `notarytool`
- `release/`: GitHub release management
- `dmgbuild/`: DMG creation using Python dmgbuild
- `plan/`: Build plan JSON parsing and management
### Nix Environment (`flake.nix`)
- Multi-SDK support: macOS 11-15, 26 via `.#macos{11,12,13,14,15,26}`
- Excludes ncurses intentionally (links against system version for TUI)
- Sets `MACOSX_DEPLOYMENT_TARGET`, `DEVELOPER_DIR`, `NIX_LIBGCCJIT_*`
## Testing
```bash
make test # All Go tests
go test ./pkg/release/... # Single package
go test -run TestName ./pkg/... # Single test
```
Tests use `_test.go` suffix alongside source files.
## Working Directories
- `sources/`: Downloaded/extracted Emacs source (gitignored)
- `builds/`: Build outputs and .app bundles (gitignored)
- `patches/`: Emacs patches applied during build
- `bin/`: Built Go binaries (gitignored)

View File

@@ -141,10 +141,10 @@ nix-flake-update:
.SILENT: flake-package-versions .SILENT: flake-package-versions
flake-package-versions: flake-package-versions:
nix develop --command -- bash -c \ nix develop --command bash -c \
'nix derivation show \ 'nix derivation show \
$$(echo $$PATH | tr ":" "\n" | grep "/nix/store" | sort -u) \ $$(echo $$PATH | tr ":" "\n" | grep "/nix/store" | sort -u) \
| jq -r ".[].name" | sort -u' | jq -r ".derivations[].name" | sort -u'
flake.pkgs: flake.nix flake.lock flake.pkgs: flake.nix flake.lock
$(MAKE) flake-package-versions > "$@" $(MAKE) flake-package-versions > "$@"

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1757545623, "lastModified": 1767313136,
"narHash": "sha256-mCxPABZ6jRjUQx3bPP4vjA68ETbPLNz9V2pk9tO7pRQ=", "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "8cd5ce828d5d1d16feff37340171a98fc3bf6526", "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github" "type": "github"
}, },
"original": { "original": {

162
flake.nix
View File

@@ -6,84 +6,100 @@
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, flake-utils }: outputs =
flake-utils.lib.eachDefaultSystem (system: {
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
# List of supported macOS SDK versions. # List of supported macOS SDK versions.
sdk_versions = [ "11" "12" "13" "14" "15" ]; sdk_versions = [
"11"
"12"
"13"
"14"
"15"
"26"
];
default_sdk_version = "11"; default_sdk_version = "11";
mkDevShell = { macos_version ? default_sdk_version }: mkDevShell =
{
macos_version ? default_sdk_version,
}:
let let
apple_sdk = pkgs.${"apple-sdk_${macos_version}"}; apple_sdk = pkgs.${"apple-sdk_${macos_version}"};
in in
pkgs.mkShell { pkgs.mkShell {
# Package list specifically excludes ncurses, so that we link # Package list specifically excludes ncurses, so that we link
# against the system version of ncurses. This ensures emacs' TUI # against the system version of ncurses. This ensures emacs' TUI
# works out of the box without the user having to manually set # works out of the box without the user having to manually set
# TERMINFO in the shell before launching emacs. # TERMINFO in the shell before launching emacs.
packages = with pkgs; [ packages = with pkgs; [
apple_sdk apple_sdk
autoconf autoconf
bash bash
cairo cairo
clang clang
coreutils coreutils
curl curl
darwin.DarwinTools # sw_vers darwin.DarwinTools # sw_vers
dbus dbus
expat expat
findutils findutils
gcc gcc
gettext gettext
giflib giflib
git git
gmp gmp
gnumake gnumake
gnupatch gnupatch
gnused gnused
gnutar gnutar
gnutls gnutls
harfbuzz harfbuzz
jansson jansson
jq jq
lcms2 lcms2
libffi libffi
libgccjit libgccjit
libiconv libiconv
libjpeg libjpeg
libpng libpng
librsvg librsvg
libtasn1 libtasn1
libunistring libunistring
libwebp libwebp
libxml2 libxml2
mailutils mailutils
nettle nettle
pkg-config pkg-config
python313Packages.dmgbuild python313Packages.dmgbuild
rsync rsync
ruby ruby
sqlite sqlite
texinfo texinfo
time time
tree-sitter tree-sitter
which which
xcbuild xcbuild
zlib zlib
]; ];
shellHook = '' shellHook = ''
export CC=clang export CC=clang
export MACOSX_DEPLOYMENT_TARGET="${macos_version}.0" export MACOSX_DEPLOYMENT_TARGET="${macos_version}.0"
export DEVELOPER_DIR="${apple_sdk}" export DEVELOPER_DIR="${apple_sdk}"
export NIX_LIBGCCJIT_VERSION="${pkgs.libgccjit.version}" export NIX_LIBGCCJIT_VERSION="${pkgs.libgccjit.version}"
export NIX_LIBGCCJIT_ROOT="${pkgs.libgccjit.outPath}" export NIX_LIBGCCJIT_ROOT="${pkgs.libgccjit.outPath}"
export BUNDLE_WITHOUT=development export BUNDLE_WITHOUT=development
''; '';
}; };
# Generate an attrset of shells for each macOS SDK version. # Generate an attrset of shells for each macOS SDK version.
versionShells = builtins.listToAttrs ( versionShells = builtins.listToAttrs (
@@ -93,10 +109,10 @@
}) sdk_versions }) sdk_versions
); );
in in
{ {
devShells = versionShells // { devShells = versionShells // {
default = mkDevShell {}; default = mkDevShell { };
}; };
} }
); );
} }

View File

@@ -13,7 +13,7 @@ coreutils-9.7
curl-8.14.1 curl-8.14.1
dbus-1.14.10 dbus-1.14.10
diffutils-3.12 diffutils-3.12
expat-2.7.1 expat-2.7.3
file-5.45 file-5.45
findutils-4.10.0 findutils-4.10.0
fontconfig-2.16.0 fontconfig-2.16.0
@@ -53,7 +53,7 @@ libxml2-2.13.8
mailutils-3.18 mailutils-3.18
nettle-3.10.1 nettle-3.10.1
nghttp2-1.65.0 nghttp2-1.65.0
openssl-3.4.2 openssl-3.4.3
patch-2.7.6 patch-2.7.6
pkg-config-wrapper-0.29.2 pkg-config-wrapper-0.29.2
python3-3.13.5 python3-3.13.5