678557caf7
Adds --capture-mic/--mic-output for a second, independently-captured audio track (mic vs system, written to separate outputs to avoid interleaving corruption). Embeds Info.plist at link time so the binary carries a stable CFBundleIdentifier and the usage-description keys TCC requires, and adds scripts/build-signed.sh + scripts/create-signing-identity.sh so a rebuilt binary keeps the same signing identity instead of losing granted permissions on every rebuild. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
87 lines
3.2 KiB
Bash
Executable File
87 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Builds audiotee, signs it with a stable identity, and installs it to a
|
|
# fixed path. Both steps matter for Core Audio process tap / microphone TCC
|
|
# permissions to survive across rebuilds — see CONTEXT.md §6.2 and §8:
|
|
#
|
|
# - SwiftPM ad-hoc-signs debug/release builds by default. Ad-hoc signatures
|
|
# are keyed off the binary's own hash, so every rebuild looks like a new
|
|
# app to TCC and permission has to be re-granted.
|
|
# - TCC has also been observed keying on binary path, so builds are installed
|
|
# to a fixed location outside .build/.
|
|
#
|
|
# Usage:
|
|
# scripts/build-signed.sh # build, sign, install to ~/bin
|
|
# scripts/build-signed.sh --reset-tcc # also reset TCC state for this
|
|
# # binary, useful after changing
|
|
# # Info.plist or the signing identity
|
|
#
|
|
# Requires a self-signed code-signing certificate in your keychain. If you
|
|
# don't have one yet:
|
|
# 1. Open Keychain Access
|
|
# 2. Keychain Access menu > Certificate Assistant > Create a Certificate...
|
|
# 3. Name it (e.g. "audiotee-dev"), Identity Type: Self Signed Root,
|
|
# Certificate Type: Code Signing
|
|
# 4. Create it, then in Keychain Access double-click it, expand "Trust",
|
|
# and set "Code Signing" to "Always Trust"
|
|
# Override auto-detection with: AUDIOTEE_SIGNING_IDENTITY="Your Cert Name"
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
BUNDLE_ID="com.stephanetailland.audiotee"
|
|
INSTALL_DIR="${AUDIOTEE_INSTALL_DIR:-$HOME/bin}"
|
|
INSTALL_PATH="$INSTALL_DIR/audiotee"
|
|
RESET_TCC=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--reset-tcc) RESET_TCC=true ;;
|
|
*)
|
|
echo "Unknown argument: $arg" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ -n "${AUDIOTEE_SIGNING_IDENTITY:-}" ]]; then
|
|
IDENTITY="$AUDIOTEE_SIGNING_IDENTITY"
|
|
else
|
|
# Real identity lines look like ` 1) <hash> "Name"`; the "N valid
|
|
# identities found" summary line has no ")" and must not be counted.
|
|
IDENTITY_LINES="$(security find-identity -v -p codesigning | grep '^ *[0-9]*)' || true)"
|
|
IDENTITY_COUNT="$(printf '%s\n' "$IDENTITY_LINES" | grep -c . || true)"
|
|
if [[ "$IDENTITY_COUNT" -eq 0 ]]; then
|
|
echo "Error: no code-signing identity found in your keychain." >&2
|
|
echo "See the comment at the top of this script for how to create one." >&2
|
|
exit 1
|
|
elif [[ "$IDENTITY_COUNT" -gt 1 ]]; then
|
|
echo "Error: multiple code-signing identities found. Set AUDIOTEE_SIGNING_IDENTITY" >&2
|
|
echo "to the one to use:" >&2
|
|
echo "$IDENTITY_LINES" >&2
|
|
exit 1
|
|
fi
|
|
IDENTITY="$(printf '%s\n' "$IDENTITY_LINES" | sed -n 's/.*"\(.*\)"/\1/p')"
|
|
fi
|
|
|
|
echo "Building (release)..."
|
|
swift build -c release
|
|
|
|
BUILT_BINARY="$REPO_ROOT/.build/release/audiotee"
|
|
|
|
echo "Signing with identity: $IDENTITY"
|
|
codesign --force --sign "$IDENTITY" --identifier "$BUNDLE_ID" "$BUILT_BINARY"
|
|
|
|
mkdir -p "$INSTALL_DIR"
|
|
cp "$BUILT_BINARY" "$INSTALL_PATH"
|
|
|
|
echo "Installed to $INSTALL_PATH"
|
|
codesign -dvvv "$INSTALL_PATH"
|
|
|
|
if [[ "$RESET_TCC" == true ]]; then
|
|
echo "Resetting TCC state for $BUNDLE_ID..."
|
|
tccutil reset SystemAudioCaptureRequests "$BUNDLE_ID" || true
|
|
tccutil reset Microphone "$BUNDLE_ID" || true
|
|
fi
|