Prebuild addon #16

Open
Sirherobrine23 wants to merge 1 commits from prebuilds into main
5 changed files with 58 additions and 18 deletions

@ -8,6 +8,17 @@ add_compile_definitions(NAPI_VERSION=8 NAPI_CPP_EXCEPTIONS)
set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(ARCH "${CMAKE_SYSTEM_PROCESSOR}")
set(OSS "${CMAKE_SYSTEM_NAME}")
string(TOLOWER ${OSS} OSS)
string(TOLOWER ${ARCH} ARCH)
if(${ARCH} STREQUAL "x86_64")
set(ARCH "x64")
elseif(${ARCH} STREQUAL "aarch64")
set(ARCH "arm64")
endif()
execute_process(COMMAND node -p "require('node-addon-api').include" execute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR OUTPUT_VARIABLE NODE_ADDON_API_DIR
@ -20,7 +31,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/genKey") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/genKey")
if(UNIX) if(UNIX)
add_definitions(-fpermissive -fexceptions -w -fpermissive -fPIC) add_definitions(-fpermissive -fexceptions -w -fpermissive)
endif() endif()
file(GLOB SOURCE_FILES file(GLOB SOURCE_FILES
@ -42,13 +53,21 @@ if(MSVC)
"ws2_32.lib" "ws2_32.lib"
"setupapi.lib" "setupapi.lib"
) )
set(OSS "win32")
elseif(UNIX AND NOT APPLE OR ANDROID) elseif(UNIX AND NOT APPLE OR ANDROID)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/linux") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/linux")
file(GLOB SOURCE_FILES ${SOURCE_FILES} file(GLOB SOURCE_FILES ${SOURCE_FILES}
"${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wireguard.c" "${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wireguard.c"
"${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wginterface.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wginterface.cpp"
) )
set(OSS "linux")
else() else()
if(ANDROID)
set(OSS "android")
elseif(APPLE)
set(OSS "darwin")
endif()
message(STATUS "Buiding go Userspace") message(STATUS "Buiding go Userspace")
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o)
file(REMOVE_RECURSE ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o) file(REMOVE_RECURSE ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o)
@ -81,7 +100,13 @@ else()
endif() endif()
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC}) add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") set_target_properties(${PROJECT_NAME}
PROPERTIES
PREFIX "" SUFFIX ".node"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/prebuild/${OSS}/${ARCH}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/prebuild/${OSS}/${ARCH}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/prebuild/${OSS}/${ARCH}"
)
target_link_libraries(${PROJECT_NAME} ${USERSPACEOBJ} ${CMAKE_JS_LIB}) target_link_libraries(${PROJECT_NAME} ${USERSPACEOBJ} ${CMAKE_JS_LIB})
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET) if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)

@ -33,7 +33,9 @@
"node": ">=16.0.0" "node": ">=16.0.0"
}, },
"binary": { "binary": {
"napi_versions": [8] "napi_versions": [
8
]
}, },
"scripts": { "scripts": {
"install": "cmake-js compile", "install": "cmake-js compile",
@ -43,12 +45,12 @@
"postpack": "tsc --build --clean" "postpack": "tsc --build --clean"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.10", "@types/node": "^22.9.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.5.3" "typescript": "^5.6.3"
}, },
"dependencies": { "dependencies": {
"cmake-js": "^7.3.0", "cmake-js": "^7.3.0",
"node-addon-api": "^8.0.0" "node-addon-api": "^8.2.2"
} }
} }

