Skip to content

Commit af3ee03

Browse files
authored
Merge pull request #31 from REVrobotics/refactor/use-cmake-js
Convert to use cmake-js and pkg-prebuilds
2 parents a146f4d + 6cbbd0d commit af3ee03

11 files changed

+947
-2115
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ prebuilds/
55
dist/
66
externalCompileTimeDeps/
77
temp/
8+
cmake-build-*/

CMakeLists.txt

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
cmake_policy(SET CMP0091 NEW)
3+
cmake_policy(SET CMP0042 NEW)
4+
5+
set (CMAKE_CXX_STANDARD 20)
6+
7+
project(node_canbridge)
8+
9+
if(NOT CMAKE_JS_INC)
10+
include("cmake-js.cmake")
11+
setup_cmakejs()
12+
endif ()
13+
14+
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/node_modules)
15+
message(FATAL_ERROR "You must run 'npm install' in order for NAPI to be available")
16+
endif()
17+
18+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
19+
20+
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
21+
# Generate node.lib
22+
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
23+
endif()
24+
25+
# Set some things up for cross-compiling on Linux using clang
26+
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
27+
if(SYSTEM STREQUAL "LinuxX64")
28+
add_compile_options("-target" "x86_64-pc-linux-gnu")
29+
elseif(SYSTEM STREQUAL "LinuxArm64")
30+
add_compile_options("-target" "aarch64-pc-linux-gnu")
31+
add_link_options("-target" "aarch64-pc-linux-gnu" "-fuse-ld=/usr/bin/aarch64-linux-gnu-ld")
32+
endif()
33+
endif()
34+
35+
add_definitions(-DNAPI_VERSION=9) # Keep in sync with binding-options.cjs, package.json binary.napi_version, and package.json prepublishOnly
36+
add_definitions(-DNAPI_DISABLE_CPP_EXCEPTIONS)
37+
38+
set(SOURCES
39+
src/addon.cc
40+
src/canWrapper.cc
41+
)
42+
43+
# Include the node-addon-api wrapper for Node-API
44+
# TODO: Figure out if this todo applies. I honestly copied it from an older project
45+
# TODO: Figure out why the build breaks without this, given that the CMake.js README
46+
# says that it will "add [node-addon-api] to the include search path automatically"
47+
# https://github.com/cmake-js/cmake-js/tree/6a2a50ba3d2e82a0ea80a8bb77cd2d3a03fb838c#node-api-and-node-addon-api
48+
execute_process(COMMAND node -p "require('node-addon-api').include"
49+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
50+
OUTPUT_VARIABLE NODE_ADDON_API_DIR
51+
)
52+
53+
string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
54+
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
55+
56+
include_directories(${NODE_ADDON_API_DIR} ${CMAKE_JS_INC} ${CMAKE_CURRENT_SOURCE_DIR}/src
57+
${CMAKE_CURRENT_SOURCE_DIR}/externalCompileTimeDeps/include)
58+
59+
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${CMAKE_JS_SRC})
60+
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
61+
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} CANBridge wpiHal wpiutil)
62+
63+
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/externalCompileTimeDeps)
64+
65+
# The ones that don't exist are just skipped
66+
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64)
67+
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64)
68+
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32)
69+
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal)
70+
71+
include(move-files.cmake)
72+
73+
foreach(CONFIG_TYPE IN LISTS CMAKE_CONFIGURATION_TYPES)
74+
# Windows
75+
create_move_target(CANBridge.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/CANBridge.dll ${CONFIG_TYPE}/CANBridge.dll)
76+
create_move_target(wpiHal.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/wpiHal.dll ${CONFIG_TYPE}/wpiHal.dll)
77+
create_move_target(wpiUtil.dll ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-win32-x64/wpiUtil.dll ${CONFIG_TYPE}/wpiUtil.dll)
78+
79+
# Linux x64
80+
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
81+
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
82+
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-x64/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)
83+
84+
# Linux Arm 32
85+
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
86+
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
87+
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm32/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)
88+
89+
# Linux Arm 64
90+
create_move_target(CANBridge.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/CANBridge.so ${CONFIG_TYPE}/CANBridge.so)
91+
create_move_target(wpiHal.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/wpiHal.so ${CONFIG_TYPE}/wpiHal.so)
92+
create_move_target(wpiUtil.so ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-linux-arm64/wpiUtil.so ${CONFIG_TYPE}/wpiUtil.so)
93+
94+
# macOS
95+
create_move_target(CANBridge.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/CANBridge.dylib ${CONFIG_TYPE}/CANBridge.dylib)
96+
create_move_target(wpiHal.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/wpiHal.dylib ${CONFIG_TYPE}/wpiHal.dylib)
97+
create_move_target(wpiUtil.dylib ${CMAKE_CURRENT_SOURCE_DIR}/prebuilds/node_canbridge-darwin-osxuniversal/wpiUtil.dylib ${CONFIG_TYPE}/wpiUtil.dylib)
98+
endforeach()

binding-options.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
name: 'node_canbridge',
3+
napi_versions: [9], // Keep in sync with CMakeLists.txt, package.json binary.napi_version, and package.json prepublishOnly
4+
}

binding.gyp

Lines changed: 0 additions & 44 deletions
This file was deleted.

