Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 9 additions & 55 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,11 @@ jobs:
cat "${RUNNER_TEMP}/webui-backend.log" 2>/dev/null || true

build-macos:
# Builds the C++ kernel + TTY, the Java GUI, the embedded-Prolog optimizer
# engine and the JPL optimizer server (OptServer), then runs the full test
# suite including the optimizer test. The optimizer test drives SecondoBDB in
# "-pl" mode (embeds libswipl, no JPL); OptServer uses JPL, which is why the
# Install step rebuilds swi-prolog from source with the Java package on.
# Builds the C++ kernel + TTY, the Java GUI and the embedded-Prolog
# optimizer engine, then runs the full test suite including the optimizer
# test. The optimizer test drives SecondoBDB in "-pl" mode, which embeds
# libswipl from the stock swi-prolog bottle -- no JPL, so no custom Prolog
# build is needed.
strategy:
fail-fast: false
matrix:
Expand All @@ -222,57 +222,11 @@ jobs:
- name: Install Homebrew packages
run: |
brew update
# Build tools + the external components the SDK used to provide.
# Build tools + the external components the SDK used to provide. The
# embedded optimizer links libswipl from the stock swi-prolog bottle;
# no JPL and no custom Prolog build are needed anymore.
brew install flex bison berkeley-db gsl jpeg-turbo boost gmp \
libxml2 readline nlohmann-json
# JPL is built against openjdk@21 -- the SAME major version as the
# Temurin JDK below that compiles OptimizerServer.java.
brew install openjdk@21
# swi-prolog's own dependencies come from bottles and are cheap; only
# the keg itself is expensive to build, and that one is cached below.
brew install --only-dependencies swi-prolog
# The Cellar path is /opt/homebrew on arm64 and /usr/local on Intel.
echo "SWIPL_CELLAR=$(brew --cellar)/swi-prolog" >> "$GITHUB_ENV"
echo "SWIPL_VERSION=$(brew info --json=v2 swi-prolog |
jq -r '.formulae[0].versions.stable')" >> "$GITHUB_ENV"

# Building swi-prolog from source takes several minutes, so keep the
# finished keg.
- name: Cache swi-prolog (built with JPL)
id: swipl-cache
uses: actions/cache@v6
with:
path: ${{ env.SWIPL_CELLAR }}
key: swipl-jpl-${{ matrix.os }}-${{ runner.arch }}-${{ env.SWIPL_VERSION }}-v1

- name: Build swi-prolog with JPL
if: steps.swipl-cache.outputs.cache-hit != 'true'
run: |
# The stock swi-prolog bottle is built with -DSWIPL_PACKAGES_JAVA=OFF,
# so it ships no jpl.jar / libjpl.dylib which the JPL optimizer
# server (OptServer) needs. Editing the formula requires the real
# homebrew/core tap rather than the API.
export HOMEBREW_NO_INSTALL_FROM_API=1
brew tap homebrew/core
formula="$(brew formula swi-prolog)"
echo "Editing formula: $formula"
sed -i '' 's/-DSWIPL_PACKAGES_JAVA=OFF/-DSWIPL_PACKAGES_JAVA=ON/' "$formula"
sed -i '' 's/^ def install/ depends_on "openjdk@21" => :build\n def install/' "$formula"
grep -nE 'SWIPL_PACKAGES_JAVA|openjdk' "$formula"
brew install --build-from-source swi-prolog

- name: Link cached swi-prolog
if: steps.swipl-cache.outputs.cache-hit == 'true'
run: |
# The cache restores the keg, but not its symlinks into the prefix.
brew link --overwrite swi-prolog

- name: Verify that JPL is present
run: |
# Guards both the fresh build and a stale/corrupt cache entry.
plbase="$(swipl --dump-runtime-variables | sed -n 's/^PLBASE="\(.*\)";/\1/p')"
ls -l "$plbase/lib/jpl.jar"
find "$plbase" -name 'libjpl.*' -print
libxml2 readline nlohmann-json swi-prolog

- name: Install Temurin JDK
uses: actions/setup-java@v5
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ makefile.algebras
/OptParser/scanner.c
/Optimizer/libregSecondo.so
/Optimizer/libregSecondo.jnilib
/Optimizer/optimizer
/Optimizer/opsyntaxg.pl
/Optimizer/tmp/
/Optimizer/.secondopltty_history
Expand All @@ -126,6 +127,7 @@ makefile.algebras
/Optimizer/TestOptimizer.log
/OptimizerBasic/libregSecondo.so
/OptimizerBasic/libregSecondo.jnilib
/Optimizer/temp_nested_list/