@ -1,5 +1,5 @@
import path from "node:path";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path";
const __dirname = import.meta.dirname || path.dirname((await import("node:url")).fileURLToPath(import.meta.url)); // Solve current __dirname in ESM module const __dirname = import.meta.dirname || path.dirname((await import("node:url")).fileURLToPath(import.meta.url)); // Solve current __dirname in ESM module
export const projectRoot = path.resolve(__dirname, ".."); export const projectRoot = path.resolve(__dirname, "..");
if (__dirname.includes(".asar")) { if (__dirname.includes(".asar")) {
@ -41,17 +41,18 @@ async function exists(filePath: string) {
return fs.access(path.resolve(filePath)).then(() => true, () => false); return fs.access(path.resolve(filePath)).then(() => true, () => false);
} }
export async function LoadAddon<T = any>(addonFile: string, exports?: Record<string, any>): Promise<T> { export async function LoadAddon<T = any>(addonFile: string, exports?: Record<string, any>): Promise<T> {
let _addonFile: string = null let _addonFile: string = null
if (await exists(addonFile)) _addonFile = addonFile; if (await exists(addonFile)) _addonFile = addonFile;
else if (await exists(path.resolve(projectRoot, addonFile))) _addonFile = path.resolve(projectRoot, addonFile) else if (await exists(path.resolve(projectRoot, addonFile))) _addonFile = path.resolve(projectRoot, addonFile)
else if (await exists(path.resolve(projectRoot, addonFile+".node"))) _addonFile = path.resolve(projectRoot, addonFile+".node") else if (await exists(path.resolve(projectRoot, addonFile + ".node"))) _addonFile = path.resolve(projectRoot, addonFile + ".node")
else if (await exists(path.resolve(projectRoot, "build/Release", addonFile))) _addonFile = path.resolve(projectRoot, "build/Release", addonFile) else if (await exists(path.resolve(projectRoot, "prebuild", process.platform, process.arch, addonFile + ".node"))) _addonFile = path.resolve(projectRoot, "prebuild", process.platform, process.arch, addonFile + ".node")
else if (await exists(path.resolve(projectRoot, "build/Release", addonFile+".node"))) _addonFile = path.resolve(projectRoot, "build/Release", addonFile+".node") else if (await exists(path.resolve(projectRoot, "build/Release", addonFile))) _addonFile = path.resolve(projectRoot, "build/Release", addonFile)
else if (await exists(path.resolve(projectRoot, "build/Debug", addonFile))) _addonFile = path.resolve(projectRoot, "build/Debug", addonFile) else if (await exists(path.resolve(projectRoot, "build/Release", addonFile + ".node"))) _addonFile = path.resolve(projectRoot, "build/Release", addonFile + ".node")
else if (await exists(path.resolve(projectRoot, "build/Debug", addonFile+".node"))) _addonFile = path.resolve(projectRoot, "build/Debug", addonFile+".node") else if (await exists(path.resolve(projectRoot, "build/Debug", addonFile))) _addonFile = path.resolve(projectRoot, "build/Debug", addonFile)
else if (await exists(path.resolve(projectRoot, "build/Debug", addonFile + ".node"))) _addonFile = path.resolve(projectRoot, "build/Debug", addonFile + ".node")
if (!_addonFile) throw new Error("Cannot load required addon") if (!_addonFile) throw new Error("Cannot load required addon")
let ext: NodeJS.Moduledlopen = {exports: Object.assign({}, exports)} let ext: NodeJS.Moduledlopen = { exports: Object.assign({}, exports) }
process.dlopen(ext, _addonFile) process.dlopen(ext, _addonFile)
return ext.exports return ext.exports
} }

@ -1,5 +1,6 @@
import path from "node:path"; import path from "node:path";
import { LoadAddon, projectRoot } from "./addons.js"; import { LoadAddon, projectRoot } from "./addons.js";
import { privateKey } from "./key.js";
export interface Peer { export interface Peer {
/** Preshared key to peer */ /** Preshared key to peer */
@ -92,8 +93,19 @@ export const addon = await LoadAddon<{
}); });
export const { export const {
constants: {driveVersion = "Unknown"}, constants: { driveVersion = "Unknown" },
getConfig, getConfig,
setConfig, setConfig,
deleteInterface deleteInterface
} = addon; } = addon;
/**
* Get current config if not exists create new interface with name
*
* @param name - Interface name
* @param config - Config to set in wireguard interface
*/
export async function updateInterface(name: string, config: SetConfig): Promise<void> {
const currentConfig = await getConfig(name).then(data => data, async (): Promise<GetConfig> => ({name: name, privateKey: await privateKey(), peers: {}}))
return setConfig({...currentConfig, ...config})
}

@ -19,7 +19,7 @@ await test("Wireguard interface", async t => {
presharedKey: await presharedKey(), presharedKey: await presharedKey(),
keepInterval: 25, keepInterval: 25,
allowedIPs: [ allowedIPs: [
format("10.66.66.%d/32", i+2) format("10.66.66.%d/32", i + 2)
], ],
} }
} }