-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild.sh
More file actions
154 lines (137 loc) · 5.93 KB
/
Copy pathbuild.sh
File metadata and controls
154 lines (137 loc) · 5.93 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
#!/usr/bin/env bash
# =============================================================================
# build.sh — direct clang++ build of the WSTP NAPI addon
#
# Uses shell-level quoting everywhere, so paths containing spaces (like
# "WSTP Backend" and "Wolfram 3.app") are handled correctly.
#
# Usage:
# bash build.sh # Release build → build/Release/wstp.node
# bash build.sh debug # Debug build → build/Debug/wstp.node
# bash build.sh clean # Remove build/
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
# ── clean ─────────────────────────────────────────────────────────────────────
if [[ "${1:-}" == "clean" ]]; then
rm -rf build
echo "Cleaned."
exit 0
fi
# ── mode ──────────────────────────────────────────────────────────────────────
BUILD_TYPE="${1:-release}"
if [[ "$BUILD_TYPE" == "debug" ]]; then
OUT_DIR="$SCRIPT_DIR/build/Debug"
OPT_FLAGS=(-O0 -g)
else
OUT_DIR="$SCRIPT_DIR/build/Release"
OPT_FLAGS=(-O2 -DNDEBUG)
fi
mkdir -p "$OUT_DIR"
OUTPUT="$OUT_DIR/wstp.node"
# ── locate node headers ───────────────────────────────────────────────────────
NODE_BIN="$(which node)"
NODE_PREFIX="$(node -p "'$NODE_BIN'.replace(/\\/(bin|MacOS)\\/node$/,'')" 2>/dev/null)"
NODE_HEADERS="${NODE_PREFIX}/include/node"
# Fallback: node-gyp cached headers
if [[ ! -f "$NODE_HEADERS/node_api.h" ]]; then
NODE_VER="$(node -p "process.version.replace('v','')")"
for candidate in \
"$HOME/Library/Caches/node-gyp/$NODE_VER/include/node" \
"$HOME/.node-gyp/$NODE_VER/include/node" \
"$HOME/.cache/node-gyp/$NODE_VER/include/node"; do
if [[ -f "$candidate/node_api.h" ]]; then
NODE_HEADERS="$candidate"
break
fi
done
fi
if [[ ! -f "$NODE_HEADERS/node_api.h" ]]; then
echo "ERROR: Could not find node_api.h. Run: node-gyp install" >&2
exit 1
fi
echo "Node headers : $NODE_HEADERS"
# ── locate node-addon-api headers ─────────────────────────────────────────────
NAPI_INCLUDE="$(node -p "require('node-addon-api').include.replace(/[\"']/g,'')" 2>/dev/null)"
if [[ -z "$NAPI_INCLUDE" || ! -f "$NAPI_INCLUDE/napi.h" ]]; then
echo "ERROR: node-addon-api not found — run: npm install" >&2
exit 1
fi
echo "NAPI headers : $NAPI_INCLUDE"
# ── locate WSTP SDK ───────────────────────────────────────────────────────────
ARCH="$(uname -m)"
case "$ARCH" in
arm64) WSTP_SUBDIR="MacOSX-ARM64" ;;
x86_64) WSTP_SUBDIR="MacOSX-x86-64" ;;
*) WSTP_SUBDIR="$ARCH" ;;
esac
# WSTP_DIR overrides everything; otherwise derive from WOLFRAM_APP (default: Wolfram 3.app)
WOLFRAM_APP_DEFAULT="/Applications/Wolfram 3.app"
if [[ -z "${WSTP_DIR:-}" ]]; then
WOLFRAM_APP="${WOLFRAM_APP:-$WOLFRAM_APP_DEFAULT}"
WSTP_SDK="$WOLFRAM_APP/Contents/SystemFiles/Links/WSTP/DeveloperKit/$WSTP_SUBDIR/CompilerAdditions"
else
WSTP_SDK="$WSTP_DIR"
fi
if [[ ! -f "$WSTP_SDK/wstp.h" ]]; then
echo "ERROR: WSTP SDK not found at: $WSTP_SDK" >&2
echo " Set WOLFRAM_APP to your Wolfram/Mathematica app bundle, e.g.:" >&2
echo " WOLFRAM_APP=/Applications/Mathematica.app bash build.sh" >&2
echo " Or set WSTP_DIR directly to the CompilerAdditions directory." >&2
exit 1
fi
echo "WSTP SDK : $WSTP_SDK"
# ── read version from package.json ───────────────────────────────────────────
ADDON_VERSION="$(node -p "JSON.parse(require('fs').readFileSync('$SCRIPT_DIR/package.json','utf8')).version")"
echo "Addon version : $ADDON_VERSION"
# ── find the node shared library for linking ──────────────────────────────────
# On macOS the node binary itself acts as the import library.
NODE_LIB="$(node -p "process.execPath")"
echo "Node lib : $NODE_LIB"
# ── compile sources ───────────────────────────────────────────────────────────
SOURCES=(
"$SCRIPT_DIR/src/addon.cc"
"$SCRIPT_DIR/src/diag.cc"
"$SCRIPT_DIR/src/wstp_expr.cc"
"$SCRIPT_DIR/src/drain.cc"
"$SCRIPT_DIR/src/evaluate_worker.cc"
"$SCRIPT_DIR/src/wstp_session.cc"
"$SCRIPT_DIR/src/wstp_reader.cc"
"$SCRIPT_DIR/src/syntax_check.cc"
)
OBJECTS=()
for SRC in "${SOURCES[@]}"; do
BASE="$(basename "$SRC" .cc)"
OBJ="$OUT_DIR/${BASE}.o"
OBJECTS+=("$OBJ")
echo "Compiling $SRC …"
clang++ \
-std=c++17 \
"${OPT_FLAGS[@]}" \
-Wall -Wextra \
-fPIC \
-fvisibility=hidden \
-DBUILDING_NODE_EXTENSION \
-DNAPI_DISABLE_CPP_EXCEPTIONS \
"-DWSTP_ADDON_VERSION=\"$ADDON_VERSION\"" \
"-DWSTP_ADDON_BUILD_DATE=\"$(date -u '+%Y-%m-%d')\"" \
-I "$NODE_HEADERS" \
-I "$NAPI_INCLUDE" \
-I "$WSTP_SDK" \
-I "$SCRIPT_DIR/src" \
-c "$SRC" \
-o "$OBJ"
done
echo "Linking $OUTPUT …"
clang++ \
-dynamiclib \
-undefined dynamic_lookup \
-o "$OUTPUT" \
"${OBJECTS[@]}" \
"$WSTP_SDK/libWSTPi4.a" \
-framework Foundation \
-framework SystemConfiguration \
-framework CoreFoundation
echo ""
echo "Build succeeded: $OUTPUT"