-3
crates/jacquard-lexicon/lexicons.kdl.example
-3
crates/jacquard-lexicon/lexicons.kdl.example
···
11
11
12
12
// Path to Cargo.toml for feature generation (optional)
13
13
// cargo-toml "Cargo.toml"
14
-
15
-
// NOTE: root-module option is currently disabled due to issues when set to non-"crate" values
16
-
// It will always use "crate" as the root module name
17
14
}
18
15
19
16
// Fetch ATProto and Bluesky lexicons from official repo
+113
nix/modules/cross.nix
+113
nix/modules/cross.nix
···
1
+
{inputs, ...}: {
2
+
imports = [inputs.rust-flake.flakeModules.nixpkgs];
3
+
4
+
perSystem = {pkgs, lib, config, system, ...}: let
5
+
# Get the filtered source from rust-project
6
+
src = config.rust-project.src;
7
+
8
+
# Helper to create a cross-compiled package
9
+
mkCrossPackage = {
10
+
crossSystem,
11
+
rustTarget,
12
+
extraArgs ? {}
13
+
}: let
14
+
# Import nixpkgs with cross-compilation configured
15
+
pkgs-cross = import inputs.nixpkgs {
16
+
inherit crossSystem;
17
+
localSystem = system;
18
+
overlays = [(import inputs.rust-overlay)];
19
+
};
20
+
21
+
# Set up crane with rust-overlay toolchain for the target
22
+
craneLib = (inputs.crane.mkLib pkgs-cross).overrideToolchain (p:
23
+
p.rust-bin.stable.latest.default.override {
24
+
targets = [rustTarget];
25
+
}
26
+
);
27
+
28
+
# Common crane args
29
+
commonArgs = {
30
+
inherit src;
31
+
pname = "jacquard-lexicon";
32
+
strictDeps = true;
33
+
doCheck = false; # Tests require lexicon corpus files
34
+
35
+
# Native build inputs (tools that run during build)
36
+
nativeBuildInputs = with pkgs; [
37
+
installShellFiles
38
+
];
39
+
40
+
postInstall = ''
41
+
# Install man pages and completions from build script output
42
+
for outdir in target/${rustTarget}/release/build/jacquard-lexicon-*/out; do
43
+
if [ -d "$outdir/man" ]; then
44
+
installManPage $outdir/man/*.1
45
+
fi
46
+
if [ -d "$outdir/completions" ]; then
47
+
for completion in $outdir/completions/*; do
48
+
case "$(basename "$completion")" in
49
+
*.bash) installShellCompletion --bash "$completion" ;;
50
+
*.fish) installShellCompletion --fish "$completion" ;;
51
+
_*) installShellCompletion --zsh "$completion" ;;
52
+
esac
53
+
done
54
+
fi
55
+
done
56
+
57
+
# Install example lexicons.kdl config
58
+
install -Dm644 ${./../../crates/jacquard-lexicon/lexicons.kdl.example} $out/share/doc/jacquard-lexicon/lexicons.kdl.example
59
+
'';
60
+
} // extraArgs;
61
+
in
62
+
craneLib.buildPackage commonArgs;
63
+
in {
64
+
packages = {
65
+
# Linux targets
66
+
jacquard-lexicon-x86_64-linux = mkCrossPackage {
67
+
crossSystem = {
68
+
config = "x86_64-unknown-linux-gnu";
69
+
};
70
+
rustTarget = "x86_64-unknown-linux-gnu";
71
+
};
72
+
73
+
jacquard-lexicon-aarch64-linux = mkCrossPackage {
74
+
crossSystem = {
75
+
config = "aarch64-unknown-linux-gnu";
76
+
};
77
+
rustTarget = "aarch64-unknown-linux-gnu";
78
+
};
79
+
80
+
# macOS targets
81
+
jacquard-lexicon-x86_64-darwin = mkCrossPackage {
82
+
crossSystem = {
83
+
config = "x86_64-apple-darwin";
84
+
};
85
+
rustTarget = "x86_64-apple-darwin";
86
+
};
87
+
88
+
jacquard-lexicon-aarch64-darwin = mkCrossPackage {
89
+
crossSystem = {
90
+
config = "aarch64-apple-darwin";
91
+
};
92
+
rustTarget = "aarch64-apple-darwin";
93
+
};
94
+
95
+
# Windows targets
96
+
jacquard-lexicon-x86_64-windows = mkCrossPackage {
97
+
crossSystem = {
98
+
config = "x86_64-w64-mingw32";
99
+
libc = "msvcrt";
100
+
};
101
+
rustTarget = "x86_64-pc-windows-gnu";
102
+
};
103
+
104
+
jacquard-lexicon-aarch64-windows = mkCrossPackage {
105
+
crossSystem = {
106
+
config = "aarch64-w64-mingw32";
107
+
libc = "msvcrt";
108
+
};
109
+
rustTarget = "aarch64-pc-windows-gnullvm";
110
+
};
111
+
};
112
+
};
113
+
}
+134
-59
scripts/package-binaries.sh
+134
-59
scripts/package-binaries.sh
···
1
1
#!/usr/bin/env bash
2
2
set -euo pipefail
3
3
4
-
# Script to package jacquard-codegen and lex-fetch binaries for distribution
5
-
# Creates tar.xz archives with binaries, README, LICENSE, and config files
4
+
# Script to package jacquard-lexicon binaries for distribution using Nix cross-compilation
5
+
# Creates tar.xz archives with binaries, man pages, completions, README, LICENSE, and config
6
6
#
7
7
# Generates two versions:
8
8
# - Unversioned archives in binaries/ (tracked in git, overwritten each build)
···
17
17
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
18
18
echo "Packaging version: $VERSION"
19
19
20
-
# Detect target triple (default to x86_64-unknown-linux-gnu)
21
-
TARGET="${CARGO_BUILD_TARGET:-x86_64-unknown-linux-gnu}"
22
-
echo "Target: $TARGET"
20
+
# Detect current system
21
+
CURRENT_SYSTEM=$(nix eval --impure --expr 'builtins.currentSystem' --raw)
22
+
echo "Current system: $CURRENT_SYSTEM"
23
+
24
+
# Map target triples to nix package names and friendly names
25
+
declare -A TARGET_TO_PACKAGE=(
26
+
["x86_64-unknown-linux-gnu"]="jacquard-lexicon-x86_64-linux"
27
+
["aarch64-unknown-linux-gnu"]="jacquard-lexicon-aarch64-linux"
28
+
["x86_64-apple-darwin"]="jacquard-lexicon-x86_64-darwin"
29
+
["aarch64-apple-darwin"]="jacquard-lexicon-aarch64-darwin"
30
+
["x86_64-pc-windows-gnu"]="jacquard-lexicon-x86_64-windows"
31
+
["aarch64-pc-windows-gnullvm"]="jacquard-lexicon-aarch64-windows"
32
+
)
33
+
34
+
# Determine which targets we can build from the current system
35
+
TARGETS=()
36
+
case "$CURRENT_SYSTEM" in
37
+
x86_64-linux)
38
+
# Linux can cross-compile to everything
39
+
TARGETS=(
40
+
"x86_64-unknown-linux-gnu"
41
+
"aarch64-unknown-linux-gnu"
42
+
"x86_64-apple-darwin"
43
+
"aarch64-apple-darwin"
44
+
"x86_64-pc-windows-gnu"
45
+
"aarch64-pc-windows-gnullvm"
46
+
)
47
+
echo "Building from x86_64-linux: All targets (Linux, macOS, Windows for x86_64 and aarch64)"
48
+
;;
49
+
aarch64-linux)
50
+
# Linux can cross-compile to everything
51
+
TARGETS=(
52
+
"aarch64-unknown-linux-gnu"
53
+
"x86_64-unknown-linux-gnu"
54
+
"x86_64-apple-darwin"
55
+
"aarch64-apple-darwin"
56
+
"x86_64-pc-windows-gnu"
57
+
"aarch64-pc-windows-gnullvm"
58
+
)
59
+
echo "Building from aarch64-linux: All targets (Linux, macOS, Windows for x86_64 and aarch64)"
60
+
;;
61
+
x86_64-darwin)
62
+
# macOS cross-compilation is limited
63
+
TARGETS=(
64
+
"x86_64-apple-darwin"
65
+
)
66
+
echo "Building from x86_64-darwin: x86_64-darwin only"
67
+
echo "Note: Cross to aarch64-darwin needs rosetta, cross to Linux/Windows needs more setup"
68
+
;;
69
+
aarch64-darwin)
70
+
# macOS aarch64 can build both macOS targets via rosetta
71
+
TARGETS=(
72
+
"aarch64-apple-darwin"
73
+
"x86_64-apple-darwin"
74
+
)
75
+
echo "Building from aarch64-darwin: macOS targets (aarch64 + x86_64 via rosetta)"
76
+
echo "Note: Cross to Linux/Windows needs more setup"
77
+
;;
78
+
*)
79
+
echo "Error: Unknown system: $CURRENT_SYSTEM"
80
+
echo "This script supports: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin"
81
+
exit 1
82
+
;;
83
+
esac
84
+
85
+
echo ""
86
+
echo "Will build for: ${TARGETS[*]}"
87
+
echo ""
23
88
24
89
# Output directories
25
90
OUTPUT_DIR="binaries"
···
27
92
mkdir -p "$OUTPUT_DIR"
28
93
mkdir -p "$RELEASES_DIR"
29
94
30
-
# Build binaries in release mode
31
-
echo "Building binaries..."
32
-
cargo build --release -p jacquard-lexicon --bin jacquard-codegen
33
-
cargo build --release -p jacquard-lexicon --bin lex-fetch
95
+
# Helper function to package for a target
96
+
package_target() {
97
+
local TARGET=$1
98
+
local PACKAGE_NAME="${TARGET_TO_PACKAGE[$TARGET]}"
34
99
35
-
# Binary locations
36
-
CODEGEN_BIN="target/release/jacquard-codegen"
37
-
LEXFETCH_BIN="target/release/lex-fetch"
100
+
echo ""
101
+
echo "======================================"
102
+
echo "Building for $TARGET"
103
+
echo "======================================"
38
104
39
-
# Verify binaries exist
40
-
if [[ ! -f "$CODEGEN_BIN" ]]; then
41
-
echo "Error: jacquard-codegen binary not found at $CODEGEN_BIN"
42
-
exit 1
43
-
fi
44
-
45
-
if [[ ! -f "$LEXFETCH_BIN" ]]; then
46
-
echo "Error: lex-fetch binary not found at $LEXFETCH_BIN"
47
-
exit 1
48
-
fi
49
-
50
-
# Helper function to package a binary
51
-
package_binary() {
52
-
local BIN_NAME=$1
53
-
local BIN_PATH=$2
54
-
local EXTRA_FILES=("${@:3}") # Additional files beyond README and LICENSE
55
-
56
-
echo "Packaging ${BIN_NAME}..."
105
+
# Build with nix using cross-compilation package
106
+
echo "Running: nix build .#${PACKAGE_NAME}"
107
+
if ! nix build ".#${PACKAGE_NAME}" -o "result-${TARGET}"; then
108
+
echo "Error: nix build failed for $TARGET"
109
+
return 1
110
+
fi
57
111
58
112
# Names for versioned and unversioned archives
59
-
local VERSIONED_NAME="${BIN_NAME}_${TARGET}_v${VERSION}"
60
-
local UNVERSIONED_NAME="${BIN_NAME}_${TARGET}"
113
+
local VERSIONED_NAME="jacquard-lexicon_${TARGET}_v${VERSION}"
114
+
local UNVERSIONED_NAME="jacquard-lexicon_${TARGET}"
61
115
62
116
# Create staging directory
63
117
local STAGE_DIR="/tmp/${VERSIONED_NAME}"
64
118
rm -rf "$STAGE_DIR"
65
119
mkdir -p "$STAGE_DIR"
66
120
67
-
# Copy files
68
-
cp "$BIN_PATH" "$STAGE_DIR/"
69
-
cp LICENSE "$STAGE_DIR/"
70
-
cp README.md "$STAGE_DIR/"
71
-
for file in "${EXTRA_FILES[@]}"; do
72
-
[[ -n "$file" ]] && cp "$file" "$STAGE_DIR/"
73
-
done
121
+
# Detect if this is a Windows target
122
+
if [[ "$TARGET" == *"windows"* ]]; then
123
+
# Windows: just binaries, README, LICENSE, example config
124
+
mkdir -p "$STAGE_DIR/bin"
125
+
cp "result-${TARGET}"/bin/*.exe "$STAGE_DIR/bin/" 2>/dev/null || true
126
+
cp LICENSE "$STAGE_DIR/"
127
+
cp README.md "$STAGE_DIR/"
74
128
75
-
# Strip binary (reduce size)
76
-
strip "$STAGE_DIR/$BIN_NAME" || echo "Warning: strip failed, skipping"
129
+
# Copy example config to a more Windows-friendly location
130
+
mkdir -p "$STAGE_DIR/examples"
131
+
cp crates/jacquard-lexicon/lexicons.kdl.example "$STAGE_DIR/examples/" 2>/dev/null || true
132
+
else
133
+
# Unix (Linux/macOS): full structure with man pages and completions
134
+
cp -r "result-${TARGET}"/* "$STAGE_DIR/"
135
+
cp LICENSE "$STAGE_DIR/"
136
+
cp README.md "$STAGE_DIR/"
137
+
fi
77
138
78
139
# Create versioned archive (for releases)
79
140
cd /tmp
80
-
tar -cJf "${VERSIONED_NAME}.tar.xz" "$VERSIONED_NAME"
81
-
mv "${VERSIONED_NAME}.tar.xz" "$PROJECT_ROOT/$RELEASES_DIR/"
82
-
echo " Created: ${RELEASES_DIR}/${VERSIONED_NAME}.tar.xz"
83
141
84
-
# Rename staging directory for unversioned archive
85
-
mv "$VERSIONED_NAME" "$UNVERSIONED_NAME"
142
+
# Use .zip for Windows, .tar.xz for Unix
143
+
if [[ "$TARGET" == *"windows"* ]]; then
144
+
zip -r "${VERSIONED_NAME}.zip" "$VERSIONED_NAME"
145
+
mv "${VERSIONED_NAME}.zip" "$PROJECT_ROOT/$RELEASES_DIR/"
146
+
echo " Created: ${RELEASES_DIR}/${VERSIONED_NAME}.zip"
86
147
87
-
# Create unversioned archive (tracked in git)
88
-
tar -cJf "${UNVERSIONED_NAME}.tar.xz" "$UNVERSIONED_NAME"
89
-
mv "${UNVERSIONED_NAME}.tar.xz" "$PROJECT_ROOT/$OUTPUT_DIR/"
90
-
echo " Created: ${OUTPUT_DIR}/${UNVERSIONED_NAME}.tar.xz"
148
+
# Rename and create unversioned archive
149
+
mv "$VERSIONED_NAME" "$UNVERSIONED_NAME"
150
+
zip -r "${UNVERSIONED_NAME}.zip" "$UNVERSIONED_NAME"
151
+
mv "${UNVERSIONED_NAME}.zip" "$PROJECT_ROOT/$OUTPUT_DIR/"
152
+
echo " Created: ${OUTPUT_DIR}/${UNVERSIONED_NAME}.zip"
153
+
else
154
+
tar -cJf "${VERSIONED_NAME}.tar.xz" "$VERSIONED_NAME"
155
+
mv "${VERSIONED_NAME}.tar.xz" "$PROJECT_ROOT/$RELEASES_DIR/"
156
+
echo " Created: ${RELEASES_DIR}/${VERSIONED_NAME}.tar.xz"
157
+
158
+
# Rename and create unversioned archive
159
+
mv "$VERSIONED_NAME" "$UNVERSIONED_NAME"
160
+
tar -cJf "${UNVERSIONED_NAME}.tar.xz" "$UNVERSIONED_NAME"
161
+
mv "${UNVERSIONED_NAME}.tar.xz" "$PROJECT_ROOT/$OUTPUT_DIR/"
162
+
echo " Created: ${OUTPUT_DIR}/${UNVERSIONED_NAME}.tar.xz"
163
+
fi
91
164
92
165
# Cleanup
93
166
rm -rf "$UNVERSIONED_NAME"
167
+
rm -f "$PROJECT_ROOT/result-${TARGET}"
94
168
cd "$PROJECT_ROOT"
95
169
}
96
170
97
-
# Package jacquard-codegen
98
-
package_binary "jacquard-codegen" "$CODEGEN_BIN"
99
-
100
-
# Package lex-fetch (with lexicons.kdl)
101
-
package_binary "lex-fetch" "$LEXFETCH_BIN" "lexicons.kdl"
171
+
# Build for all targets
172
+
for target in "${TARGETS[@]}"; do
173
+
package_target "$target" || echo "Warning: build failed for $target, continuing..."
174
+
done
102
175
103
176
# Print summary
104
177
echo ""
105
178
echo "Packaging complete!"
106
179
echo ""
107
180
echo "Tracked archives (binaries/):"
108
-
ls -lh "$OUTPUT_DIR"/*.tar.xz
181
+
ls -lh "$OUTPUT_DIR"/*.tar.xz 2>/dev/null || true
182
+
ls -lh "$OUTPUT_DIR"/*.zip 2>/dev/null || true
109
183
echo ""
110
184
echo "Release archives (binaries/releases/):"
111
-
ls -lh "$RELEASES_DIR"/*.tar.xz
185
+
ls -lh "$RELEASES_DIR"/*.tar.xz 2>/dev/null || true
186
+
ls -lh "$RELEASES_DIR"/*.zip 2>/dev/null || true
112
187
113
188
# Generate checksums for tracked archives
114
189
echo ""
115
190
echo "Generating checksums for tracked archives..."
116
191
cd "$OUTPUT_DIR"
117
-
sha256sum *.tar.xz > SHA256SUMS
192
+
sha256sum *.tar.xz *.zip 2>/dev/null > SHA256SUMS || true
118
193
echo "Checksums written to ${OUTPUT_DIR}/SHA256SUMS"
119
194
cat SHA256SUMS
120
195
···
122
197
echo ""
123
198
echo "Generating checksums for release archives..."
124
199
cd "$PROJECT_ROOT/$RELEASES_DIR"
125
-
sha256sum *.tar.xz > SHA256SUMS
200
+
sha256sum *.tar.xz *.zip 2>/dev/null > SHA256SUMS || true
126
201
echo "Checksums written to ${RELEASES_DIR}/SHA256SUMS"
127
202
cat SHA256SUMS