Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

embedding chibi-scheme statically in an application #1000

Open
Mateus-Carmo31 opened this issue Sep 19, 2024 · 1 comment
Open

embedding chibi-scheme statically in an application #1000

Mateus-Carmo31 opened this issue Sep 19, 2024 · 1 comment

Comments

@Mateus-Carmo31
Copy link

Mateus-Carmo31 commented Sep 19, 2024

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.

@edvardo1
Copy link

edvardo1 commented Nov 16, 2024

Hi, I've been able to do this by copying the lib/ folder into the same directory as the program is being executed (I've also checked if it actually statically linked it with ldd and verified that no libchibi-scheme was there.), also your program doesn't actually run without the substitution s/(random-integer 10)/(number->string &)/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants