Hello,
Is there is a way for ECL only to generate a bunch of .cpp files that can be fed to existing build system? I'm halfway there by generating C from my (ffi:c-inline) stuff like:
(compile-file "src/common/lisp/lispinterface.lisp" :output-file "src/common/lisp/lispinterface.cpp").
But how do I initialize it on app startup? Looks like
void init_fas_CODE(cl_object flag)
should be called, but with what parameters?
Some background: I am trying to embed ECL in a big C++ app with its own byzantine build system (ftjam with own layer on top of it). These C++ functions I am interfacing are not exposed externally (and I prefer not to), thus trying to load .fas file at runtime results in linker error. Also, I can't use (build-program) which won't work together with the build system.
However, if (build-program) knows how to neatly pack whole initialization into one C function, that would solve the problem, too.
Regards,
Juraj
Hello,
Juraj Variny writes:
Hello,
Is there is a way for ECL only to generate a bunch of .cpp files that can be fed to existing build system? I'm halfway there by generating C from my (ffi:c-inline) stuff like:
(compile-file "src/common/lisp/lispinterface.lisp" :output-file "src/common/lisp/lispinterface.cpp").
generally that's how it's done (generating the C files).
But how do I initialize it on app startup? Looks like
void init_fas_CODE(cl_object flag)
should be called, but with what parameters?
I'm afraid that it won't work the way you want it to run. Standalone executables (and the shared libraries), still require libecl to run (linked either dynamically or statically, note however that static linkage results in covering code you link with with LGPLv2).
Some background: I am trying to embed ECL in a big C++ app with its own byzantine build system (ftjam with own layer on top of it). These C++ functions I am interfacing are not exposed externally (and I prefer not to), thus trying to load .fas file at runtime results in linker error. Also, I can't use (build-program) which won't work together with the build system.
However, if (build-program) knows how to neatly pack whole initialization into one C function, that would solve the problem, too.
As already said, C code requires ECL runtime (library). Path I would suggest would be linking ECL dynamically (providing .so file or .dll depending on platform), and loading the code in built FAS file with the ECL's si_load_binary.
Note, that if you don't change the platform nor the ECL, you may precompile FAS and load them at your convenience later.
Regards,
Juraj
Best regards, Daniel
In the end have hacked it together using c:build-static-library, which leaves things to be desired:
(let ((compiler::*USER-CC-FLAGS* "-I... put here $CFLAGS from the build system....") (compiler::*USER-LD-FLAGS* "... put here $LDFLAGS from the build system... ") (objfile (compile-file "src/common/lisp/lispinterface" :system-p t))) (print objfile) (print (c:build-static-library "lispinterface" :lisp-files (list objfile) :init-name "lispinterface_INIT")))
For example the CFLAGS and LDFLAGS must be synchronized with the build system somehow. The resulting liblispinterface.a must be added to linker for whole project. Rest of the application then calls only cl_boot and lispinterface_INIT like:
cl_object the_block = read_VV(OBJNULL, lispinterface_INIT);
So I'd still like to see ECL function that would do above but only generate all C/C++ output file(s) without compiling.
Currently it's possible only when you specify output for compile-file, (setf c::*delete-files* nil) and fish C files out from /tmp.
Regards,
Juraj
On Monday 29 February 2016 13:28:09 you wrote:
Hello,
Juraj Variny writes:
Hello,
Is there is a way for ECL only to generate a bunch of .cpp files that can be fed to existing build system? I'm halfway there by generating C from my (ffi:c-inline) stuff like:
(compile-file "src/common/lisp/lispinterface.lisp" :output-file "src/common/lisp/lispinterface.cpp").
generally that's how it's done (generating the C files).
But how do I initialize it on app startup? Looks like
void init_fas_CODE(cl_object flag)
should be called, but with what parameters?
I'm afraid that it won't work the way you want it to run. Standalone executables (and the shared libraries), still require libecl to run (linked either dynamically or statically, note however that static linkage results in covering code you link with with LGPLv2).
Some background: I am trying to embed ECL in a big C++ app with its own byzantine build system (ftjam with own layer on top of it). These C++ functions I am interfacing are not exposed externally (and I prefer not to), thus trying to load .fas file at runtime results in linker error. Also, I can't use (build-program) which won't work together with the build system.
However, if (build-program) knows how to neatly pack whole initialization into one C function, that would solve the problem, too.
As already said, C code requires ECL runtime (library). Path I would suggest would be linking ECL dynamically (providing .so file or .dll depending on platform), and loading the code in built FAS file with the ECL's si_load_binary.
Note, that if you don't change the platform nor the ECL, you may precompile FAS and load them at your convenience later.
Regards,
Juraj
Best regards, Daniel
Thanks for the information how you have resolved the issue. As far as I see in the code, compile-file shouldn't delete files, if the names were provided:
(to-delete (nconc (unless c-file (list c-pathname)) (unless h-file (list h-pathname)) (unless data-file (list data-pathname))))
I would much appreciate, if you could submit this proposal as a feature request on the gitlab.com/embeddable-common-lisp/ecl/issues with the description of the interface and expected result and an example of the expected output (may be a pseudo-code of course). It will simplify things for me greatly.
Regards, Daniel
Juraj Variny writes:
In the end have hacked it together using c:build-static-library, which leaves things to be desired:
(let ((compiler::*USER-CC-FLAGS* "-I... put here $CFLAGS from the build system....") (compiler::*USER-LD-FLAGS* "... put here $LDFLAGS from the build system... ") (objfile (compile-file "src/common/lisp/lispinterface" :system-p t))) (print objfile) (print (c:build-static-library "lispinterface" :lisp-files (list objfile) :init-name "lispinterface_INIT")))
For example the CFLAGS and LDFLAGS must be synchronized with the build system somehow. The resulting liblispinterface.a must be added to linker for whole project. Rest of the application then calls only cl_boot and lispinterface_INIT like:
cl_object the_block = read_VV(OBJNULL, lispinterface_INIT);
So I'd still like to see ECL function that would do above but only generate all C/C++ output file(s) without compiling.
Currently it's possible only when you specify output for compile-file, (setf c::*delete-files* nil) and fish C files out from /tmp.
Regards,
Juraj
On Monday 29 February 2016 13:28:09 you wrote:
Hello,
Juraj Variny writes:
Hello,
Is there is a way for ECL only to generate a bunch of .cpp files that can be fed to existing build system? I'm halfway there by generating C from my (ffi:c-inline) stuff like:
(compile-file "src/common/lisp/lispinterface.lisp" :output-file "src/common/lisp/lispinterface.cpp").
generally that's how it's done (generating the C files).
But how do I initialize it on app startup? Looks like
void init_fas_CODE(cl_object flag)
should be called, but with what parameters?
I'm afraid that it won't work the way you want it to run. Standalone executables (and the shared libraries), still require libecl to run (linked either dynamically or statically, note however that static linkage results in covering code you link with with LGPLv2).
Some background: I am trying to embed ECL in a big C++ app with its own byzantine build system (ftjam with own layer on top of it). These C++ functions I am interfacing are not exposed externally (and I prefer not to), thus trying to load .fas file at runtime results in linker error. Also, I can't use (build-program) which won't work together with the build system.
However, if (build-program) knows how to neatly pack whole initialization into one C function, that would solve the problem, too.
As already said, C code requires ECL runtime (library). Path I would suggest would be linking ECL dynamically (providing .so file or .dll depending on platform), and loading the code in built FAS file with the ECL's si_load_binary.
Note, that if you don't change the platform nor the ECL, you may precompile FAS and load them at your convenience later.
Regards,
Juraj
Best regards, Daniel