-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild-target-sdk.sh
More file actions
executable file
·173 lines (153 loc) · 6.1 KB
/
build-target-sdk.sh
File metadata and controls
executable file
·173 lines (153 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env bash
# Packages a target SDK tarball for cross-compilation.
# Runs on CI after build-vendor.sh. Copies vendor .a files and C bridge .o files
# into a tarball that can be downloaded with `chad target add <name>`.
set -euo pipefail
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
VENDOR_DIR="$REPO_DIR/vendor"
C_BRIDGES_DIR="$REPO_DIR/c_bridges"
# Detect platform
UNAME_S=$(uname -s)
UNAME_M=$(uname -m)
if [ "$UNAME_S" = "Darwin" ]; then
TARGET_OS="macos"
elif [ "$UNAME_S" = "Linux" ]; then
TARGET_OS="linux"
else
echo "Unsupported OS: $UNAME_S"
exit 1
fi
if [ "$UNAME_M" = "x86_64" ]; then
TARGET_ARCH="x64"
LLVM_ARCH="x86_64"
elif [ "$UNAME_M" = "aarch64" ] || [ "$UNAME_M" = "arm64" ]; then
TARGET_ARCH="arm64"
LLVM_ARCH="aarch64"
else
echo "Unsupported arch: $UNAME_M"
exit 1
fi
TARGET_NAME="${TARGET_OS}-${TARGET_ARCH}"
TRIPLE="${LLVM_ARCH}-unknown-linux-gnu"
if [ "$TARGET_OS" = "macos" ]; then
TRIPLE="${LLVM_ARCH}-apple-darwin"
fi
echo "==> Building target SDK: ${TARGET_NAME}"
echo " Triple: ${TRIPLE}"
SDK_DIR="$REPO_DIR/.sdk-staging/${TARGET_NAME}"
rm -rf "$SDK_DIR"
mkdir -p "$SDK_DIR/vendor" "$SDK_DIR/bridges"
# Copy vendor libraries
echo " Copying vendor libraries..."
cp "$VENDOR_DIR/bdwgc/libgc.a" "$SDK_DIR/vendor/"
cp "$VENDOR_DIR/yyjson/libyyjson.a" "$SDK_DIR/vendor/"
cp "$VENDOR_DIR/libuv/build/libuv.a" "$SDK_DIR/vendor/"
cp "$VENDOR_DIR/picohttpparser/picohttpparser.o" "$SDK_DIR/vendor/"
if [ -f "$VENDOR_DIR/tree-sitter/libtree-sitter.a" ]; then
cp "$VENDOR_DIR/tree-sitter/libtree-sitter.a" "$SDK_DIR/vendor/"
fi
# Copy tree-sitter TypeScript objects if they exist
if [ -d "$REPO_DIR/build" ]; then
for obj in tree-sitter-typescript-parser.o tree-sitter-typescript-scanner.o; do
if [ -f "$REPO_DIR/build/$obj" ]; then
cp "$REPO_DIR/build/$obj" "$SDK_DIR/vendor/"
fi
done
if [ -f "$REPO_DIR/build/treesitter-bridge.o" ]; then
cp "$REPO_DIR/build/treesitter-bridge.o" "$SDK_DIR/bridges/"
fi
fi
# Copy C bridge object files
echo " Copying bridge objects..."
for bridge in child-process-bridge.o os-bridge.o time-bridge.o base64-bridge.o url-bridge.o regex-bridge.o dotenv-bridge.o watch-bridge.o lws-bridge.o multipart-bridge.o child-process-spawn.o; do
if [ -f "$C_BRIDGES_DIR/$bridge" ]; then
cp "$C_BRIDGES_DIR/$bridge" "$SDK_DIR/bridges/"
fi
done
# Package sysroot for Linux targets (needed when cross-compiling from macOS).
# Includes CRT startup objects, system libraries, and GCC support files that
# the linker needs to produce a working ELF binary.
if [ "$TARGET_OS" = "linux" ]; then
SYSROOT_DIR="$SDK_DIR/sysroot"
mkdir -p "$SYSROOT_DIR/usr/lib"
# Find the system lib directory: multiarch (Debian/Ubuntu), lib64, or /usr/lib
MULTIARCH_DIR="/usr/lib/${UNAME_M}-linux-gnu"
if [ ! -d "$MULTIARCH_DIR" ]; then
MULTIARCH_DIR="/usr/lib64"
fi
if [ ! -d "$MULTIARCH_DIR" ]; then
MULTIARCH_DIR="/usr/lib"
fi
# On modern Ubuntu, .a files can be linker scripts with absolute paths
# (e.g. libm.a contains: GROUP ( /usr/lib/.../libm-2.39.a /usr/lib/.../libmvec.a )).
# This function copies the actual archives and rewrites scripts with local paths.
copy_sysroot_lib() {
local src="$1"
local dst_dir="$2"
local name=$(basename "$src")
# Real archives start with "!<arch>" — copy directly
if head -c7 "$src" 2>/dev/null | grep -q '!<arch>'; then
cp "$src" "$dst_dir/"
return
fi
# Linker script — copy all referenced .a files, then rewrite with local paths
for ref in $(grep -o '/[^ )"]*\.a' "$src" 2>/dev/null); do
[ -f "$ref" ] && cp -n "$ref" "$dst_dir/"
done
# Strip directory paths, drop AS_NEEDED blocks (shared lib refs not needed for -static)
sed -e 's|/[^ )]*\/||g' -e 's|AS_NEEDED ( [^)]* )||g' "$src" > "$dst_dir/$name"
}
if [ -d "$MULTIARCH_DIR" ]; then
echo " Copying sysroot from $MULTIARCH_DIR..."
# CRT startup objects — crt1.o is for static linking, Scrt1.o for PIE/shared
for crt in crt1.o Scrt1.o crti.o crtn.o; do
[ -f "$MULTIARCH_DIR/$crt" ] && cp "$MULTIARCH_DIR/$crt" "$SYSROOT_DIR/usr/lib/"
done
# System libraries — use copy_sysroot_lib to handle linker scripts
for lib in libc.a libm.a libdl.a librt.a libpthread.a libc_nonshared.a libmvec.a; do
[ -f "$MULTIARCH_DIR/$lib" ] && copy_sysroot_lib "$MULTIARCH_DIR/$lib" "$SYSROOT_DIR/usr/lib/"
done
fi
# GCC support objects and libraries (crtbeginS.o, crtendS.o, libgcc.a, libgcc_s.so)
GCC_DIR=$(find /usr/lib/gcc/${UNAME_M}-linux-gnu -maxdepth 1 -type d 2>/dev/null | sort -V | tail -1)
if [ -n "$GCC_DIR" ] && [ -d "$GCC_DIR" ]; then
echo " Copying GCC support from $GCC_DIR..."
# crtbeginT.o/crtendT.o for static, crtbeginS.o/crtendS.o for shared/PIE
for obj in crtbeginT.o crtendT.o crtbeginS.o crtendS.o crtbegin.o crtend.o; do
[ -f "$GCC_DIR/$obj" ] && cp "$GCC_DIR/$obj" "$SYSROOT_DIR/usr/lib/"
done
[ -f "$GCC_DIR/libgcc.a" ] && cp "$GCC_DIR/libgcc.a" "$SYSROOT_DIR/usr/lib/"
[ -f "$GCC_DIR/libgcc_eh.a" ] && cp "$GCC_DIR/libgcc_eh.a" "$SYSROOT_DIR/usr/lib/"
# libgcc_s might be a linker script or symlink — copy the actual .so
for f in $GCC_DIR/libgcc_s.so* /lib/${UNAME_M}-linux-gnu/libgcc_s.so*; do
[ -f "$f" ] && cp -L "$f" "$SYSROOT_DIR/usr/lib/"
done
fi
echo " Sysroot contents:"
ls "$SYSROOT_DIR/usr/lib/"
fi
# Write sdk.json metadata
VERSION="0.1.0"
if [ -f "$REPO_DIR/package.json" ]; then
VERSION=$(node -e "console.log(require('./package.json').version)" 2>/dev/null || echo "0.1.0")
fi
cat > "$SDK_DIR/sdk.json" <<EOF
{
"version": "${VERSION}",
"triple": "${TRIPLE}",
"os": "${TARGET_OS}",
"arch": "${TARGET_ARCH}",
"libc": "$([ "$TARGET_OS" = "linux" ] && echo "gnu" || echo "system")"
}
EOF
# Create tarball — contents are at the top level (vendor/, bridges/, sdk.json)
TARBALL="$REPO_DIR/chadscript-target-${TARGET_NAME}.tar.gz"
echo " Creating tarball: $TARBALL"
tar -czf "$TARBALL" -C "$SDK_DIR" .
# Show what we built
echo ""
echo "Target SDK '${TARGET_NAME}' built successfully"
echo " Tarball: $TARBALL"
echo " Size: $(du -h "$TARBALL" | cut -f1)"
ls -la "$SDK_DIR/vendor/"
ls -la "$SDK_DIR/bridges/"