如何在cmake中添加cuda源代码的定义 [英] How to add definitions for cuda source code in cmake
问题描述
我在Visual Studio 2013,Windows 10,CMake 3.5.1。
使用标准C ++正常编译,例如:
CMakeLists.txt
项目(测试)
add_definitions DWINDOWS_DLL_API = __ declspec(dllexport))
add_definitions(/ DFOO = 1)
设置(PROJECT_SRCS $ {PROJECT_SOURCE_DIR} /src/Test.cpp)
设定(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
#includeTest.h
/
Test :: Test(){
int a = 0;
if(FOO)a ++;但是,只需更改CMakeLists以使用CUDA NVCC结果编译完全相同的代码即可。 inidentifier FOO and WINDOWS_DLL_API is undefined:项目(测试)
add_definitions WINDOWS_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)
$ b b cuda_add_library($ {PROJECT_NAME} SHARED $ {PROJECT_SRCS} $ {PROJECT_INCS})
花费一些时间googling,最近我得到的是改变add_definitions的语法如下所示,适用于FOO,但不是WINDOWS_DLL_API。错误消息是nvcc fatal:当指定outputfile时,非链接阶段需要一个输入文件。注意,如果此语法应用于标准C ++,将会出现错误。
b add_definitions( - DWINDOWS_DLL_API = __ declspec(dllexport))
add_definitions( - DFOO = 1)
设置(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
#includeTest.h
#define FOO 1
Test :: Test(){
int a = 0;
if(FOO)a ++;
}
如何为cuda指定一个宏(特别是__declspec(dllexport)源代码使用CMake?
解决方案由于你在评论中请求它,这里是我/库。
通用头文件基于预处理器标志(以及一些内部默认标志:
_WINxx $ c)定义实际的编译器可见性属性$ c>):
// eximport.h
#pragma once
#if defined(_WIN32)||定义(_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
使用
#includeeximport.h
class MYLIB_API MyLibClass
{
//
};
在您的CMake中,您只需要
#如果myLib被构建为共享
target_add_definition(myLibTarget mylib_SHARED)
#或
$ b b#如果myLib被构建为静态
target_add_definition(myLibTarget mylib_STATIC)
如果
myLib
在某处使用(静态或共享)不定义任何
注意: code> add_definitions
target_add_definitions
命令你不需要(实际上不应该)需要显式指定编译器标志$ c> / D /-D
)。当这些命令的参数是CMake; -lists时,CMake会为你这样做。
一般方法(包括跨平台解决方案)应该可以使用一些宏(黑色)魔术使用 GitHub:Eyenseo / ABI 。 (免责声明:我尚未测试。)
I am on Visual Studio 2013, Windows 10, CMake 3.5.1.
Everything compiles properly with standard C++, for example:
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++; }
However, simply changing the CMakeLists to compile the exact same code with CUDA NVCC results in "identifier FOO and WINDOWS_DLL_API is undefined":
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})
After spending some time googling, the closest I get is changing the syntax of add_definitions as shown below which works for "FOO" but not for "WINDOWS_DLL_API". The error message is "nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified". Note that if this syntax is applied on standard C++ an error will occur.
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})
I also verified that without specifying the definitions in CMake everything compiles even with CUDA NVCC like below:
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++; }
How can I specify a macro (specifically __declspec(dllexport)) for a cuda source code using CMake?
解决方案Since you've requested it in the comments, here is how I/we do it in our libraries.
A general header file defines the actual compiler visibility attribute based on a preprocessor flag (and some internal default flags:
_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
And use it in the way of
#include "eximport.h" class MYLIB_API MyLibClass { // };
In your CMake you just do
# 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)
If
myLib
is used somewhere (either static or shared) don't define any.Note: With CMake's
add_definitions
/target_add_definitions
commands you don't (actually shouldn't) need to explicitly specify the compiler flag (/D
/-D
). CMake will do that for you when the arguments of those commands are CMake ;-lists.
A more general approach (including a cross-platform solution) should be possible with some macro (black) magic using GitHub:Eyenseo/ABI. (Disclaimer: I haven't tested it yet.)
这篇关于如何在cmake中添加cuda源代码的定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!