Theory

For this sample program, we really add nothing particularly new, but it bears restating that we have several main sections of code to deal with:

  1. The Regression.hs file, along with Regression_proxy.idl, Regression.i, and wrap_start_haskell.c, which represent the computational core of the application, written in Haskell

  2. The loader.py file, which represents a Python module with a single function paired_arrays_from_file, which reads a file containing our application data and returns a tuple of two lists of doubles

  3. The regression_test.e file, which contains the stateful Eiffel shell of the program, responsible for overall program flow and data state

And to generate the supporting files, we will be invoking the following tools, libraries, and scripts:

  1. The ihc command will generate glue code for calling the Haskell regression functions from C (unfortunately, we still must do some hand-editing here--in the actual example directory, the Makefile script actually copies a pre-edited file over the generated file to simulate this)

  2. The make_all_eiffel_stubs.py script will invoke its helper scripts in order to make an Eiffel shadow class LOADER to reflect the Python loader.py module

  3. The swig program will export both the Haskell-exported functions and the Python/C API functions into C-compatible source and header files

  4. The ePolyglot library will allow for interaction between the Eiffel program and the generated Python code, through the C stubs exposed by swig

  5. The compile_to_c command will generate C source files from the generated and handwritten Eiffel files

  6. The gcc compiler will generate object files from the existing C files

  7. The ghc Haskell compiler will generate object files from the existing Haskell files, as well as generating the link step to glue everything together.

For such a simple program, that's a lot of additional work in the build process, but a Makefile script simplifies things considerably--although it's worth noting that by now, with so many interrelated dependencies, the Makefile itself is probably more work than the application source code. With all the source code in place and the Makefile ready to go, we need only type make...

And the build process breaks with mysterious linkage errors:

/usr/lib/python1.5/config/libpython1.5.a(fileobject.o): In function `file_seek':/usr/src/bs/BUILD/Python-1.5.2/Objects/fileobject.c:275: undefined reference to `fseeko'
/usr/lib/python1.5/config/libpython1.5.a(compile.o): In function `com_addopname':
/usr/src/bs/BUILD/Python-1.5.2/Python/compile.c:804: undefined reference to `__rawmemchr'
/usr/lib/python1.5/config/libpython1.5.a(sysmodule.o): In function `makepathobject':
/usr/src/bs/BUILD/Python-1.5.2/Python/sysmodule.c:462: undefined reference to `__rawmemchr'
/usr/lib/python1.5/config/libpython1.5.a(tokenizer.o): In function `tok_nextc':
/usr/src/bs/BUILD/Python-1.5.2/Parser/tokenizer.c:203: undefined reference to `__rawmemchr'
/usr/src/bs/BUILD/Python-1.5.2/Parser/tokenizer.c:252: undefined reference to `__rawmemchr'
/usr/src/bs/BUILD/Python-1.5.2/Parser/tokenizer.c:276: undefined reference to `__rawmemchr'
/usr/lib/python1.5/config/libpython1.5.a(tokenizer.o):/usr/src/bs/BUILD/Python-1.5.2/Parser/tokenizer.c:315: more undefined references to `__rawmemchr' follow
/usr/lib/python1.5/config/libpython1.5.a(posixmodule.o): In function `posix_fstatvfs':
/usr/src/bs/BUILD/Python-1.5.2/Modules/./posixmodule.c:3048: undefined reference to `fstatvfs'
/usr/lib/python1.5/config/libpython1.5.a(posixmodule.o): In function `posix_statvfs':
/usr/src/bs/BUILD/Python-1.5.2/Modules/./posixmodule.c:3100: undefined reference to `statvfs'
collect2: ld returned 1 exit status