CMake配置问题:含CUDA文件的C++项目在VS2022中编译失败
A single input file is required for a non-link phase when an outputfile is specified 错误根源
这个nvcc错误是因为编译选项被错误传递给CUDA编译器:原CMake中将MSVC的OpenMP选项/openmp:llvm全局应用到所有编译目标(包括CUDA源文件),但nvcc无法识别该选项,导致编译参数混乱;同时存在冗余的CUDA配置,进一步加剧了冲突。
修复后的CMake配置
cmake_minimum_required(VERSION 3.16) project(collisions LANGUAGES CXX CUDA) # 收集源文件(注:建议手动列出源文件替代GLOB,避免遗漏新增文件) file(GLOB PROJECT_SOURCES_CPP "src/*/*.cpp" "src/*/*/*.cpp") file(GLOB PROJECT_SOURCES_CU "src/*/*.cu") # 查找OpenMP(若项目依赖,建议添加REQUIRED确保找到) find_package(OpenMP) add_executable(${PROJECT_NAME} ${PROJECT_SOURCES_CPP} ${PROJECT_SOURCES_CU}) # 添加依赖 add_dependencies(${PROJECT_NAME} glfw glad glm) # 设置头文件路径 target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/) # 仅对C++源文件应用OpenMP编译选项 if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/openmp:llvm>) endif() # 配置CUDA相关属性 set_target_properties(${PROJECT_NAME} PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} ) # 链接依赖库 target_link_libraries(${PROJECT_NAME} PRIVATE glfw glad glm OpenMP::OpenMP_CXX )
关键修改点说明
移除冗余的CUDA配置
现代CMake(3.10+)通过project(xxx LANGUAGES CUDA)已自动启用CUDA语言支持,无需find_package(CUDA REQUIRED)和enable_language(CUDA),重复调用会引发配置冲突。分离C++与CUDA的编译选项
原代码中COMPILE_FLAGS会把OpenMP选项全局应用,导致nvcc收到不认识的/openmp:llvm。改用target_compile_options配合$<$<COMPILE_LANGUAGE:CXX>:...>条件,仅对C++源文件应用该选项,避免干扰CUDA编译。简化CUDA库链接
启用CUDA语言后,CMake会自动处理CUDA核心库的链接,无需手动添加${CUDA_LIBRARIES},避免重复链接或版本不匹配问题。明确CUDA主机编译器
添加CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}确保nvcc使用当前配置的MSVC编译器,避免主机编译器与CUDA工具链不兼容。优化OpenMP配置
使用OpenMP::OpenMP_CXX目标链接替代手动拼接CMAKE_CXX_FLAGS,这是现代CMake的标准做法,更可靠且能自动处理不同编译器的差异。
额外注意事项
- 尽量避免使用
file(GLOB)收集源文件:GLOB不会自动识别新增的源文件,建议手动列出所有.cpp和.cu文件,确保编译完整性。 - 验证CUDA与MSVC版本兼容性:确保使用的CUDA版本支持Visual Studio 2022(例如CUDA 11.6及以上版本)。
- 检查
.cu文件语法:确保CUDA源文件使用正确的函数修饰符(如__global__、__device__),符合nvcc编译规范。
内容的提问来源于stack exchange,提问作者Cortacesped