/bin/*.jpg
/bin/*.dbf
Expand Down
28 changes: 0 additions & 28 deletions CM-Scripts/initdemo.sh

This file was deleted.

6 changes: 2 additions & 4 deletions CM-Scripts/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,14 @@ done

#
# Optimizer tests (skippable via SECONDO_SKIP_OPTIMIZER_TESTS, e.g. when the
# optimizer and the JPL optimizer server were not built). TestOptimizer drives
# the optimizer through the embedded Prolog interface; TestOptServer exercises
# the JPL optimizer server (OptServer) over its socket protocol.
# optimizer was not built). TestOptimizer drives the optimizer through the
# embedded Prolog interface.
#
if [ "${SECONDO_SKIP_OPTIMIZER_TESTS:-}" == "true" ]; then
echo "*** Skipping optimizer tests (SECONDO_SKIP_OPTIMIZER_TESTS=true) ***"
else
echo "*** Executing optimizer tests ***"
runTest ${buildDir}/Optimizer "TestOptimizer" "time TestOptimizer" $timeOutMax
runTest ${buildDir}/Optimizer "TestOptServer" "time TestOptServer" $timeOutMax
# Guards against the SecondoPL autoloading regression (must_be/2 spam at
# optimizer startup); see Optimizer/TestSecondoPLStartup.
runTest ${buildDir}/Optimizer "TestSecondoPLStartup" \
Expand Down
63 changes: 11 additions & 52 deletions CM-Scripts/secondo-detect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ secondo_realpath() {
( cd "$(dirname "$p")" 2>/dev/null && printf '%s/%s\n' "$(pwd)" "$(basename "$p")" )
}

# Map a Prolog version number (e.g. 90209) to the JPL binding directory that
# OptServer/OptParser/Jpl build (10/30/70/82). Mirrors makefile.optimizer.
secondo_jplver() {
local v=${1:-0}
if [ "$v" -lt 50200 ] 2>/dev/null; then echo 10
elif [ "$v" -lt 70000 ] 2>/dev/null; then echo 30
elif [ "$v" -lt 80200 ] 2>/dev/null; then echo 70
else echo 82; fi
}

secondo_detect() {
local os machine cand jc jvmdir opener
os=$(uname -s); machine=$(uname -m)
Expand All @@ -58,34 +48,20 @@ secondo_detect() {
export SECONDO_PLATFORM

# --- Prolog (single source of truth: the swipl binary itself) ------------
# `swipl --dump-runtime-variables` reports version AND lib dir together, so
# the JPL binding directory can never drift from the linked libswipl.
# `swipl --dump-runtime-variables` reports the lib/include dirs together, so
# they can never drift from the linked libswipl. The embedded optimizer links
# libswipl in -pl mode; it needs no JPL (that was only the retired OptServer).
local swipl=${SECONDO_SWIPL:-$(command -v swipl 2>/dev/null || command -v pl 2>/dev/null)}
SECONDO_PL_FOUND=no
if [ -n "$swipl" ] && "$swipl" --dump-runtime-variables >/dev/null 2>&1; then
# sets PLBASE, PLLIBDIR, PLVERSION, PLARCH, PLSOEXT, ... as shell vars
eval "$("$swipl" --dump-runtime-variables)"
: "${PL_VERSION:=$PLVERSION}"
: "${SWI_HOME_DIR:=$PLBASE}"
: "${PL_LIB_DIR:=$PLLIBDIR}"
: "${PL_DLL_DIR:=$PLLIBDIR}"
: "${PL_INCLUDE_DIR:=$PLBASE/include}"
: "${PL_LIB:=swipl}"
: "${JPL_JAR:=$PLBASE/lib/jpl.jar}"
# The JPL library is libjpl.so on Linux but libjpl.dylib on macOS, while
# swipl reports PLSOEXT=so on BOTH. Probe for the file that is really there
# rather than deriving its name from PLSOEXT.
if [ -z "${JPL_DLL:-}" ]; then
for _jpl in "$PLLIBDIR/libjpl.$PLSOEXT" "$PLLIBDIR/libjpl.dylib" \
"$PLLIBDIR/libjpl.so"; do
if [ -f "$_jpl" ]; then JPL_DLL=$_jpl; break; fi
done
# Nothing found: keep the conventional name so --check can report it.
: "${JPL_DLL:=$PLLIBDIR/libjpl.$PLSOEXT}"
unset _jpl
fi
export PL_VERSION SWI_HOME_DIR PL_LIB_DIR PL_DLL_DIR PL_INCLUDE_DIR
export PL_LIB JPL_JAR JPL_DLL
export SWI_HOME_DIR PL_LIB_DIR PL_DLL_DIR PL_INCLUDE_DIR PL_LIB
SECONDO_PL_FOUND=yes
fi

Expand Down Expand Up @@ -194,7 +170,7 @@ secondo_detect() {
[ -n "${LIBRARY_PATH:-}" ] && export LIBRARY_PATH
fi

# --- JVM runtime dir (only the optimizer / JPL / JNI need libjvm) ---------
# --- JVM runtime dir (only the JNI-based algebras need libjvm) -----------
# libdb_cxx and libswipl resolve on the default loader path; libjvm never
# does, so this is the single directory the runtime linker actually needs.
jvmdir=""
Expand Down Expand Up @@ -246,48 +222,31 @@ secondo_detect() {
# Warn about drift/mismatch cases that used to fail silently.
# Returns non-zero if anything was flagged.
secondo_env_warnings() {
local w=0 live_swipl live_ver
local w=0
if [ "${SECONDO_PL_FOUND:-no}" != yes ]; then
echo " ! swipl not found -> optimizer disabled (install swi-prolog, or set SECONDO_SWIPL)"; w=1
fi
if [ -z "${J2SDK_ROOT:-}" ] || [ ! -e "${J2SDK_ROOT:-/nonexistent}" ]; then
echo " ! JDK not found -> Java GUI / optimizer server will not build (set J2SDK_ROOT)"; w=1
echo " ! JDK not found -> Java GUI will not build (set J2SDK_ROOT)"; w=1
fi
if [ ! -f "${BERKELEY_DB_DIR:-/nonexistent}/include/db_cxx.h" ]; then
echo " ! db_cxx.h not under ${BERKELEY_DB_DIR:-?} (set BERKELEY_DB_DIR)"; w=1
fi
# OptServer/OptTest link against libjpl; without it they fail late, at link
# time. A swipl built without the Java package ships no JPL at all.
if [ "${SECONDO_PL_FOUND:-no}" = yes ] && [ ! -f "${JPL_DLL:-/nonexistent}" ]; then
echo " ! JPL library not found at ${JPL_DLL:-?} -> optimizer server will not link"
echo " (swi-prolog must be built with the Java package, see the macOS install guide)"
w=1
fi
# exported PL_VERSION vs the swipl actually on PATH now (stale shell / upgrade)
live_swipl=${SECONDO_SWIPL:-$(command -v swipl 2>/dev/null || command -v pl 2>/dev/null)}
if [ -n "$live_swipl" ] && [ -n "${PL_VERSION:-}" ]; then
live_ver=$("$live_swipl" --dump-runtime-variables 2>/dev/null \
| sed -n 's/^PLVERSION="\([0-9]*\)".*/\1/p')
if [ -n "$live_ver" ] && [ "$live_ver" != "$PL_VERSION" ]; then
echo " ! PL_VERSION=$PL_VERSION but $live_swipl reports $live_ver -> re-source your .secondorc"; w=1
fi
fi
return $w
}

