[Openmcl-devel] self-contained executable library - how does it access command line arg[1]?

Gary Byers gb at clozure.com
Fri Dec 30 13:24:37 PST 2011

Please listen carefully.

You can't get at a single non-option argument because CCL has traditionally
processed this as a heap image name (and has done so in the kernel - for
obvious reasons - so there's no easy way to override this.)

The time it would take to write a trivial shell script to work around this
is likely less than has been spent discussing this issue.

a) the utility of that traditional treatment of a single argument is questionable
b) no one wants to keep discussing this issue

I changed the trunk the other night so that a single non-option argument
isn't processed specially.

I have no idea what's hard to understand about this.

On Fri, 30 Dec 2011, Mark H. David wrote:

> I'm trying to do something pretty quick.  I don't claim this is an 
> application worth
> distributing.  We're using this in house.  So what's wrong with that?  So, I 
> DO think it's right
> for Lisp's to in general to support creating simple 
> not-necessarily-that-distributable executables.
> For the "ultimate", I could see doing a lot of things really differently.  I 
> might not even use Lisp.
> Somewhere along the evolution I'd surely use something like Didier's 
> sophisticated command
> line processor.   But why can't I do my simple thing now?  I don't hear good 
> reasons.
> In our case, it's an executable that starts a hunchentoot
> web server on port 8080 by default, or on the port specified by arg 1 if 
> provided.
> I have a function that saves an executable image on all my Lisps (SBCL, CCL).
> Then I have a function that grabs arg 1 from the list #+sbcl <some var> #+ccl 
> <some var>
> (that's all the "porting" I have to do), and parses out the integer in arg 1 
> if present.  That's
> all I need.
> Regarding doing scripts, well, it complicates the save-image abstraction I've
> got to have this work so differently on SBCL (and any other Lisp I've ever 
> known about)
> vs. CCL.  If I really have to do a script, I'll have to do it for both SBCL 
> and CCL.
> So then the other thing Gary trivializes a bit too much is creating a script.
> First the part about "/path/to", and then the part about this having to run 
> on Windows
> in addition to Unix (= Mac?).
> The functionality you get with an executable is you can move it to any 
> location in the
> file system, and call it from any location in the file system, and it just 
> works, or at least
> getting it to start up and do its thing is not prevented per se by where it's 
> located and where
> you call it from.
> Now, with a script + executable, you have to move two files.
> OK, maybe having to move two files now is not that big a deal, but it is 
> rather simpler if
> there's just one.
> But then: we'd have to either hardcode the /path/to part of it, or get into 
> having some environment
> variable to control it or have it figure out the location of the script.  I 
> don't know a trivial way to really
> get the directory the script is in.  There are lots of google discussions 
> about how to do this in
> various shells.  I think some work OK in some cases, but then don't work if 
> you've got links or
> other complications.  And there's fun with quoting whitespace ("path with 
> space/to") in whatever
> scripting language you've got.  This is the joy of doing it just for unix. 
> Let's assume this works
> for Mac.
> But then there's Windows.  So, now I've got to do this all for windows. 
> Besides / -> \, there
> is a new world of fun google'able discussions about how to figure out the 
> script directory.
> (And/or new environment variable conventions, if you want to go that route.)
> One other thing about an executable: when you do control-c to interrupt it, 
> it just dies or does
> whatever it does.  In a script, at least on Windows, it asks if you want to 
> interrupt the batch
> job.   It's just another oddity and annoyance.
> If there were a really good reason for this simple thing I want to do to be 
> "trivial effort" (or
> whatever), I could see being for it.  But there's really no reason -- just 
> the historical one of handling
> the one-arg case of supplying the image name.  I think there's a really good 
> case for continuing to
> handle that IFF the image is not embedded, for compatibility with past 
> practice and
> consistency with doc (I assume it's doc'd), and for the simplicity it 
> provides for that functionality.
> I think: of course it makes perfect sense for an imageless executable to 
> snarf the first arg
> as the image name -- it needs an image name, and on the other hand it makes 
> perfect sense
> for an embedded-image executable to not do that -- it doesn't need an image 
> name.
> Then the only thing needed is to doc and make available without needing 
> double ::'s the variable
> with all the command line args.
> So, those are my thoughts, and hope this helps folks better understand.
> Thanks,
> Mark
> On 12/29/2011 8:02 AM, Gary Byers wrote:
>> If CCL is invoked with a single argument whose first character isn't
>> #\-, that argument is interpreted by the kernel as the name of a heap
>> image to load.
>> Arguments that are processed by the kernel are removed from argc/argv
>> and don't appear in CCL:*COMMAND-LINE-ARGUMENT-LIST* (which is exported
>> but not documented.)
>> So what Mark was asking to be told wasn't so about
>> $ foo bar
>> or
>> $ ccl64 bar
>> is indeed so, unless your library changes the kernel's behavior or unless
>> foo is a shell script which inserts a "--" in the right place.
>> Some people have argued that this treatment of a single argument as 
>> shorthand
>> for "--image-name arg" or "-I arg" should be suppressed if the kernel 
>> contains
>> an embedded image.  That'd be a (minor) incompatible change, and I'd 
>> personally
>> prefer to just drop the shorthand rather than have it behave differently in
>> the embedded/non-embedded cases.
>> The only reason that I can think of to continue to support the single-arg
>> shorthand is that the feature's been around for a long time and some people
>> may be used to it (and some ... shell scripts ...  used to invoke a 
>> customized
>> CCL might use that shorthand, though that's probably less likely.)
>> The strongest reason that I can think of for dropping support for the 
>> shorthand
>> is that it would cause large parts of this discussion to die, and that's 
>> pretty
>> attractive at the moment.
>> I changed this in the trunk a little while ago (in r15159).  This means 
>> that:
>> - something like
>> $ ccl64 foo
>> will no longer be treated as shorthand for
>> $ ccl64 --image-name foo
>> and some habits/shell scripts/.emacs files/etc may need to change.
>> - the standard toplevel-function will complain about the unrecognized 
>> argument
>> and exit.  (There's a separate issue as to how this behavior can be 
>> extended
>> and customized.)
>> - an image saved with a custom toplevel function will see "foo" on
>>   *COMMAND-LINE-ARGUMENTS-LIST* and can process it however it wants to.
>> - all of the above is true regardless of whether the executable contains
>>   an embedded heap image or not.
>> - there may still be issues related to whether a particular application
>>   wants arguments to be processed by the kernel (and, if applicable, by
>>   the standard toplevel function) and it still seems like shell scripts
>>   offer the greatest application-specific flexibility.  The magic treatment
>>   of a single non-option argument is a separate issue, and hopefully that
>>   issue won't come up as often without that special treatment.
>> On Thu, 29 Dec 2011, Didier Verna wrote:
>>> "Mark H. David" <mhd at yv.org> wrote:
>>>> I don't see any way to get the first arg to a self-contained
>>>> executable. I find it hard to believe you cannot save an exe as "foo",
>>>> and then have your application interpret
>>>>   foo bar
>>>> typed on the command line however it wants.
>>>> and from trying stuff out is that you cannot get that.  You can only have 
>>>> it
>>>> interpret
>>>>   foo -- bar
>>>> Is that true?
>>>  No.
>>>> Say it ain't so.
>>>  it ain't so.
>>> CCL has a ccl::*command-line-argument-list* variable for that. You can
>>> access cmdline arguments after dumping an executable with something like
>>> this:
>>> (ccl:save-application name
>>>          :toplevel-function #'function
>>>          :init-file nil
>>>          :error-handler :quit
>>>          :prepend-kernel t)
>>> You may be interested in my command-line options management library[1],
>>> which provides portable cmdline manipulation and executable dumping
>>> across several compilers, including CCL. If you're not interested in the
>>> whole stuff, take a look at the file util.lisp.
>>> Footnotes:
>>> [1]  http://www.lrde.epita.fr/~didier/software/lisp/clon.php
>>> -- 
>>> Resistance is futile. You will be jazzimilated.
>>> Scientific site:   http://www.lrde.epita.fr/~didier
>>> Music (Jazz) site: http://www.didierverna.com
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list