chibi-scheme
chibi-scheme copied to clipboard
embedding chibi-scheme statically in an application
I'd like to build chibi-scheme as a static library to be used as a scripting language in an application. I looked into the manual, but all I could find were instructions to build the command-line repl statically, not libchibi-scheme itself.
Looking into the Makefile, I was able to compile the library statically with the following parameters (CMake):
ExternalProject_Add(
chibi-scheme
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme
GIT_REPOSITORY https://github.com/ashinn/chibi-scheme.git
GIT_TAG master
UPDATE_COMMAND ""
CONFIGURE_COMMAND make clibs.c -C ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme/src/chibi-scheme
BUILD_COMMAND make libchibi-scheme.a SEXP_USE_DL=0 CPPFLAGS="-DSEXP_USE_STATIC_LIBS -DSEXP_USE_STATIC_LIBS_NO_INCLUDE=0" -j8 -C ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme/src/chibi-scheme
INSTALL_COMMAND ""
)
ExternalProject_Add_Step(
chibi-scheme copy2bin
COMMENT "Copying chibi-scheme .scm libs to root path."
COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme/src/chibi-scheme/lib ${CMAKE_SOURCE_DIR}
DEPENDEES build
)
add_library( libchibi-scheme STATIC IMPORTED )
set_target_properties( libchibi-scheme PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme/src/chibi-scheme/libchibi-scheme.a)
file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(main ${SRC_FILES})
target_include_directories(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/chibi-scheme/src/chibi-scheme/include)
target_compile_options(main PRIVATE -fsanitize=address -DSEXP_USE_DL=0 -DSEXP_USE_STATIC_LIBS -DSEXP_USE_STATIC_LIBS_NO_INCLUDE=0)
target_link_options(main PRIVATE -fsanitize=address)
target_link_libraries(main PUBLIC libchibi-scheme)
Using the generated libchibi-scheme.a and the sexp.h/eval.h headers worked correctly, and I was able to generate an executable that evaluated a .scm file. However, importing SRFIs does not work correctly. For instance, in the following sample program that reads a file defining a function and calls that function from C++:
main.cpp:
#include "chibi/eval.h"
#include "chibi/sexp.h"
#include <cstdio>
void dostuff(sexp ctx)
{
sexp_gc_var5(file_path, res, proc, string, tmp);
sexp_gc_preserve5(ctx, file_path, res, proc, string, tmp);
file_path = sexp_c_string(ctx, "scripts/test1.scm", -1);
res = sexp_load(ctx, file_path, NULL);
if (sexp_exceptionp(res))
{
sexp_print_exception(ctx, res, sexp_current_error_port(ctx));
}
proc = sexp_intern(ctx, "test-func", -1);
string = sexp_c_string(ctx, "World!", -1);
tmp = sexp_list2(ctx, proc, string);
res = sexp_eval(ctx, tmp, NULL);
if (sexp_exceptionp(res))
{
sexp_print_exception(ctx, res, sexp_current_error_port(ctx));
}
sexp_gc_release5(ctx);
}
int main(void) {
sexp ctx;
sexp_scheme_init();
ctx = sexp_make_eval_context(NULL, NULL, NULL, 0, 0);
sexp_load_standard_env(ctx, NULL, SEXP_SEVEN);
sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1);
dostuff(ctx);
sexp_destroy_context(ctx);
return 0;
}
test1.scm:
(import (srfi 27))
(define (test-func arg)
(if (string? arg)
(begin
(display (string-append "Hello, " arg (random-integer 10)))
(newline))
(begin
(display "Error!")
(newline))))
I get the following output:
ERROR: couldn't find include: "srfi/27/rand.so"
ERROR: undefined variable: test-func
SRFI-27 is one of the SRFIs included in clibs.c, so I was under the impression that I would be able to import and use it, even without having to build it as a dynamic module. Is there a proper way to embed chibi-scheme statically into a program, while still getting access to some of the implemented SRFIs? My main objective is to avoid needing to install chibi-scheme or distribute the shared library together with the executable.