3

I've got a very large Lisp project whose output I'd like to programmatically pipe to a Python program, i.e. use Python to call the Lisp program on some input and get the output back into Python.

The project only compiles in Clozure Common Lisp (ccl64) and I did try to find a way to turn it into an executable (I'm using Mac OS X), but that ran into a lot of dead ends (I am not a Lisp programmer).

This documentation for Clozure Common Lisp should provide the solution to the above, but I was not able to understand it. The examples I made created a file, but Terminal would not run them as executables.

How to create executable for ccl64

I tried to follow this question's answer Compiling Common Lisp to an executable except using ccl64's save application function.

$ ccl64
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!
? (in-package :ccl)  
#<Package "CCL">
? (defun main () (print "hello"))
MAIN
? (save-application "hello" :toplevel-function #'main)

I am trying to use Python's subprocess to invoke ccl64, run the Lisp program, and get the output. However, subprocess for some reason refuses to run the ccl64 command. Here is what I wrote so far:

import subprocess

process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
out, err = process.communicate()

The variable out should contain the output of getting the usage/help from ccl64. Instead I get an error:

Traceback (most recent call last):
  File "sub.py", line 3, in <module>
    process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

How can I get Python to invoke ccl64 and get output from the Lisp project?

2
  • 2
    Specify the full path to the ccl64 binary. Commented Dec 1, 2014 at 5:16
  • To extend a bit what @LePetitPrince says: When you're typing on a terminal, typing just ccl64 works because the executable is in your PATH environment variable but (by default), subprocess doesn't know that PATH. Find where the ccl64 executable lives and pass the whole path to your Popen call. Commented Dec 1, 2014 at 5:23

1 Answer 1

5

The error in your Python code is clear: No such file or directory.

You need to tell in your Python code which application you want to run in a way that it actually finds it.

It's also not clear why you save a Lisp executable somewhere named hello, but you are not trying to call it. With the necessary path. Your code tries to call Clozure CL - without the necessary path - but why? You just saved an executable. Why would you call Clozure CL to run it? I would also save the executable with prepending the kernel - that makes it self-contained.

Example:

Calling Clozure CL:

rjmba:~ joswig$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!

Defining the main function:

? (defun main () (print "hello"))
MAIN

Saving an executable:

? (save-application "hello" :toplevel-function #'main :prepend-kernel t)

Running the new executable from the same directory:

rjmba:~ joswig$ ./hello

"hello" 

Calling a Clozure CL application with an argument:

bash-3.2$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!

The function ccl::command-line-arguments returns the arguments as a list. The first item is the called application itself.

? (defun main ()                                                                
    (print (second (ccl::command-line-arguments))))
MAIN

? (save-application "hello"                                                     
                    :toplevel-function #'main                                   
                    :prepend-kernel t)

Calling it:

bash-3.2$ ./hello hello!

"hello!"
Sign up to request clarification or add additional context in comments.

4 Comments

I made the executable with Clozure CL, but when I go to the terminal and enter hello (the name of the file created), the terminal does not run it.
That works. However when I run my executable, it crashes and then launches the ccl64 repl, frozen in it. The main function is simply (defun main (string) (my-fun string)).
This function works: (defun main () (print "hi") (quit)). I turned it into an executable called hi. But suppose I wish to print an arbitrary string. How can I make it so when I type ./hi hello!, the console prints hello!.
I think this global value is what I need to use: *command-line-argument-list*.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.