使用CMake.js结合Google Test测试Node.js Addon的链接错误求助
问题描述
在Mac OS系统上,我尝试用Google Test测试通过CMake.js构建的Node.js Addon。Addon目标可正常构建运行,但Google Test测试目标出现V8方法未定义的链接错误。打印CMAKE_JS_SRC和CMAKE_JS_LIB变量发现二者均为空,不清楚如何通过target_link_libraries()为测试可执行文件添加Node/V8库;若将add_executable()换成add_library(),测试目标可构建但无法运行。
附上我的CMakeLists.txt代码:
cmake_minimum_required(VERSION 3.14) include_directories(my_project) set(CMAKE_CXX_STANDARD 14) set(CMAKE_C_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive") set(CMAKE_CXX_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive") project (addon) include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.12.1 ) FetchContent_MakeAvailable(googletest) include_directories(${CMAKE_JS_INC} "my_project/include/pkcs11/v2.40/") file(GLOB SOURCE_FILES "my_project/*.c" "my_project/*.h" "my_project/*.cpp") add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ) ## google_test enable_testing() file(GLOB TEST_FILES "test/*.cc" "test/utils/*.c") add_executable( my_project_google_test ${TEST_FILES} ) target_include_directories(my_project_google_test PRIVATE test/utils/*.h ) target_link_libraries( my_project_google_test PRIVATE GTest::gtest_main ${CMAKE_JS_LIB} ) include(GoogleTest) gtest_discover_tests(my_project_google_test)
解决方案
1. 核心问题说明
CMake.js仅会为.node类型的共享库目标自动注入CMAKE_JS_INC、CMAKE_JS_SRC、CMAKE_JS_LIB等变量,直接将这些变量用于测试可执行文件时会为空,导致无法链接V8/Node.js相关库。
2. 手动配置Node.js/V8依赖
在Mac上,可通过Node.js自带的配置信息获取编译和链接所需参数,修改CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.14) include_directories(my_project) set(CMAKE_CXX_STANDARD 14) set(CMAKE_C_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive") set(CMAKE_CXX_FLAGS "-Wno-pointer-sign -fno-signed-char -std=c99 -fpermissive") project (addon) include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.12.1 ) FetchContent_MakeAvailable(googletest) include_directories(${CMAKE_JS_INC} "my_project/include/pkcs11/v2.40/") file(GLOB SOURCE_FILES "my_project/*.c" "my_project/*.h" "my_project/*.cpp") add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ) ## google_test enable_testing() file(GLOB TEST_FILES "test/*.cc" "test/utils/*.c") # 获取Node.js头文件路径 execute_process( COMMAND node -p "require('node-addon-api').include" OUTPUT_VARIABLE NODE_ADDON_API_INCLUDE OUTPUT_STRIP_TRAILING_WHITESPACE ) # 获取Node.js链接库参数 execute_process( COMMAND node -p "process.config.target_defaults.libraries" OUTPUT_VARIABLE NODE_LIBRARIES OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND node -p "process.config.variables.node_shared_lib_dir" OUTPUT_VARIABLE NODE_LIB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) add_executable( my_project_google_test ${TEST_FILES} ) target_include_directories(my_project_google_test PRIVATE ${NODE_ADDON_API_INCLUDE} ${CMAKE_JS_INC} test/utils "my_project/include/pkcs11/v2.40/" ) target_link_directories(my_project_google_test PRIVATE ${NODE_LIB_DIR} ) target_link_libraries( my_project_google_test PRIVATE GTest::gtest_main ${NODE_LIBRARIES} node # 链接Mac上的Node.js共享库libnode.dylib ) include(GoogleTest) gtest_discover_tests(my_project_google_test)
3. 运行测试注意事项
Mac上运行测试时,需要指定Node.js库的加载路径,执行命令:
DYLD_LIBRARY_PATH=$(node -p "process.config.variables.node_shared_lib_dir") ./my_project_google_test
4. 替代方案(推荐)
如果测试代码不需要直接调用V8 API,建议只测试Addon中的纯C/C++业务逻辑,避免链接Node.js/V8库的麻烦;若需测试Addon的Node.js绑定逻辑,改用Jest等Node.js侧测试框架直接调用Addon接口更稳妥。
内容的提问来源于stack exchange,提问作者user2960174
相关产品推荐
相关产品推荐

