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

From: Rainer Joswig
Subject: Re: Loading a file from an executable in SBCL
Date: 
Message-ID: <joswig-464367.17441502072008@news-europe.giganews.com>
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/
From: Pascal J. Bourguignon
Subject: Re: Loading a file from an executable in SBCL
Date: 
Message-ID: <7ciqvo9tcx.fsf@pbourguignon.anevia.com>
"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