#| This is a small simple stupid script intended to make executable (native) program from LISP code. Works only with Embedded Common Lisp (ECL), OS-independent. invoke thru ecl: ecl -load f.lisp -- -compile yourprogram.lisp -output executablefilename invoke as standalone: ./maker -compile yourprogram.lisp -output executablefilename |# ;; lets find command line key "-compile" and determine NEXT command line argument ;; Note: while we looking for key, if we succeed, we gonna check for fname existence (defun lets-find-file-to-compile (lst) (if (null lst) ; if our list is EMPTY (nil) nil ; return NIL (let* ( ;otherwise - do some work. first of all -- local variables (key (first lst)) (fname (second lst)) (fileexists (probe-file fname)) ; this variable depends on another one ) (progn ; now, with these variables, will do our job ;(format t "Analyzing pair ~A ~A~%" key fname) ; just do some fancy output (if (string-equal key "-compile") ; compare strings, case insensitive (if (not fname) ; if fname is NIL, "not NIL" will be T and we must understand: there is no fname here nil ; nothing here (list exhausted) (progn (if fileexists ; do this file exists? fileexists ; if yes, return it's name (truename, including path : check probe-name syntax) nil ; if no, return nothing ) ) ) (lets-find-file-to-compile (cdr lst)) ; work with tail of a list ) ) ) ) ) ;; same thing, but without existance checking (defun lets-determine-executable-filename (lst) (if (null lst) ; if our list is EMPTY (nil) nil ; return NIL (let* ( (key (first lst)) (fname (second lst)) ) (progn ;otherwise - do some work ;(format t "Analyzing pair ~A ~A~%" key fname) ; just do some fancy output (if (string-equal key "-output") ; compare strings, case insensitive (if (not fname) ; if fname is NIL, "not NIL" will be T and we must understand: there is no fname here nil ; nothing here (list exhausted) fname ; return ) (lets-determine-executable-filename (cdr lst)) ; work with tail of a list ) ) ) ) ) (defun compiler () (let* ( (commandline (ext:command-args)) ; first arg is a name of invoked program, rest of them are actual arguments (args (cdr commandline)) ; we dont need first argument (to-compile (lets-find-file-to-compile args)) (executable (lets-determine-executable-filename args)) ) (progn (format t "EmbeddedCommonLisp -> native executable simple maker; (c) Eugene A. Solo~%") (format t "Invoked with arguments: ~A~%" commandline) (if (and to-compile executable) ; both shudn't be empty (NIL) strings (let* ( (objectfile (concatenate 'string executable ".o")) (objects (list objectfile)) ) (progn (format t "Will compile: ~A~%" to-compile) (format t "Will write executable: ~A~%" executable) (format t "Objectfile: ~A~%" objectfile) (format t "Objects (list): ~A~%" objects) ;------------------------------------------------------- (compile-file to-compile :system-p t :output-file objectfile) (c::build-program executable :lisp-files objects) ;------------------------------------------------------- ) ) (progn (format t "Program usage:~%~A -compile yourprogram.lisp -output executablefilename~%" (car commandline)) ) ) ) ) ) (compiler) ; calling... (quit) ; all work is done
И сама себя собирает, что забавно :)
Под виндой, в линуксе для х86 и для ARM работает одинаково.
Компилер ecl 13.5.1