@@ -53,36 +53,60 @@ if [ ! -d "$COIN_INSTALL/include/coin-or" ]; then
5353 export CXX=em++
5454 export AR=emar
5555 export RANLIB=emranlib
56-
57- # Build CLP (includes CoinUtils)
58- " $COINBREW " fetch Clp
59- " $COINBREW " build Clp \
60- --prefix=" $COIN_INSTALL " \
61- --no-prompt \
62- --static \
63- --disable-shared \
64- --enable-static \
65- --tests=none
66-
67- # Build CBC (includes CGL)
68- " $COINBREW " fetch Cbc
69- " $COINBREW " build Cbc \
70- --prefix=" $COIN_INSTALL " \
71- --no-prompt \
72- --static \
73- --disable-shared \
74- --enable-static \
75- --tests=none
76-
77- # Build IPOPT with MUMPS
78- " $COINBREW " fetch Ipopt
79- " $COINBREW " build Ipopt \
80- --prefix=" $COIN_INSTALL " \
81- --no-prompt \
82- --static \
83- --disable-shared \
84- --enable-static \
85- --tests=none
56+ export F77=" fort77"
57+ export FC=" fort77"
58+ export FFLAGS=" -O2 -fPIC"
59+ export FCFLAGS=" -O2 -fPIC"
60+ export LDFLAGS=" -L$EMSDK /upstream/emscripten/cache/sysroot/lib/wasm32-emscripten"
61+
62+ # 1. Shallow clone repositories explicitly to avoid slow complete fetches
63+ # and network drops from coinbrew, while remaining in batch mode.
64+ echo " Shallow cloning COIN-OR packages (latest master)..."
65+ fetch_shallow () {
66+ local proj=$1
67+ if [ ! -d " $BUILD_DIR /$proj " ]; then
68+ echo " --> Cloning $proj ..."
69+ git clone --depth 1 " https://github.com/coin-or/$proj .git" " $BUILD_DIR /$proj "
70+ else
71+ echo " --> $proj already cloned."
72+ fi
73+ }
74+
75+ fetch_shallow Clp
76+ fetch_shallow Cbc
77+ fetch_shallow Ipopt
78+ fetch_shallow Bonmin
79+ fetch_shallow Couenne
80+
81+ # 2. Build solvers sequentially.
82+ # We do NOT use --reconfigure here, because it cascades and forces
83+ # coinbrew to redundantly rebuild all shared dependencies!
84+ # Pass the -L path to ALL builds uniformly so that Mumps (a transitive
85+ # dependency via Ipopt) can find libf2c.a in the Emscripten sysroot.
86+ COIN_LDFLAGS=" -static -L$EMSDK /upstream/emscripten/cache/sysroot/lib/wasm32-emscripten"
87+
88+ for pkg in Clp Cbc Ipopt Bonmin Couenne; do
89+ echo " --- Building $pkg ---"
90+
91+ # Ipopt and MINLP solvers need built-in LAPACK (no system LAPACK for WASM)
92+ EXTRA_FLAGS=" "
93+ if [ " $pkg " = " Ipopt" ] || [ " $pkg " = " Bonmin" ] || [ " $pkg " = " Couenne" ]; then
94+ EXTRA_FLAGS=" --with-lapack=BUILD"
95+ fi
96+
97+ " $COINBREW " build " $pkg " \
98+ --prefix=" $COIN_INSTALL " \
99+ --disable-shared \
100+ --host=wasm32-unknown-emscripten \
101+ --enable-static \
102+ --tests=none \
103+ --reconfigure \
104+ LDFLAGS=" $COIN_LDFLAGS " \
105+ LT_LDFLAGS=" -all-static" \
106+ --no-prompt \
107+ --verbosity=2 \
108+ $EXTRA_FLAGS
109+ done
86110
87111 cd " $PACKAGE_DIR "
88112fi
91115echo " Compiling COIN-OR WASM module..."
92116mkdir -p " $WASM_DIR "
93117
94- cat > " $BUILD_DIR /coinor_wasm_entry.c " << 'ENTRY_EOF '
118+ cat > " $BUILD_DIR /coinor_wasm_entry.cpp " << 'ENTRY_EOF '
95119/*
96120 * COIN-OR WASM entry points.
97- * Provides simplified C functions callable from JavaScript via Emscripten ccall().
121+ * Provides simplified C/C++ functions callable from JavaScript via Emscripten ccall().
98122 */
99123#include <stdlib.h>
100124#include <string.h>
101125
102126#define HAVE_IPOPT
103127#define HAVE_CLP
104128#define HAVE_CBC
129+ #define HAVE_BONMIN
130+ #define HAVE_COUENNE
105131
106132#include "coinor-interface.c"
133+ #include "coinor-minlp-interface.cpp"
134+
135+ extern "C" {
107136
108137/* IPOPT callback types from addFunction() */
109138typedef int (*wasm_eval_f)(int n, double* x, int new_x, double* obj, void* ud);
@@ -238,23 +267,28 @@ int coinor_cbc_wasm(
238267 coinor_result_free(&result);
239268 return result.status;
240269}
270+ } // extern "C"
241271ENTRY_EOF
242272
243- emcc -O2 \
273+ em++ -O2 \
274+ -std=c++14 \
244275 -I" $COIN_INSTALL /include/coin-or" \
245276 -I" $SRC_DIR " \
246- " $BUILD_DIR /coinor_wasm_entry.c " \
277+ " $BUILD_DIR /coinor_wasm_entry.cpp " \
247278 -L" $COIN_INSTALL /lib" \
279+ -lcouenne \
280+ -lbonmin \
248281 -lipopt \
249282 -lClp \
250283 -lCbc \
251- -lCoinUtils \
252- -lOsiClp \
253284 -lCgl \
285+ -lOsi \
286+ -lOsiClp \
287+ -lCoinUtils \
254288 -lm \
255289 -s MODULARIZE=1 \
256290 -s EXPORT_ES6=1 \
257- -s EXPORTED_FUNCTIONS=' ["_coinor_ipopt_wasm","_coinor_clp_wasm","_coinor_cbc_wasm","_malloc","_free"]' \
291+ -s EXPORTED_FUNCTIONS=' ["_coinor_ipopt_wasm","_coinor_clp_wasm","_coinor_cbc_wasm","_coinor_bonmin_wasm","_coinor_couenne_wasm"," _malloc","_free"]' \
258292 -s EXPORTED_RUNTIME_METHODS=' ["addFunction","removeFunction","ccall","cwrap"]' \
259293 -s ALLOW_TABLE_GROWTH=1 \
260294 -s ALLOW_MEMORY_GROWTH=1 \
0 commit comments