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

Qt Creator中CUDA项目编译报错LNK2001: 未解析外部符号threadIdx

Qt Creator CUDA项目链接错误:LNK2001 未解析外部符号threadIdx

我在Qt Creator中创建了CUDA项目,使用MSVC 2022 PE-x64工具链,CUDA版本为12.5。Visual Studio中的CUDA示例代码可正常编译,但当前项目编译时出现错误:error: LNK2001: unresolved external symbol threadIdx。尝试调整CMake中注释的配置项均未解决问题,项目现有配置及代码如下:

原CMake配置

cmake_minimum_required(VERSION 3.28)
#set(CMAKE_CUDA_COMPILER "nvcc")
project(OpenGLCuda VERSION 0.1 LANGUAGES CUDA CXX)
# set(CUDA_64_BIT_DEVICE_CODE_DEFAULT ON)


set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)




find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
        #kernel.cu
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(OpenGLCuda
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
        #kernel.cu
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET OpenGLCuda APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(OpenGLCuda SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(OpenGLCuda
            ${PROJECT_SOURCES}
            kernel.cu
        )
    endif()
endif()

target_link_libraries(OpenGLCuda PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)


# if(NOT DEFINED CMAKE_CUDA_STANDARD)
#     message(STATUS "NOT DEFINED CMAKE_CUDA_STANDARD")
#     set(CMAKE_CUDA_STANDARD 11)
#     set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# endif()
# set_target_properties(OpenGLCuda PROPERTIES
#                             CUDA_SEPARABLE_COMPILATION ON)

find_package(CUDAToolkit REQUIRED)
message(STATUS "Found CUDA ${CUDA_VERSION_STRING} at ${CUDA_TOOLKIT_ROOT_DIR}")
target_link_libraries(OpenGLCuda PRIVATE CUDA::cudart CUDA::cudart_static)


# set(CMAKE_CUDA_COMPILER "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v12.5\\bin\\nvcc.exe")

#set(CUDA_LINK_LIBRARIES_KEYWORD PUBLIC)


# if(_cuda_build_shared_libs)
#   # If we are setting up code for a shared library, then we need to add extra flags for
#   # compiling objects for shared libraries.
#   set(CUDA_HOST_SHARED_FLAGS ${CMAKE_SHARED_LIBRARY_${CUDA_C_OR_CXX}_FLAGS})
# else()
#   set(CUDA_HOST_SHARED_FLAGS)
# endif()

# Locate sources and headers for this project
# find_package(CUDA QUIET)
# include_directories(${CUDA_INCLUDE_DIRS})
# SET(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
# SET(LIBS ${LIBS} ${ALL_CUDA_LIBS})



# Compile Info
set_target_properties(OpenGLCuda PROPERTIES CUDA_ARCHITECTURES all)
target_compile_features(OpenGLCuda PUBLIC cxx_std_11)
target_compile_features(OpenGLCuda PUBLIC cuda_std_11)
set_target_properties(OpenGLCuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_source_files_properties(kernel.cu PROPERTIES LANGUAGE CUDA)


# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.OpenGLCuda)
endif()
set_target_properties(OpenGLCuda PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS OpenGLCuda
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(OpenGLCuda)
endif()

原kernel.cu代码

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
int f1()
{
    printf("C++ version: %ld\n", __cplusplus);
    return  0;
}

cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);

__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    c[i] = a[i] + b[i];
}

修复方案

问题核心

错误LNK2001: unresolved external symbol threadIdx是因为CUDA设备代码(__global__函数)未被nvcc正确编译,导致链接时找不到设备端符号。具体问题出在CMake配置的两处:

  1. Qt6分支未包含kernel.cu,该文件仅在Qt5非Android分支被添加,Qt6环境下完全没参与编译
  2. CUDA_ARCHITECTURES all指定过于宽泛,在新版本CUDA中可能引发编译兼容性问题

修改后的CMake配置

cmake_minimum_required(VERSION 3.28)
project(OpenGLCuda VERSION 0.1 LANGUAGES CUDA CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

# 统一包含所有源文件,避免分支差异
set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
        kernel.cu
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(OpenGLCuda
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
else()
    if(ANDROID)
        add_library(OpenGLCuda SHARED
            ${PROJECT_SOURCES}
        )
    else()
        add_executable(OpenGLCuda
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(OpenGLCuda PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

find_package(CUDAToolkit REQUIRED)
message(STATUS "Found CUDA ${CUDA_VERSION_STRING} at ${CUDA_TOOLKIT_ROOT_DIR}")
target_link_libraries(OpenGLCuda PRIVATE CUDA::cudart)

# 指定适配的CUDA架构,替换为你的GPU架构(比如75=RTX20系,86=RTX30系,89=RTX40系)
set_target_properties(OpenGLCuda PROPERTIES CUDA_ARCHITECTURES 75;86;89)
set_target_properties(OpenGLCuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

set_target_properties(OpenGLCuda PROPERTIES
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

if(QT_VERSION VERSION_LESS 6.1.0)
  set_target_properties(OpenGLCuda PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER com.example.OpenGLCuda)
endif()

include(GNUInstallDirs)
install(TARGETS OpenGLCuda
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(OpenGLCuda)
endif()

额外提示

  • 若后续需要调用addWithCuda函数,需补充实现该函数(目前仅声明未定义,可能引发新的链接错误)
  • 确保Qt Creator的工具链配置正确指向MSVC 2022 x64,且CUDA环境变量已正确配置

内容的提问来源于stack exchange,提问作者M M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:32:03