Skip to content

Release 9.6.5 - #583

Merged
scijones merged 73 commits into
developmentfrom
cmake-release-9.6.5
May 6, 2026
Merged

scijones merged 73 commits into
developmentfrom
cmake-release-9.6.5

Conversation

@scijones

@scijones scijones commented May 6, 2026

Copy link
Copy Markdown
Contributor

Merges the cmake-release-9.6.5 branch into development for the 9.6.5 release.

The branch already incorporates all of development's intervening release-tooling work; the merge into the branch resolved 3 add/add or content conflicts (release.yml, assemble-release.cmake, cmake-multi-platform.yml) by keeping the branch versions, since each was a more mature iteration of the same in-flight work.

Full cmake-multi-platform.yml CI passes on the branch (build-nix x8, build-windows x4, build-svs x3, build-swig x3, plus test_performance now functional on unprivileged runners).

amininger and others added 30 commits May 16, 2025 11:01
…ith conjunctive conditions

this deals with conjunctive conditions that include a positive and negative test for the same symbol. it's a debugging workaround, not a fix, for now.
i fixed a use-after-free by refcounting on orphaned justifications
… and orphaned wmes from epmems perspective

Basically, we would invalidate epmem_ids when elements still remained in working memory because their links were through excluded links only, which could be correct, except their temporal intervals did persist in episodic memory, leaving orphaned intervals, which, when you think about what happens if a connection comes back, is kind of correct actually. so i made the refcounts match. the orphaned subtrees in epmem are harmless w.r.t. reconstruction i think and do go away if elements are truly gone from wmem, so we'll test this out.
… node goes away and comes back even though it didn't really, because of exclusions, we just need to make sure the id reservations don't mess up.
- Bump version from 9.6.4 to 9.6.5 across all version files
- Fix CMake Export.h: define _USRDLL (shared) / STATIC_LINKED (static) on Windows
- Add CPack ZIP generator for Windows
- Add Windows job to cmake-multi-platform.yml CI (Ninja + MSVC)
- Merged amininger's svs_cmake_build branch

- Added asio/eigen dependencies to conanfile.py (asio 1.36.0)

- Fixed _WIN32_WINNT: guarded in portability_windows.h, set to 0x0601 for SVS

- Fixed socklen_t: replaced macro with ws2tcpip.h include

- Added Release-svs-test preset to CMakePresets.json
All configure presets now inherit conan-release instead of the
nonexistent conan-debug preset. Build presets no longer carry
redundant configuration/inherits fields that conflict with the
single-config Ninja generator.
- Add SWIG_TCL option: generates Tcl_sml_ClientInterface shared library
  and platform-specific pkgIndex.tcl
- Add SWIG_CSHARP option: generates C# wrapper DLL and managed sources
  (dotnet build for managed assembly is optional)
- Fix Java SWIG: add -package sml flag so generated classes have correct
  package declaration
- Replace bash compile script with cross-platform CMake commands for
  Java SWIG post-build (jar creation)
- Add JAVA_DEBUGGER option (requires SWIG_JAVA) that builds 4 JARs:
  soar-debugger-api.jar, soar-smljava.jar, soar-debugger.jar, and
  SoarJavaDebugger.jar (launcher)
- Uses add_custom_target (not add_custom_command OUTPUT) to avoid
  Ninja file-level dependency issues with sml.jar POST_BUILD artifact
- Auto-detects SWT platform (win64/gtk64/osx64 + arm variants)
- Add Release-swig preset: Release build with SVS + SWIG Tcl/Java +
  Java Debugger enabled
- New build-swig job runs on ubuntu, macOS, and Windows
- Installs SWIG, JDK 21, Tcl dev headers (Linux/macOS only)
- Windows builds with SWIG_TCL=OFF (no Tcl dev headers in CI)
- Builds using Release-swig preset with SVS + SWIG Java + Debugger
- Uploads SWIG artifacts (JARs, native libraries) on release/dispatch
…#465)

