mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Add native module support on Windows
This commit is contained in:
parent
ada24f33f3
commit
902cc2cf0e
8 changed files with 127 additions and 30 deletions
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
|
@ -195,14 +195,20 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- name: build
|
||||
run: |
|
||||
cmake -B build -G "Visual Studio 17 2022" -A ${{matrix.arch}}
|
||||
cmake -B build -DBUILD_EXAMPLES=ON -G "Visual Studio 17 2022" -A ${{matrix.arch}}
|
||||
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
||||
cmake --build build --config ${{matrix.buildType}} --target function_source
|
||||
cmake --build build --config ${{matrix.buildType}} --target fib
|
||||
cmake --build build --config ${{matrix.buildType}} --target point
|
||||
- name: stats
|
||||
run: |
|
||||
build\${{matrix.buildType}}\qjs.exe -qd
|
||||
- name: test
|
||||
run: |
|
||||
cp build\${{matrix.buildType}}\fib.dll examples\
|
||||
cp build\${{matrix.buildType}}\point.dll examples\
|
||||
build\${{matrix.buildType}}\qjs.exe examples\test_fib.js
|
||||
build\${{matrix.buildType}}\qjs.exe examples\test_point.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_bjson.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
||||
|
@ -224,14 +230,20 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- name: build
|
||||
run: |
|
||||
cmake -B build -G "Visual Studio 17 2022" -T ClangCL
|
||||
cmake -B build -DBUILD_EXAMPLES=ON -G "Visual Studio 17 2022" -T ClangCL
|
||||
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
||||
cmake --build build --config ${{matrix.buildType}} --target function_source
|
||||
cmake --build build --config ${{matrix.buildType}} --target fib
|
||||
cmake --build build --config ${{matrix.buildType}} --target point
|
||||
- name: stats
|
||||
run: |
|
||||
build\${{matrix.buildType}}\qjs.exe -qd
|
||||
- name: test
|
||||
run: |
|
||||
cp build\${{matrix.buildType}}\fib.dll examples\
|
||||
cp build\${{matrix.buildType}}\point.dll examples\
|
||||
build\${{matrix.buildType}}\qjs.exe examples\test_fib.js
|
||||
build\${{matrix.buildType}}\qjs.exe examples\test_point.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_bjson.js
|
||||
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
||||
|
@ -257,14 +269,20 @@ jobs:
|
|||
ninja.exe --version
|
||||
- name: build
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
|
||||
cmake -B build -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
|
||||
cmake --build build --target qjs_exe
|
||||
cmake --build build --target function_source
|
||||
cmake --build build --target fib
|
||||
cmake --build build --target point
|
||||
- name: stats
|
||||
run: |
|
||||
build\qjs.exe -qd
|
||||
- name: test
|
||||
run: |
|
||||
cp build\fib.dll examples\
|
||||
cp build\point.dll examples\
|
||||
build\qjs.exe examples\test_fib.js
|
||||
build\qjs.exe examples\test_point.js
|
||||
build\qjs.exe tests\test_bigint.js
|
||||
build\qjs.exe tests\test_bjson.js
|
||||
build\qjs.exe tests\test_closure.js
|
||||
|
|
|
@ -273,7 +273,7 @@ target_link_libraries(function_source ${qjs_libs})
|
|||
# Examples
|
||||
#
|
||||
|
||||
if(BUILD_EXAMPLES AND NOT WIN32)
|
||||
if(BUILD_EXAMPLES)
|
||||
add_executable(hello
|
||||
gen/hello.c
|
||||
)
|
||||
|
@ -290,13 +290,15 @@ if(BUILD_EXAMPLES AND NOT WIN32)
|
|||
target_compile_definitions(hello_module PRIVATE ${qjs_defines})
|
||||
target_link_libraries(hello_module ${qjs_libs})
|
||||
|
||||
if(NOT WIN32)
|
||||
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 ${qjs_libs})
|
||||
endif()
|
||||
if(APPLE)
|
||||
target_link_options(fib PRIVATE -undefined dynamic_lookup)
|
||||
endif()
|
||||
|
@ -307,10 +309,12 @@ if(BUILD_EXAMPLES AND NOT WIN32)
|
|||
C_VISIBILITY_PRESET default
|
||||
)
|
||||
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
|
||||
if(WIN32)
|
||||
target_link_libraries(point ${qjs_libs})
|
||||
endif()
|
||||
if(APPLE)
|
||||
target_link_options(point PRIVATE -undefined dynamic_lookup)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(test_fib
|
||||
examples/fib.c
|
||||
|
|
|
@ -61,7 +61,15 @@ static int js_fib_init(JSContext *ctx, JSModuleDef *m)
|
|||
#define JS_INIT_MODULE js_init_module_fib
|
||||
#endif
|
||||
|
||||
JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
||||
#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)
|
||||
{
|
||||
JSModuleDef *m;
|
||||
m = JS_NewCModule(ctx, module_name, js_fib_init);
|
||||
|
|
|
@ -141,7 +141,15 @@ static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
|||
return 0;
|
||||
}
|
||||
|
||||
JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
||||
#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)
|
||||
{
|
||||
JSModuleDef *m;
|
||||
m = JS_NewCModule(ctx, module_name, js_point_init);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* example of JS module importing a C module */
|
||||
import * as os from "os";
|
||||
|
||||
import { fib } from "./fib.so";
|
||||
const isWin = os.platform === 'win32';
|
||||
const { fib } = await import(`./fib.${isWin ? 'dll' : 'so'}`);
|
||||
|
||||
console.log("Hello World");
|
||||
console.log("fib(10)=", fib(10));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/* example of JS module importing a C module */
|
||||
import { Point } from "./point.so";
|
||||
import * as os from "os";
|
||||
|
||||
const isWin = os.platform === 'win32';
|
||||
const { Point } = await import(`./point.${isWin ? 'dll' : 'so'}`);
|
||||
|
||||
function assert(b, str)
|
||||
{
|
||||
|
|
BIN
gen/test_fib.c
BIN
gen/test_fib.c
Binary file not shown.
|
@ -96,6 +96,14 @@ extern char **environ;
|
|||
|
||||
#define MAX_SAFE_INTEGER (((int64_t) 1 << 53) - 1)
|
||||
|
||||
#ifndef QJS_NATIVE_MODULE_SUFFIX
|
||||
#ifdef _WIN32
|
||||
#define QJS_NATIVE_MODULE_SUFFIX ".dll"
|
||||
#else
|
||||
#define QJS_NATIVE_MODULE_SUFFIX ".so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* TODO:
|
||||
- add socket calls
|
||||
*/
|
||||
|
@ -483,7 +491,53 @@ typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx,
|
|||
const char *module_name);
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__wasi__)
|
||||
#if defined(_WIN32)
|
||||
static JSModuleDef *js_module_loader_so(JSContext *ctx,
|
||||
const char *module_name)
|
||||
{
|
||||
JSModuleDef *m;
|
||||
HINSTANCE hd;
|
||||
JSInitModuleFunc *init;
|
||||
char *filename = NULL;
|
||||
size_t len = strlen(module_name);
|
||||
JS_BOOL is_absolute = len > 2 && ((module_name[0] >= 'A' && module_name[0] <= 'Z') ||
|
||||
(module_name[0] >= 'a' && module_name[0] <= 'z')) && module_name[1] == ':';
|
||||
JS_BOOL is_relative = len > 2 && module_name[0] == '.' && (module_name[1] == '/' || module_name[1] == '\\');
|
||||
if (is_absolute || is_relative) {
|
||||
filename = (char *)module_name;
|
||||
} else {
|
||||
filename = js_malloc(ctx, len + 2 + 1);
|
||||
if (!filename)
|
||||
return NULL;
|
||||
strcpy(filename, "./");
|
||||
strcpy(filename + 2, module_name);
|
||||
}
|
||||
hd = LoadLibraryA(filename);
|
||||
if (filename != module_name)
|
||||
js_free(ctx, filename);
|
||||
if (hd == NULL) {
|
||||
JS_ThrowReferenceError(ctx, "js_load_module '%s' error: %lu",
|
||||
module_name, GetLastError());
|
||||
goto fail;
|
||||
}
|
||||
init = (JSInitModuleFunc *)(uintptr_t)GetProcAddress(hd, "js_init_module");
|
||||
if (!init) {
|
||||
JS_ThrowReferenceError(ctx, "js_init_module '%s' not found: %lu",
|
||||
module_name, GetLastError());
|
||||
goto fail;
|
||||
}
|
||||
m = init(ctx, module_name);
|
||||
if (!m) {
|
||||
JS_ThrowReferenceError(ctx, "js_call_module '%s' initialization error",
|
||||
module_name);
|
||||
fail:
|
||||
if (hd != NULL)
|
||||
FreeLibrary(hd);
|
||||
return NULL;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
#elif defined(__wasi__)
|
||||
static JSModuleDef *js_module_loader_so(JSContext *ctx,
|
||||
const char *module_name)
|
||||
{
|
||||
|
@ -599,7 +653,7 @@ JSModuleDef *js_module_loader(JSContext *ctx,
|
|||
{
|
||||
JSModuleDef *m;
|
||||
|
||||
if (has_suffix(module_name, ".so")) {
|
||||
if (has_suffix(module_name, QJS_NATIVE_MODULE_SUFFIX)) {
|
||||
m = js_module_loader_so(ctx, module_name);
|
||||
} else {
|
||||
size_t buf_len;
|
||||
|
|
Loading…
Reference in a new issue