Dovrei aggiungere la fonte delle librerie invece di collegarle?


14

Sono relativamente nuovo in C ++, quindi non sono sicuro di come gestire al meglio le piccole dipendenze (ad esempio un linguaggio di scripting o un parser JSON / YAML / XML).

Devo creare progetti separati e collegarli come libreria statica o ci sono degli svantaggi nel mettere i file .h / .cpp nel mio progetto principale?

Quest'ultimo sembra molto più semplice perché ho trascorso diverse ore a gestire librerie incompatibili (impostazioni diverse del compilatore durante la creazione della libreria), ma non voglio iniziare a imparare C ++ nel modo sbagliato.

Se è preferibile tenerli come librerie separate, come è meglio mantenere sincronizzati i flag di compilazione in modo che i file .lib / .a si colleghino correttamente alla mia applicazione?

(Attualmente sto lavorando con MSVC 2015, ma l'obiettivo è quello di compilare su Mac OS X e iOS usando XCode / clang, in modo da avere a che fare con almeno 3 diversi tipi di librerie (Win x86, Mac x64, ARM) )


5
Osserva ABIss e ti guarderanno dentro
Basilevs,

1
Tieni presente che alcune librerie sono destinate a essere utilizzate in questo modo. Il modello di utilizzo preferito della libreria SQLite consiste nel rilasciare il file sorgente e di intestazione combinati nell'albero dei sorgenti di un'applicazione C o C ++ da compilare nell'eseguibile.
Mark Benningfield,

Risposte:


6

TLDR;

Nel caso si aggiungere la fonte? X
dovrebbe aggiungere la fonte? DEPENDS

Ecco il perché ...

In passato, il tempo di compilazione era un problema che avevano anche i progetti più piccoli. Compilare le tue fonti e non preoccuparti mai della memorizzazione nella cache dei risultati del compilatore è stato sicuramente interessante per alcuni. Questo è un punto per le biblioteche per te irrilevanti.

Un altro importante è il controllo delle versioni. Hai davvero bisogno di versioni ciascuna libreria separatamente? Eseguire test su ognuno? Distribuirlo tra molti membri del team? Le biblioteche sono fantastiche se lo fai e sono comode da spostare, ma sembra che non ti interessi neanche a questo.

L'ultimo punto qui è, è un sovraccarico aggiunto, e la caduta dei file di origine è più facile nel tuo caso, il che dà un punto molto forte alla caduta nelle fonti piuttosto che all'utilizzo delle librerie. Come hai notato, una volta apportata una modifica alle impostazioni di un singolo compilatore, devi inseguire tutte le dipendenze in caso contrario.

Conosco tutto questo per esperienza:

Per i progetti Swift, uso sicuramente i framework (librerie) e li collego, poiché è facile da configurare usando Xcode. Ho anche davvero bisogno del controllo delle versioni, dei test e del disaccoppiamento lì, quindi è per questo.

Per i progetti Mono (C #), per Unity, ho iniziato con l'approccio alla moda di scomporre il progetto in librerie, compilare e testare ciascuno di essi, il che è stato fantastico ... ma una volta che ho lasciato cadere le librerie in Unity, sono successi tutti i tipi di problemi , dalla versione compromessa di Mono Unity, semplicemente al comportamento a volte diverso che il codice mostra quando cambia piattaforma. Non avere un solo IDE qui per gestire tutte le librerie è stata una vera seccatura, quindi mettere tutte le fonti in Unity è stata una grande vittoria per la produttività.

Infine, per te più rilevante, un progetto di gioco in C ++ a cui ho lavorato. Un motore di gioco, client di rete in tempo reale, client di rete HTTP, AI e un archivio di persistenza sono stati scritti per questo gioco, proprio sul lato client. Cosa ho optato per? CLion + Librerie. Anche se stavo usando le librerie, non mi sembrava di esserlo. Tutte le fonti erano nel progetto IDE di CLion e componendo CMakeLists, sono stato in grado di innescare tutte le build e collegarle in un solo colpo.

In conclusione , direi che usare le librerie è una soluzione a prova di futuro, ma anche un'ottimizzazione prematura se non necessaria. Per quanto ho potuto accertare dalla tua situazione, passare da MSVC a Xcode sarà una seccatura se avrai un obiettivo con più build. Quindi, inseriscilo e mantieni il maggior isolamento possibile per il momento in cui potresti dover usare le librerie.

PS: Sto vivendo un dilemma simile in questi giorni con la docker. Dovrei comporre? Devo solo eseguire localmente? .. ecc. Anche Elisir, in quanto ti consente di creare applicazioni all'interno della stessa applicazione. Devo farlo? O separare l'app nei cosiddetti micro-servizi? ... ecc. Non esiste un proiettile d'argento, misura sempre te stesso, come YMMV.


2

Il collegamento con le librerie C ++ richiede molta seccatura e richiede molta conoscenza e impegno per farlo correttamente. Può essere intimidatorio per gli studenti C ++.


Spesso gli autori / manutentori di una specifica libreria C ++ ne tengono conto e raccomandano in un modo o nell'altro.

In altre parole, se gli autori / manutentori intendono che la libreria sia inclusa dalle intestazioni (solo * .h e .hpp), o includa dalla fonte ( .h *, o .c ), lo avrebbe detto chiaramente nel readme o documentazione.


Le librerie progettate e mantenute per essere multipiattaforma (e compatibili con più fornitori e ambienti di compilatori C ++) avranno spesso un sistema makefile o un sistema di configurazione build (come CMake). Questi sistemi vengono utilizzati per generare spessori di intestazione che appianano le differenze della piattaforma e per generare script che richiameranno il compilatore e il linker sui file di origine utilizzando le opzioni della riga di comando appropriate e nella sequenza corretta. A seconda della piattaforma e della configurazione, questi sistemi di compilazione possono includere o escludere determinate intestazioni o file di origine oppure possono definire o annullare la definizione di determinati simboli del preprocessore.


Andare contro la raccomandazione degli autori / manutentori è possibile, ma ciò richiede sempre un ampio sforzo di porting. La quantità di lavoro richiesta per tale sforzo di porting può essere paragonabile al porting su un diverso ambiente C ++.


Poiché Visual C ++ utilizza il proprio sistema di compilazione basato su un file di descrizione del progetto (in parte basato su XML), è abbastanza diverso dal sistema di compilazione basato su script utilizzato in Linux. L'approccio utilizzato da CMake è che CMake esegua le impostazioni di configurazione e quindi emetta l'intera struttura del progetto Visual C ++, con le opzioni di configurazione inserite nei file * .vcxproj.

Se si verificano problemi durante il collegamento C ++ con Visual C ++, le impostazioni di compilazione nei file * .vcxproj possono essere modificate utilizzando la GUI di Visual Studio (utilizzando la finestra di dialogo delle pagine delle proprietà del progetto). Ciò presuppone che tu comprenda a fondo i significati e le conseguenze di una dozzina di importanti impostazioni di compilazione e collegamento C ++.

Ora arriva la parte più stupida dell'utilizzo di Visual C ++: se stai usando una dozzina di librerie di terze parti diverse, cambiare le impostazioni di compilazione per tutti loro significa andare in ogni file * .vcxproj e ripetere la stessa modifica sulla GUI per una dozzina volte. Una seccatura, ma può essere fatto, se sai come farlo correttamente.

La maggior parte degli studenti di Visual C ++ apprende queste impostazioni nel modo più duro, osservando gli errori del compilatore e del linker di Visual C ++, identificati dal loro codice di errore. Ad esempio, si potrebbe cercare LNK2005, con il significato superficiale di "Il simbolo simbolo è stato definito più di una volta", ma con la consapevolezza che la definizione duplicata non deriva da un errore di programmazione imprudente, invece potrebbe essere accaduto a causa di alcuni conflitti o errate applicazioni delle opzioni di compilazione e collegamento.


Per fornire una risposta più specifica e utile alla tua situazione, dovrai conoscere i nomi delle librerie che intendi utilizzare, nonché gli errori di collegamento o altre difficoltà che incontri. Puoi trovare le risposte esistenti a queste domande nei forum di discussione della rispettiva biblioteca. Queste domande tendono ad essere taggate con "problemi di collegamento", "windows" e "visual C ++".

Una guida da principiante a esperto su questo tema è possibile, ma sarà specifica per il progetto. Preferenze diverse scelte da progetti diversi richiederanno una riscrittura completa della guida.


Se si utilizza CMake per emettere .vcxproj, anziché modificare .vcxproj è possibile modificare la configurazione di CMake
Caleth

1

Direi di sì, purché sia ​​più facile. Ci sono molti vantaggi:

  1. Il risultato sarà un codice più veloce e migliore, soprattutto se si attiva l'ottimizzazione del tempo di collegamento.

  2. Al tuo IDE piacerà di più, ad esempio ti permetterà (si spera) di saltare all'implementazione (.cpp) del codice della libreria, piuttosto che solo all'interfaccia (.h), che è estremamente utile quando lavori con codice mal documentato (es. la maggior parte del codice).

  3. Spesso ti consente di aggiungere la dipendenza come un sottomodulo git, che è un modo un po 'confuso ma in realtà abbastanza buono per avere dipendenze (per C ++ comunque, che non ha praticamente nessun sistema di build sano). Rende davvero facile aggiornare la libreria e testare diverse versioni.

  4. Non devi preoccuparti che una dipendenza venga compilata con MSVC ++ 2013, mentre stai usando il 2017 per esempio. O condiviso vs MSVCRT statico.

  5. Puoi facilmente compilare in modalità debug ed entrare nella libreria.

L'unica ragione per cui penso che non vorrai farlo, è se la libreria è grande e ha un sistema di compilazione complesso che non vuoi replicare nel tuo, ad esempio Boost o LLVM. Ma per le biblioteche semplici non c'è davvero un aspetto negativo.

Ad esempio, utilizzo libusb in alcuni progetti e devo supportare Windows. libusb usa gli autotools che sono uno scherzo di un sistema di compilazione e non funzionano comunque su Windows. Forniscono binari precompilati ma sono costruiti con MSVC ++ 2013 e non funzioneranno con il 2017. La soluzione di gran lunga più semplice è stata quella di aggiungere tutti i file .c e .h pertinenti al mio progetto.


2
1) davvero? Una libreria statica è solo una raccolta di file oggetto, proprio come se li avessi appena compilati.
Baldrickk,

Puoi creare un archivio di .ofile che sono stati compilati -fltoma che in realtà non sono una libreria statica - per Clang sono file bitcode LLVM. E ovviamente non funzionerà se usi librerie statiche fornite da qualcun altro.
Timmmm,

ok, aggiorniamo questa discussione - non vedo l'ora di imparare altre cose :)
Baldrickk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.