2016-08-29 50 views
2

我在Visual Studio 2013,Windows 10,CMake 3.5.1上。如何在cmake中添加cuda源代碼的定義

一切與標準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 fatal:輸出文件被指定時,非鏈接階段需要單個輸入文件」。請注意,如果將此語法應用於標準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))?

+0

您是否嘗試過用簡單的預處理器標誌變量將dll api宏定義包裝在單獨的頭文件中? Cuda編譯器可能會在命令行中與定義中的特殊字符發生衝突。 –

+0

@Torbjörn這是有效的,但這意味着我將有一個全局的頭文件,其中包含我所有的代碼。如果這是我們能做的最好的,如果你把它寫成答案我會接受它 – user3667089

回答

0

既然你已經在評論中請求了它,這裏是我/我們如何在我們的圖書館中做到這一點。

一般頭文件的基礎上定義的預處理器標誌的實際編譯visibility屬性(和一些內部默認的標誌:_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) 

如果在某處(靜態或共享)使用不定義任何。

注:通過CMake的add_definitions/target_add_definitions命令你不這樣做(其實不應該)需要明確指定編譯器標誌(/D/-D)。當這些命令的參數是CMake; -lists時,CMake會爲你做這件事。


的更一般的方法(包括跨平臺解決方案)應該是可能的,使用一些GitHub:Eyenseo/ABI宏(黑色)魔法。 (免責聲明:我還沒有測試過

相關問題