2016-08-29 3 views
2

Ich bin auf Visual Studio 2013, Windows 10, CMake 3.5.1.Hinzufügen von Definitionen für Cuda-Quellcode in cmake

Alles kompiliert richtig mit Standard-C++, zum Beispiel:

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++; 
} 

jedoch einfach ändern die CMakeLists ing die exakt gleiche Code mit CUDA NVCC Ergebnisse in „identifier FOO und WINDOWS_DLL_API ist nicht definiert“ zu kompilieren:

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}) 

Nachdem er einige Zeit googeln zu verbringen, in der Nähe ich ändert sich die Syntax von add_definitions wie unten gezeigt, funktioniert für "FOO" aber nicht für "WINDOWS_DLL_API". Die Fehlermeldung lautet "nvcc fatal: Eine einzelne Eingabedatei wird für eine Nicht-Link-Phase benötigt, wenn eine Ausgabedatei angegeben wird". Beachten Sie, dass ein Fehler auftritt, wenn diese Syntax auf Standard-C++ angewendet wird.

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}) 

Ich überprüfte auch, dass die Definitionen in CMake alles ohne Angabe sogar mit CUDA NVCC kompiliert wie unten:

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++; 
} 

Wie kann ich ein Makro (speziell __declspec (dllexport)) für einen cuda-Quellcode mit CMake angeben?

+0

Haben Sie versucht, die DLL-API-Makro-Definition in eine separate Header-Datei mit einer einfachen Präprozessor-Flag-Variable zu umhüllen? Der Cuda-Compiler könnte mit den Sonderzeichen in der Definition in der Befehlszeile kämpfen. –

+0

@ Torbjörn Das funktioniert, aber das bedeutet, ich werde eine globale Header-Datei haben, wo alle meine Code enthalten müssen. Wenn das das Beste ist, was wir tun können, wenn Sie es als Antwort aufschreiben, werde ich es akzeptieren – user3667089

Antwort

0

Da Sie es in den Kommentaren angefordert haben, hier ist, wie ich/wir es in unseren Bibliotheken tun.

Eine allgemeine Header-Datei definiert die tatsächliche Attribut Compiler Sichtbarkeit auf einem Präprozessor-basiert (und einige interne Standardfahnen: _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 

Und es in der Art und Weise der Nutzung von

#include "eximport.h" 

class MYLIB_API MyLibClass 
{ 
    // 
}; 

In Ihrem CMake tun Sie nur

# 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) 

Wenn myLib wird irgendwo verwendet (entweder statisch oder geteilt), keine definieren.

Hinweis: Bei CMake der add_definitions/target_add_definitions Befehle, die Sie nicht (eigentlich nicht sollte) müssen explizit die Compiler-Flag angeben (/D/-D). CMake wird das für Sie tun, wenn die Argumente dieser Befehle CMake; -Listen sind.


einen allgemeineren Ansatz (einschließlich einer plattformübergreifende Lösung) sollte mit GitHub:Eyenseo/ABI mit einigen Makro (schwarz) Magie möglich sein. (Haftungsausschluss: Ich habe es noch nicht getestet.)

Verwandte Themen