Removing ASDF dependency from compiled program

196 Views Asked by At

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?

0

There are 0 best solutions below