Ciò che fa il linker ELF è che garantisce che il linker statico e dinamico produca lo stesso risultato. Quindi, usare gli oggetti condivisi non crea nuovi problemi. Puoi crearne alcuni se usi visibilità o versione o script linker non predefiniti, ma ovviamente non lo faresti se non è sicuro in quel caso particolare.
Ora se usi set incompatibili di flag di compilazione per creare oggetti diversi, sia condivisi che statici, in una applicazione, avrai dei problemi. Puoi avere due tipi di problemi:
-
I flag sono così incompatibili che la convenzione di chiamata, il layout della struttura o qualche altro parametro di questo tipo è diverso tra i moduli. Ovviamente l'unica soluzione è sapere quali opzioni del compilatore devono sempre essere impostate sui valori predefiniti della piattaforma.
-
I flag modificano il contenuto delle intestazioni e quindi violano una regola di definizione. Gli autori di librerie standard, almeno quelle open source, sanno bene come evitare la rottura della compatibilità tra gli oggetti. Ma se hai una libreria speciale a cui l'autore non fa attenzione, puoi metterti nei guai e assicurarti che i flag di compilazione siano compatibili.
In Linux non ho visto succedere questi problemi. Tutti sanno di non toccare i flag del compilatore che potrebbero rompere nulla e non ci sono versioni incompatibili speciali per il debug o simili (gcc può emettere informazioni di debug nell'ottimizzazione della build, quindi normalmente si ottiene semplicemente la versione non stoppata dello stesso oggetto o ultimamente anche solo il debug informazioni per l'oggetto normale divisi in file separati).
Questo è diverso da Windows, dove:
- A causa del modo in cui le librerie condivise necessitano di esportazione e importazione esplicite, non si uniranno simboli (come istanze di template o impedimenta di classe) generati in diverse librerie condivise.
- Avere debug separati e release runtime che differiscono sia nella libreria condivisa utilizzata che nel lotto della magia del preprocessore. Significa che non è possibile collegare la build di debug alle librerie create con la versione di rilascio, quindi ogni libreria deve fornire la versione di debug e release. E spesso variante per il collegamento statico e dinamico. E nonostante tutti questi problemi, non penso che il supporto per il debug su Windows sia migliore; per esempio. Linux libc ha dei ganci per sostituire l'allocatore (con debug uno) che è sempre macroscopico su Windows e Linux ha grandi strumenti come Valgrind.
- Molti flag del compilatore vengono capovolti per vari motivi di compatibilità, causando ulteriori complicazioni. Va detto che Microsoft è in una posizione più difficile qui. Dal momento che si rivolgono principalmente ai programmatori a codice chiuso, devono supporre che le cose non possano essere ricompilate e debbano fornire vari kludges di compatibilità per far funzionare le cose. Le persone Linux presumono che le cose possano essere ricompilate e cambino quando le cose diventano troppo complicate, come lo era il passaggio al formato ELF; Il formato ELF è stato creato tra il 1997 e il 1999, mentre gli oggetti Windows sono ancora retrocompatibili con quelli precedenti di Windows 3.1. Al costo di tutto il caos.