;; Hacked into lisp2exe.lsp by Cyril Slobin 16-Nov-07 ;; Restarted from scratch with newLISP 10.2.1 20-Mar-10 ;; link.lsp - v.1.1 ;; link.lsp - v.1.2 fix for '.exe' problem on CYGWIN ;; link.lsp - v.1.3 no code change, added note for win32 dll ;; link.lsp - v.1.4 no code change, reformatted comments ;; link.lsp - v.1.5 no code change, changed dllEvalStr to newlispEvalStr ;; link.lsp - v.1.6 eliminated old quoted write-buffer syntax for 10.0 ;; ;; links newLISP executable and a .lsp source file to a new ;; executable containing both. This way newLISp and a source ;; file can be packaged together for easier distribution and install. ;; ;; ;; NOTES FOR LINKING AND IMPORTING WIN32 DLLs ;; Since newLISP v.7.3.16 CYGWIN is not supported anymore for ;; linking source to the executable, use a native Win32 instead ;; which also can be used in an CYGWIN environment ;; ;; When importing a linked win32 dll from win32 programs other ;; then newlisp.exe, than the following statment should be executed ;; directly after importing functions and before any 'newlispEvalStr' ;; statment: (dllName ) where is the file ;; name of the linked win32 newlisp dll. This will enable the autoload ;; of linked newlisp source in the dll. When importing to newlisp.exe ;; this is not required. ;; ;; How it works: ;; ============= ;; copies the original newLISP.exe to newExeName ;; then searches for '@@@@@@@@', which is the place holder ;; for the exe offset to append lisp source and for a simple ;; encryption key derived from the source size ;; the file in lispSourceName gets encrypted and appended ;; to the a copy of newLISP.exe with a new name. ;; ;; the new executable file will not load init.lsp but ;; the appended file instead ;; ;; How to use on CYGWIN WIn32: ;; =========================== ;; example: to link the source mySource.lsp to myProg.exe ;; ;; (link "newlisp.exe" "myProg.exe" "mySource.lsp") ;; ;; then: ;; ;; c:\> myProg ;; ;; ;; On Linux/freeBSD implementations: ;; ================================= ;; (link "newlisp" "myProg" "mySource.lsp") ;; ;; and to execute myProg assuming myProg is in the current directory ;; ;; /home/joe > ./myProg ;; (define (link orgExe newExeName lispSourceName) (println "original newlisp executable:" orgExe) (println "new executable:" newExeName) (println "source:" lispSourceName) (set 'size (first (file-info orgExe))) ;; copy newLISP.exe to the newExeName (copy-file orgExe newExeName) ;; get the binary representation of size (set 'buff (pack "ld" size)) ;; open the new exe for update (set 'handle (open newExeName "u")) (search handle "@@@@@@@@") ;; this field gets read by the newLISP startup (write-buffer handle buff 4) (set 'buff (read-file lispSourceName)) (set 'keylen (pack "ld" (length buff))) (write-buffer handle keylen 4) ;; append lisp source encrypted at the end (seek handle size) (set 'buff (encrypt buff (string (length buff)))) (write-buffer handle buff (length buff)) (close handle)) ;; eof (unless (and (member (length (main-args)) '(3 4)) (ends-with (main-args 0) "newlisp.exe" 1) (ends-with (main-args 1) "lisp2exe.lsp" 1) (ends-with (main-args 2) ".lsp" 1)) (println "Usage: lisp2exe file.lsp [file.exe]") (exit)) (setq interpreter (main-args 0)) (setq lispfile (main-args 2)) (if (= (length (main-args)) 4) (setq exefile (main-args 3)) (setq exefile (replace {\.lsp$} (string lispfile) ".exe" 1))) (link interpreter exefile lispfile) (exit)