如何在cmake中添加cuda源代码的定义

时间:2016-08-29 23:23:24

标签: c++ cuda cmake dllexport nvcc

我使用的是Visual Studio 2013,Windows 10,CMake 3.5.1。

所有内容都使用标准C ++正确编译,例如:

的CMakeLists.txt

project(Test)

add_definitions(/D "WINDOWS_DLL_API=__declspec(dllexport)")
add_definitions(/D "FOO=1")

set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/src/Test.cpp)    
set(PROJECT_INCS ${PROJECT_SOURCE_DIR}/include/Test.h)

include_directories(${PROJECT_SOURCE_DIR}/include)

add_library(${PROJECT_NAME} SHARED ${PROJECT_SRCS} ${PROJECT_INCS})

Test.h

class WINDOWS_DLL_API Test{
 public:
  Test();
};

Test.cpp的

#include "Test.h" 

Test::Test(){
  int a = 0;
  if (FOO) a++;
}

但是,只需更改CMakeLists以使用CUDA NVCC编译完全相同的代码就会导致"标识符FOO和WINDOWS_DLL_API未定义":

project(Test)

add_definitions(/D "WINDOWS_DLL_API=__declspec(dllexport)")
add_definitions(/D "FOO=1")

set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/src/Test.cu)    
set(PROJECT_INCS ${PROJECT_SOURCE_DIR}/include/Test.cuh)

include_directories(${PROJECT_SOURCE_DIR}/include)

find_package( CUDA REQUIRED )

cuda_add_library(${PROJECT_NAME} SHARED ${PROJECT_SRCS} ${PROJECT_INCS})

花了一些时间谷歌搜索后,我得到的最接近的是改变add_definitions的语法,如下所示,适用于" FOO"但不适用于" WINDOWS_DLL_API"。错误消息是" nvcc致命错误:当指定输出文件时,非链接阶段需要单个输入文件"。请注意,如果在标准C ++上应用此语法,则会发生错误。

project(Test)

add_definitions("-DWINDOWS_DLL_API=__declspec(dllexport)")
add_definitions("-DFOO=1")

set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/src/Test.cu)    
set(PROJECT_INCS ${PROJECT_SOURCE_DIR}/include/Test.cuh)

include_directories(${PROJECT_SOURCE_DIR}/include)

find_package( CUDA REQUIRED )

cuda_add_library(${PROJECT_NAME} SHARED ${PROJECT_SRCS} ${PROJECT_INCS})

我还验证了如果没有在CMake中指定定义,即使使用CUDA NVCC也会编译所有内容,如下所示:

Test.h

#define WINDOWS_DLL_API __declspec(dllexport)

class WINDOWS_DLL_API Test{
 public:
  Test();
};

Test.cpp的

#include "Test.h" 
#define FOO 1

Test::Test(){
  int a = 0;
  if (FOO) a++;
}

如何使用CMake为cuda源代码指定宏(特别是__declspec(dllexport))?

1 个答案:

答案 0 :(得分:0)

由于您已在评论中提出要求,因此我/我们在图书馆中执行此操作。

通用头文件根据预处理器标志(以及一些内部默认标志:_WINxx)定义实际的编译器可见性属性:

// eximport.h
#pragma once

#if defined(_WIN32) || defined(_WIN64)
#define DECL_EXPORT __declspec(dllexport)
#define DECL_IMPORT __declspec(dllimport)
#else
#define DECL_EXPORT
#define DECL_IMPORT
#endif

#if defined(mylib_SHARED) || defined(mylib_STATIC)
#ifdef mylib_SHARED
#define MYLIB_API DECL_EXPORT
#else
#define MYLIB_API
#endif
#else
#define MYLIB_API DECL_IMPORT
#endif

的方式使用它
#include "eximport.h"

class MYLIB_API MyLibClass
{
  //
};

在你的CMake中你只是做

# in case myLib is build as shared
target_add_definition(myLibTarget mylib_SHARED)

# or

# in case myLib is build as static
target_add_definition(myLibTarget mylib_STATIC)

如果在某处(静态或共享)使用myLib,请不要定义任何内容。

注意:使用CMake的add_definitions / target_add_definitions命令,您不必(实际上不应该)明确指定编译器标志({{ 1}} / /D)。当这些命令的参数为CMake时,CMake将为您执行此操作; -lists。

使用GitHub:Eyenseo/ABI的一些宏(黑色)魔法应该可以实现更通用的方法(包括跨平台解决方案)。 (免责声明:我还没有对它进行过测试。