cmake-js.cmake

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# This exists for pure-CMake builds, mainly useful for IDEs.
2+
function(setup_cmakejs)
3+
find_program(CMAKEJS "cmake-js")
4+
find_program(NPM "npm")
5+
# first, check if we have NPM:
6+
if(NPM)
7+
message(VERBOSE "NPM found.")
8+
else()
9+
message(FATAL_ERROR "NPM not found. This project requires Node.js")
10+
endif()
11+
12+
if(CMAKEJS)
13+
message(VERBOSE "CMake.js found.")
14+
else()
15+
message(ERROR "CMake.js not found, installing globally...")
16+
execute_process(COMMAND ${NPM_COMMAND} install -g cmake-js
17+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
18+
OUTPUT_VARIABLE NPM_OUTPUT)
19+
message(STATUS "CMake.js should now be installed.")
20+
message(VERBOSE ${NPM_OUTPUT})
21+
endif()
22+
23+
24+
if(WIN32)
25+
set(NPM_COMMAND ${NPM}.cmd)
26+
set(CMAKEJS_CMD ${CMAKEJS}.cmd)
27+
else()
28+
set(NPM_COMMAND ${NPM})
29+
set(CMAKEJS_CMD ${CMAKEJS})
30+
endif()
31+
32+
function(GET_VARIABLE INPUT_STRING VARIABLE_TO_SELECT OUTPUT_VARIABLE)
33+
set(SEARCH_STRING "${VARIABLE_TO_SELECT}=\"")
34+
string(LENGTH "${SEARCH_STRING}" SEARCH_STRING_LENGTH)
35+
string(LENGTH "${INPUT_STRING}" INPUT_STRING_LENGTH)
36+
37+
string(REPLACE "\\\\" "\\" INPUT_STRING "${INPUT_STRING}")
38+
39+
string(FIND "${INPUT_STRING}" "${VARIABLE_TO_SELECT}=\"" SEARCH_STRING_INDEX)
40+
41+
if(SEARCH_STRING_INDEX EQUAL -1)
42+
string(FIND "${INPUT_STRING}" "${VARIABLE_TO_SELECT}=" SEARCH_STRING_INDEX)
43+
44+
math(EXPR SEARCH_STRING_INDEX "${SEARCH_STRING_INDEX}+${SEARCH_STRING_LENGTH}-1")
45+
46+
string(SUBSTRING "${INPUT_STRING}" ${SEARCH_STRING_INDEX} ${INPUT_STRING_LENGTH} AFTER_SEARCH_STRING)
47+
string(FIND "${AFTER_SEARCH_STRING}" "'" QUOTE_INDEX)
48+
string(SUBSTRING "${AFTER_SEARCH_STRING}" "0" "${QUOTE_INDEX}" RESULT_STRING)
49+
set("${OUTPUT_VARIABLE}" "${RESULT_STRING}" PARENT_SCOPE)
50+
51+
else()
52+
math(EXPR SEARCH_STRING_INDEX "${SEARCH_STRING_INDEX}+${SEARCH_STRING_LENGTH}")
53+
54+
string(SUBSTRING "${INPUT_STRING}" ${SEARCH_STRING_INDEX} ${INPUT_STRING_LENGTH} AFTER_SEARCH_STRING)
55+
string(FIND "${AFTER_SEARCH_STRING}" "\"" QUOTE_INDEX)
56+
string(SUBSTRING "${AFTER_SEARCH_STRING}" "0" "${QUOTE_INDEX}" RESULT_STRING)
57+
set("${OUTPUT_VARIABLE}" "${RESULT_STRING}" PARENT_SCOPE)
58+
59+
endif()
60+
endfunction(GET_VARIABLE)
61+
62+
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
63+
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
64+
execute_process(COMMAND "${CMAKEJS_CMD}" print-configure --debug
65+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
66+
OUTPUT_VARIABLE CMAKE_JS_OUTPUT
67+
)
68+
else()
69+
execute_process(COMMAND "${CMAKEJS_CMD}" print-configure
70+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
71+
OUTPUT_VARIABLE CMAKE_JS_OUTPUT
72+
)
73+
endif ()
74+
75+
message(VERBOSE ${CMAKE_JS_OUTPUT})
76+
77+
get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_JS_INC" CMAKE_JS_INC)
78+
set(CMAKE_JS_INC "${CMAKE_JS_INC}" PARENT_SCOPE)
79+
80+
get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_JS_LIB" CMAKE_JS_LIB)
81+
set(CMAKE_JS_LIB "${CMAKE_JS_LIB}" PARENT_SCOPE)
82+
83+
get_variable("${CMAKE_JS_OUTPUT}" "CMAKE_LIBRARY_OUTPUT_DIRECTORY" CMAKE_LIBRARY_OUTPUT_DIRECTORY)
84+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" PARENT_SCOPE)
85+
86+
message(STATUS "[CMakeJS] Set up variables.")
87+
endfunction(setup_cmakejs)

lib/binding.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export enum ThreadPriority {
3636
// Needs to match HAL_CAN_IS_FRAME_REMOTE
3737
export const RTR_FRAME_BIT = 0x80000000;
3838

39+
let bindingOptions = require("../binding-options.cjs");
40+
3941
export class CanBridgeInitializationError extends Error {
4042
cause: any;
4143

@@ -71,7 +73,7 @@ export class CanBridge {
7173

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

7678
this.getDevices = promisify(addon.getDevices);
7779
this.registerDeviceToHAL = addon.registerDeviceToHAL;

move-files.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
function (create_move_target name src dest)
3+
if(EXISTS ${src})
4+
configure_file(${src} ${dest} COPYONLY)
5+
endif()
6+
endfunction()

0 commit comments

Comments
 (0)