summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--cmake/NodeJS.cmake600
-rw-r--r--cmake/loop-uv.cmake14
-rw-r--r--cmake/mbgl.cmake31
-rw-r--r--cmake/node.cmake121
-rw-r--r--package.json2
-rw-r--r--platform/macos/config.cmake4
-rw-r--r--platform/node/index.js3
8 files changed, 122 insertions, 669 deletions
diff --git a/Makefile b/Makefile
index 576312cabf..e54fe6313b 100644
--- a/Makefile
+++ b/Makefile
@@ -111,8 +111,7 @@ run-benchmark-%: benchmark
$(MACOS_OUTPUT_PATH)/$(BUILDTYPE)/mbgl-benchmark --benchmark_filter=$* ${BENCHMARK_ARGS}
.PHONY: node-benchmark
-node-benchmark: $(MACOS_PROJ_PATH)
- set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'node-benchmark' build $(XCPRETTY)
+node-benchmark: node
.PHONY: run-node-benchmark
run-node-benchmark: node-benchmark
@@ -136,7 +135,11 @@ offline: $(MACOS_PROJ_PATH)
.PHONY: node
node: $(MACOS_PROJ_PATH)
- set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-node' build $(XCPRETTY)
+ set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-node (Active ABI)' build $(XCPRETTY)
+
+.PHONY: node-all
+node-all: $(MACOS_PROJ_PATH)
+ set -o pipefail && $(MACOS_XCODEBUILD) -scheme 'mbgl-node (All ABIs)' build $(XCPRETTY)
.PHONY: macos-test
macos-test: $(MACOS_PROJ_PATH)
@@ -362,7 +365,11 @@ run-glfw-app: glfw-app
.PHONY: node
node: $(LINUX_BUILD)
- $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(LINUX_OUTPUT_PATH) mbgl-node
+ $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(LINUX_OUTPUT_PATH) mbgl-node.active
+
+.PHONY: node-all
+node-all: $(LINUX_BUILD)
+ $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(LINUX_OUTPUT_PATH) mbgl-node.all
.PHONY: compdb
compdb: $(LINUX_BUILD)
@@ -706,6 +713,7 @@ codestyle:
.PHONY: clean
clean:
-rm -rf ./build \
+ ./lib/*.node \
./platform/android/gradle/configuration.gradle \
./platform/android/MapboxGLAndroidSDK/build \
./platform/android/MapboxGLAndroidSDK/.externalNativeBuild \
diff --git a/cmake/NodeJS.cmake b/cmake/NodeJS.cmake
deleted file mode 100644
index 8e0ec56982..0000000000
--- a/cmake/NodeJS.cmake
+++ /dev/null
@@ -1,600 +0,0 @@
-# NOTE: We're using a patched version of the original https://github.com/cjntaylor/node-cmake
-
-# Our version is in https://github.com/mapbox/node-cmake/blob/mapbox-gl-native/NodeJS.cmake and
-# contains these patches:
-# - https://github.com/cjntaylor/node-cmake/pull/20
-# - https://github.com/cjntaylor/node-cmake/pull/22
-# - https://github.com/cjntaylor/node-cmake/pull/23
-
-# Defaults for standard Node.js builds
-set(NODEJS_DEFAULT_URL https://nodejs.org/download/release)
-set(NODEJS_DEFAULT_VERSION installed)
-set(NODEJS_VERSION_FALLBACK latest)
-set(NODEJS_DEFAULT_NAME node)
-set(NODEJS_DEFAULT_CHECKSUM SHASUMS256.txt)
-set(NODEJS_DEFAULT_CHECKTYPE SHA256)
-
-include(CMakeParseArguments)
-
-# Find a path by walking upward from a base directory until the path is
-# found. Sets the variable ${PATH} to False if the path can't
-# be determined
-function(find_path_parent NAME BASE PATH)
- set(ROOT ${BASE})
- set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
- set(DRIVE "^[A-Za-z]?:?/$")
- while(NOT ROOT MATCHES ${DRIVE} AND NOT EXISTS ${ROOT}/${NAME})
- get_filename_component(ROOT ${ROOT} DIRECTORY)
- set(${PATH} ${ROOT}/${NAME} PARENT_SCOPE)
- endwhile()
- if(ROOT MATCHES ${DRIVE})
- set(${PATH} False PARENT_SCOPE)
- endif()
-endfunction()
-
-# Shortcut for finding standard node module locations
-macro(find_nodejs_module NAME BASE PATH)
- find_path_parent(node_modules/${NAME} ${BASE} ${PATH})
-endmacro()
-
-# Download with a bit of nice output (without spewing progress)
-function(download_file DESCRIPTION URL FILE)
- message(STATUS "Downloading: ${URL}")
- file(DOWNLOAD
- ${URL}
- ${FILE}.tmp
- ${ARGN}
- STATUS RESULT
- )
- list(GET RESULT 0 STATUS)
- if(STATUS)
- list(GET result 1 MESSAGE)
- message(FATAL_ERROR "Unable to download ${DESCRIPTION} from ${URL}: ${MESSAGE}")
- else()
- file(RENAME ${FILE}.tmp ${FILE})
- endif()
-endfunction()
-
-# Embedded win_delay_load_hook file so that this file can be copied
-# into projects directly (recommended practice)
-function(nodejs_generate_delayload_hook OUTPUT)
- file(WRITE ${OUTPUT} "")
- file(APPEND ${OUTPUT} "/*\n")
- file(APPEND ${OUTPUT} " * When this file is linked to a DLL, it sets up a delay-load hook that\n")
- file(APPEND ${OUTPUT} " * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'\n")
- file(APPEND ${OUTPUT} " * dynamically. Instead of trying to locate the .exe file it'll just return\n")
- file(APPEND ${OUTPUT} " * a handle to the process image.\n")
- file(APPEND ${OUTPUT} " *\n")
- file(APPEND ${OUTPUT} " * This allows compiled addons to work when node.exe or iojs.exe is renamed.\n")
- file(APPEND ${OUTPUT} " */\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "#ifdef _MSC_VER\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "#ifndef DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
- file(APPEND ${OUTPUT} "#define DELAYIMP_INSECURE_WRITABLE_HOOKS\n")
- file(APPEND ${OUTPUT} "#endif\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "#ifndef WIN32_LEAN_AND_MEAN\n")
- file(APPEND ${OUTPUT} "#define WIN32_LEAN_AND_MEAN\n")
- file(APPEND ${OUTPUT} "#endif\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "#include <windows.h>\n")
- file(APPEND ${OUTPUT} "#include <Shlwapi.h>\n")
- file(APPEND ${OUTPUT} "#include <delayimp.h>\n")
- file(APPEND ${OUTPUT} "#include <string.h>\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {\n")
- file(APPEND ${OUTPUT} " if (event != dliNotePreLoadLibrary) return NULL;\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " if (_stricmp(info->szDll, \"iojs.exe\") != 0 &&\n")
- file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.exe\") != 0 &&\n")
- file(APPEND ${OUTPUT} " _stricmp(info->szDll, \"node.dll\") != 0)\n")
- file(APPEND ${OUTPUT} " return NULL;\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // Get a handle to the current process executable.\n")
- file(APPEND ${OUTPUT} " HMODULE processModule = GetModuleHandle(NULL);\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // Get the path to the executable.\n")
- file(APPEND ${OUTPUT} " TCHAR processPath[_MAX_PATH];\n")
- file(APPEND ${OUTPUT} " GetModuleFileName(processModule, processPath, _MAX_PATH);\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // Get the name of the current executable.\n")
- file(APPEND ${OUTPUT} " LPSTR processName = PathFindFileName(processPath);\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // If the current process is node or iojs, then just return the proccess \n")
- file(APPEND ${OUTPUT} " // module.\n")
- file(APPEND ${OUTPUT} " if (_stricmp(processName, \"node.exe\") == 0 ||\n")
- file(APPEND ${OUTPUT} " _stricmp(processName, \"iojs.exe\") == 0) {\n")
- file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
- file(APPEND ${OUTPUT} " }\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // If it is another process, attempt to load 'node.dll' from the same \n")
- file(APPEND ${OUTPUT} " // directory.\n")
- file(APPEND ${OUTPUT} " PathRemoveFileSpec(processPath);\n")
- file(APPEND ${OUTPUT} " PathAppend(processPath, \"node.dll\");\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " HMODULE nodeDllModule = GetModuleHandle(processPath);\n")
- file(APPEND ${OUTPUT} " if(nodeDllModule != NULL) {\n")
- file(APPEND ${OUTPUT} " // This application has a node.dll in the same directory as the executable,\n")
- file(APPEND ${OUTPUT} " // use that.\n")
- file(APPEND ${OUTPUT} " return (FARPROC) nodeDllModule;\n")
- file(APPEND ${OUTPUT} " }\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} " // Fallback to the current executable, which must statically link to \n")
- file(APPEND ${OUTPUT} " // node.lib\n")
- file(APPEND ${OUTPUT} " return (FARPROC) processModule;\n")
- file(APPEND ${OUTPUT} "}\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "PfnDliHook __pfnDliNotifyHook2 = load_exe_hook;\n")
- file(APPEND ${OUTPUT} "\n")
- file(APPEND ${OUTPUT} "#endif\n")
-endfunction()
-
-# Sets up a project to build Node.js native modules
-# - Downloads required dependencies and unpacks them to the build directory.
-# Internet access is required the first invocation but not after (
-# provided the download is successful)
-# - Sets up several variables for building against the downloaded
-# dependencies
-# - Guarded to prevent multiple executions, so a single project hierarchy
-# will only call this once
-function(nodejs_init)
- # Prevents this function from executing more than once
- if(NODEJS_INIT)
- return()
- endif()
-
- # Regex patterns used by the init function for component extraction
- set(HEADERS_MATCH "^([A-Fa-f0-9]+)[ \t]+([^-]+)-(headers|v?[0-9.]+)-(headers|v?[0-9.]+)([.]tar[.]gz)$")
- set(LIB32_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-x86)?(/)?([^/]*)(.lib)$")
- set(LIB64_MATCH "(^[0-9A-Fa-f]+)[\t ]+(win-)?(x64/)(.*)(.lib)$")
-
- # Parse function arguments
- cmake_parse_arguments(nodejs_init
- "" "URL;NAME;VERSION;CHECKSUM;CHECKTYPE" "" ${ARGN}
- )
-
- # Allow the download URL to be overridden by command line argument
- # NODEJS_URL
- if(NODEJS_URL)
- set(URL ${NODEJS_URL})
- else()
- # Use the argument if specified, falling back to the default
- set(URL ${NODEJS_DEFAULT_URL})
- if(nodejs_init_URL)
- set(URL ${nodejs_init_URL})
- endif()
- endif()
-
- # Allow name to be overridden by command line argument NODEJS_NAME
- if(NODEJS_NAME)
- set(NAME ${NODEJS_NAME})
- else()
- # Use the argument if specified, falling back to the default
- set(NAME ${NODEJS_DEFAULT_NAME})
- if(nodejs_init_NAME)
- set(NAME ${nodejs_init_NAME})
- endif()
- endif()
-
- # Allow the checksum file to be overridden by command line argument
- # NODEJS_CHECKSUM
- if(NODEJS_CHECKSUM)
- set(CHECKSUM ${NODEJS_CHECKSUM})
- else()
- # Use the argument if specified, falling back to the default
- set(CHECKSUM ${NODEJS_DEFAULT_CHECKSUM})
- if(nodejs_init_CHECKSUM)
- set(CHECKSUM ${nodejs_init_CHECKSUM})
- endif()
- endif()
-
- # Allow the checksum type to be overriden by the command line argument
- # NODEJS_CHECKTYPE
- if(NODEJS_CHECKTYPE)
- set(CHECKTYPE ${NODEJS_CHECKTYPE})
- else()
- # Use the argument if specified, falling back to the default
- set(CHECKTYPE ${NODEJS_DEFAULT_CHECKTYPE})
- if(nodejs_init_CHECKTYPE)
- set(CHECKTYPE ${nodejs_init_CHECKTYPE})
- endif()
- endif()
-
- # Allow the version to be overridden by the command line argument
- # NODEJS_VERSION
- if(NODEJS_VERSION)
- set(VERSION ${NODEJS_VERSION})
- else()
- # Use the argument if specified, falling back to the default
- set(VERSION ${NODEJS_DEFAULT_VERSION})
- if(nodejs_init_VERSION)
- set(VERSION ${nodejs_init_VERSION})
- endif()
- endif()
-
- # "installed" is a special version that tries to use the currently
- # installed version (determined by running node)
- set(NODEJS_INSTALLED False CACHE BOOL "Node.js install status" FORCE)
- if(VERSION STREQUAL "installed")
- if(NOT NAME STREQUAL ${NODEJS_DEFAULT_NAME})
- message(FATAL_ERROR
- "'Installed' version identifier can only be used with"
- "the core Node.js library"
- )
- endif()
- # Fall back to the "latest" version if node isn't installed
- set(VERSION ${NODEJS_VERSION_FALLBACK})
- find_program(NODEJS_BINARY NAMES nodejs node)
- if(NODEJS_BINARY)
- execute_process(
- COMMAND ${NODEJS_BINARY} --version
- RESULT_VARIABLE INSTALLED_VERSION_RESULT
- OUTPUT_VARIABLE INSTALLED_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- if(INSTALLED_VERSION_RESULT STREQUAL "0")
- set(NODEJS_INSTALLED True CACHE BOOL
- "Node.js install status" FORCE
- )
- set(VERSION ${INSTALLED_VERSION})
- endif()
- endif()
- endif()
-
- # Create a temporary download directory
- set(TEMP ${CMAKE_CURRENT_BINARY_DIR}/temp)
- file(MAKE_DIRECTORY ${TEMP})
-
- # Unless the target is special version "latest", the parameters
- # necessary to construct the root path are known
- if(NOT VERSION STREQUAL "latest")
- set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
- # Extract checksums from the existing checksum file
- set(CHECKSUM_TARGET ${ROOT}/CHECKSUM)
- endif()
-
- # If we're trying to determine the version or we haven't saved the
- # checksum file for this version, download it from the specified server
- if(VERSION STREQUAL "latest" OR
- (DEFINED ROOT AND NOT EXISTS ${ROOT}/CHECKSUM))
- if(DEFINED ROOT)
- # Clear away the old checksum in case the new one is different
- # and/or it fails to download
- file(REMOVE ${ROOT}/CHECKSUM)
- endif()
- file(REMOVE ${TEMP}/CHECKSUM)
- download_file(
- "checksum file"
- ${URL}/${VERSION}/${CHECKSUM}
- ${TEMP}/CHECKSUM
- INACTIVITY_TIMEOUT 10
- )
- # Extract checksums from the temporary file
- set(CHECKSUM_TARGET ${TEMP}/CHECKSUM)
- endif()
-
- # Extract the version, name, header archive and archive checksum
- # from the file. This first extract is what defines / specifies the
- # actual version number and name.
- file(STRINGS
- ${CHECKSUM_TARGET} HEADERS_CHECKSUM
- REGEX ${HEADERS_MATCH}
- LIMIT_COUNT 1
- )
- if(NOT HEADERS_CHECKSUM)
- file(REMOVE ${TEMP}/CHECKSUM)
- if(DEFINED ROOT)
- file(REMOVE ${ROOT}/CHECKSUM)
- endif()
- message(FATAL_ERROR "Unable to extract header archive checksum")
- endif()
- string(REGEX MATCH ${HEADERS_MATCH} HEADERS_CHECKSUM ${HEADERS_CHECKSUM})
- set(HEADERS_CHECKSUM ${CMAKE_MATCH_1})
- set(NAME ${CMAKE_MATCH_2})
- if(CMAKE_MATCH_3 STREQUAL "headers")
- set(VERSION ${CMAKE_MATCH_4})
- else()
- set(VERSION ${CMAKE_MATCH_3})
- endif()
- set(HEADERS_ARCHIVE
- ${CMAKE_MATCH_2}-${CMAKE_MATCH_3}-${CMAKE_MATCH_4}${CMAKE_MATCH_5}
- )
- # Make sure that the root directory exists, and that the checksum
- # file has been moved over from temp
- if(DEFINED ROOT)
- set(OLD_ROOT ${ROOT})
- endif()
- set(ROOT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${VERSION})
- if(DEFINED OLD_ROOT AND NOT ROOT STREQUAL "${OLD_ROOT}")
- file(REMOVE ${TEMP}/CHECKSUM)
- file(REMOVE ${ROOT}/CHECKSUM)
- message(FATAL_ERROR "Version/Name mismatch")
- endif()
- file(MAKE_DIRECTORY ${ROOT})
- if(EXISTS ${TEMP}/CHECKSUM)
- file(REMOVE ${ROOT}/CHECKSUM)
- file(RENAME ${TEMP}/CHECKSUM ${ROOT}/CHECKSUM)
- endif()
-
- # Now that its fully resolved, report the name and version of Node.js being
- # used
- message(STATUS "NodeJS: Using ${NAME}, version ${VERSION}")
-
- # Download the headers for the version being used
- # Theoretically, these could be found by searching the installed
- # system, but in practice, this can be error prone. They're provided
- # on the download servers, so just use the ones there.
- if(NOT EXISTS ${ROOT}/include)
- file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
- download_file(
- "Node.js headers"
- ${URL}/${VERSION}/${HEADERS_ARCHIVE}
- ${TEMP}/${HEADERS_ARCHIVE}
- INACTIVITY_TIMEOUT 10
- EXPECTED_HASH ${CHECKTYPE}=${HEADERS_CHECKSUM}
- )
- execute_process(
- COMMAND ${CMAKE_COMMAND} -E tar xfz ${TEMP}/${HEADERS_ARCHIVE}
- WORKING_DIRECTORY ${TEMP}
- )
-
- # This adapts the header extraction to support a number of different
- # header archive contents in addition to the one used by the
- # default Node.js library
- unset(NODEJS_HEADERS_PATH CACHE)
- find_path(NODEJS_HEADERS_PATH
- NAMES src include
- PATHS
- ${TEMP}/${NAME}-${VERSION}-headers
- ${TEMP}/${NAME}-${VERSION}
- ${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}-headers
- ${TEMP}/${NODEJS_DEFAULT_NAME}-${VERSION}
- ${TEMP}/${NODEJS_DEFAULT_NAME}
- ${TEMP}
- NO_DEFAULT_PATH
- )
- if(NOT NODEJS_HEADERS_PATH)
- message(FATAL_ERROR "Unable to find extracted headers folder")
- endif()
-
- # Move the headers into a standard location with a standard layout
- file(REMOVE ${TEMP}/${HEADERS_ARCHIVE})
- file(REMOVE_RECURSE ${ROOT}/include)
- if(EXISTS ${NODEJS_HEADERS_PATH}/include/node)
- file(RENAME ${NODEJS_HEADERS_PATH}/include/node ${ROOT}/include)
- elseif(EXISTS ${NODEJS_HEADERS_PATH}/src)
- file(MAKE_DIRECTORY ${ROOT}/include)
- if(NOT EXISTS ${NODEJS_HEADERS_PATH}/src)
- file(REMOVE_RECURSE ${ROOT}/include)
- message(FATAL_ERROR "Unable to find core headers")
- endif()
- file(COPY ${NODEJS_HEADERS_PATH}/src/
- DESTINATION ${ROOT}/include
- )
- if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/uv/include)
- file(REMOVE_RECURSE ${ROOT}/include)
- message(FATAL_ERROR "Unable to find libuv headers")
- endif()
- file(COPY ${NODEJS_HEADERS_PATH}/deps/uv/include/
- DESTINATION ${ROOT}/include
- )
- if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/v8/include)
- file(REMOVE_RECURSE ${ROOT}/include)
- message(FATAL_ERROR "Unable to find v8 headers")
- endif()
- file(COPY ${NODEJS_HEADERS_PATH}/deps/v8/include/
- DESTINATION ${ROOT}/include
- )
- if(NOT EXISTS ${NODEJS_HEADERS_PATH}/deps/zlib)
- file(REMOVE_RECURSE ${ROOT}/include)
- message(FATAL_ERROR "Unable to find zlib headers")
- endif()
- file(COPY ${NODEJS_HEADERS_PATH}/deps/zlib/
- DESTINATION ${ROOT}/include
- )
- endif()
- file(REMOVE_RECURSE ${NODEJS_HEADERS_PATH})
- unset(NODEJS_HEADERS_PATH CACHE)
- endif()
-
- # Only download the libraries on windows, since its the only place
- # its necessary. Note, this requires rerunning CMake if moving
- # a module from one platform to another (should happen automatically
- # with most generators)
- if(WIN32)
- # Download the win32 library for linking
- file(STRINGS
- ${ROOT}/CHECKSUM LIB32_CHECKSUM
- LIMIT_COUNT 1
- REGEX ${LIB32_MATCH}
- )
- if(NOT LIB32_CHECKSUM)
- message(FATAL_ERROR "Unable to extract x86 library checksum")
- endif()
- string(REGEX MATCH ${LIB32_MATCH} LIB32_CHECKSUM ${LIB32_CHECKSUM})
- set(LIB32_CHECKSUM ${CMAKE_MATCH_1})
- set(LIB32_PATH win-x86)
- set(LIB32_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
- set(LIB32_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB32_NAME})
- if(NOT EXISTS ${ROOT}/${LIB32_PATH})
- file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
- download_file(
- "Node.js windows library (32-bit)"
- ${URL}/${VERSION}/${LIB32_TARGET}
- ${TEMP}/${LIB32_PATH}/${LIB32_NAME}
- INACTIVITY_TIMEOUT 10
- EXPECTED_HASH ${CHECKTYPE}=${LIB32_CHECKSUM}
- )
- file(REMOVE_RECURSE ${ROOT}/${LIB32_PATH})
- file(MAKE_DIRECTORY ${ROOT}/${LIB32_PATH})
- file(RENAME
- ${TEMP}/${LIB32_PATH}/${LIB32_NAME}
- ${ROOT}/${LIB32_PATH}/${LIB32_NAME}
- )
- file(REMOVE_RECURSE ${TEMP}/${LIB32_PATH})
- endif()
-
- # Download the win64 library for linking
- file(STRINGS
- ${ROOT}/CHECKSUM LIB64_CHECKSUM
- LIMIT_COUNT 1
- REGEX ${LIB64_MATCH}
- )
- if(NOT LIB64_CHECKSUM)
- message(FATAL_ERROR "Unable to extract x64 library checksum")
- endif()
- string(REGEX MATCH ${LIB64_MATCH} LIB64_CHECKSUM ${LIB64_CHECKSUM})
- set(LIB64_CHECKSUM ${CMAKE_MATCH_1})
- set(LIB64_PATH win-x64)
- set(LIB64_NAME ${CMAKE_MATCH_4}${CMAKE_MATCH_5})
- set(LIB64_TARGET ${CMAKE_MATCH_2}${CMAKE_MATCH_3}${LIB64_NAME})
- if(NOT EXISTS ${ROOT}/${LIB64_PATH})
- file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
- download_file(
- "Node.js windows library (64-bit)"
- ${URL}/${VERSION}/${LIB64_TARGET}
- ${TEMP}/${LIB64_PATH}/${LIB64_NAME}
- INACTIVITY_TIMEOUT 10
- EXPECTED_HASH ${CHECKTYPE}=${LIB64_CHECKSUM}
- )
- file(REMOVE_RECURSE ${ROOT}/${LIB64_PATH})
- file(MAKE_DIRECTORY ${ROOT}/${LIB64_PATH})
- file(RENAME
- ${TEMP}/${LIB64_PATH}/${LIB64_NAME}
- ${ROOT}/${LIB64_PATH}/${LIB64_NAME}
- )
- file(REMOVE_RECURSE ${TEMP}/${LIB64_PATH})
- endif()
- endif()
-
- # The downloaded headers should always be set for inclusion
- list(APPEND INCLUDE_DIRS ${ROOT}/include)
-
- # Look for the NAN module, and add it to the includes
- find_nodejs_module(
- nan
- ${CMAKE_CURRENT_SOURCE_DIR}
- NODEJS_NAN_DIR
- )
- if(NODEJS_NAN_DIR)
- list(APPEND INCLUDE_DIRS ${NODEJS_NAN_DIR})
- endif()
-
- # Under windows, we need a bunch of libraries (due to the way
- # dynamic linking works)
- if(WIN32)
- # Generate and use a delay load hook to allow the node binary
- # name to be changed while still loading native modules
- set(DELAY_LOAD_HOOK ${CMAKE_CURRENT_BINARY_DIR}/win_delay_load_hook.c)
- nodejs_generate_delayload_hook(${DELAY_LOAD_HOOK})
- set(SOURCES ${DELAY_LOAD_HOOK})
-
- # Necessary flags to get delayload working correctly
- list(APPEND LINK_FLAGS
- "-IGNORE:4199"
- "-DELAYLOAD:iojs.exe"
- "-DELAYLOAD:node.exe"
- "-DELAYLOAD:node.dll"
- )
-
- # Core system libraries used by node
- list(APPEND LIBRARIES
- kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
- odbc32.lib Shlwapi.lib DelayImp.lib
- )
-
- # Also link to the node stub itself (downloaded above)
- if(CMAKE_CL_64)
- list(APPEND LIBRARIES ${ROOT}/${LIB64_PATH}/${LIB64_NAME})
- else()
- list(APPEND LIBRARIES ${ROOT}/${LIB32_PATH}/${LIB32_NAME})
- endif()
- else()
- # Non-windows platforms should use these flags
- list(APPEND DEFINITIONS _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64)
- endif()
-
- # Special handling for OSX / clang to allow undefined symbols
- # Define is required by node on OSX
- if(APPLE)
- list(APPEND LINK_FLAGS "-undefined dynamic_lookup")
- list(APPEND DEFINITIONS _DARWIN_USE_64_BIT_INODE=1)
- endif()
-
- # Export all settings for use as arguments in the rest of the build
- set(NODEJS_VERSION ${VERSION} PARENT_SCOPE)
- set(NODEJS_SOURCES ${SOURCES} PARENT_SCOPE)
- set(NODEJS_INCLUDE_DIRS ${INCLUDE_DIRS} PARENT_SCOPE)
- set(NODEJS_LIBRARIES ${LIBRARIES} PARENT_SCOPE)
- set(NODEJS_LINK_FLAGS ${LINK_FLAGS} PARENT_SCOPE)
- set(NODEJS_DEFINITIONS ${DEFINITIONS} PARENT_SCOPE)
-
- # Prevents this function from executing more than once
- set(NODEJS_INIT TRUE PARENT_SCOPE)
-endfunction()
-
-# Helper function for defining a node module
-# After nodejs_init, all of the settings and dependencies necessary to do
-# this yourself are defined, but this helps make sure everything is configured
-# correctly. Feel free to use it as a model to do this by hand (or to
-# tweak this configuration if you need something custom).
-function(add_nodejs_module NAME)
- # Make sure node is initialized (variables set) before defining the module
- if(NOT NODEJS_INIT)
- message(FATAL_ERROR
- "Node.js has not been initialized. "
- "Call nodejs_init before adding any modules"
- )
- endif()
- # In order to match node-gyp, we need to build into type specific folders
- # ncmake takes care of this, but be sure to set CMAKE_BUILD_TYPE yourself
- # if invoking CMake directly
- if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
- message(FATAL_ERROR
- "Configuration type must be specified. "
- "Set CMAKE_BUILD_TYPE or use a different generator"
- )
- endif()
-
- # A node module is a shared library
- add_library(${NAME} SHARED ${NODEJS_SOURCES} ${ARGN})
- # Add compiler defines for the module
- # Two helpful ones:
- # MODULE_NAME must match the name of the build library, define that here
- target_compile_definitions(${NAME}
- PRIVATE MODULE_NAME=${NAME}
- PUBLIC ${NODEJS_DEFINITIONS}
- )
- # This properly defines includes for the module
- target_include_directories(${NAME} PUBLIC ${NODEJS_INCLUDE_DIRS})
-
- # Add link flags to the module
- target_link_libraries(${NAME} ${NODEJS_LIBRARIES})
-
- # Set required properties for the module to build properly
- # Correct naming, symbol visiblity and C++ standard
- set_target_properties(${NAME} PROPERTIES
- OUTPUT_NAME ${NAME}
- PREFIX ""
- SUFFIX ".node"
- MACOSX_RPATH ON
- C_VISIBILITY_PRESET hidden
- CXX_VISIBILITY_PRESET hidden
- POSITION_INDEPENDENT_CODE TRUE
- CMAKE_CXX_STANDARD_REQUIRED TRUE
- CXX_STANDARD 11
- LINK_FLAGS "${NODEJS_LINK_FLAGS}"
- )
-
- # Make sure we're buiilding in a build specific output directory
- # Only necessary on single-target generators (Make, Ninja)
- # Multi-target generators do this automatically
- # This (luckily) mirrors node-gyp conventions
- if(NOT CMAKE_CONFIGURATION_TYPES)
- set_property(TARGET ${NAME} PROPERTY
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BUILD_TYPE}
- )
- endif()
-endfunction()
diff --git a/cmake/loop-uv.cmake b/cmake/loop-uv.cmake
new file mode 100644
index 0000000000..e1d3166b63
--- /dev/null
+++ b/cmake/loop-uv.cmake
@@ -0,0 +1,14 @@
+add_library(mbgl-loop-uv INTERFACE)
+
+target_sources(mbgl-loop-uv INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/async_task.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/run_loop.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/timer.cpp
+)
+
+target_include_directories(mbgl-loop-uv INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+)
+
+create_source_groups(mbgl-loop-uv)
diff --git a/cmake/mbgl.cmake b/cmake/mbgl.cmake
index f087c32511..88e24e3536 100644
--- a/cmake/mbgl.cmake
+++ b/cmake/mbgl.cmake
@@ -17,12 +17,32 @@ if(WITH_NODEJS)
message(FATAL_ERROR "Could not find npm")
endif()
+ execute_process(
+ COMMAND "${NodeJS_EXECUTABLE}" -e "process.stdout.write(process.versions.node)"
+ RESULT_VARIABLE _STATUS_CODE
+ OUTPUT_VARIABLE NodeJS_VERSION
+ ERROR_VARIABLE _STATUS_MESSAGE
+ )
+ if(NOT _STATUS_CODE EQUAL 0)
+ message(FATAL_ERROR "Could not detect Node.js version: ${_STATUS_MESSAGE}")
+ endif()
+
+ execute_process(
+ COMMAND "${NodeJS_EXECUTABLE}" -e "process.stdout.write(process.versions.modules)"
+ RESULT_VARIABLE _STATUS_CODE
+ OUTPUT_VARIABLE NodeJS_ABI
+ ERROR_VARIABLE _STATUS_MESSAGE
+ )
+ if(NOT _STATUS_CODE EQUAL 0)
+ message(FATAL_ERROR "Could not detect Node.js ABI version: ${_STATUS_MESSAGE}")
+ endif()
+
function(_npm_install DIRECTORY NAME ADDITIONAL_DEPS)
SET(NPM_INSTALL_FAILED FALSE)
if("${DIRECTORY}/package.json" IS_NEWER_THAN "${DIRECTORY}/node_modules/.${NAME}.stamp")
message(STATUS "Running 'npm install' for ${NAME}...")
execute_process(
- COMMAND ${NodeJS_EXECUTABLE} ${npm_EXECUTABLE} install --ignore-scripts
+ COMMAND "${NodeJS_EXECUTABLE}" "${npm_EXECUTABLE}" install --ignore-scripts
WORKING_DIRECTORY "${DIRECTORY}"
RESULT_VARIABLE NPM_INSTALL_FAILED)
if(NOT NPM_INSTALL_FAILED)
@@ -32,7 +52,7 @@ if(WITH_NODEJS)
add_custom_command(
OUTPUT "${DIRECTORY}/node_modules/.${NAME}.stamp"
- COMMAND ${NodeJS_EXECUTABLE} ${npm_EXECUTABLE} install --ignore-scripts
+ COMMAND "${NodeJS_EXECUTABLE}" "${npm_EXECUTABLE}" install --ignore-scripts
COMMAND ${CMAKE_COMMAND} -E touch "${DIRECTORY}/node_modules/.${NAME}.stamp"
WORKING_DIRECTORY "${DIRECTORY}"
DEPENDS ${ADDITIONAL_DEPS} "${DIRECTORY}/package.json"
@@ -72,7 +92,12 @@ endif()
# Generate source groups so the files are properly sorted in IDEs like Xcode.
function(create_source_groups target)
- get_target_property(sources ${target} SOURCES)
+ get_target_property(type ${target} TYPE)
+ if(type AND type STREQUAL "INTERFACE_LIBRARY")
+ get_target_property(sources ${target} INTERFACE_SOURCES)
+ else()
+ get_target_property(sources ${target} SOURCES)
+ endif()
foreach(file ${sources})
get_filename_component(file "${file}" ABSOLUTE)
string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" group "${file}")
diff --git a/cmake/node.cmake b/cmake/node.cmake
index 90bec6575c..b6f7bb9dc0 100644
--- a/cmake/node.cmake
+++ b/cmake/node.cmake
@@ -1,87 +1,96 @@
# Load Node.js
-include(cmake/NodeJS.cmake)
-nodejs_init()
+include(node_modules/@mapbox/cmake-node-module/module.cmake)
-add_library(mbgl-loop-node STATIC
- platform/default/async_task.cpp
- platform/default/run_loop.cpp
- platform/default/timer.cpp
-)
+add_library(mbgl-loop-node INTERFACE)
-target_include_directories(mbgl-loop-node
- PRIVATE include
- PRIVATE src
+target_sources(mbgl-loop-node INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/async_task.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/run_loop.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default/timer.cpp
)
-target_include_directories(mbgl-loop-node PUBLIC ${NODEJS_INCLUDE_DIRS})
+target_include_directories(mbgl-loop-node INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+)
create_source_groups(mbgl-loop-node)
-xcode_create_scheme(TARGET mbgl-loop-node)
-add_nodejs_module(mbgl-node
- platform/node/src/node_mapbox_gl_native.cpp
+
+add_node_module(mbgl-node
+ INSTALL_DIR "lib"
+ NAN_VERSION "2.10.0"
+ EXCLUDE_NODE_ABIS 47 51 59 # Don't build old beta ABIs 5.x, 7.x, and 9.x
)
-# NodeJS.cmake forces C++11.
-# https://github.com/cjntaylor/node-cmake/issues/18
-set_target_properties("mbgl-node" PROPERTIES CXX_STANDARD 14)
-
-target_sources(mbgl-node
- PRIVATE platform/node/src/node_logging.hpp
- PRIVATE platform/node/src/node_logging.cpp
- PRIVATE platform/node/src/node_conversion.hpp
- PRIVATE platform/node/src/node_map.hpp
- PRIVATE platform/node/src/node_map.cpp
- PRIVATE platform/node/src/node_request.hpp
- PRIVATE platform/node/src/node_request.cpp
- PRIVATE platform/node/src/node_feature.hpp
- PRIVATE platform/node/src/node_feature.cpp
- PRIVATE platform/node/src/node_thread_pool.hpp
- PRIVATE platform/node/src/node_thread_pool.cpp
- PRIVATE platform/node/src/node_expression.hpp
- PRIVATE platform/node/src/node_expression.cpp
- PRIVATE platform/node/src/util/async_queue.hpp
+target_sources(mbgl-node INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_mapbox_gl_native.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_mapbox_gl_native.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_logging.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_logging.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_conversion.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_map.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_map.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_request.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_request.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_feature.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_feature.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_thread_pool.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_thread_pool.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_expression.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/node_expression.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/node/src/util/async_queue.hpp
)
-target_include_directories(mbgl-node
- PRIVATE platform/default
+target_include_directories(mbgl-node INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/platform/default
)
-target_link_libraries(mbgl-node
- PRIVATE mbgl-core
- PRIVATE mbgl-loop-node
+target_link_libraries(mbgl-node INTERFACE
+ mbgl-core
+ mbgl-loop-node
)
-target_add_mason_package(mbgl-node PRIVATE geojson)
+target_add_mason_package(mbgl-node INTERFACE geojson)
-add_custom_command(
- TARGET mbgl-node
- POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mbgl-node> ${CMAKE_SOURCE_DIR}/lib/mapbox_gl_native.node
-)
+add_custom_target(mbgl-node.active DEPENDS mbgl-node.abi-${NodeJS_ABI})
mbgl_platform_node()
create_source_groups(mbgl-node)
-initialize_xcode_cxx_build_settings(mbgl-node)
+foreach(ABI IN LISTS mbgl-node::abis)
+ initialize_xcode_cxx_build_settings(mbgl-node.abi-${ABI})
+ xcode_create_scheme(
+ TARGET mbgl-node.abi-${ABI}
+ NAME "mbgl-node (ABI ${ABI})"
+ )
+endforeach()
+
+xcode_create_scheme(
+ TARGET mbgl-node.active
+ TYPE library
+ NAME "mbgl-node (Active ABI)"
+)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.all
+ TYPE library
+ NAME "mbgl-node (All ABIs)"
)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.active
TYPE node
- NAME "node tests"
+ NAME "node tests (Active ABI)"
ARGS
"node_modules/.bin/tape platform/node/test/js/**/*.test.js"
)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.active
TYPE node
- NAME "node render tests"
+ NAME "node render tests (Active ABI)"
ARGS
"platform/node/test/render.test.js"
OPTIONAL_ARGS
@@ -90,9 +99,9 @@ xcode_create_scheme(
)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.active
TYPE node
- NAME "node query tests"
+ NAME "node query tests (Active ABI)"
ARGS
"platform/node/test/query.test.js"
OPTIONAL_ARGS
@@ -101,9 +110,9 @@ xcode_create_scheme(
)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.active
TYPE node
- NAME "node expression tests"
+ NAME "node expression tests (Active ABI)"
ARGS
"platform/node/test/expression.test.js"
OPTIONAL_ARGS
@@ -112,9 +121,9 @@ xcode_create_scheme(
)
xcode_create_scheme(
- TARGET mbgl-node
+ TARGET mbgl-node.active
TYPE node
- NAME "node-benchmark"
+ NAME "node-benchmark (Active ABI)"
ARGS
"platform/node/test/benchmark.js"
OPTIONAL_ARGS
diff --git a/package.json b/package.json
index c3f0d7b8ae..39f64a3967 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
},
"license": "BSD-2-Clause",
"dependencies": {
- "nan": "~2.10",
+ "@mapbox/cmake-node-module": "^1.0.0",
"node-pre-gyp": "^0.6.37",
"npm-run-all": "^4.0.2"
},
diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake
index 28573258d9..aa3f17eea1 100644
--- a/platform/macos/config.cmake
+++ b/platform/macos/config.cmake
@@ -154,7 +154,5 @@ macro(mbgl_platform_benchmark)
endmacro()
macro(mbgl_platform_node)
- target_link_libraries(mbgl-node
- PRIVATE "-Wl,-bind_at_load"
- )
+ # Define macro to enable this target on this platform
endmacro()
diff --git a/platform/node/index.js b/platform/node/index.js
index 5944a0a27d..6f6b33058a 100644
--- a/platform/node/index.js
+++ b/platform/node/index.js
@@ -2,9 +2,8 @@
// Shim to wrap req.respond while preserving callback-passing API
-var mbgl = require('../../lib/mapbox_gl_native.node');
+var mbgl = require('../../lib/mbgl-node.abi-' + process.versions.modules);
var constructor = mbgl.Map.prototype.constructor;
-var process = require('process');
var Map = function(options) {
if (!(options instanceof Object)) {