Skip to content

Convert to use cmake-js and pkg-prebuilds #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ prebuilds/
dist/
externalCompileTimeDeps/
temp/
cmake-build-*/
98 changes: 98 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0042 NEW)

set (CMAKE_CXX_STANDARD 20)

project(node_canbridge)

if(NOT CMAKE_JS_INC)
include("cmake-js.cmake")
setup_cmakejs()
endif ()

if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/node_modules)
message(FATAL_ERROR "You must run 'npm install' in order for NAPI to be available")
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
# Generate node.lib
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
endif()

# Set some things up for cross-compiling on Linux using clang
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(SYSTEM STREQUAL "LinuxX64")
add_compile_options("-target" "x86_64-pc-linux-gnu")
elseif(SYSTEM STREQUAL "LinuxArm64")
add_compile_options("-target" "aarch64-pc-linux-gnu")
add_link_options("-target" "aarch64-pc-linux-gnu" "-fuse-ld=/usr/bin/aarch64-linux-gnu-ld")
endif()
endif()

add_definitions(-DNAPI_VERSION=9) # Keep in sync with binding-options.cjs, package.json binary.napi_version, and package.json prepublishOnly
add_definitions(-DNAPI_DISABLE_CPP_EXCEPTIONS)

set(SOURCES
src/addon.cc
src/canWrapper.cc
)

# Include the node-addon-api wrapper for Node-API
# TODO: Figure out if this todo applies. I honestly copied it from an older project
# TODO: Figure out why the build breaks without this, given that the CMake.js README
# says that it will "add [node-addon-api] to the include search path automatically"
# https://github.com/cmake-js/cmake-js/tree/6a2a50ba3d2e82a0ea80a8bb77cd2d3a03fb838c#node-api-and-node-addon-api
execute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)

string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})

include_directories(${NODE_ADDON_API_DIR} ${CMAKE_JS_INC} ${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/externalCompileTimeDeps/include)

add_library(${PROJECT_NAME} SHARED ${SOURCES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} CANBridge wpiHal wpiutil)

target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/externalCompileTimeDeps)

# The ones that don't exist are just skipped
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal)

include(move-files.cmake)

foreach(CONFIG_TYPE IN LISTS CMAKE_CONFIGURATION_TYPES)
# Windows
create_move_target(CANBridge.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/CANBridge.dll ${CONFIG_TYPE}/CANBridge.dll)
create_move_target(wpiHal.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/wpiHal.dll ${CONFIG_TYPE}/wpiHal.dll)
create_move_target(wpiUtil.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/wpiUtil.dll ${CONFIG_TYPE}/wpiUtil.dll)

# Linux x64
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)

# Linux Arm 32
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)

# Linux Arm 64
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)

# macOS
create_move_target(CANBridge.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/CANBridge.dylib ${CONFIG_TYPE}/CANBridge.dylib)
create_move_target(wpiHal.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/wpiHal.dylib ${CONFIG_TYPE}/wpiHal.dylib)
create_move_target(wpiUtil.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/wpiUtil.dylib ${CONFIG_TYPE}/wpiUtil.dylib)
endforeach()
4 changes: 4 additions & 0 deletions binding-options.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
name: 'node_canbridge',
napi_versions: [9], // Keep in sync with CMakeLists.txt, package.json binary.napi_version, and package.json prepublishOnly
}
44 changes: 0 additions & 44 deletions binding.gyp

This file was deleted.

87 changes: 87 additions & 0 deletions cmake-js.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# This exists for pure-CMake builds, mainly useful for IDEs.
function(setup_cmakejs)
find_program(CMAKEJS "cmake-js")
find_program(NPM "npm")
# first, check if we have NPM:
if(NPM)
message(VERBOSE "NPM found.")
else()
message(FATAL_ERROR "NPM not found. This project requires Node.js")
endif()

if(CMAKEJS)
message(VERBOSE "CMake.js found.")
else()
message(ERROR "CMake.js not found, installing globally...")
execute_process(COMMAND ${NPM_COMMAND} install -g cmake-js
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE NPM_OUTPUT)
message(STATUS "CMake.js should now be installed.")
message(VERBOSE ${NPM_OUTPUT})
endif()


