【问题标题】:CMake script for CUDA 6.0 with C++11带有 C++11 的 CUDA 6.0 的 CMake 脚本
【发布时间】:2014-08-16 06:58:45
【问题描述】:

我正在为我的 CUDA 6.0 + Boost 1.55.0 + OpenCV 2.4.9 项目开发 64 位 Mac OSX 10.9,使用 makefile 编译,但由于我最终将在 64 位 Windows 8.1 上对其进行测试,所以我以为我会熟悉 CMake。由于我使用的是 C++11,因此我使用 clang++(版本 5.1 (clang-503.0.40),g++ 现在在小牛中链接到)和 CUDA 代码分别使用 nvcc 生成目标文件,然后链接对象文件一起用于我的 makefile 中的最终可执行文件。

我不知道如何在 CMake 中执行此操作。我尝试将 CUDA 代码编译为静态库(同时使用 CMake 内置程序和 FindCUDA.cmake 实用程序),然后链接它,但这不起作用。我一直无法在网上找到考虑到 C++11 的解决方案。

到目前为止,这是我的 CMake 脚本:

cmake_minimum_required(VERSION 2.8)

project(pupil_tracker)

include_directories(include)
include_directories(include/cuda)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode arch=compute_20, code=sm_20)
#set(CUDA_HOST_COMPILER clang++) # Fails with 'invalid argument '-std=c++11' not allowed with 'C/ObjC''

find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}) # So CMake finds FindOpenCV.cmake
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

CUDA_ADD_LIBRARY(cuda_obj STATIC src/cuda/Tools.cu) # Doesn't seem to work

add_executable(main src/main.cpp src/CenteredHaarFeature.cpp src/PupilTracker.cpp src/Tools.cpp)

target_link_libraries(main ${Boost_LIBRARIES})
target_link_libraries(main ${CUDA_LIBRARIES})
target_link_libraries(main ${OpenCV_LIBS})
target_link_libraries(main ${cuda_obj})

install(TARGETS main DESTINATION ../bin)

如果一切都失败了,我将不得不尝试在我的 Windows 机器上设置一个 MSVC 项目来做同样的事情。

【问题讨论】:

    标签: macos c++11 cuda cmake


    【解决方案1】:

    CMAKE_CXX_FLAGS 可能会干扰 NVCC 编译,因此您必须小心放置它们的位置。

    我通过仅使用 CUDA 库的非常简单的示例重新创建了您的设置。在重新排列和编辑了一些 CMake 命令后,我能够编译和运行程序。

    CMakeLists.txt:

    cmake_minimum_required(VERSION 2.8)
    
    project(pupil_tracker)
    
    include_directories(include)
    include_directories(include/cuda)
    
    # removed a space and added C++11 functionality (note the double '--' for NVCC)
    set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode arch=compute_20,code=sm_20;--std=c++11)
    set(CUDA_HOST_COMPILER clang++) # shouldn't fail anymore
    
    # didn't test with Boost
    # find_package(Boost COMPONENTS system filesystem REQUIRED)
    # include_directories(${Boost_INCLUDE_DIR})
    
    find_package(CUDA REQUIRED)
    include_directories(${CUDA_INCLUDE_DIRS})
    
    # didn't test with OpenCV
    # set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}) # So CMake finds FindOpenCV.cmake
    # find_package(OpenCV REQUIRED)
    # include_directories(${OpenCV_INCLUDE_DIRS})
    
    CUDA_ADD_LIBRARY(cuda_obj STATIC src/cuda/Tools.cu) # works for me now
    
    # moved the CXX flags to after the cuda_add_library call
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
    add_executable(main src/main.cpp src/Tools.cpp) # only used one c++ class for this test
    
    # target_link_libraries(main ${Boost_LIBRARIES})
    target_link_libraries(main ${CUDA_LIBRARIES})
    # target_link_libraries(main ${OpenCV_LIBS})
    target_link_libraries(main cuda_obj) # changed ${cuda_obj} to cuda_obj
    
    install(TARGETS main DESTINATION ../bin)
    

    项目目录设置可以从 CMake 文件中推断出来,但为了澄清,它看起来像:

    项目目录:

    • CMakeLists.txt
    • 包括
      • 工具.hpp
      • cuda
        • Tools.cuh
    • 源代码
      • main.cpp
      • 工具.cpp
      • cuda
        • Tools.cu

    Tools.cuh:

    #ifndef TOOLS_CUH
    #define TOOLS_CUH
    
    extern "C"
    {
        void do_cuda_stuff();
    }
    
    #endif
    

    Tools.cu:

    #include <cuda_runtime.h>
    #include <stdio.h>
    
    extern "C"
    {
        __global__
        void do_cuda_stuff_kernel()
        {
            int idx = blockIdx.x * blockDim.x + threadIdx.x;
            printf("Hello from thread %d!\n", idx);
        }
    
        void do_cuda_stuff()
        {
            // 2 blocks, 3 threads each
            do_cuda_stuff_kernel<<<2, 3>>>();
            cudaDeviceSynchronize(); // to print results
        }
    }
    

    工具.hpp:

    #ifndef TOOLS_HPP
    #define TOOLS_HPP
    
    class Tools
    {
    public:
        int execute();
    };
    
    #endif
    

    工具.cpp:

    #include "Tools.hpp"
    #include "Tools.cuh"
    
    int Tools::execute()
    {
        do_cuda_stuff();
        return 0;
    }
    

    main.cpp:

    #include "Tools.hpp"
    
    int main(void)
    {
        Tools tools;
        return tools.execute();
    }
    

    输出:

    Hello from thread 3!
    Hello from thread 4!
    Hello from thread 5!
    Hello from thread 0!
    Hello from thread 1!
    Hello from thread 2!
    

    我目前使用的是 CUDA 7.5 和 OSX 10.10,但我认为最大的问题是 CMAKE_CXX_FLAGS 变量的位置。希望这可以帮助!干杯!

    【讨论】:

    • 已经有一段时间了,所以我可以很容易地确认您的回答,但感谢您的回复。我不知道 CMAKE_CXX_FLAGS 可能会干扰,所以这很可能是问题所在,所以我接受了你的回答。我有一个类似的项目布局,但即使我在编译之前有标志,我也让它工作,看起来像。我删除了 CUDA_ADD_LIBRARY,而是直接将源代码添加到 add_executable 函数中。我还添加了 set(CUDA_SEPARABLE_COMPILATION ON),IIRC 可以减轻 C/C++ 和 CUDA 的编译。
    • 是的,我认为您已经继续前进,但希望它可以帮助其他一些偶然发现这个问题的人。我最近才知道可分离编译选项,所以请检查一下,但我很高兴你能正常工作
    • 当然,无论如何我都感谢您的帮助。如果我再次使用 CUDA,这可能会变得有用 :)
    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2017-02-24
    相关资源
    最近更新 更多