2013-06-13 4 views
20

Ho sviluppato software multipiattaforma in C++. Come so, Linux .so ha esportato tutti i simboli di default, bene attraverso "gcc -fvisibility=hidden" Posso impostare tutti i simboli esportati come nascosti, quindi impostare __attribute__(visibility("default")) per la classe e la funzione che voglio esportare, così posso controllare ciò che voglio esportare.Qual è l'equivalente di CMake per "gcc -fvisibility = hidden" quando si controlla il simbolo esportato di una libreria condivisa?

La mia domanda è, usando CMake, come posso fare il lavoro come controllo "gcc -fvisibility = hidden"?

risposta

39

Invece di impostare flag di compilazione direttamente, dovresti utilizzare una versione CMake corrente e le proprietà <LANG>_VISIBILITY_PRESET. In questo modo puoi evitare specifiche del compilatore nelle tue CMakeLists e migliorare l'applicabilità multipiattaforma (evitando errori come supportare GCC e non Clang).

cioè se si utilizza C++ che si sia chiamata set(CMAKE_CXX_VISIBILITY_PRESET hidden) per impostare la proprietà a livello globale, o set_target_properties(MyTarget PROPERTIES CXX_VISIBILITY_PRESET hidden) per limitare l'impostazione a una libreria specifica o di destinazione eseguibile. Se stai usando C, sostituisci CXX con C nei comandi sopracitati. Si consiglia inoltre di esaminare la proprietà VISIBLITY_INLINES_HIDDEN.

La documentazione per GENERATE_EXPORT_HEADER include ulteriori suggerimenti ed esempi relativi a entrambe le proprietà.

+1

Non riesco a trovare alcun esempio corretto di questo. Potresti elaborare? La mia ipotesi sarebbe per C++ SET_TARGET_PROPERTIES (mytarget CXX_VISIBILITY_PRESET nascosto) – Abai

+0

@Abai ulteriori dettagli aggiunti – Joe

+0

Grazie @Joe, che funziona benissimo! – Abai

4

È possibile aggiungere un flag per il compilatore cmake così:

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") 

Per assicurarsi che questo solo fatto sotto Linux è possibile utilizzare questo codice:

IF(UNIX) 
    IF(CMAKE_COMPILER_IS_GNUCC) 
     SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") 
    ENDIF(CMAKE_COMPILER_IS_GNUCC) 
ENDIF(UNIX) 
+0

Infatti, -fvisibility = nascosto può essere utilizzato anche con clang quindi se si vuole essere in grado di utilizzare entrambi i compilatori con questa funzione è possibile usare qualcosa come: IF ("$ {} CMAKE_CXX_COMPILER_ID" STREQUAL "GNU" OR "$ {CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") ... ENDIF() – piponazo