if(WIN32)
set(NPM_COMMAND ${NPM}.cmd)
set(CMAKEJS_CMD ${CMAKEJS}.cmd)
else()
set(NPM_COMMAND ${NPM})
set(CMAKEJS_CMD ${CMAKEJS})
endif()

function(GET_VARIABLE INPUT_STRING VARIABLE_TO_SELECT OUTPUT_VARIABLE)
set(SEARCH_STRING "${VARIABLE_TO_SELECT}=\"")
string(LENGTH "${SEARCH_STRING}" SEARCH_STRING_LENGTH)
string(LENGTH "${INPUT_STRING}" INPUT_STRING_LENGTH)

string(REPLACE "\\\\" "\\" INPUT_STRING "${INPUT_STRING}")

string(FIND "${INPUT_STRING}" "${VARIABLE_TO_SELECT}=\"" SEARCH_STRING_INDEX)

if(SEARCH_STRING_INDEX EQUAL -1)
string(FIND "${INPUT_STRING}" "${VARIABLE_TO_SELECT}=" SEARCH_STRING_INDEX)

math(EXPR SEARCH_STRING_INDEX "${SEARCH_STRING_INDEX}+${SEARCH_STRING_LENGTH}-1")

string(SUBSTRING "${INPUT_STRING}" ${SEARCH_STRING_INDEX} ${INPUT_STRING_LENGTH} AFTER_SEARCH_STRING)
string(FIND "${AFTER_SEARCH_STRING}" "'" QUOTE_INDEX)
string(SUBSTRING "${AFTER_SEARCH_STRING}" "0" "${QUOTE_INDEX}" RESULT_STRING)
set("${OUTPUT_VARIABLE}" "${RESULT_STRING}" PARENT_SCOPE)

else()
math(EXPR SEARCH_STRING_INDEX "${SEARCH_STRING_INDEX}+${SEARCH_STRING_LENGTH}")

string(SUBSTRING "${INPUT_STRING}" ${SEARCH_STRING_INDEX} ${INPUT_STRING_LENGTH} AFTER_SEARCH_STRING)
string(FIND "${AFTER_SEARCH_STRING}" "\"" QUOTE_INDEX)
string(SUBSTRING "${AFTER_SEARCH_STRING}" "0" "${QUOTE_INDEX}" RESULT_STRING)
set("${OUTPUT_VARIABLE}" "${RESULT_STRING}" PARENT_SCOPE)

endif()
endfunction(GET_VARIABLE)

string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
execute_process(COMMAND "${CMAKEJS_CMD}" print-configure --debug
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE CMAKE_JS_OUTPUT
)
else()
execute_process(COMMAND "${CMAKEJS_CMD}" print-configure
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE CMAKE_JS_OUTPUT
)
endif ()

message(VERBOSE ${CMAKE_JS_OUTPUT})

get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_JS_INC" CMAKE_JS_INC)
set(CMAKE_JS_INC "${CMAKE_JS_INC}" PARENT_SCOPE)

get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_JS_LIB" CMAKE_JS_LIB)
set(CMAKE_JS_LIB "${CMAKE_JS_LIB}" PARENT_SCOPE)

get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_LIBRARY_OUTPUT_DIRECTORY" CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" PARENT_SCOPE)

message(STATUS "[CMakeJS] Set up variables.")
endfunction(setup_cmakejs)
4 changes: 3 additions & 1 deletion lib/binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export enum ThreadPriority {
// Needs to match HAL_CAN_IS_FRAME_REMOTE
export const RTR_FRAME_BIT = 0x80000000;

let bindingOptions = require("../binding-options.cjs");

export class CanBridgeInitializationError extends Error {
cause: any;

Expand Down Expand Up @@ -71,7 +73,7 @@ export class CanBridge {

constructor() {
try {
const addon = require('node-gyp-build')(path.join(__dirname, '..'));
const addon = require("pkg-prebuilds")(path.join(__dirname, '..'), bindingOptions);

this.getDevices = promisify(addon.getDevices);
this.registerDeviceToHAL = addon.registerDeviceToHAL;
Expand Down
6 changes: 6 additions & 0 deletions move-files.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

function (create_move_target name src dest)
if(EXISTS ${src})
configure_file(${src} ${dest} COPYONLY)
endif()
endfunction()
Loading