Perché i compilatori in genere generano solo eseguibili per la piattaforma su cui sono installati?

10

Sono uno sviluppatore C ++ e nel tentativo di comprendere meglio lo sviluppo multipiattaforma, sto cercando di capire meglio alcuni dettagli di implementazione dei compilatori e come creano esattamente i binari specifici del sistema operativo. Nel bel mezzo del mio studio mi sono reso conto che, almeno per un po ', la maggior parte dei compilatori che hai scaricato per una piattaforma specifica erano binari compilati solo per quella piattaforma. Quindi, se hai scaricato un IDE fornito con un exe del compilatore per Windows, il compilatore sarebbe in grado di compilare il tuo programma solo per applicazioni Windows x86-x64 e non per applicazioni Linux o Mac.

Ora capisco che piattaforme diverse richiedono formati binari diversi, ma cosa rende difficile per dire il compilatore C ++ visuale su Windows per generare un file eseguibile binario linux? Finché le istruzioni di assemblaggio per la CPU non sono in esecuzione, così come le librerie specifiche del sistema operativo, non dovresti essere in grado di compilare gli eseguibili per qualsiasi piattaforma su qualsiasi macchina?

    
posta Jason 23.03.2017 - 02:45
fonte

3 risposte

17

what makes it difficult for say the visual C++ compiler on windows to generate a linux binary executable file?

Oltre alla riluttanza a farlo da parte di Microsoft, assolutamente nulla. Gli ostacoli non sono tecnici.

I toolchain di sviluppo sono solo programmi che prendono input e producono output. Visual C ++ produce l'assembly x86 e quindi usa un assemblatore per convertirlo in un file oggetto COFF. Se Microsoft volesse farlo generare ELF, è solo un codice: l'assembly entra, ELF si spegne. Non c'è nulla di magico nei file di oggetti o nelle librerie; sono solo blocchi di dati in un formato ben compreso.

All'inizio dell'età della pietra, la compilazione incrociata era molto più difficile perché, molto spesso, avresti dovuto scrivere la catena di strumenti per la piattaforma di destinazione in assembly per la piattaforma su cui sarebbe stata eseguita. Ciò significava che se tutto quello che c'era al mondo fossero le architetture VAX, M68K e Alpha, una suite completa di compilatori incrociati richiederebbe la scrittura di nove di essi, principalmente da zero. (Da VAX a VAX, da VAX a M68K, da VAX a Alpha, da M68K a VAX, da M68K a M68K, ecc.) È un po 'esagerato dal momento che parti del compilatore VAX possono essere riutilizzate e collegato a generatori di codice per ciascun target (ad esempio, VAX, M68K e Alpha, ciascuno scritto per VAX.)

Questo problema scomparve quando iniziammo a scrivere compilatori in una lingua che non era legata a un processore specifico, come ad esempio C. Andando su quella strada significa che scrivi l'intera toolchain una volta in C e usi una scrittura per il compilatore C della piattaforma locale per costruirlo. (Si usa spesso il compilatore per ricompilare se stesso dopo che è stato riavviato nel compilatore della piattaforma locale, ma questa è un'altra discussione.) La conclusione di questo è che la costruzione di un cross-compiler è diventato essenzialmente lo stesso sforzo di creare un compilatore nativo su la piattaforma locale. L'unica differenza significativa è che da qualche parte nel processo di compilazione, gli hai detto di compilare il generatore di codice per la tua piattaforma di destinazione invece di quella per la piattaforma locale, che sarebbe stata la scelta logica. GCC ha fatto (e continua a farlo) costruendo un binario per coppia di piattaforme locali / target.

Con l'evoluzione dell'architettura dei compilatori, è diventato utile includere e creare semplicemente tutti i generatori di codice con il prodotto e selezionare quale viene utilizzato in fase di esecuzione. Clang / LLVM fa questo, e sono sicuro che ce ne sono altri.

Una volta che hai una toolchain funzionante (compilatore, assemblatore, linker), le librerie si costruiscono da fonti e alla fine si finisce con tutto ciò che serve per produrre un file eseguibile per qualche altra piattaforma.

    
risposta data 23.03.2017 - 04:12
fonte
8

Sì, se hai tutte le informazioni sulla tua piattaforma di destinazione, allora non dovrebbe importare quale piattaforma stai effettivamente eseguendo.

Ci sono due problemi che tendono a spuntare:

  1. Le persone non si concentrano su di esso perché è uno scenario meno comune. Spesso l'unica cosa che si esegue la compilazione incrociata è un compilatore, quindi è possibile interrompere la compilazione incrociata. Meno attenzione significa supporto peggiore.
  2. I programmi non banali richiedono molto più del semplice codice. Gestire l'inclusione / il collegamento alle librerie diventa un po 'più semplice quando si hanno le librerie per la piattaforma su cui si sta eseguendo. Saranno in una posizione ben nota, in una codifica ben nota.

Ovviamente non sono insormontabili. Principalmente, ottieni compilatori che prendono di mira la piattaforma su cui eseguono perché è ciò che la gente vuole.

    
risposta data 23.03.2017 - 03:32
fonte
2

Non sono d'accordo con la tua premessa. Ci sono milioni di sviluppatori Android e iOS. E tutti usano i compilatori in esecuzione su Windows o Mac, producendo codice per un computer completamente diverso.

Non otterrai un cross-compiler se non ci sarà alcuna richiesta da parte del mercato. Le persone che sviluppano il codice per un desktop Linux, per esempio, hanno per la maggior parte un desktop Linux disponibile e useranno un compilatore basato su Linux - molto più veloce se si può eseguire l'applicazione direttamente sulla macchina in cui è compilata senza trasportarla sulla rete, molto più facile e veloce avere un debugger in esecuzione sulla stessa macchina e così via.

Quindi quanti più soldi farebbe Microsoft se i compilatori compilassero anche per Linux? Circa $ 0. Quanto più software per Windows verrebbe creato? Nessuna. Quanto più software Linux verrebbe creato? Non ne ho idea, ma non è qualcosa a cui importa Microsoft. Quale sarebbe il costo? Abbastanza considerevolmente. I compilatori devono essere privi di bug. Devono essere testati.

Un altro problema: se scrivi un compilatore scrivendo su Windows hai bisogno di qualcuno che sappia scrivere software Windows. Se scrivi un compilatore per Linux hai bisogno di qualcuno che sappia scrivere software Linux. Se si scrive un compilatore per Linux in esecuzione su Windows, all'improvviso è necessario il pane di sviluppatori molto più raro che conosce sia Windows che Linux.

    
risposta data 23.03.2017 - 22:54
fonte

Leggi altre domande sui tag