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配置的两处:
- Qt6分支未包含
kernel.cu,该文件仅在Qt5非Android分支被添加,Qt6环境下完全没参与编译 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
相关产品推荐
相关产品推荐