Cherry-pick of garfieldnate's PR #465. Changes GetParameterValue to throw
std::invalid_argument instead of returning NULL (which caused segfaults).
Adds SWIG %exception block to translate C++ exceptions to language-native
exceptions (ValueError in Python, IllegalArgumentException in Java, etc.).
Includes tests for Python, Java, and Tcl.

Fixes #451.
Co-authored-by: garfieldnate <garfieldnate@gmail.com>
Add soarversion.h.in template that uses @soar_VERSION_MAJOR/MINOR/PATCH@
variables, generated by configure_file() into the build tree. This makes
the CMakeLists.txt project(VERSION x.y.z) the single source of truth for
CMake builds. The hand-maintained Core/shared/soarversion.h is kept for
SCons builds.
Downstream consumers using find_package(soar) now automatically resolve
the transitive SQLite3 dependency (and asio/Eigen3 when SVS is enabled).
… violation

The previous commit accidentally reverted the id-reservation fix along
with the excluded-WME ref-count experiment. This restores the fix:
epmem_id_replacement now stores {pool*, child_n_id} at the time the
epmem_id is assigned, so that _epmem_remove_wme returns the correct
child_n_id to the pool rather than reading the potentially-stale live
value from w->value->id->epmem_id.
Uninitialized variable in child_spread could cause runtime check failure
on MSVC debug builds.
- Library OUTPUT_NAME: soar-9.6.5 -> Soar (matches SCons naming)
- Headers install to include/ (flat) instead of include/soar/
- UnitTests executable renamed from test_soar to UnitTests
- Add install rules for UnitTests, SoarTestAgents, settings.soar, launcher scripts
- Java macOS JNI: .dylib -> .jnilib (matches SoarShuffler expectations)
- Tcl/C# PREFIX: only strip lib prefix on Windows (Unix keeps default)
- Install SMLJava external JARs (commons-logging, log4j, stopwatch)
- Add RUNTIME and ARCHIVE destinations to Java SWIG install rule
  so the JNI DLL and import lib are installed to java/ on Windows
  (previously only LIBRARY was specified, which is a no-op for
  SHARED libraries on Windows DLL platforms)
- Add BUILD_SHARED_LIBS=ON to Release-swig preset: SWIG bindings
  must link against a shared Soar library so all modules share
  a single kernel instance at runtime
- New workflow_dispatch-triggered release.yml builds on all 4 platforms
  (Windows x86_64, Linux x86_64, macOS x86_64, macOS ARM64)
- Each platform: conan install → cmake configure → build → cmake --install
- Assembly job downloads all 4 install trees, clones external repos
  (Agents, Release-Support, VisualSoar, Domains-Eaters-TankSoar),
  builds VisualSoar, and runs scripts/assemble-release.sh
- assemble-release.sh maps cmake install layout to SoarShuffler-compatible
  multiplatform zip structure (bin/<platform>/, bin/java/, include/, etc.)
- Optional GitHub Release creation (draft) with zip + tutorial PDFs

Platform-specific SWIG bindings:
  Linux/macOS: Java + Tcl + Python + C#
  Windows: Java + Python + C# (Tcl skipped — no dev headers on CI)
TclSoarLib embeds a Tcl interpreter in the Soar kernel (loaded at runtime
via Register_Library). Previously only built by SCons, now has a proper
CMakeLists.txt.

- Tcl/CMakeLists.txt: MODULE library from src/{main,TclSoarLib}.cpp,
  links soar_lib + Tcl, installs module + tcl/ support scripts
- CMakePresets.json: TCLSOARLIB=ON in Release-swig preset
- release.yml: install magicsplat-tcl-tk on Windows CI, enable SWIG_TCL
  on all platforms (was OFF on Windows)
- assemble-release.sh: copy tclsoarlib binary per-platform and tcl/
  support scripts cross-platform
