1
+ name : OCaml Binding CI (Ubuntu + macOS)
2
+
3
+ on :
4
+ push :
5
+ branches : [ "**" ]
6
+ pull_request :
7
+ branches : [ "**" ]
8
+
9
+ jobs :
10
+ build-test :
11
+ strategy :
12
+ matrix :
13
+ os : [ubuntu-latest, macos-latest]
14
+ ocaml-version : ["5"]
15
+ fail-fast : false
16
+ runs-on : ${{ matrix.os }}
17
+
18
+ steps :
19
+ - name : Checkout code
20
+ uses : actions/checkout@v4
21
+
22
+ # Cache ccache (shared across runs)
23
+ - name : Cache ccache
24
+ uses : actions/cache@v4
25
+ with :
26
+ path : ~/.ccache
27
+ key : ${{ runner.os }}-ccache-${{ github.sha }}
28
+ restore-keys : |
29
+ ${{ runner.os }}-ccache-
30
+
31
+ # Cache opam (compiler + packages)
32
+ - name : Cache opam
33
+ uses : actions/cache@v4
34
+ with :
35
+ path : ~/.opam
36
+ key : ${{ runner.os }}-opam-${{ matrix.ocaml-version }}-${{ github.sha }}
37
+ restore-keys : |
38
+ ${{ runner.os }}-opam-${{ matrix.ocaml-version }}-
39
+
40
+ # Setup OCaml via action
41
+ - uses : ocaml/setup-ocaml@v3
42
+ with :
43
+ ocaml-compiler : ${{ matrix.ocaml-version }}
44
+ opam-disable-sandboxing : true
45
+
46
+ # Platform-specific dependencies
47
+ - name : Install system dependencies (Ubuntu)
48
+ if : matrix.os == 'ubuntu-latest'
49
+ run : |
50
+ sudo apt-get update
51
+ sudo apt-get install -y \
52
+ bubblewrap m4 libgmp-dev pkg-config ninja-build ccache
53
+
54
+ - name : Install system dependencies (macOS)
55
+ if : matrix.os == 'macos-latest'
56
+ run : |
57
+ brew install gmp pkg-config ninja ccache
58
+
59
+ - name : Install required opam packages
60
+ run : opam install -y ocamlfind zarith
61
+
62
+ - name : 🔍 OCaml toolchain sanity check (with ocamlfind)
63
+ run : |
64
+ eval $(opam env)
65
+ echo "📦 OCaml version: $(ocamlc -version)"
66
+ echo ""
67
+
68
+ echo "📍 Shell-resolved paths:"
69
+ for bin in ocamlc ocamlopt ocamlc.opt ocamlopt.opt ocamldep ocamldep.opt ocamlfind; do
70
+ if command -v $bin >/dev/null 2>&1; then
71
+ echo "✅ Found $bin at: $(which $bin)"
72
+ else
73
+ echo "❌ Missing $bin"
74
+ fi
75
+ done
76
+
77
+ echo ""
78
+ echo "📂 OPAM_SWITCH_PREFIX/bin:"
79
+ ls -al "$OPAM_SWITCH_PREFIX/bin"
80
+
81
+ echo ""
82
+ echo "📎 ocamlfind configuration:"
83
+ if command -v ocamlfind >/dev/null 2>&1; then
84
+ echo " 🔧 ocamlc : $(ocamlfind printconf ocamlc)"
85
+ echo " 🔧 ocamlopt : $(ocamlfind printconf ocamlopt)"
86
+ echo " 🔧 ocamldep : $(ocamlfind printconf ocamldep)"
87
+ echo " 🔧 stdlib : $(ocamlfind printconf stdlib)"
88
+ echo " 🔧 ld.conf : $(ocamlfind printconf ld.conf)"
89
+ else
90
+ echo "⚠️ ocamlfind not found, skipping ocamlfind printconf"
91
+ fi
92
+
93
+ echo ""
94
+ echo "📌 PATH : $PATH"
95
+
96
+ # Optional fail-fast to stop build if anything is missing
97
+ echo ""
98
+ echo "🚨 Manually checking for required binaries..."
99
+ for required in ocamlc ocamlopt ocamlfind; do
100
+ if ! command -v $required >/dev/null 2>&1; then
101
+ echo "❌ Required binary '$required' is missing. Failing build."
102
+ exit 1
103
+ fi
104
+ done
105
+
106
+ exit 1
107
+
108
+ # Configure
109
+ - name : Configure with CMake
110
+ env :
111
+ RUNNER_OS : ${{ runner.os }}
112
+ CC : ${{ matrix.os == 'macos-latest' && 'ccache clang' || 'ccache gcc' }}
113
+ CXX : ${{ matrix.os == 'macos-latest' && 'ccache clang++' || 'ccache g++' }}
114
+ run : |
115
+ mkdir -p build
116
+ cd build
117
+ eval $(opam env)
118
+ echo "CC: $CC"
119
+ echo "CXX: $CXX"
120
+ echo "OCAMLFIND: $(which ocamlfind)"
121
+ echo "OCAML: $(which ocamlc)"
122
+ echo "OCAML_VERSION: $(ocamlc -version)"
123
+ echo "OCAMLLIB: $OCAMLLIB"
124
+ env | grep OCAML
125
+ cmake .. \
126
+ -G Ninja \
127
+ -DZ3_BUILD_LIBZ3_SHARED=ON \
128
+ -DZ3_BUILD_OCAML_BINDINGS=ON \
129
+ -DZ3_BUILD_JAVA_BINDINGS=OFF \
130
+ -DZ3_BUILD_PYTHON_BINDINGS=OFF \
131
+ -DZ3_BUILD_CLI=OFF \
132
+ -DZ3_BUILD_TEST_EXECUTABLES=OFF \
133
+ -DCMAKE_VERBOSE_MAKEFILE=TRUE
134
+
135
+ - name : Build Z3 and OCaml bindings
136
+ run : |
137
+ ccache -z || true
138
+ cd build
139
+ ninja build_z3_ocaml_bindings
140
+ ccache -s || true
141
+
142
+ - name : Compile ml_example.byte
143
+ run : |
144
+ ocamlfind ocamlc -o ml_example.byte \
145
+ -package zarith \
146
+ -linkpkg \
147
+ -I build/src/api/ml \
148
+ -dllpath build/src/api/ml \
149
+ build/src/api/ml/z3ml.cma \
150
+ examples/ml/ml_example.ml
151
+
152
+ - name : Run ml_example.byte
153
+ run : ./ml_example.byte
154
+
155
+ - name : Compile ml_example (native)
156
+ run : |
157
+ ocamlfind ocamlopt -o ml_example \
158
+ -package zarith \
159
+ -linkpkg \
160
+ -I build/src/api/ml \
161
+ build/src/api/ml/z3ml.cmxa \
162
+ examples/ml/ml_example.ml
163
+
164
+ - name : Run ml_example (native)
165
+ run : ./ml_example
0 commit comments