From f05af1bbbb9224929cd07405cead3909a56d51fc Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Fri, 30 May 2025 15:04:22 +0100 Subject: [PATCH] Integrate Maxima build into ASDF configuration --- README | 31 ++++++++++++++-------------- ham.asd | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/README b/README index d652540..88643d6 100644 --- a/README +++ b/README @@ -21,22 +21,21 @@ To then run the simulation: SETUP -Before the ASDF system can be loaded, you must build the Maxima -sources locally and install them into a directory (I couldn't get -Maxima's ASDF system to load successfully otherwise, though I'm not -entirely sure why this fixes it). This can be done with: +If you have :sdl2 available and the sources are in ASDF's registry, +loading the system should just work™: - cd maxima - mkdir $PWD-install - ./bootstrap - ./configure --prefix=$PWD-install - make -j - make install + (asdf:load-system :ham) -I'll try to figure out if this step itself can be done with ASDF at -some point ;) +Otherwise, the full process fetching :sdl2 with Quicklisp and adding +the current directory to ASDF's registry is -Once that's done you should be able to load the system with -(asdf:load-system :ham), given that the sources are in your ASDF -registry. The system also uses :sdl2, so make sure that's available --- you can get it with (ql:quickload :sdl2) if you're so inclined. + (ql:quickload :sdl2) + (push *default-pathname-defaults* asdf:*central-registry*) + (asdf:load-system :ham) + +Maxima ended up being a bit of a pain to build fully within ASDF so +the ASDF config first compiles it with its autotools set-up (so you'll +need autoconf et al) and uses the FASLs from that build when possible. +It's a little cursed but it does the job. I did have to call +asdf::mark-operation-done directly so it might break with future +versions of ASDF (I'm using version 3.3.1 at time of writing). diff --git a/ham.asd b/ham.asd index a341b57..8b6e09d 100644 --- a/ham.asd +++ b/ham.asd @@ -4,14 +4,62 @@ (in-package :asdf-user) (eval-when (:compile-toplevel :load-toplevel :execute) - (let ((base-dir - (make-pathname :directory (pathname-directory *load-pathname*)))) - (pushnew (merge-pathnames "maxima/src/" base-dir) - asdf:*central-registry* - :test #'equal) - (pushnew (merge-pathnames "maxima-interface/" base-dir) - asdf:*central-registry* - :test #'equal))) + (let* ((base-dir + (make-pathname :directory (pathname-directory *load-pathname*))) + (maxima-dir (merge-pathnames "maxima/" base-dir)) + (maxima-src-dir (merge-pathnames "src/" maxima-dir)) + (maxima-install-dir (merge-pathnames "maxima-install/" base-dir))) + (unless (probe-file (merge-pathnames "bin/maxima" maxima-install-dir)) + (uiop:with-current-directory (maxima-dir) + (uiop:run-program "./bootstrap" + :output *standard-output* + :error-output *error-output*) + (uiop:run-program (format nil "./configure --prefix=~A" + (namestring maxima-install-dir)) + :output *standard-output* + :error-output *error-output*) + (uiop:run-program "make -j" + :output *standard-output* + :error-output *error-output*) + (uiop:run-program "make install" + :output *standard-output* + :error-output *error-output*))) + (pushnew maxima-src-dir + asdf:*central-registry* + :test #'equal) + (pushnew (merge-pathnames "maxima-interface/" base-dir) + asdf:*central-registry* + :test #'equal) + (defparameter *maxima-src-dir* maxima-src-dir))) + +(defun prebuilt-maxima-fasl (source-file) + (let ((source-path (asdf:component-pathname source-file))) + (when (uiop:subpathp source-path *maxima-src-dir*) + (let ((fasl-file + (make-pathname + :directory (substitute "src/binary-sbcl" "src" + (pathname-directory source-path) + :test #'string=) + :name (pathname-name source-path) + :type "fasl"))) + (when (probe-file fasl-file) + (list fasl-file)))))) + +(defmethod asdf:output-files :around ((op asdf:compile-op) + (c asdf:cl-source-file)) + (or (prebuilt-maxima-fasl c) + (call-next-method))) + +(defmethod asdf:perform :around ((op asdf:compile-op) + (c asdf:cl-source-file)) + (if (prebuilt-maxima-fasl c) + (asdf::mark-operation-done op c) + (call-next-method))) + +(defmethod asdf:input-files :around ((op asdf:load-op) + (c asdf:cl-source-file)) + (or (prebuilt-maxima-fasl c) + (call-next-method))) (defsystem :ham :version "0.1.0"