From: Parth Malwankar
Subject: Loading a file from an executable in SBCL
Date:
Message-ID: <op.udn6tem9y4b379@localhost>
Hello,
I am trying to make an executable with SBCL. The executable "load"s
a file which calls a function from the package. This works well from
the sbcl interactive prompt but fails when I make an exe.
Here is a sample app that represents this scenario.
core.lisp
============
(in-package #:test-pkg)
(defun hello ()
(format t "Hello World !!!~%"))
(defun loader-fun ()
(load "testload.lisp"))
packages.lisp
=============
(in-package :cl-user)
(defpackage #:test-pkg
(:use :common-lisp)
(:export #:hello
#:loader-fun))
testload.lisp
=============
; the file that is loaded
(hello)
test-pkg.asd
============
(defsystem :test-pkg
:version "0.1"
:components ((:file "packages")
(:file "core")))
make-exe.lisp
=============
(require 'asdf)
(asdf:operate 'asdf:load-op 'test-pkg)
(in-package :test-pkg)
(sb-ext:save-lisp-and-die "test" :executable t
:toplevel 'test-pkg:loader-fun)
Here is the interaction at the prompt:
This is SBCL 1.0.17.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
................. snipped messages .............
Linedit version 0.16.1 [smart mode]
CL-USER(1): (asdf:operate 'asdf:load-op 'test-pkg)
; loading system definition from
/home/parth/.sbcl/systems/test-pkg.asd into
; #<PACKAGE "ASDF0">
; registering #<SYSTEM :TEST-PKG {B642739}> as TEST-PKG
NIL
CL-USER(2): (in-package :test-pkg)
#<PACKAGE "TEST-PKG">
TEST-PKG(3): (loader-fun)
Hello World !!!
T
TEST-PKG(4):
I create the executable like this:
[parth:~/bld/src/tmp]% sbcl --load make-exe.lisp
This is SBCL 1.0.17.debian, an implementation of ANSI Common Lisp.
............... snipped messages ...............
writing 27721728 bytes from the dynamic space at 0x09000000
done]
Running of the executable:
[parth:~/bld/src/tmp]% ./test
; in: LAMBDA NIL
; (HELLO)
;
; caught STYLE-WARNING:
; undefined function: HELLO
;
; caught STYLE-WARNING:
; This function is undefined:
; HELLO
;
; compilation unit finished
; caught 2 STYLE-WARNING conditions
debugger invoked on a UNDEFINED-FUNCTION in thread #<THREAD "initial
thread" {AA70759}>:
The function HELLO is undefined.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
(no restarts: If you didn't do this on purpose, please report it as a
bug.)
("bogus stack frame")
0]
I find that if I change loader-fun to the following it works fine:
(defun loader-fun ()
(in-package #:test-pkg)
(load "testload.lisp")
(sb-ext:quit))
However, even though its working now, I am somewhat confused and would
appreciate any pointers on what might be happening by the more experienced
folks here.
It appears that loader-fun, gets invoked in a different context from
test-pkg when invoked from the command line. Is this the right way to load
a file? Should I be doing the 'in-package' above or is there some other
ideomatic way of doing this?
Also, is my way of creating the exe (make-exe.lisp) the standard way to do
this with sbcl? What is the recommended way?
Thanks very much.
--
Parth Malwankar
In article <·················@localhost>,
"Parth Malwankar" <·················@parth.malwankar> wrote:
> Hello,
>
> I am trying to make an executable with SBCL. The executable "load"s
> a file which calls a function from the package. This works well from
> the sbcl interactive prompt but fails when I make an exe.
>
> Here is a sample app that represents this scenario.
>
> core.lisp
> ============
> (in-package #:test-pkg)
>
> (defun hello ()
> (format t "Hello World !!!~%"))
>
> (defun loader-fun ()
> (load "testload.lisp"))
>
>
> packages.lisp
> =============
> (in-package :cl-user)
>
> (defpackage #:test-pkg
> (:use :common-lisp)
> (:export #:hello
> #:loader-fun))
>
>
> testload.lisp
> =============
> ; the file that is loaded
> (hello)
>
> test-pkg.asd
> ============
> (defsystem :test-pkg
> :version "0.1"
> :components ((:file "packages")
> (:file "core")))
>
> make-exe.lisp
> =============
> (require 'asdf)
> (asdf:operate 'asdf:load-op 'test-pkg)
> (in-package :test-pkg)
>
> (sb-ext:save-lisp-and-die "test" :executable t
> :toplevel 'test-pkg:loader-fun)
>
>
> Here is the interaction at the prompt:
>
> This is SBCL 1.0.17.debian, an implementation of ANSI Common Lisp.
> More information about SBCL is available at <http://www.sbcl.org/>.
> ................. snipped messages .............
> Linedit version 0.16.1 [smart mode]
> CL-USER(1): (asdf:operate 'asdf:load-op 'test-pkg)
>
> ; loading system definition from
> /home/parth/.sbcl/systems/test-pkg.asd into
> ; #<PACKAGE "ASDF0">
> ; registering #<SYSTEM :TEST-PKG {B642739}> as TEST-PKG
> NIL
> CL-USER(2): (in-package :test-pkg)
>
> #<PACKAGE "TEST-PKG">
> TEST-PKG(3): (loader-fun)
> Hello World !!!
> T
> TEST-PKG(4):
>
> I create the executable like this:
> [parth:~/bld/src/tmp]% sbcl --load make-exe.lisp
> This is SBCL 1.0.17.debian, an implementation of ANSI Common Lisp.
> ............... snipped messages ...............
> writing 27721728 bytes from the dynamic space at 0x09000000
> done]
>
> Running of the executable:
> [parth:~/bld/src/tmp]% ./test
>
> ; in: LAMBDA NIL
> ; (HELLO)
> ;
> ; caught STYLE-WARNING:
> ; undefined function: HELLO
>
> ;
> ; caught STYLE-WARNING:
> ; This function is undefined:
> ; HELLO
> ;
> ; compilation unit finished
> ; caught 2 STYLE-WARNING conditions
>
> debugger invoked on a UNDEFINED-FUNCTION in thread #<THREAD "initial
> thread" {AA70759}>:
> The function HELLO is undefined.
>
> Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
>
> (no restarts: If you didn't do this on purpose, please report it as a
> bug.)
>
> ("bogus stack frame")
> 0]
>
> I find that if I change loader-fun to the following it works fine:
>
> (defun loader-fun ()
> (in-package #:test-pkg)
> (load "testload.lisp")
> (sb-ext:quit))
>
> However, even though its working now, I am somewhat confused and would
> appreciate any pointers on what might be happening by the more experienced
> folks here.
>
> It appears that loader-fun, gets invoked in a different context from
> test-pkg when invoked from the command line. Is this the right way to load
> a file? Should I be doing the 'in-package' above or is there some other
> ideomatic way of doing this?
>
> Also, is my way of creating the exe (make-exe.lisp) the standard way to do
> this with sbcl? What is the recommended way?
>
> Thanks very much.
Check what package the application has as value of *package*
on startup. If you expect something different, you have to
set it somewhere...
To be safe, put an in-package form into testload.lisp or
write (test-pkg:hello) in that file.
Another way to set the package temporarily is:
...
(let ((*package* (find-package "TEST-PKG")))
(load "testload.lisp"))
...
--
http://lispm.dyndns.org/
"Parth Malwankar" <·················@parth.malwankar> writes:
> I find that if I change loader-fun to the following it works fine:
>
> (defun loader-fun ()
> (in-package #:test-pkg)
> (load "testload.lisp")
> (sb-ext:quit))
>
> However, even though its working now, I am somewhat confused and would
> appreciate any pointers on what might be happening by the more experienced
> folks here.
>
> It appears that loader-fun, gets invoked in a different context from
> test-pkg when invoked from the command line. Is this the right way to load
> a file?
Yes. It might be prudent to put IN-PACKAGE at the beginning of each
file. Or not. Not having any IN-PACKAGE in the files allow you to
load them in different environment. On the other hand, you can always
shadow IN-PACKAGE. Perhaps what would NOT be nice is to put
(|CL|:|IN-PACKAGE| ...) in the files, but (in-package ...) is ok.
> Should I be doing the 'in-package' above or is there some other
> ideomatic way of doing this?
Well in your case you definitely need to execute in-package sometimes
after launching again the saved image. The in-package before
save-lisp-and-die is useless.
(sb-ext:save-lisp-and-die "test"
:executable t
:toplevel (lambda ()
(unwind-protect (progn (in-package :test-pkg)
(test-pkg:loader-fun))
(sb-ext:quit 0)))) ; just to be sure.
> Also, is my way of creating the exe (make-exe.lisp) the standard way to do
> this with sbcl? What is the recommended way?
That's how I do it.
--
__Pascal Bourguignon__
From: Parth Malwankar
Subject: Re: Loading a file from an executable in SBCL
Date:
Message-ID: <op.udocadv7y4b379@localhost>
On Wed, 02 Jul 2008 21:21:58 +0530, Pascal J. Bourguignon
<···@informatimago.com> wrote:
> "Parth Malwankar" <·················@parth.malwankar> writes:
>> I find that if I change loader-fun to the following it works fine:
>>
>> (defun loader-fun ()
>> (in-package #:test-pkg)
>> (load "testload.lisp")
>> (sb-ext:quit))
>>
>> However, even though its working now, I am somewhat confused and would
>> appreciate any pointers on what might be happening by the more
>> experienced
>> folks here.
>>
>> It appears that loader-fun, gets invoked in a different context from
>> test-pkg when invoked from the command line. Is this the right way to
>> load
>> a file?
>
> Yes. It might be prudent to put IN-PACKAGE at the beginning of each
> file. Or not. Not having any IN-PACKAGE in the files allow you to
> load them in different environment. On the other hand, you can always
> shadow IN-PACKAGE. Perhaps what would NOT be nice is to put
> (|CL|:|IN-PACKAGE| ...) in the files, but (in-package ...) is ok.
>
>
>> Should I be doing the 'in-package' above or is there some other
>> ideomatic way of doing this?
>
> Well in your case you definitely need to execute in-package sometimes
> after launching again the saved image. The in-package before
> save-lisp-and-die is useless.
>
>
> (sb-ext:save-lisp-and-die "test"
> :executable t
> :toplevel (lambda ()
> (unwind-protect (progn (in-package :test-pkg)
> (test-pkg:loader-fun))
> (sb-ext:quit 0)))) ; just to be
> sure.
>
>
>> Also, is my way of creating the exe (make-exe.lisp) the standard way to
>> do
>> this with sbcl? What is the recommended way?
>
> That's how I do it.
>
Thanks everyone for the help. This makes sense. I put in a
print for *package* as suggested and it turns out to be
"COMMON-LISP-USER". I incorrectly expected it to be the same as
the file in which loader-fun is defined.
Setting the package in :toplevel worked very well.
--
Parth Malwankar