You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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语言支持即可修复:

  1. 移除find_package(CUDA REQUIRED)和cuda_add_library,CMake 3.8+已原生支持CUDA作为编译语言
  2. 修正CMAKE_BUILD_TYPE为标准首字母大写格式
  3. 用原生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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:27:23