Come controllare le dipendenze opzionali di una libreria di sola intestazione in 'CMake'?

1

Sto sviluppando la mia libreria di sola intestazione che voglio usare come framework in altri software. Sto utilizzando CMake per l'impostazione di target dimostrativi, test e così via.

Tuttavia, non sono sicuro di come gestire le dipendenze della mia biblioteca. Attualmente sto usando il seguente approccio:

FIND_PACKAGE( foo )

Ho un file config/foo.hh.in di configurazione per foo che controlla se il pacchetto esiste:

#ifndef FOO_HH__
#define FOO_HH__
  #cmakedefine HAVE_FOO
#endif

Nel CMakeLists.txt principale, lo faccio:

CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/include/config/foo.hh.in ${CMAKE_SOURCE_DIR}/include/config/foo.hh )

Nel codice, posso quindi fare:

#include "config/foo.hh"
#ifdef HAVE_FOO
  // Code that is specific to having the 'foo' library available
#endif

Il problema con questo approccio è che funziona solo una volta , vale a dire quando la libreria viene installata per la prima volta e tutte le dipendenze vengono controllate. Dato che sono non che spedisco le dipendenze opzionali con la mia biblioteca, mi chiedo se questo sia un buon approccio. Cosa succede se l'utente decide di installare una dipendenza opzionale dopo che installa la mia libreria? In questo caso, non sarò in grado di rilevare la presenza della libreria.

In che modo risolvi questo problema? Cosa sto sbagliando con questo approccio?

    
posta Gnosophilon 14.02.2018 - 14:30
fonte

1 risposta

2

Normalmente, quando costruisci e installa software, decidi quali funzionalità saranno disponibili quando crei il software, non quando lo utilizzi, quindi direi che l'approccio ha un senso.

Ad ogni modo se si desidera consentire l'installazione del software e le funzionalità rilevate in un secondo momento, penso che si possa fare qualcosa di simile (si noti che questo funzionerà solo se gli utenti della libreria useranno CMake) :

  1. Rimuovi il controllo FIND_PACKAGE(foo) nel tuo CMakeLists.txt principale e in #cmakedefine nel tuo file di configurazione.

  2. Esporta un obiettivo per la tua libreria utilizzando add_library(INTERFACE) , export(TARGET) se non lo fai già (vedi add_library , esportazione e install documentazione dei comandi per i dettagli).

  3. Aggiungi un file MyProjectConfig.cmake se non ne hai uno (consulta qui ).

  4. Dentro il tuo MyProjectConfig.cmake , dopo aver incluso i file di destinazione, puoi fare qualcosa di simile a questo:

    find_package(foo QUIET)
    if(foo_FOUND)
        target_compile_definitions(MyTarget INTERFACE HAVE_FOO)
    endif()
    
  5. Gli utenti della libreria dovranno collegare il target e la definizione verrà aggiunta solo se la libreria viene trovata sul sistema quando la libreria utente è configurata . La tua libreria può essere utilizzata in questo modo:

    find_package(MyProject)
    add_library(bar [...])
    target_link_libraries(bar MyProject::MyTarget)
    
risposta data 14.02.2018 - 18:26
fonte