未定义对“cudaRegisterLinkedBinary”的引用 - CMake 中的链接错误?

Spa*_*102 2 c++ linux cuda cmake

我在配备 GT 650M GPU 的 64 位 2013 Mac 上通过双引导运行 CentOS 7.8。我正在使用 CMake 3.17、CUDA 10.0 和 GCC 4.8.5。所有 CUDA 示例都经过测试并且工作正常,并且我能够完美编译其他标准 C++ 代码。

我已将完整项目简化为一个简单的测试用例,如下所示,其中 CMakeLists 文件为:

CMAKE_MINIMUM_REQUIRED(VERSION 3.8)

PROJECT(test LANGUAGES CUDA CXX C)

SET(CMAKE_VERBOSE_MAKEFILE ON)

MESSAGE(STATUS "Setting to Release mode")
SET(CMAKE_BUILD_TYPE "Release")

# Set CUDA flags
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=sm_30 -rdc=true")

# Set flags
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -ffast-math")
MESSAGE(STATUS "Setting g++ flags for Release configuration")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")   ## Optimize
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ")  ## Strip binary

ADD_SUBDIRECTORY( src )
Run Code Online (Sandbox Code Playgroud)

在 /src 文件夹中,我有另一个 CMake 文件来收集源文件:

INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} )

SET(test_SRCS
   rsmain.cu
   SGP4.cu
   SGP4.cuh
)

 function(my_add_executable TargetName)
   set(Files ${ARGV})
   list(REMOVE_AT Files 0)
   add_executable(${TargetName} ${Files})
   set_target_properties(${TargetName} PROPERTIES
                             RUNTIME_OUTPUT_DIRECTORY
                                 "${CMAKE_SOURCE_DIR}/build")
 endfunction()

my_add_executable(test ${test_SRCS})
INSTALL( TARGETS test DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)

如图所示,有三个主要源文件 - SGP4.cu 和 SGP4.cuh 都是空的,而 rsmain.cu 只是:

/// Main function
int main(int argc, char *argv[])
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当尝试构建时,我得到以下输出:

[me@localhost build]$ cmake3 ..
-- The CUDA compiler identification is NVIDIA 10.0.130
-- The CXX compiler identification is GNU 4.8.5
-- The C compiler identification is GNU 4.8.5
-- Check for working CUDA compiler: /usr/local/cuda-10.0/bin/nvcc
-- Check for working CUDA compiler: /usr/local/cuda-10.0/bin/nvcc - works
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- No build configuration specified, defaulting to Release
-- Setting general compiler flags for detected compiler: gnu-g++
-- Setting g++ flags for Release configuration
-- Configuring done
-- Generating done
-- Build files have been written to: /home/me/Documents/test/build
[me@localhost build]$ make
/usr/bin/cmake3 -S/home/me/Documents/test -B/home/me/Documents/test/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake3 -E cmake_progress_start /home/me/Documents/test/build/CMakeFiles /home/me/Documents/test/build/CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/me/Documents/test/build'
make  -f src/CMakeFiles/test.dir/build.make src/CMakeFiles/test.dir/depend
make[2]: Entering directory `/home/me/Documents/test/build'
cd /home/me/Documents/test/build && /usr/bin/cmake3 -E cmake_depends "Unix Makefiles" /home/me/Documents/test /home/me/Documents/test/src /home/me/Documents/test/build /home/me/Documents/test/build/src /home/me/Documents/test/build/src/CMakeFiles/test.dir/DependInfo.cmake --color=
Scanning dependencies of target test
make[2]: Leaving directory `/home/me/Documents/test/build'
make  -f src/CMakeFiles/test.dir/build.make src/CMakeFiles/test.dir/build
make[2]: Entering directory `/home/me/Documents/test/build'
[ 33%] Building CUDA object src/CMakeFiles/test.dir/rsmain.cu.o
cd /home/me/Documents/test/build/src && /usr/local/cuda-10.0/bin/nvcc   -I/home/me/Documents/test/src -I/home/me/Documents/test/build/src -I/home/me/Documents/test/build  -arch=sm_30 -rdc=true -O3 -DNDEBUG   -std=c++03 -x cu -c /home/me/Documents/test/src/rsmain.cu -o CMakeFiles/test.dir/rsmain.cu.o
[ 66%] Building CUDA object src/CMakeFiles/test.dir/SGP4.cu.o
cd /home/me/Documents/test/build/src && /usr/local/cuda-10.0/bin/nvcc   -I/home/me/Documents/test/src -I/home/me/Documents/test/build/src -I/home/me/Documents/test/build  -arch=sm_30 -rdc=true -O3 -DNDEBUG   -std=c++03 -x cu -c /home/me/Documents/test/src/SGP4.cu -o CMakeFiles/test.dir/SGP4.cu.o
[100%] Linking CUDA executable ../test
cd /home/me/Documents/test/build/src && /usr/bin/cmake3 -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
/usr/bin/g++  -s  CMakeFiles/test.dir/rsmain.cu.o CMakeFiles/test.dir/SGP4.cu.o -o ../test  -lcudadevrt -lcudart_static  -L"/usr/local/cuda-10.0/targets/x86_64-linux/lib/stubs" -L"/usr/local/cuda-10.0/targets/x86_64-linux/lib" -lcudadevrt -lcudart_static -lrt -lpthread -ldl
CMakeFiles/test.dir/rsmain.cu.o: In function `__sti____cudaRegisterAll()':
tmpxft_00004eed_00000000-5_rsmain.cudafe1.cpp:(.text.startup+0x25): undefined reference to `__cudaRegisterLinkedBinary_41_tmpxft_00004eed_00000000_6_rsmain_cpp1_ii_main'
CMakeFiles/test.dir/SGP4.cu.o: In function `__sti____cudaRegisterAll()':
tmpxft_00004f02_00000000-5_SGP4.cudafe1.cpp:(.text.startup+0x15): undefined reference to `__cudaRegisterLinkedBinary_39_tmpxft_00004f02_00000000_6_SGP4_cpp1_ii_71922fcb'
collect2: error: ld returned 1 exit status
make[2]: *** [test] Error 1
make[2]: Leaving directory `/home/me/Documents/test/build'
make[1]: *** [src/CMakeFiles/test.dir/all] Error 2
make[1]: Leaving directory `/home/me/Documents/test/build'
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)

谁能解释一下这个“cudaRegisterLinkedBinary”的东西是什么?我尝试了很多方法来解决这个问题,但到目前为止没有任何效果。任何软件包版本是否有问题?CMakeLists 中出现问题?CUDA 和我的硬件存在兼容性问题吗?

值得注意的是,当我在 HPC 服务器(也运行 CentOS 7 和 Cuda 10.0)上测试时,完整的代码编译并运行得很好 - 但在我的个人 PC 上,它在链接步骤中失败了。我什至已经确认两个安装中的 .bashrc 文件是相同的,但它没有修复任何问题。我目前还可以毫无问题地编译 NVIDIA 的 OptiX 软件(也使用 CUDA)。

任何意见,将不胜感激。如果我遗漏了任何必需的详细信息,请告诉我。

编辑:答案添加如下。解决。

Spa*_*102 6

终于解决了这个问题。这是我的主要 CMakeLists 文件:

CMAKE_MINIMUM_REQUIRED(VERSION 3.8)

PROJECT(test LANGUAGES C CXX CUDA)
SET(CMAKE_BUILD_TYPE "Release")

# Set CUDA flags
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=sm_30 -rdc=true")

# Set flags
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -ffast-math -O3")
MESSAGE(STATUS "Setting g++ flags for Release configuration")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s")  ## Strip binary

ADD_SUBDIRECTORY( src )

Run Code Online (Sandbox Code Playgroud)

在 /src CMakeLists 文件中,我必须进行更改:

INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} )

SET(test_SRCS
   rsmain.cu
   SGP4.cu
   SGP4.cuh
)

 function(my_add_executable TargetName)
   set(Files ${ARGV})
   list(REMOVE_AT Files 0)
   add_executable(${TargetName} ${Files})
   set_target_properties(${TargetName} PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON
                             RUNTIME_OUTPUT_DIRECTORY
                                 "${CMAKE_SOURCE_DIR}/build")
 endfunction()

my_add_executable(test ${test_SRCS})
INSTALL( TARGETS test DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)

将 CUDA_RESOLVE_DEVICE_SYMBOLS 设置为 ON 就是更改。在我的主项目中,我还必须对涉及任何 CUDA 文件的每个目标重复此操作。现在一切都可以完美编译并运行。