Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Successfully builds in windows using msys and Enthought Python #5

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ there, run setup.py like so::
Then install::

python setup.py install

Windows Instructions
--------------------

It seems that cspice neesds to be rebuilt to work with common Windows Python
code bases. To accomplish this::

1. Download the cygwin gCC 32bit Windows Spice toolkit here
http://naif.jpl.nasa.gov/naif/toolkit_C.html
2. Extract the file into the PySpice folder. This will create
a cspice folder right next to spice and tests.
3. Delete cspice\lib\* We need to re-build these for your platform.
3. Run mkproduct_cspice.bat with a build environment that supports
your python distribution. If you don't do much development, but
have Enthoguht Python (EPD or Canopy), this appears to just work.
4. Run `python setup.py build_ext -c mingw32`
THE `-c mingw32` is VERY important!
5.



64 bit vs 32 bit
----------------
Expand Down
76 changes: 76 additions & 0 deletions mkprodct_cspice.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
rem
rem mkcspice.bat Adapted to build cspice under windows / msys
rem
rem Creates cspice.lib for MS Visual C++ and moves it to the
rem appropriate Toolkit directory.
rem
rem
rem Version 3.1.0 19-OCT-2003 (BVS)
rem
rem added -DNON_ANSI_STDIO compile option.
rem
rem Version 3.0.0 03-NOV-1999 (NJB)
rem
rem fixed the last "set cl" command.
rem
rem Version 2.0.0 26-FEB-1999 (NJB)
rem
rem Added OMIT_BLANK_CC preprocessor flag.
rem
rem Version 1.0.0 29-DEC-1998 (NJB)
rem

cd cspice\src\cspice

set cl= /c /O2 -D_COMPLEX_DEFINED -DMSDOS -DOMIT_BLANK_CC -DNON_ANSI_STDIO

rem
rem The optimization algorithm has a very tough time with zzsecptr.c,
rem so exempt this routine from optimization.
rem

rename zzsecprt.c zzsecprt.x

rem
rem Compile everything else.
rem

REM BEGIN FISCHER MOD
REM for %%f in (*.c) do cl %%f
gcc -I..\..\include -c -O2 -D_COMPLEX_DEFINED -DOMIT_BLANK_CC -DNON_ANSI_STDIO -DMSDOS *.c
REM ENDFISCHERMOD

rem
rem Set the cl variable to omit optimization. Compile zzsecprt.c.
rem


REM BEGIN FISCHER MOD
REM set cl= /c -D_COMPLEX_DEFINED -DMSDOS -DOMIT_BLANK_CC
REM END

rename zzsecprt.x zzsecprt.c

REM BEGIN FISCHER MOD
REM cl zzsecprt.c
gcc -I..\..\include -c -D_COMPLEX_DEFINED -DOMIT_BLANK_CC -DMSDOS zzsecprt.c
REM END

dir /b *.o > temp.lst

REM BEGIN FISCHER MOD
REM link -lib /out:cspice.lib @temp.lst

REM gcc -o cspice.lib @temp.lst
ar -cq cspice.lib @temp.lst
gcc -shared -o cspice.dll @temp.lst
REM END FISCHER MOD


move cspice.lib ..\..\lib
move cspice.dll ..\..\lib


rem del *.o
del temp.lst

77 changes: 50 additions & 27 deletions mkwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def __setattr__(self, key, val):
'gfevnt_c', 'gffove_c', 'gfocce_c', 'gfuds_c', 'uddc_c', 'uddf_c',
)

custom_list = ('spkw10_c', 'getelm_c',
)

module_defs = []
cspice_src = None

Expand Down Expand Up @@ -200,8 +203,11 @@ def get_doc(function_name):

return '"%s"' % doc.getvalue()

def gen_wrapper(prototype, buffer):
prototype = remove_extra_spaces(prototype)
def gen_function(prototype_obj, prototype_comment, python_function_name, buffer):
# declare the function for this wrapper
# I moved this block of code to a separate function for readability. It's
# still pretty cumbersome, but hey! it works.

manually_build_returnVal = False
input_list = []
input_name_list = []
Expand All @@ -216,37 +222,12 @@ def gen_wrapper(prototype, buffer):
# likely STRING_LEN above).
string_output_num = 0

# parse up the given prototype into its fundamental pieces. this function
# returns a container object with all the information parsed up.
prototype_obj = parse_prototype(prototype)

# check the exclude list before continuing
if prototype_obj.function_name in exclude_list: return False

# the string that is passed to PyArg_ParseTuple for getting the
# arguments list and Py_BuildValue for returning results
parse_tuple_string = ""
buildvalue_string = ""

# remove the _c suffix for the python function name
python_function_name = prototype_obj.function_name.rsplit('_c',1)[0]

