【问题标题】:C++ with CUDA project in CMake gives error: nvlink fatal : Could not open input file 'CMakeFiles/MY_APP.dir/src/MY_APP.cpp.o' (target: sm_35)CMake 中带有 CUDA 项目的 C++ 给出错误:nvlink 致命:无法打开输入文件'CMakeFiles/MY_APP.dir/src/MY_APP.cpp.o'(目标:sm_35)
【发布时间】:2024-04-28 15:20:02
【问题描述】:

您好,我正在处理一个 C++ 项目,并且有一个运行良好的 cmake 文件,直到我尝试将 cuda 添加到 C++ 项目中。我正在 NVIDIA Jetson Nano 上构建这个项目。

我在构建时收到此错误:

nvlink fatal : Could not open input file 'CMakeFiles/MY_APP.dir/src/MY_APP.cpp.o' (target: sm_35)

下面的其余错误如下所示:

CMakeFiles/MY_APP.dir/build.make:552: recipe for target 

'CMakeFiles/MY_APP.dir/cmake_device_link.o' failed
make[2]: *** [CMakeFiles/MY_APP.dir/cmake_device_link.o] Error 1
make[2]: Leaving directory '/home/me/Code/MyApp/build'
CMakeFiles/Makefile2:127: recipe for target 'CMakeFiles/MY_APP.dir/all' failed
make[1]: *** [CMakeFiles/MY_APP.dir/all] Error 2
make[1]: Leaving directory '/home/me/Code/MY_APP/build'
Makefile:155: recipe for target 'all' failed
make: *** [all] Error 2
make: Leaving directory '/home/me/Code/MY_APP/build'

我使用名为 confgure.sh 的脚本运行我的 cmake 文件,它看起来像这样:


#!/bin/sh

cmake -S . -B build -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 -DCMAKE_CUDA_COMPILER=/usr/local/cuda-10.2/bin/nvcc

我使用名为 build.sh 的脚本运行我的 make 文件,它看起来像这样:


#!/bin/sh

make -C build

我的 Cmake 文件如下所示:

cmake_minimum_required(VERSION 3.21.0)
project(MY_APP VERSION 0.0.0)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

enable_language(CUDA)

# Pass options to NVCC
set(
    CUDA_NVCC_FLAGS
    ${CUDA_NVCC_FLAGS};
    -O3 -gencode arch=compute_35,code=sm_35
    )