scijones added 29 commits April 21, 2026 12:52
Follow-up to the revert of PR #465 (commit 828c80c). Re-lands the
diagnostic improvement requested in issue #451 -- tell the user which
parent+attribute was missing -- but uses std::cerr + NULL return instead
of throwing std::invalid_argument. This matches moschmdt's own alternate
suggestion in #451 ('replace the throw with a print command, e.g. cout,
and do not throw an error to remain API compatible') and garfieldnate's
acknowledgement that 'returning null and printing to cerr would be very
easy; we already print to cerr throughout Soar'. Avoids breaking existing
callers (and SWIG/Java consumers where the thrown exception was getting
silently swallowed by SML event-handler frames). Also keeps the
trailing-whitespace cleanup from the reverted commit.

Refs #451, #465.
…eturn

The cerr output still produces too much noise in agents that legitimately
probe for optional attributes. Full rollback to pre-#465 behavior.
Whitespace cleanup from 828c80c is preserved.
Python 3.8+ on Windows no longer searches PATH or the .pyd's own directory
for extension-module dependencies, so importing Python_sml_ClientInterface
failed with 'DLL load failed' because the loader couldn't find Soar.dll
sitting right next to the .pyd. The old 9.6.4 .pyd statically linked the
kernel so this was invisible; the 9.6.5 CMake build links Soar.dll
dynamically, exposing the issue.