# One-line summary (+ warnings). This is what the build prints once per run.
secondo_env_summary() {
local jplver pl
jplver=$(secondo_jplver "${PL_VERSION:-0}")
if [ "${SECONDO_PL_FOUND:-no}" = yes ]; then pl="${PL_VERSION} -> JPL/${jplver}"; else pl="none"; fi
local pl
if [ "${SECONDO_PL_FOUND:-no}" = yes ]; then pl="${SWI_HOME_DIR:-found}"; else pl="none"; fi
printf 'secondo env: platform %s | swipl %s | jdk %s | bdb %s\n' \
"${SECONDO_PLATFORM:-?}" "$pl" "${J2SDK_ROOT:-MISSING}" "${BERKELEY_DB_DIR:-MISSING}"
secondo_env_warnings
}

# The variables that make/runtime care about, in one place.
SECONDO_VARS='SECONDO_BUILD_DIR SECONDO_PLATFORM PL_VERSION SWI_HOME_DIR PL_LIB_DIR
PL_DLL_DIR PL_INCLUDE_DIR PL_LIB JPL_JAR JPL_DLL J2SDK_ROOT SECONDO_JAVA
SECONDO_VARS='SECONDO_BUILD_DIR SECONDO_PLATFORM SWI_HOME_DIR PL_LIB_DIR
PL_DLL_DIR PL_INCLUDE_DIR PL_LIB J2SDK_ROOT SECONDO_JAVA
BERKELEY_DB_DIR BERKELEY_DB_LIB SECONDO_READLINE_DIR SECONDO_JPEG_DIR
SECONDO_FLEX_DIR SECONDO_LIBXML2_DIR SECONDO_JVM_LIB_DIR SECONDO_CONFIG
PD_HEADER PD_DVI_VIEWER PD_PS_VIEWER'
Expand Down
Loading
Loading