OK, l'ho capito: questo è molto più doloroso di quanto dovrebbe essere. Fino a poco tempo fa, le persone di Kitware non capivano perché qualcuno avrebbe mai voluto creare una DLL dalle librerie statiche. La loro argomentazione è che dovrebbero sempre esserci file sorgente nella directory principale (ad esempio top_project
nel mio caso) perché è effettivamente un progetto a sé stante. Io vedo le cose in modo diverso & Ho bisogno di rompere top_project
in sottoprogetti più piccoli che non dovrebbero esistere indipendentemente (cioè non è necessario creare un progetto completo per loro & aggiungerli usando ExternalProject_Add
). Inoltre, quando spedisco la mia libreria condivisa (per esempio, ad esempio con una Java Native Interface), non voglio spedire dozzine di librerie condivise perché ciò equivarrebbe a esporre il layout interno del mio progetto. Ad ogni modo, avendo - penso - fatto un caso per creare una libreria condivisa da librerie statiche, procederò con i dettagli tecnici.
Nel CMakeLists.txt di subproject1
e subproject2
, è necessario creare il tuo target utilizzando la funzione di libreria di oggetti (introdotto nel CMake 2.8.8):
add_library(${PROJECT_NAME} OBJECT ${SRC})
dove SRC
indica l'elenco dei file di origine (nota che questi dovrebbero essere impostati esplicitamente nel file CMakeLists.txt poiché consente a make di rilanciare CMake quando viene rilevata una modifica di CMakeLists.txt, ad es.durante l'aggiunta o la rimozione di un file)
Nel top_project
, aggiungere i sottoprogetti utilizzando:
add_subdirectory(subproject1)
add_subdirectory(subproject2)
Per vedere i simboli dalla libreria statica, uso:
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
È quindi possibile creare la libreria condivisa utilizzando:
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
Ho trovato che qualsiasi "normale" libr ary (cioè non oggetto) deve essere aggiunto in un comando separato add_library
, altrimenti viene semplicemente ignorato.
per gli eseguibili, è possibile utilizzare:
add_executable(name_of_executable $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive")
target_link_libraries(name_of_executable ${PROJECT_NAME}
ripeto che questo funziona solo a partire dalla versione 2.8.8 di CMake. Inoltre, CMake gestisce le dipendenze estremamente bene. & è multipiattaforma perché non è molto meno doloroso dei semplici vecchi Makefile & sicuramente meno flessibili.
Sto usando cmake 3.4. + E aggiungo semplicemente librerie statiche alla libreria condivisa e sono compilate in un unico file :) L'ho provato su Android :) –
qualcuno avrebbe un suggerimento su come farlo in MSVC? Sto usando qmake e non cmake ma posso gestire i passaggi da solo, se riesco a capirli ... –