set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
FILE(GLOB_RECURSE MY_CUDA_SRCS src/*.cu)

configure_file(src/MyAppConfig.h.in MyAppConfig.h)

#collect cpp files
FILE(GLOB_RECURSE SRC src/*.cpp)

find_package(CUDA QUIET)
if(CUDA_FOUND)
    SET(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
    include_directories(${CUDA_INCLUDE_DIRS})
    get_filename_component(CUDA_LIBRARY_DIR ${CUDA_CUDART_LIBRARY} DIRECTORY)
    set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-L${CUDA_LIBRARY_DIR}")
    SET(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    #${CUDA_CUDART_LIBRARY}
    #${CMAKE_CUDA_RUNTIME_LIBRARY}
    #)
    SET(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    message(STATUS "CUDA_LIBRARIES: ${CUDA_INCLUDE_DIRS} ${ALL_CUDA_LIBS}")
    set(CUDA_PROPAGATE_HOST_FLAGS ON)
    set(CUDA_SEPARABLE_COMPILATION ON)
    list(APPEND CUDA_NVCC_FLAGS -gencode=arch=compute_35,code=sm_35)

    #collect CUDA files
    FILE(GLOB_RECURSE CUDA_SRC src/*.cu)

    #build static library
    #CUDA_ADD_LIBRARY(my_cuda_lib ${CUDA_SRC} STATIC)

    cuda_compile(cuda_objs ${CUDA_SRC})
    SET(SRC ${cuda_objs} ${SRC})

    SET(LIBS ${LIBS} ${my_cuda_lib})
endif()

link_libraries(${cuda_objs})

set_source_files_properties(${SRC} PROPERTIES LANGUAGE CUDA)

message("using cuda_add_executable")
cuda_add_executable(${PROJECT_NAME} ${SRC})

target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR})

target_link_libraries(${PROJECT_NAME} ${LIBS})

#DOWNLOAD ALL THE SUBMODULES
find_package(Git QUIET)
if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
# Update submodules as needed
    option(GIT_SUBMODULE, "Check submodules during build" ON)
    if (GIT_SUBMODULE)
        message(STATUS "Submodule update")
        execute_process(COMMAND ${GIT_EXECUTABLE}
                        submodule update --init --recursvie
                        WORKING_DIRECTORY {CMAKE_CURRENT_SOURCE_DIR}
                        RESULT_VARIABLE_GIT_SUBMOD_RESULT)
        if (NOT GIT_SUBMOD_RESULT EQUAL "0")
            message(FATAL_ERROR
                "git submodule update --init failed with ${GIT_SUMOD_RESULT},
                please check submodule")
        endif()
    endif()
endif()

#CHECK ALL THE SUBMODULES
if (NOT EXISTS
"${PROJECT_SOURCE_DIR}/external/Simple-Websocket-Server/CMakeLists.txt")
    message(FATAL_ERROR
            "The Simple-Websocket-Server submodule was not downloaded!
            GIT_SUBMODULE was turned off or failed. Please update submodule")
endif()

add_subdirectory(external/Simple-Websocket-Server)

include_directories(PUBLIC external/Simple-Websocket-Server)

find_package(PythonLibs REQUIRED)
find_package(pybind11 REQUIRED)

include_directories(${PYTHON_INCLUDE_DIRS})

target_link_libraries(${PROJECT_NAME}
    curl pthread crypto boost_system jsoncpp ${PYTHON_LIBRARIES} cudart 
    #<some-of-my-other-libraries>
)

install(TARGETS ${PROJECT_NAME} DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/MyAppConfig.h" DESTINATION include)

include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${MY_APP_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${MY_APP_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${MY_APP_VERSION_PATCH}")
include(CPack)

set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION 
    "${CMAKE_CUDA_COMPILER} ${_CMAKE_CUDA_EXTRA_FLAGS} -c ${MY_CUDA_SRCS}")

message(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION)

我不知道如何将 CUDA 添加到我已经包含一堆 C++ 文件的项目中,我需要能够从 main.cpp 以外的 .cpp 文件调用我的 .cu 文件,我需要在 CMake 中建造这座建筑,我在 jetson nano 上做这件事。有解决此错误的帮助吗?

【问题讨论】:

  • “我在构建时收到此错误:”您在此之后立即发布的内容(或我可以看到的此问题中的其他任何地方)不是错误。
  • 对不起,我的意思是,“我收到错误:nvlink fatal : Could not open input file 'CMakeFiles/MY_APP.dir/src/MY_APP.cpp.o' (target: sm_35) I将编辑问题
  • 我修正了问题中的错误。

标签: c++ cmake cuda linker-errors nvidia-jetson-nano


【解决方案1】:

您混淆了许多与 CUDA 相关的定义和命令,包括 CMake 中支持 CUDA 的早期“时代”中的一些。

除此之外:

  1. 您的 CMakeLists.txt 正在覆盖您的 CUDA 编译器位置的环境设置。
  2. ...实际上,您不必费心设置该位置,因为您已经设置了 CUDA 工具包根目录。
  3. 不要将find_package(CUDA) 与 3.17 或 3.18 或更高版本的 CMake 一起使用。对于所有与工具包相关的路径,请使用 find_package(CUDAToolkit)`,它确实...好,少但也多。
  4. 不要使用cuda_add_+suffix 命令。由于 CMake 原生支持 CUDA,因此您可以使用常规的 add_executableadd_library 等。

您的 CMakeLists.txt 文件还有其他问题 - 并非所有问题都与 CUDA 相关,但这应该足以让您入门。不过,它本身可能无法解决您遇到的特定底线问题。

您可能希望查看使用 CUDA 和最新 CMake 版本的公共存储库,以了解这是如何完成的。

【讨论】:

  • 我混淆的许多与 CMake 相关的概念是由于在一个又一个错误中遇到错误,并在互联网上寻找修复以尝试纠正每个错误,然后在收到先前的错误后得到不同的错误离开,然后冲洗并重复,导致 CMakeLists.txt 越来越混乱。
  • @user904542:嗯,您可能发现了一些不太理想的建议,此外,它们中的大多数都考虑到 CMake 的早期版本,不再相关/不建议使用。此外,如果您的 CUDA 安装是由 /usr/local/cuda 链接的,您甚至不需要费心处理包装脚本,您应该坚持通常的 CMake 调用。
  • 我让它编译,并使用你的提示运行。我摆脱了更改 nvcc 编译器的行,并添加了以下行: set_target_properties(${PROJECT_NAME} PROPERTIES CUDA_SEPARABLE_COMPILATION ON) (通过查看此示例):github.com/jclay/modern-cmake-cuda/blob/master/CMakeLists.txt。现在,我试图通过查看它是否可以与 2 个 .cu 文件一起使用来继续前进,但是我得到了未定义的外部符号,显然我必须为此使用 -dc 或可重定位设备代码进行编译。尝试查看如何在 cmake 中执行此操作,如果遇到困难,我可能需要发布一个新问题。
  • @user904542:嗯,这是一个非常初级的例子,但它非常有效......你并不总是需要可分离的编译,但有时你需要。您可以在 Kitware 的 CMake 文档中了解它,或者直接通过 DDG 来了解它。