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 : 🔍 Debug ocamlfind + ocamlc.opt issue
63
+ run : |
64
+ set -e # fail on error
65
+
66
+ eval $(opam env)
67
+
68
+ echo "🔎 ocamlc : $(which ocamlc)"
69
+ echo "🔎 ocamlopt : $(which ocamlopt)"
70
+ echo "🔎 ocamlfind : $(which ocamlfind)"
71
+ echo "🔎 All ocamlfind on path:"
72
+ which -a ocamlfind
73
+
74
+ echo ""
75
+ echo "📄 Writing test.ml"
76
+ echo 'let () = print_endline "Hello from OCaml"' > test.ml
77
+
78
+ echo ""
79
+ echo "🧪 ocamlc compile"
80
+ ocamlc test.ml -o test_bytecode
81
+
82
+ echo ""
83
+ echo "🧪 ocamlopt compile"
84
+ ocamlopt test.ml -o test_native
85
+
86
+ echo ""
87
+ echo "🧪 ocamlfind ocamlc compile"
88
+ ocamlfind ocamlc -package zarith -linkpkg test.ml -o test_bytecode_find
89
+
90
+ echo ""
91
+ echo "🧪 ocamlfind ocamlopt compile"
92
+ ocamlfind ocamlopt -package zarith -linkpkg test.ml -o test_native_find
93
+
94
+ echo ""
95
+ echo "🧪 FULLPATH ocamlfind ocamlc compile"
96
+ /home/runner/work/z3/z3/_opam/bin/ocamlfind ocamlc -package zarith -linkpkg test.ml -o test_bytecode_full
97
+
98
+ echo ""
99
+ echo "🧪 FULLPATH ocamlfind ocamlopt compile"
100
+ /home/runner/work/z3/z3/_opam/bin/ocamlfind ocamlopt -package zarith -linkpkg test.ml -o test_native_full
101
+
102
+ echo ""
103
+ echo "✅ All compiles passed."
104
+
105
+ - name : 🧪 Debug OPAM + GITHUB_PATH setup
106
+ run : |
107
+ echo "🔍 PATH at this step:"
108
+ echo "$PATH" | tr ':' '\n'
109
+
110
+ echo ""
111
+ echo "📁 Listing \$GITHUB_PATH file (if exists):"
112
+ if [ -f "$GITHUB_PATH" ]; then
113
+ cat "$GITHUB_PATH"
114
+ else
115
+ echo "❌ GITHUB_PATH file does not exist at $GITHUB_PATH"
116
+ fi
117
+
118
+ echo ""
119
+ echo "📦 OPAM_SWITCH_PREFIX = $OPAM_SWITCH_PREFIX"
120
+ echo ""
121
+ echo "📂 Listing contents of \$OPAM_SWITCH_PREFIX/bin:"
122
+ ls -al "$OPAM_SWITCH_PREFIX/bin" || echo "❌ Directory does not exist"
123
+
124
+ echo ""
125
+ echo "🔍 Check if PATH includes _opam/bin:"
126
+ echo "$PATH" | grep "_opam/bin" || echo "❌ _opam/bin NOT in PATH"
127
+
128
+ echo ""
129
+ echo "✅ Done."
130
+
131
+ # Configure
132
+ - name : Configure with CMake
133
+ env :
134
+ RUNNER_OS : ${{ runner.os }}
135
+ CC : ${{ matrix.os == 'macos-latest' && 'ccache clang' || 'ccache gcc' }}
136
+ CXX : ${{ matrix.os == 'macos-latest' && 'ccache clang++' || 'ccache g++' }}
137
+ run : |
138
+ mkdir -p build
139
+ cd build
140
+ eval $(opam env)
141
+ echo "CC: $CC"
142
+ echo "CXX: $CXX"
143
+ echo "OCAMLFIND: $(which ocamlfind)"
144
+ echo "OCAMLC: $(which ocamlc)"
145
+ echo "OCAMLOPT: $(which ocamlopt)"
146
+ echo "OCAML_VERSION: $(ocamlc -version)"
147
+ echo "OCAMLLIB: $OCAMLLIB"
148
+ env | grep OCAML
149
+ cmake .. \
150
+ -G Ninja \
151
+ -DZ3_BUILD_LIBZ3_SHARED=ON \
152
+ -DZ3_BUILD_OCAML_BINDINGS=ON \
153
+ -DZ3_BUILD_JAVA_BINDINGS=OFF \
154
+ -DZ3_BUILD_PYTHON_BINDINGS=OFF \
155
+ -DZ3_BUILD_CLI=OFF \
156
+ -DZ3_BUILD_TEST_EXECUTABLES=OFF \
157
+ -DCMAKE_VERBOSE_MAKEFILE=TRUE
158
+
159
+ - name : Build Z3 and OCaml bindings
160
+ run : |
161
+ ccache -z || true
162
+ eval $(opam env)
163
+ cd build
164
+ ninja build_z3_ocaml_bindings
165
+ ccache -s || true
166
+
167
+ - name : Compile ml_example.byte
168
+ run : |
169
+ eval $(opam env)
170
+ ocamlfind ocamlc -o ml_example.byte \
171
+ -package zarith \
172
+ -linkpkg \
173
+ -I build/src/api/ml \
174
+ -dllpath build/src/api/ml \
175
+ build/src/api/ml/z3ml.cma \
176
+ examples/ml/ml_example.ml
177
+
178
+ - name : Run ml_example.byte
179
+ run : |
180
+ eval $(opam env)
181
+ ocamlrun ./ml_example.byte
182
+
183
+ - name : Compile ml_example (native)
184
+ run : |
185
+ eval $(opam env)
186
+ ocamlfind ocamlopt -o ml_example \
187
+ -package zarith \
188
+ -linkpkg \
189
+ -I build/src/api/ml \
190
+ build/src/api/ml/z3ml.cmxa \
191
+ examples/ml/ml_example.ml
192
+
193
+ - name : Run ml_example (native)
194
+ run : ./ml_example
0 commit comments