I want to compile an ECL program into a standalone, portable executable. But no matter what I try, it still needs to load "asdf" to work.
This is partially an AB problem, since I want to remove ASDF dependency because when run with valgrind, my program cannot get behind loading ASDF no matter how long I wait. But I would also want to make a standalone executable in a future for easy deployment, so both A and B problems need to be addressed.
What works
Currently I compile the program by building static libraries and loading them all in a C program. The last library defines a main function which I call to enter the process.
#include <ecl/ecl.h>
extern void init_alexandria(cl_object);
extern void init_float_features(cl_object);
extern void init_cl_opengl(cl_object);
extern void init_sdl2(cl_object);
extern void init_mypackage(cl_object);
int ecl_init_modules() {
ecl_init_module(NULL, init_alexandria);
ecl_init_module(NULL, init_float_features);
ecl_init_module(NULL, init_cl_opengl);
ecl_init_module(NULL, init_sdl2);
ecl_init_module(NULL, init_mypackage);
return 0;
}
int main (int argc, char **argv) {
cl_boot(argc, argv);
ecl_init_modules();
cl_eval(c_string_to_object("(mypackage::main)"));
cl_shutdown();
return 0;
}
Libraries are build with asdf:make-build
(asdf:make-build :sdl2
:type :static-library
:monolithic t
:move-here #P"./dist/"
:prologue-code '(require :asdf)
:init-name "init_sdl2")
(asdf:make-build :alexandria
:type :static-library
:move-here #P"./dist/"
:init-name "init_alexandia")
(asdf:make-build :float-features
:type :static-library
:move-here #P"./dist/"
:init-name "init_float_features")
(asdf:make-build :cl-opengl
:type :static-library
:move-here #P"./dist/"
:init-name "init_cl_opengl")
(asdf:make-build :mypackage
:type :static-library
:move-here #P"./dist/"
:init-name "init_mypackage")
And finally I can build and executable with gcc.
gcc main.c dist/*.a -o mypackage -lecl
Then when I run my program, it includes asdf.fas as instructed, but at least runs and works correctly.
;;; Loading #P"/usr/lib/ecl-21.2.1/ecl-quicklisp.fas"
;;; Loading #P"/usr/lib/ecl-21.2.1/ecl-curl.fas"
;;; Loading #P"/usr/lib/ecl-21.2.1/sockets.fas"
;;; Loading "/home/infinite_users/quicklisp/setup.lisp"
;;; Loading #P"/usr/lib/ecl-21.2.1/asdf.fas"
Using SDL Library Version: 2.0.10
Setting up window/gl.
What I want
I want to remove ASDF dependency and to do that I need to remove all "requires" from my source code. This means removing :prologue-code '(require :asdf)
from the build declaration of "sdl2".
Doing so causes "missing package" issues that can be resolved by building it's dependencies as static library and loading into the program. However I hit the road-block when I try to satisfy dependencies of "CFFI", which depends on "UIOP". The program doesn't load anything, just like I want it to, but throws an error as soon as it starts.
Condition of type: SIMPLE-ERROR
The packages
((UIOP/OS . #<UIOP/OS package>) (UIOP/PATHNAME . #<UIOP/PATHNAME package>))
were referenced in compiled file
NIL
but have not been created
This is a problem, because I cannot build UIOP nor ASDF as a library. asdf:make-build
returns (NIL) and doesn't signal any other error. I tried compiling "fas" files that are being loaded and load them in my "main.c" source file but ECL doesn't seem to have this kind of feature. How can I proceed from here?