Ask Your Question

Revision history [back]

This works as of Sage 7.3 on Mac OS X El Capitan. As an example, a file hello.pyx with the simple code

def hello():
    return 'Hello World!'

print(hello())

can be coverted to C with the command

sage -cython --embed hello.pyx

and then compiled for running with the command

gcc hello.c -I/usr/include/python2.7/ -lpython2.7

Executing the result by typing ./a.out displays the expected greeting.

This works appears to work as of Sage 7.3 on Mac OS X El Capitan. As an example, a only to a limited extent, for reasons that will be come clear. Start with a pure Python example to highlight the changes necessary to import Sage. A file hello.pyx hello.pyx with the simple code

def hello():
    return 'Hello World!'

print(hello())
print('Hello World!')

can be coverted converted to C with the command

sage -cython --embed hello.pyx

and then compiled for running with the command

gcc hello.c -I/usr/include/python2.7/ -I/usr/include/python2.7 -lpython2.7

Executing the result by typing ./a.out displays the expected greeting.

Now try a similar piece of code with a Sage numeric function in a file import.pyx:

from sage.all import *
print(bessel_J(0,1.))

Compiling with the same commands produces the reported error

ImportError: No module named sage.all

when executing the result. This error can be avoided by pointing the compiler to folders under Sage's location /path/to/sage/ so that it knows where to find Sage-specific libraries, including the version of Python that ships with Sage.

While the Cython command remains the same, the compiler command becomes

gcc import.pyx -I/path/to/sage/local/include/python2.7 -L/path/to/sage/local/lib -lpython2.7

The compiler program can now find the required module, but unfortunately another error appears upon execution:

RuntimeError: You must get the file local/bin/sage-maxima.lisp

Since that file gets installed with Sage, the source of this error is how Sage is written. The Maxima interface does an explicit check for this file when Sage starts, as can be seen in the source code, but this depends on having an environment variable set. This error can be avoided by entering

export SAGE_LOCAL=/path/to/sage/local

at the command line. Executing the compiled result now gives the output

? cannot open `standard.lib`
0.765197686558

which has the desired numeric output, but another error message. Since standard.lib is part of the Singular library, there is clearly another hard-coded path issue somewhere else in Sage.

Since the compiled program depends explicitly on setting an environment variable, it hardly qualifies as a stand-alone executable. Even worse, attempting to process symbolic manipulations as simple as

from sage.all import *
x=var('x')
print(x)

produces the C-related error

SystemError: NULL result without error in PyObject_Call

Looks like you can compile numeric parts of Sage to C to some extent, but for the symbolics would need to cythonize and compile everything.