Prepend a tiny os.add_dll_directory(__file__'s dir) shim to the
SWIG-generated Python_sml_ClientInterface.py at build time, guarded by
a marker so it is idempotent under incremental rebuilds. No-op on
non-Windows and on Python < 3.8.
…ion .pyd

Restores the 9.6.4 behavior: one Python_sml_ClientInterface .pyd that works
on every CPython 3.8+ on the user's machine, regardless of which minor
version we happened to build against in CI. Users were hitting 'DLL load
failed (or one of its dependencies)' because the CMake build linked the
.pyd to a versioned pythonXY.dll (e.g. python313.dll from the CI runner)
which users with a different minor version (e.g. 3.12) don't have.

9.6.4's SCons build did this via SOAR_PYTHON_ABI3=1 + -DPy_LIMITED_API.
This reintroduces the equivalent under CMake:
  * find_package(Python3 ... Development.SABIModule) (requires CMake 3.26)
  * target_link_libraries(... Python3::SABIModule) instead of Python3::Python,
    so the .pyd links to python3.dll (the stable-ABI forwarding stub)
  * target_compile_definitions(... Py_LIMITED_API=0x03080000) setting the
    3.8 floor
  * SWIG flag -py3-stable-abi (requires SWIG 4.2+) so SWIG emits wrapper
    code that only touches the limited C API
  * Output SUFFIX .abi3.pyd / .abi3.so so Python's importer recognizes it
    as a stable-ABI module.
Fixes macOS Java Debugger failure 'Library not loaded: @rpath/libSoar.dylib'
and the analogous Linux ld.so failure. The wrapper libraries were linked
with @rpath-relative references but no rpath was baked in, so dlopen fell
through to the JVM/Python/Tcl interpreter's own library search and gave up.

New helper soar_swig_set_rpath() applied to all five SWIG wrapper targets
(javascript, python, java, tcl, csharp). Sets INSTALL_RPATH with three
entries so the same binary works in:
  - flat bin/ layout (SCons release, CPack bundle): @loader_path / $ORIGIN
  - GNUInstallDirs layout (cmake --install): @loader_path/../lib
  - one-level-up bundles: @loader_path/..

Windows is a no-op: DLL search already includes the loader's directory,
and the Python stable-ABI case is handled by prepend_dll_shim.cmake.
Commit 384c0bd added nlohmann_json in preparation for porting moschmdt's
OperatorExplanationManager (which needs JSON output for 'explain operator
--json'). After reviewing with upstream author, the operator-explanation
and sp --check features are preliminary / not well tested, so we've
decided not to port them for 9.6.5. Removing the unused dependency.

Reverts the nlohmann_json lines from root CMakeLists.txt, Config.cmake.in,
and conanfile.py. SQLite3 + asio + eigen deps retained.
…r pkgIndex.tcl into out/ for SCons parity; add dev helper script

- CMakePresets.json: Release-swig preset now sets SWIG_PYTHON=ON (the preset advertises 'all SWIG bindings' but was missing Python).
- Core/ClientSMLSWIG/CMakeLists.txt: POST_BUILD also copies pkgIndex_<platform>.tcl into SOAR_OUT_DIR so the 9.6.5 Tcl package can be loaded from out/ the same way SCons users expect (prior stale out/pkgIndex.tcl was advertising 9.6.4 and caused 'package provide' version mismatch).
- scripts/win-build-release-swig.cmd: single-shot helper that loads conanvcvars + SWIG PATH, then runs cmake configure/build for Release-swig. Documents the Windows build recipe.

Smoke-tested all 4 bindings on Windows from out/ after build:
- soar.exe --help: OK
- python -c 'import Python_sml_ClientInterface; create agent': OK
- tclsh package require tcl_sml_clientinterface; create agent: OK
- java -Djava.library.path=.. sml.Kernel.CreateKernelInNewThread + CreateAgent: OK
…rce of truth

Root CMakeLists.txt already sets project(soar VERSION 9.6.5) and configure_file()s soarversion.h.in from it. SoarCLI had its own VERSION 9.6.5 string that was (a) unused by any code path and (b) a second place to remember to bump at release time. Removing so there is one version string in the tree (plus the hand-maintained Core/shared/soarversion.h kept for SCons parity).

PerformanceTests/CMakeLists.txt and UnitTests/CMakeLists.txt already had no VERSION string - no change needed there.
…ed .py to out/

Root cause of user-reported ModuleNotFoundError on Windows: CPython's importlib.machinery.EXTENSION_SUFFIXES on Windows is only ['.cp<ver>-win_amd64.pyd', '.pyd']. Unlike Unix, Windows does NOT recognize the .abi3 infix, so '_Python_sml_ClientInterface.abi3.pyd' is INVISIBLE to 'import _Python_sml_ClientInterface' and Python reports ModuleNotFoundError (not a DLL-load ImportError).

Fix: on Windows, set the SWIG target SUFFIX to '.pyd' (no abi3 infix). Stable-ABI behavior is preserved because it comes from Py_LIMITED_API at compile time and linking python3.dll at link time, NOT from the filename. Unix (.abi3.so) unchanged.

Also: POST_BUILD now mirrors the patched Python_sml_ClientInterface.py into SOAR_OUT_DIR after the DLL-search shim is prepended. Keeps SCons-parity layout working (out/Python_sml_ClientInterface.py + out/_Python_sml_ClientInterface.pyd side-by-side) for users who build without cmake --install.

Verified locally: with stripped PATH and PYTHONPATH=out, 'import Python_sml_ClientInterface; Kernel.CreateKernelInNewThread()' succeeds.
UnitTests.exe looks up ./SoarUnitTests/<file>.soar relative to CWD. CMake's install rule put fixtures at <prefix>/SoarTestAgents/ and assemble-release never copied them, so fixture-based tests (BasicTests, BuiltinRHSTests, Chunking*, etc.) failed in the zip while pure-API tests (AgentTest, AliasTest) passed. Match SCons layout by installing SoarTestAgents/ contents as SoarUnitTests/ and having assemble-release copy that dir alongside UnitTests.exe.
…ebugger launcher: redirect stderr to nul/dev-null in Release builds only
- Override CMAKE_*_OUTPUT_DIRECTORY_<CONFIG> for multi-config generators (VS, Xcode) so VS doesn't add a Release/ subdir.

- Move SoarJavaDebugger.jar (launcher) and the supporting jar tree (sml.jar, soar-debugger*.jar, SWT, jfreechart, etc.) into out/java/ so the launcher manifest's relative classpath resolves against out/.

- Add Debug-swig-full preset mirroring Release-swig (SVS, all SWIG bindings, Java Debugger, TclSoarLib) for live kernel debugging. Both Debug and Release land in out/, last build wins, matching historical SCons behavior.
Removes build_manual job and the PDF download/install steps in assemble.
…es gated on TRACE_SMEM_SYSPARAM; drop redundant CLI 'Knowledge added' message
- Drop stale Ant-Version line from Debugger manifest1 (build is jar cfm via CMake)

- Update Created-By to match CI runner JDK (Temurin 11)

- Bump Date stamp to 2026-05-05 and copyright year to 2026

- Bump copyright years on SMLJava and DebuggerAPI manifests to 2026
GitHub's ubuntu-latest moved to 24.04 (glibc 2.39), causing libSoar.so to require GLIBC_2.38 and refuse to load on Ubuntu 22.04 LTS, Debian 12, and other still-supported distros.

Pin to ubuntu-22.04 (supported by GitHub through April 2027) so the Linux artifact runs anywhere with glibc >= 2.35. Same fix in cmake-multi-platform.yml so CI tests what we ship.
Without an explicit deployment target, Xcode/clang stamps binaries with the SDK version of the build host (currently macOS 14 on GitHub's macos-latest runner), which excludes users on macOS 13 -- still receiving Apple security updates.

Set the floor to 13.0 so artifacts run on every supported macOS. Wrapped in 'NOT DEFINED' so users can still override on the command line.
Ubuntu 22.04 apt ships SWIG 4.0.2, which generates Python wrappers that use non-stable-ABI symbols (PyTuple_GET_SIZE, PyCFunction_GET_FLAGS, Py_TYPE struct access, PyUnicode_AsUTF8). Combined with our Py_LIMITED_API=0x03080000 build flag, that produces 'undeclared in this scope' errors.

SWIG 4.2+ generates limited-API-compliant code. PyPI's swig package tracks upstream (currently 4.3+); use it on Linux instead of apt.

Also fix the matrix.os == 'ubuntu-latest' condition in cmake-multi-platform.yml that broke when we pinned build-nix to ubuntu-22.04.
…uilt

The previous release.yml expected to find Eaters_TankSoar.jar at Release-Support/SoarShuffler/jars/.

Build it from Domains-Eaters-TankSoar via Ant in the assemble job. Ant is preinstalled on ubuntu-latest, build.xml's swt target self-skips on non-Windows, and the resulting jar is platform-independent so one build serves all OSs.

Update both assemble-release.cmake and assemble-release.sh to source the jar from the new location.
The build-nix and build-windows matrices set SVS=OFF in every preset, so test_svs (added to ctest only when SVS=ON) was never run on CI. New build-svs job runs Release-svs-test on ubuntu-22.04, macos-latest, and windows-latest to cover that gap.
test_performance failed in cmake-multi-platform.yml because (1) the script used 'nice -n -10' which requires CAP_SYS_NICE and aborts under errexit on unprivileged GH runners, and (2) './PerformanceTests' wasn't found because the binary lives in SOAR_OUT_DIR while the script runs in the build/PerformanceTests/ test working directory.

do_performance_test.sh now auto-detects whether negative niceness is permitted and falls back to no nice when it isn't, and accepts PERF_BIN/UNIT_BIN env overrides. PerformanceTests/CMakeLists.txt passes absolute target paths via ENVIRONMENT.

Separately: build-swig on windows-latest was pre-existing-broken because choco's magicsplat-tcl-tk doesn't expose dev headers in a find_package-friendly form. Override SWIG_TCL=OFF / TCLSOARLIB=OFF for the Windows fast-CI path; release.yml already builds Tcl 8.6.13 from source for the actual shipped Windows zip.
PerformanceTests is add_subdirectory'd before UnitTests in the top-level CMakeLists, so $<TARGET_FILE:UnitTests> doesn't resolve at configure time. The script only references UNIT_BIN under the -u flag (default off), so we just drop it; PERF_BIN is sufficient.
Resolves overlapping release-tooling adds on development (release.yml, assemble-release.cmake, cmake-multi-platform.yml additions). Branch versions are kept verbatim because every conflicting hunk on development is a less-mature iteration of work that the release branch already contains in finished form (Eaters jar built from source, SWIG installed via PyPI, ubuntu-22.04 pin, manifest refresh, etc.).
@scijones
scijones merged commit 0bb872a into development May 6, 2026
86 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants