CMake配置CUDA类设备构造函数分离编译链接失败求助
CUDA设备端类构造函数CMake编译链接错误解决
问题描述
使用CMake编译链接CUDA设备端类构造函数时触发未解析外部函数错误,仅在调用类内函数时出现该问题。手动用nvcc添加-dc和-dlink参数编译链接可正常运行。
错误输出
ptxas fatal : Unresolved extern function '_ZN4TestC1Ev' CMake Error at genetic_program_lib_generated_test.cu.o.debug.cmake:282 (message): Error generating file /article/src/build/CMakeFiles/genetic_program_lib.dir/src/./genetic_program_lib_generated_test.cu.o
原CMake配置
cmake_minimum_required(VERSION 3.22) project(GeneticProgramming) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/article/src/build") set(CMAKE_BUILD_TYPE debug) include_directories(include) # 添加CUDA源文件到变量 file(GLOB CUDA_SOURCES src/genetic_program.cu src/test.cu src/test2.cu) file(GLOB MAIN main/main.cpp) # 查找CUDA包 find_package(CUDA REQUIRED) cuda_add_library(genetic_program_lib ${CUDA_SOURCES}) set_target_properties(genetic_program_lib PROPERTIES CUDA_SEPARABLE_COMPILATION ON) # 创建可执行文件 add_executable(out ${MAIN}) target_link_libraries(out genetic_program_lib)
相关代码文件
主函数文件(main/main.cpp)
#include <genetic_program.hpp> int main() { genetic_program(); return 0; }
genetic_program.hpp
#pragma once #include <iostream> int genetic_program();
genetic_program.cu
#include <genetic_program.hpp> #include <test.cuh> int genetic_program() { test<<<1,1>>>(); return 0; }
test.cuh
#pragma once #include <iostream> #include <test2.cuh> __global__ void test();
test.cu
#include <test.cuh> __global__ void test(){ printf("Hello World!\n"); Test t; t.test2t(); }
test2.cuh
#pragma once #include <iostream> class Test { public: __device__ Test(); __device__ void test2t(); };
test2.cu
#include <test2.cuh> __device__ Test::Test() { printf("Test::Test()\n"); } __device__ void Test::test2t() { printf("Test::test2t()\n"); }
解决方案
问题源于旧版cuda_add_library命令对CUDA分离编译的支持不完善,改用CMake原生CUDA语言支持即可修复:
- 移除
find_package(CUDA REQUIRED)和cuda_add_library,CMake 3.8+已原生支持CUDA作为编译语言 - 修正
CMAKE_BUILD_TYPE为标准首字母大写格式 - 用原生
add_library创建库并启用分离编译属性
修改后的CMake配置:
cmake_minimum_required(VERSION 3.22) project(GeneticProgramming LANGUAGES CXX CUDA) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/article/src/build") set(CMAKE_BUILD_TYPE Debug) include_directories(include) # 显式添加源文件(推荐替换GLOB,避免遗漏风险) set(CUDA_SOURCES src/genetic_program.cu src/test.cu src/test2.cu ) set(MAIN main/main.cpp) # 创建CUDA静态库并启用分离编译 add_library(genetic_program_lib STATIC ${CUDA_SOURCES}) set_target_properties(genetic_program_lib PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_STANDARD 14 # 根据CUDA版本适配,可选 ) # 创建可执行文件并链接库 add_executable(out ${MAIN}) target_link_libraries(out PRIVATE genetic_program_lib)
关键说明
- 通过
project(...) LANGUAGES CXX CUDA明确告知CMake编译C++和CUDA代码,无需手动查找CUDA包 CUDA_SEPARABLE_COMPILATION ON会自动执行-dc编译可重定位设备代码、-dlink完成设备端链接的流程,和手动编译逻辑完全一致- 替换
file(GLOB)为显式列源文件,可避免GLOB在文件变更时的遗漏问题
内容的提问来源于stack exchange,提问作者Václav Hrbek
相关产品推荐
相关产品推荐