# Add the C function prototype to the source code output.
t = '/* %s */' % prototype
prototype_comment_list = []
while len(t) > 80:
count = 79
while t[count-1] != ',' and count > 1:
count -= 1

prototype_comment_list.append(t[:count])
t = t[count:]
if t:
prototype_comment_list.append(t)

prototype_comment = '\n'.join(prototype_comment_list)

# declare the function for this wrapper
buffer.write(
"\n%s\nstatic PyObject * spice_%s(PyObject *self, PyObject *args)\n{" % \
(prototype_comment, python_function_name));
Expand Down Expand Up @@ -534,7 +515,49 @@ def gen_wrapper(prototype, buffer):
pass # for now; TODO: figure out what to do

buffer.write("\n}");
return python_function_name


def gen_wrapper(prototype, buffer):
prototype = remove_extra_spaces(prototype)


# parse up the given prototype into its fundamental pieces. this function
# returns a container object with all the information parsed up.
prototype_obj = parse_prototype(prototype)

# remove the _c suffix for the python function name
python_function_name = prototype_obj.function_name.rsplit('_c',1)[0]


# check the exclude list before continuing.
if (prototype_obj.function_name in exclude_list and
prototype_obj.function_name not in custom_list ): return False

# Add the C function prototype to the source code output.
t = '/* %s */' % prototype
prototype_comment_list = []
while len(t) > 80:
count = 79
while t[count-1] != ',' and count > 1:
count -= 1

prototype_comment_list.append(t[:count])
t = t[count:]
if t:
prototype_comment_list.append(t)

prototype_comment = '\n'.join(prototype_comment_list)


# If it's not a custom command, add the function to the spicemodule.c output
if prototype_obj.function_name not in custom_list:
gen_function(prototype_obj, prototype_comment, python_function_name, buffer, )

# Custom commands still get a doc string and module_defs. I tried making
# them separate modules, but the static linking of cspice meant that modules
# furnsh'd under one module were not available under the custom module.

# dig out the function name from the source file
doc = get_doc(prototype_obj.function_name)

Expand Down
2 changes: 2 additions & 0 deletions pyspice.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include <stdio.h>

#include "spicemodule_custom.h"

#ifndef __PYSPICE_H__
#define __PYSPICE_H__ 1

Expand Down
38 changes: 32 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from shutil import copy
from subprocess import PIPE, Popen

WINDOWS = os.sys.platform == 'win32'


APP_NAME = os.path.basename(os.getcwd())
SHARE_DIR = os.path.join('share', 'spicedoc')

Expand All @@ -28,14 +31,20 @@
class LibError(Exception): pass

def build_cspice():
libfile_path = os.path.join(CSPICE_SRC, 'lib', 'cspice.a')
if os.path.exists(libfile_path):
libfile_paths = (os.path.join(CSPICE_SRC, 'lib', 'cspice.a'),
os.path.join(CSPICE_SRC, 'lib', 'cspice.lib'),
)
if any(os.path.exists(x) for x in libfile_paths):
return

curr_dir = os.getcwd()
try:
os.chdir(CSPICE_SRC)
makeall = Popen('/bin/csh makeall.csh', shell=True)
if WINDOWS:
makeall = Popen('mkprodct_cspice.bat', shell=True)

else:
os.chdir(CSPICE_SRC)
makeall = Popen('/bin/csh makeall.csh', shell=True)
status = os.waitpid(makeall.pid, 0)[1]

if status != 0:
Expand All @@ -44,7 +53,11 @@ def build_cspice():
os.chdir(curr_dir)

def find_libs():
for libfile in ('cspice.a', 'csupport.a'):
if WINDOWS:
libfile_list = ('cspice.lib', )
else:
libfile_list = ('cspice.a', )
for libfile in libfile_list:
libfile_path = os.path.join(CSPICE_SRC, 'lib', libfile)
lib_libfile_path = os.path.join(CSPICE_SRC, 'lib', 'lib' + libfile)

Expand Down Expand Up @@ -79,6 +92,19 @@ def set_build_paths():
path = os.path.join(CSPICE_SRC, dirname)
sys.argv.append('%s%s' % (flag, path))

spice_custom = Extension(
'_spice',
sources = ['pyspice.c', 'spicemodule.c',
'spicemodule_custom.c'
],
libraries = ['cspice'],
include_dirs=[os.path.join(CSPICE_SRC, 'include'),],
library_dirs=[os.path.join(CSPICE_SRC, 'lib'),],
define_macros=[#('MSDOS', None),
('_COMPLEX_DEFINED', None),
('OMIT_BLANK_CC', None)],
)

try:
build_cspice()
make_spice_module()
Expand All @@ -96,7 +122,7 @@ def set_build_paths():
version = '1.0',
description = 'Spice Wrapper Module',
packages = ['spice'],
ext_modules = [module1]
ext_modules = [spice_custom]
)
finally:
cleanup()
Loading