quickjs.h: Add JS_MODULE_EXTERN macro and use it in examples/

The new macro is a counterpart to JS_EXTERN, but for binary C modules.
This commit introduces one more preprocessor define that must be set
when building C modules.

This commit changes examples/fib.c and examples/point.c to use the new
macro, while also removing redundant JS_SHARED_LIBRARY. Additionally,
the includes use the angled brackets now since quickjs.h is supposed to
be external to the binary modules.

meson.build is fixed to properly add the include directory; the manual
header copying has also been removed as it is redundant.

Signed-off-by: Zurab Kvachadze <[email protected]>
This commit is contained in:
Zurab Kvachadze authored and Saúl Ibarra Corretgé committed 2026-02-09 14:28:55 +01:00
1 parent fe7a959088
commit 8fd3258d35
6 files changed
+87 -52

No files matched your search

+32 -11
View File
@@ -304,6 +304,23 @@ if(QJS_LIB_TYPE STREQUAL "SHARED_LIBRARY")
)
endif()
# An interface library for modules.
add_library(qjs_module_lib INTERFACE)
target_include_directories(qjs_module_lib INTERFACE
$<TARGET_PROPERTY:qjs,INTERFACE_INCLUDE_DIRECTORIES>
)
target_compile_definitions(qjs_module_lib INTERFACE
QUICKJS_NG_MODULE_BUILD
$<TARGET_PROPERTY:qjs,INTERFACE_COMPILE_DEFINITIONS>
)
if(WIN32)
# Since Windows cannot resolve symbols at load time, we need to
# explicitly link it to qjs.
target_link_libraries(qjs_module_lib INTERFACE
qjs
)
endif()
if(NOT QJS_BUILD_LIBC)
add_library(qjs-libc STATIC quickjs-libc.c)
target_compile_definitions(qjs-libc PRIVATE ${qjs_defines})
@@ -442,6 +459,15 @@ target_link_libraries(function_source PRIVATE qjs)
#
if(QJS_BUILD_EXAMPLES)
if(WIN32 AND NOT (QJS_LIB_TYPE STREQUAL "SHARED_LIBRARY"))
message(AUTHOR_WARNING
"Binary modules used with static qjs on Windows. There might be\n"
"runtime errors when the module is used due to two copies of qjs\n"
"in memory.\n"
"Please use \"-DBUILD_SHARED_LIBS=true\" if possible."
)
endif()
add_executable(hello
gen/hello.c
)
@@ -461,35 +487,30 @@ if(QJS_BUILD_EXAMPLES)
add_library(fib MODULE examples/fib.c)
set_target_properties(fib PROPERTIES
PREFIX ""
C_VISIBILITY_PRESET default
)
target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY)
if(WIN32)
target_link_libraries(fib PRIVATE qjs)
elseif(APPLE)
target_link_libraries(fib PRIVATE qjs_module_lib)
if(APPLE)
target_link_options(fib PRIVATE -undefined dynamic_lookup)
endif()
add_library(point MODULE examples/point.c)
set_target_properties(point PROPERTIES
PREFIX ""
C_VISIBILITY_PRESET default
)
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
if(WIN32)
target_link_libraries(point PRIVATE qjs)
elseif(APPLE)
target_link_libraries(point PRIVATE qjs_module_lib)
if(APPLE)
target_link_options(point PRIVATE -undefined dynamic_lookup)
endif()
add_executable(test_fib
examples/fib.c
gen/test_fib.c
)
add_qjs_libc_if_needed(test_fib)
target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(test_fib PRIVATE ${qjs_defines})
target_link_libraries(test_fib PRIVATE qjs)
# Loads fib.so which depends on symbols from libqjs.
set_target_properties(test_fib PROPERTIES ENABLE_EXPORTS TRUE)
endif()
# Install target
+3 -16
View File
@@ -21,7 +21,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "../quickjs.h"
#include <quickjs.h>
#define countof(x) (sizeof(x) / sizeof((x)[0]))
@@ -55,21 +56,7 @@ static int js_fib_init(JSContext *ctx, JSModuleDef *m)
countof(js_fib_funcs));
}
#ifdef JS_SHARED_LIBRARY
#define JS_INIT_MODULE js_init_module
#else
#define JS_INIT_MODULE js_init_module_fib
#endif
#ifndef JS_EXTERN
#ifdef _WIN32
#define JS_EXTERN __declspec(dllexport)
#else
#define JS_EXTERN
#endif
#endif
JS_EXTERN JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
JS_MODULE_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
{
JSModuleDef *m;
m = JS_NewCModule(ctx, module_name, js_fib_init);
+4 -6
View File
@@ -3,9 +3,8 @@ shared_module(
'fib.c',
name_prefix: '',
gnu_symbol_visibility: 'default',
c_args: ['-DJS_SHARED_LIBRARY'],
dependencies: host_system == 'windows' ? qjs_dep : [],
gnu_symbol_visibility: 'hidden',
dependencies: qjs_module_dep,
)
shared_module(
@@ -13,7 +12,6 @@ shared_module(
'point.c',
name_prefix: '',
gnu_symbol_visibility: 'default',
c_args: ['-DJS_SHARED_LIBRARY'],
dependencies: host_system == 'windows' ? qjs_dep : [],
gnu_symbol_visibility: 'hidden',
dependencies: qjs_module_dep,
)
+4 -10
View File
@@ -21,9 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "../quickjs.h"
#include <math.h>
#include <quickjs.h>
#define countof(x) (sizeof(x) / sizeof((x)[0]))
/* Point Class */
@@ -141,15 +143,7 @@ static int js_point_init(JSContext *ctx, JSModuleDef *m)
return 0;
}
#ifndef JS_EXTERN
#ifdef _WIN32
#define JS_EXTERN __declspec(dllexport)
#else
#define JS_EXTERN
#endif
#endif
JS_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
JS_MODULE_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
{
JSModuleDef *m;
m = JS_NewCModule(ctx, module_name, js_point_init);
+22 -9
View File
@@ -181,13 +181,6 @@ qjs_lib = library(
qjs_srcs,
qjs_libc ? qjs_libc_srcs : [],
# export public headers
generator(
find_program('cp', 'xcopy'),
output: ['@PLAINNAME@'],
arguments: ['@INPUT@', '@OUTPUT@'],
).process(qjs_hdrs),
dependencies: qjs_sys_deps,
link_with: cutils_lib,
c_args: qjs_c_args,
@@ -214,10 +207,23 @@ qjs_dep = declare_dependency(
compile_args: qjs_dep_args,
link_with: qjs_lib,
dependencies: qjs_sys_deps,
include_directories: qjs_lib.private_dir_include(),
include_directories: include_directories('.'),
variables: qjs_export_variables,
)
if host_system != 'windows'
qjs_module_dep = declare_dependency(
compile_args: [qjs_dep_args, '-DQUICKJS_NG_MODULE_BUILD'],
include_directories: include_directories('.'),
)
else
qjs_module_dep = declare_dependency(
compile_args: [qjs_dep_args, '-DQUICKJS_NG_MODULE_BUILD'],
include_directories: include_directories('.'),
# Windows can't resolve symbols at runtime thus we explicitly link to qjs.
dependencies: qjs_dep,
)
endif
if qjs_libc
qjs_libc_dep = declare_dependency(
@@ -643,6 +649,14 @@ alias_target('codegen',
)
if examples.allowed()
if host_system == 'windows' and get_option('default_library') != 'shared'
warning('Binary modules used with static qjs on Windows.')
warning(
'There might be runtime errors when the modules are used due to',
'two copies of qjs in memory.'
)
warning('Please use "-Ddefault_library=shared" if possible.')
endif
executable(
'hello',
'gen/hello.c',
@@ -663,7 +677,6 @@ if examples.allowed()
executable(
'test_fib',
'examples/fib.c',
'gen/test_fib.c',
c_args: qjs_c_args,
+22
View File
@@ -111,6 +111,28 @@ extern "C" {
# define JS_LIBC_EXTERN JS_EXTERN
#endif
/*
* `JS_MODULE_EXTERN` -- helper macro that must be used to mark `js_init_module`
* and other public functions of the binary modules. See examples/ for examples
* of the usage.
*
* Windows note: -DQUICKJS_NG_MODULE_BUILD must be set when building a binary
* module to properly set __declspec.
*/
#ifdef QUICKJS_NG_PLAT_WIN32
# ifdef QUICKJS_NG_MODULE_BUILD
# define JS_MODULE_EXTERN __declspec(dllexport)
# else
# define JS_MODULE_EXTERN __declspec(dllimport)
# endif
#else
# ifdef QUICKJS_NG_CC_GNULIKE
# define JS_MODULE_EXTERN __attribute__((visibility("default")))
# else
# define JS_MODULE_EXTERN /* nothing */
# endif
#endif /* QUICKJS_NG_PLAT_WIN32 */
/* Borrowed from Folly */
#ifndef JS_PRINTF_FORMAT
#ifdef _MSC_VER