2010-11-11 15 views
10

Oltre all'utilizzo di -nostdlib e al collegamento di crt1.o -lc -lgcc, esiste un modo semplice per impedire a gcc di collegare crtbegin[S].o e crtend[S].o? Questi file non sono così grandi, ma sto giocando con piccoli binari e vorrei rimuovere il codice di supporto C++ inutile che non è necessario per i programmi C. (Presumibilmente, gcc li collega anche per i programmi C nel caso in cui si stia utilizzando una libreria C++ con variabili globali degli oggetti. Risparmierò a tutti il ​​dispetto su come dovrebbe generare chiamate iniziali di inizializzazione sicure ovunque l'oggetto globale sia referenziato in moduli C++ piuttosto che l'inizializzazione degli oggetti globali prima main ...)C'è un modo semplice per fare gcc omettere crtbegin.o/crtend.o?

non sarei contrario a piratare il file gcc specs per rendere il collegamento del C++ file di supporto alla condizione che tali e quali, ma sono non sono sicuro di come lo farei. Forse c'è già un bel modo?

+0

Credo che siano necessari anche per le funzioni '__attribute__ ((costruttore)' (e 'distruttore'). (e sono lontano da un esperto in C++, ma mi è stato detto che per conformarsi allo standard, i costruttori globali devono succedere prima che venga chiamato 'main()') – caf

+0

@caf: Ho avuto l'impressione che il Lo standard C++ specifica che i costruttori vengono chiamati in un tempo non specificato tra l'invocazione del programma e la prima volta che l'oggetto viene usato (e ovviamente in un ordine non specificato, a parte i casi in cui un oggetto fa riferimento a un altro e quindi invoca la "prima volta che viene utilizzato") . Hai un riferimento al contrario? –

+0

Probabilmente si tratta di un "teach di egg-sucking", ma hai provato a utilizzare 'gcc' per compilare e andare direttamente al tuo linker di sistema (probabilmente' ld') per il passaggio del collegamento effettivo in modo da avere un maggiore controllo sul collegamento? –

risposta

6
gcc -wrapper sh,-c,'z= ; for i ; do [ "$z" ] || set -- ; z=1 ; 
    case "$i" in *crtbegin*.o|*crtend*.o) ;; *) set -- "[email protected]" "$i" ;; esac ; 
    done ; exec "$0" "[email protected]"' 
+1

qualcuno può spiegare cosa sta succedendo nello script sopra? –

+0

@ 4aRkKn1gh7: L'opzione '-wrapper' consente a gcc di richiamare comandi esterni eseguiti tramite un programma wrapper. Il programma wrapper è uno script di shell che elimina qualsiasi argomento che corrisponda a '* crtbegin * .o' o' * crtend * .o' prima di richiamare il comando richiesto. È solo scritto in linea sulla riga di comando piuttosto che salvare lo script in un file. –

3

Penso che sia necessaria l'opzione -nostartfiles. Questo è quello che mi serve comunque per le cose incorporate.

+1

Questo è un buon inizio (non è un gioco di parole), ma omette anche 'crt1.o' che contiene il punto di ingresso' _start'. –

+0

@R ..: Sono sicuro che è possibile configurare ENTRYPOINT nello script del linker. – leppie

+0

Sì, so che potrei farlo in quel modo, ma è molto peggio che trovare il percorso di 'crt1.o' e usare la linea di comando' gcc' per collegarmi. Fondamentalmente stavo cercando la cosa più simile a un modo portabile per ottenere gcc da non collegare in cose inutili, e le risposte sembrano essere che non ce n'è. –

Problemi correlati