CMake编译CUDA程序时如何静态链接cuFFT库?
如何在CMake中静态链接cuFFT库编译CUDA示例程序?
我需要编译NVIDIA CUDALibrarySamples中的1d_c2c示例,目标是通过静态版本的cuFFT库(-lcufft_static)完成编译链接。在Makefile中只需在编译命令添加-lcufft_static即可实现,但在CMake中尝试多种写法都遇到问题:
尝试过的方法及错误
直接引用静态库变量:
target_link_libraries(${ROUTINE}_example PRIVATE ${CUDA_cufft_static_LIBRARY})无效果,链接时仍使用动态库。
使用CMake CUDA目标:
根据建议改用:target_link_libraries(${ROUTINE}_example PRIVATE CUDA::cufft_static CUDA::cudart)出现链接错误:
/usr/bin/ld: /opt/cuda/lib64/libcufft_static.a(cbdouble_32bit_prime_callback_RT_SM35_plus.o): in function `__sti____cudaRegisterAll()': cbdouble_32bit_prime_callback_RT_SM35_plus.compute_86.cudafe1.cpp:(.text.startup+0x1d): undefined reference to `__cudaRegisterLinkedBinary_61_cbdouble_32bit_prime_callback_RT_SM35_plus_compute_86_cpp1_ii_dc5d5345'移除
find_package(CUDAToolkit REQUIRED):
CMake直接报错找不到目标:CMake Error at CMakeLists.txt:82 (target_link_libraries): Target "1d_c2c_example" links to: CUDA::cufft_static but the target was not found.
示例代码与当前CMake配置
1d_c2c_example.cpp
#include <complex> #include <iostream> #include <random> #include <vector> #include <cuda_runtime.h> #include <cufftXt.h> #include "cufft_utils.h" int main(int argc, char *argv[]) { cufftHandle plan; cudaStream_t stream = NULL; int n = 8; int batch_size = 2; int fft_size = batch_size * n; using scalar_type = float; using data_type = std::complex<scalar_type>; std::vector<data_type> data(fft_size); for (int i = 0; i < fft_size; i++) { data[i] = data_type(i, -i); } std::printf("Input array:\n"); for (auto &i : data) { std::printf("%f + %fj\n", i.real(), i.imag()); } std::printf("=====\n"); cufftComplex *d_data = nullptr; CUFFT_CALL(cufftCreate(&plan)); CUFFT_CALL(cufftPlan1d(&plan, data.size(), CUFFT_C2C, batch_size)); CUDA_RT_CALL(cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking)); CUFFT_CALL(cufftSetStream(plan, stream)); // Create device data arrays CUDA_RT_CALL(cudaMalloc(reinterpret_cast<void **>(&d_data), sizeof(data_type) * data.size())); CUDA_RT_CALL(cudaMemcpyAsync(d_data, data.data(), sizeof(data_type) * data.size(), cudaMemcpyHostToDevice, stream)); CUFFT_CALL(cufftExecC2C(plan, d_data, d_data, CUFFT_FORWARD)); CUFFT_CALL(cufftExecC2C(plan, d_data, d_data, CUFFT_INVERSE)); CUDA_RT_CALL(cudaMemcpyAsync(data.data(), d_data, sizeof(data_type) * data.size(), cudaMemcpyDeviceToHost, stream)); CUDA_RT_CALL(cudaStreamSynchronize(stream)); /* free resources */ CUDA_RT_CALL(cudaFree(d_data)) CUFFT_CALL(cufftDestroy(plan)); CUDA_RT_CALL(cudaStreamDestroy(stream)); CUDA_RT_CALL(cudaDeviceReset()); return EXIT_SUCCESS; }
当前CMakeLists.txt
cmake_minimum_required(VERSION 3.18) set(ROUTINE 1d_c2c) project( "${ROUTINE}_example" DESCRIPTION "GPU-Accelerated Fast Fourier Transforms" HOMEPAGE_URL "https://docs.nvidia.com/cuda/cufft/index.html" LANGUAGES CXX CUDA) set(CMAKE_CUDA_ARCHITECTURES 80) find_package(CUDAToolkit REQUIRED) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) if("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() set(CMAKE_CUDA_ARCHITECTURES 80) #if(CMAKE_CUDA_ARCHITECTURES LESS 60) #set(CMAKE_CUDA_ARCHITECTURES 60 70 75 80 86) #endif() set(BUILD_SHARED_LIBS OFF) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CUFFT_LIBRARIES ${CUDA_cufft_LIBRARY} ${CUDA_culibos_LIBRARY} ${CUDA_cudart_LIBRARY}) add_executable(${ROUTINE}_example) target_include_directories(${ROUTINE}_example PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/../utils) target_sources(${ROUTINE}_example PRIVATE ${PROJECT_SOURCE_DIR}/${ROUTINE}_example.cpp) set(CMAKE_CUDA_ARCHITECTURES 80) #target_link_libraries(${ROUTINE}_example PRIVATE ${CUDA_cufft_static_LIBRARY} CUDA::cufft CUDA::cudart) target_link_libraries(${ROUTINE}_example PRIVATE CUDA::cufft_static CUDA::cudart)
解决方案
静态链接cuFFT时,需要补充依赖库并调整链接配置,具体修改如下:
修改后的CMakeLists.txt关键部分
# 确保静态链接全局设置 set(BUILD_SHARED_LIBS OFF) # 替换原target_link_libraries为以下内容 target_link_libraries(${ROUTINE}_example PRIVATE CUDA::cufft_static CUDA::cudart_static CUDA::culibos )
关键说明
- 使用静态CUDA运行时库:
CUDA::cudart_static替代CUDA::cudart,确保运行时库也静态链接,避免动态依赖。 - 添加culibos依赖:静态cuFFT库依赖CUDA的
culibos库,提供基础设备函数支持,缺失会导致链接错误。 - 确保BUILD_SHARED_LIBS为OFF:全局禁用动态库构建,强制CMake优先选择静态库目标。
- 确认CUDA架构匹配:
CMAKE_CUDA_ARCHITECTURES设置需与你的GPU架构一致(示例中为80,对应Ampere架构),避免设备代码不兼容。
完成上述修改后,重新执行CMake配置与编译即可成功静态链接cuFFT库。
内容的提问来源于stack exchange,提问作者MANOS
相关产品推荐
相关产品推荐

