I've created this simple sample project.
Source files
CmakeLists.txt
cmake_minimum_required(VERSION 3.21)
cmake_policy(VERSION 3.21)
project(qjs_test LANGUAGES C)
add_executable(
qjs_test
main.c
)
find_package(qjs REQUIRED CONFIG NAMES qjs quickjs)
find_package(Threads REQUIRED)
target_link_libraries(qjs_test PUBLIC qjs Threads::Threads ${CMAKE_DL_LIBS})
main.c
#include <quickjs.h>
int main() {
JSRuntime *runtime = JS_NewRuntime();
JS_FreeRuntime(runtime);
return 0;
}
Building
I've cloned the current master branch of quickjs-ng into ./quickjs, and tried to build (full log attached; it's fairly long and not all of it is relevant):
bash-3.2$ cmake -Bbuild/quickjs -S./quickjs "-DCMAKE_INSTALL_PREFIX=$PWD/install" "-DCMAKE_PREFIX_PATH=$PWD/install"
-- The C compiler identification is AppleClang 17.0.0.17000603
-- Detecting C compiler ABI info
...
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/build/quickjs
bash-3.2$ cmake --build build/quickjs
[ 4%] Building C object CMakeFiles/cutils.dir/cutils.c.o
[ 9%] Linking C static library libcutils.a
[ 9%] Built target cutils
[ 14%] Building C object CMakeFiles/qjs.dir/dtoa.c.o
...
[100%] Linking C executable function_source
[100%] Built target function_source
bash-3.2$ cmake --install build/quickjs
-- Install configuration: "Release"
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/include/quickjs.h
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/bin/qjs
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/bin/qjsc
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/lib/libqjs.a
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/lib/cmake/quickjs/qjsConfig.cmake
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/lib/cmake/quickjs/qjsConfig-release.cmake
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/LICENSE
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/test_point.js
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/hello.js
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/test_fib.js
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/meson.build
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/fib_module.js
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/point.c
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/fib.c
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/pi_bigint.js
-- Installing: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/install/share/doc/quickjs/examples/hello_module.js
bash-3.2$ cmake -Bbuild/qjs_test -S. "-DCMAKE_INSTALL_PREFIX=$PWD/install" "-DCMAKE_PREFIX_PATH=$PWD/install"
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (0.1s)
-- Generating done (0.0s)
-- Build files have been written to: /private/var/folders/4p/s82tj31s75n_8rlzw_nvz4t40000gn/T/tmp.CXu7DV1T8f/build/qjs_test
bash-3.2$ cmake --build build/qjs_test
[ 50%] Building C object CMakeFiles/qjs_test.dir/main.c.o
[100%] Linking C executable qjs_test
Undefined symbols for architecture arm64:
"___dbuf_put_u16", referenced from:
_lre_compile in libqjs.a[3](libregexp.c.o)
_re_parse_alternative in libqjs.a[3](libregexp.c.o)
_re_emit_range in libqjs.a[3](libregexp.c.o)
_re_emit_range in libqjs.a[3](libregexp.c.o)
_re_emit_range in libqjs.a[3](libregexp.c.o)
_re_emit_range in libqjs.a[3](libregexp.c.o)
_JS_WriteString in libqjs.a[5](quickjs.c.o)
...
_JS_NewStringLen in libqjs.a[5](quickjs.c.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [qjs_test] Error 1
make[1]: *** [CMakeFiles/qjs_test.dir/all] Error 2
make: *** [all] Error 2
bash-3.2$
It looks like this is because you build cutils into a private library and link it into the qjs executable, but the cutils lib is not built into libqjs nor is it installed and exposed in the qjs target. In my case, I can work around it by either explicitly linking in the cutils lib:
find_library(CUTILS cutils PATHS "${CMAKE_SOURCE_DIR}/build/quickjs" REQUIRED)
target_link_libraries(qjs_test PUBLIC qjs Threads::Threads ${CMAKE_DL_LIBS} ${CUTILS})
Or adding the cutils.c file to my own build:
add_executable(
qjs_test
main.c
./quickjs/cutils.c
)
Fix
Quickjs needs to either export cutils symbols somehow (either by exposing the cutils library or including the object in the qjs library), inline the functions (by moving the cutils.c definitions to cutils.h and making them all static inline), or do some platform-specific post-link symbol localization.
I think the most simple and obvious choice would be the inlining, if you want to avoid name collision. Exposing them would probably necessitate a mass-rename of most of cutils symbols, and post-link symbol localization is platform specific, toolchain specific, and I have no idea what all the necessary tools even are, personally.
I've created this simple sample project.
Source files
CmakeLists.txt
main.c
Building
I've cloned the current master branch of quickjs-ng into
./quickjs, and tried to build (full log attached; it's fairly long and not all of it is relevant):It looks like this is because you build cutils into a private library and link it into the qjs executable, but the cutils lib is not built into libqjs nor is it installed and exposed in the
qjstarget. In my case, I can work around it by either explicitly linking in the cutils lib:Or adding the cutils.c file to my own build:
Fix
Quickjs needs to either export cutils symbols somehow (either by exposing the cutils library or including the object in the qjs library), inline the functions (by moving the cutils.c definitions to cutils.h and making them all
static inline), or do some platform-specific post-link symbol localization.I think the most simple and obvious choice would be the inlining, if you want to avoid name collision. Exposing them would probably necessitate a mass-rename of most of cutils symbols, and post-link symbol localization is platform specific, toolchain specific, and I have no idea what all the necessary tools even are, personally.