Skip to content

Instantly share code, notes, and snippets.

@gdianaty
Last active October 2, 2024 23:14
Show Gist options
  • Save gdianaty/33c3190a217cd188ea43cd4b06618ba9 to your computer and use it in GitHub Desktop.
Save gdianaty/33c3190a217cd188ea43cd4b06618ba9 to your computer and use it in GitHub Desktop.
CMake.js Inclusion Function for ordinary CMake

CMake.js Inclusion Function for ordinary CMake

I recently had an issue where my IDE (Visual Studio) had no support for CMake.js and this was my solution. This solution sets up all the CMake.js variables. By defining CMAKE_JS_INC and CMAKE_JS_LIB for use in your project. Just call setup_cmakejs() to define the variables. It is also compatible with Windows development environments. Linux and macOS are untested, but assumedly work just fine.

Happy coding!

Here's an example just in case you need it:

cmake_minimum_required(VERSION 3.2.2)

include("cmakejs.cmake")
setup_cmakejs()

project (my_project_name)
include_directories(${CMAKE_JS_INC})
file(GLOB SOURCE_FILES "main.cpp")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})

set_target_properties(${PROJECT_NAME} PROPERTIES 
		PREFIX 				""
		SUFFIX 				".node"
        	RUNTIME_OUTPUT_DIRECTORY 	${ARTIFACTS_DIRECTORY}
        	LINKER_LANGUAGE 		CXX
		)

target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
# Authored by Graham Dianaty for Bitlogix Technologies. Based on code from Rene Hollander. ==========//
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...")
exec_program(${NPM_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR} ARGS install -g cmake-js 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(FIND "${INPUT_STRING}" "${VARIABLE_TO_SELECT}=\"" SEARCH_STRING_INDEX)
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)
endfunction(GET_VARIABLE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
exec_program("${CMAKEJS_CMD}" ${CMAKE_CURRENT_SOURCE_DIR}
ARGS print-configure --debug
OUTPUT_VARIABLE CMAKE_JS_OUTPUT
)
else()
exec_program("${CMAKEJS_CMD}" ${CMAKE_CURRENT_SOURCE_DIR}
ARGS print-configure
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)
@gdianaty
Copy link
Author

If you define the CMake variable for NPM_COMMAND with the desired package manager's executable elsewhere in your project (i.e. prior to function being called) you should be able to get this functionality. As far as I know, the syntax used above should work with yarn and will
almost definitely work with pnpm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment