diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c56e12..617bccd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,31 @@ jobs: if: ${{ matrix.buildType == 'Release' }} run: | time ./build/run-test262 -m -c test262.conf -a + linux-examples: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: build + run: | + mkdir build + cd build + cmake -DBUILD_EXAMPLES=ON -DCMAKE_VERBOSE_MAKEFILE=ON .. + cd .. + cmake --build build -j$(getconf _NPROCESSORS_ONLN) + - name: test + run: | + ldd build/hello + ldd build/hello_module + ldd build/test_fib + ./build/hello + ./build/hello_module + ./build/test_fib + cp build/fib.so examples/ + cp build/point.so examples/ + cp build/bjson.so tests/ + ./build/qjs examples/test_fib.js + ./build/qjs examples/test_point.js + ./build/qjs tests/test_bjson.js linux-shared: runs-on: ubuntu-latest steps: @@ -175,6 +200,31 @@ jobs: ./build/qjs tests/test_loop.js ./build/qjs tests/test_std.js ./build/qjs tests/test_worker.js + macos-examples: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: build + run: | + mkdir build + cd build + cmake -DBUILD_EXAMPLES=ON .. + cd .. + cmake --build build -j$(getconf _NPROCESSORS_ONLN) + - name: test + run: | + otool -L build/hello + otool -L build/hello_module + otool -L build/test_fib + ./build/hello + ./build/hello_module + ./build/test_fib + cp build/fib.so examples/ + cp build/point.so examples/ + cp build/bjson.so tests/ + ./build/qjs examples/test_fib.js + ./build/qjs examples/test_point.js + ./build/qjs tests/test_bjson.js macos-shared: runs-on: macos-latest steps: diff --git a/.gitignore b/.gitignore index e1d6b40..2919dbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ *.a *.orig +*.so .obj/ build/ examples/hello examples/hello_module -examples/point.so examples/test_fib hello.c microbench diff --git a/CMakeLists.txt b/CMakeLists.txt index fbeba2e..927e534 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ if(BUILD_SHARED_LIBS) message(STATUS "Building a shared library") endif() +option(BUILD_EXAMPLES "Build examples" OFF) option(CONFIG_ASAN "Enable AddressSanitizer (ASan)" OFF) option(CONFIG_MSAN "Enable MemorySanitizer (MSan)" OFF) option(CONFIG_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF) @@ -114,6 +115,10 @@ set(qjs_sources ) list(APPEND qjs_defines _GNU_SOURCE) +list(APPEND qjs_libs qjs m pthread) +if(NOT MINGW) + list(APPEND qjs_libs dl) +endif() add_library(qjs ${qjs_sources}) target_compile_definitions(qjs PRIVATE ${qjs_defines}) @@ -128,6 +133,17 @@ target_include_directories(qjs PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) # QuickJS bytecode compiler # +add_executable(qjsc + qjsc.c + quickjs-libc.c +) +target_compile_definitions(qjsc PRIVATE ${qjs_defines}) +target_link_libraries(qjsc ${qjs_libs}) + + +# QuickJS CLI +# + add_custom_command( OUTPUT repl.c COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -c -o ./repl.c -m ${CMAKE_CURRENT_SOURCE_DIR}/repl.js @@ -137,20 +153,6 @@ add_custom_command( SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/repl.js ) -add_executable(qjsc - qjsc.c - quickjs-libc.c -) -target_compile_definitions(qjsc PRIVATE ${qjs_defines}) -target_link_libraries(qjsc qjs m pthread) -if(NOT MINGW) - target_link_libraries(qjsc dl) -endif() - - -# QuickJS CLI -# - add_executable(qjs_exe qjs.c quickjs-libc.c @@ -160,9 +162,9 @@ set_target_properties(qjs_exe PROPERTIES OUTPUT_NAME "qjs" ) target_compile_definitions(qjs_exe PRIVATE ${qjs_defines}) -target_link_libraries(qjs_exe qjs m pthread) +target_link_libraries(qjs_exe ${qjs_libs}) if(NOT MINGW) - target_link_libraries(qjs_exe dl) + set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE) endif() @@ -174,9 +176,113 @@ add_executable(run-test262 run-test262.c ) target_compile_definitions(run-test262 PRIVATE ${qjs_defines}) -target_link_libraries(run-test262 qjs m pthread) -if(NOT MINGW) - target_link_libraries(run-test262 dl) +target_link_libraries(run-test262 ${qjs_libs}) + + +# Examples +# + +if(BUILD_EXAMPLES AND NOT MINGW) + list(APPEND HELLO_OPTS + -fno-string-normalize + -fno-map + -fno-promise + -fno-typedarray + -fno-typedarray + -fno-regexp + -fno-json + -fno-eval + -fno-proxy + -fno-date + -fno-module-loader + ) + add_custom_command( + OUTPUT hello.c + COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o ./hello.c ${HELLO_OPTS} ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js + DEPENDS qjsc + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Compile hello.js to a C file with bytecode embeddee" + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js + ) + add_executable(hello + ${CMAKE_CURRENT_BINARY_DIR}/hello.c + quickjs-libc.c + ) + target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(hello PRIVATE ${qjs_defines}) + target_link_libraries(hello ${qjs_libs}) + + list(APPEND HELLO_MODULE_OPTS + -fno-string-normalize + -fno-map + -fno-typedarray + -fno-regexp + -fno-json + -fno-eval + -fno-proxy + -fno-date + ) + add_custom_command( + OUTPUT hello_module.c + COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o ./hello_module.c ${HELLO_MODULE_OPTS} -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js + DEPENDS qjsc + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Compile hello_module.js to a C file with bytecode embeddee" + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js + ) + add_executable(hello_module + ${CMAKE_CURRENT_BINARY_DIR}/hello_module.c + quickjs-libc.c + ) + target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(hello_module PRIVATE ${qjs_defines}) + target_link_libraries(hello_module ${qjs_libs}) + + if(NOT MINGW) + add_library(fib MODULE examples/fib.c) + set_target_properties(fib PROPERTIES + PREFIX "" + ) + target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY) + if(APPLE) + target_link_options(fib PRIVATE -undefined dynamic_lookup) + endif() + + add_library(point MODULE examples/point.c) + set_target_properties(point PROPERTIES + PREFIX "" + ) + target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY) + if(APPLE) + target_link_options(point PRIVATE -undefined dynamic_lookup) + endif() + + add_library(bjson MODULE tests/bjson.c) + set_target_properties(bjson PROPERTIES + PREFIX "" + ) + target_compile_definitions(bjson PRIVATE JS_SHARED_LIBRARY) + if(APPLE) + target_link_options(bjson PRIVATE -undefined dynamic_lookup) + endif() + endif() + + add_custom_command( + OUTPUT test_fib.c + COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o test_fib.c -M ${CMAKE_CURRENT_SOURCE_DIR}/examples/fib.so,fib -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js + DEPENDS qjsc + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Compile test_fib.js to a C file with bytecode embedded" + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js + ) + add_executable(test_fib + ${CMAKE_CURRENT_BINARY_DIR}/test_fib.c + examples/fib.c + quickjs-libc.c + ) + target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(test_fib PRIVATE ${qjs_defines}) + target_link_libraries(test_fib ${qjs_libs}) endif() diff --git a/quickjs-libc.c b/quickjs-libc.c index 61c69b2..2020bdc 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -486,8 +486,8 @@ static JSModuleDef *js_module_loader_so(JSContext *ctx, if (filename != module_name) js_free(ctx, filename); if (!hd) { - JS_ThrowReferenceError(ctx, "could not load module filename '%s' as shared library", - module_name); + JS_ThrowReferenceError(ctx, "could not load module filename '%s' as shared library: %s", + module_name, dlerror()); goto fail; }