Compatibilità binaria tra Mac OS X e Linux


27

Preparatevi, questa domanda apparirà probabilmente ingenua e / o sciocca, visto che sono relativamente nuovo al funzionamento interno di sistemi come unix e alla programmazione in generale.

Pronto? Ok! Attraverserò circa 3 livelli di ludicrosità, aumentando man mano che procederò.


Abbiamo due sistemi con hardware simile (il punto principale è il processore, diciamo un Intel Core 2 duo standard).

Uno è in esecuzione (inserisci qui la tua distribuzione Linux: Ubuntu verrà utilizzato d'ora in poi) e l'altro è in esecuzione, diciamo Mac OS X.

Uno compila un programma equivalente, diciamo qualcosa del tipo:

int main()
{
    int cat = 33;
    int dog = 5*cat;
    return dog;
}

Il codice è estremamente semplice, perché non voglio ancora considerare le implicazioni delle librerie condivise.

Quando compilato sui rispettivi sistemi. La differenza principale tra l'uscita non è una questione di ELF vs Mach-O? Se uno dovesse eliminare ogni binario della formattazione, lasciando un binario piatto, le istruzioni della macchina smontata non sarebbero le stesse? (con forse alcune differenze a seconda delle abitudini / tendenze dei compilatori).

1.) Se si sviluppasse un programma per riconfezionare il binario piatto prodotto dal nostro sistema Ubuntu, nella formattazione Mach-O, verrebbe eseguito nel sistema Mac OS X? Quindi, se uno avesse solo il binario compilato del presunto programma sopra e uno avesse questo strumento mistico per il riconfezionamento di binari piatti, i programmi semplici sarebbero in grado di funzionare sul sistema Mac OS X?


Ora andiamo un po 'oltre.

Ora abbiamo un programma con sorgente come:

#include <stdio.h>
int main()
{
    printf("I like tortoises, but not porpoises");
    return 0;
}

2.) Supponendo che questo programma sia compilato e staticamente collegato, il nostro programma magico sarebbe ancora in grado di riconfezionare il file binario grezzo nel formato Mach-O e farlo funzionare su mac os X? Visto che non avrebbe bisogno di fare affidamento su altri binari, (per i quali il sistema mac non avrebbe in questo caso)


E ora per il livello finale;

3.) E se usassimo questo presunto programma per convertire tutte le librerie condivise necessarie nel formato Mach-O, e poi invece compilassimo il programma sopra con collegamento dinamico. Il programma sarebbe ancora riuscito a funzionare?

Per il momento dovrebbe essere così, ovviamente ogni passo dell'assurdità si basa sulla base precedente, anche per avere un senso. quindi se il primo pilastro viene distrutto, dubito che ci sarebbero molti meriti per i livelli rimanenti.

Sicuramente non mi spingerei nemmeno a pensarci con programmi che hanno in mente la GUI. I sistemi di finestre sarebbero probabilmente un altro mal di testa. Sto prendendo in considerazione solo i programmi da riga di comando in questa fase.

Ora invito il mondo a correggermi e mi dico tutto ciò che non va nella mia assurda linea di pensiero.


l'equivalente dei binari di Wine for OS X è Darling: darling.dolezel.info
strugee,

Risposte:


25

Dimentichi una cosa cruciale, ovvero che il tuo programma dovrà interagire con il sistema operativo per fare qualcosa di interessante.

Le convenzioni sono diverse tra Linux e OS X, quindi lo stesso binario non può essere eseguito così com'è senza essenzialmente avere un pezzo di codice dipendente dal sistema operativo per poter interagire con esso. Molte di queste cose sono nascoste nelle librerie, che è quindi necessario collegare e ciò significa che il programma deve essere collegabile, e anche il collegamento è diverso tra i due sistemi.

E così continua all'infinito. Ciò che in superficie sembra fare la stessa cosa è molto diverso nei dettagli reali.


5
Questo è fondamentalmente corretto su quale sia il problema, ma il problema non è in realtà le librerie (che potrebbero essere trascinate insieme) ma le chiamate di sistema, che sono richieste al kernel del sistema operativo. Se il sistema operativo non fornisce un'interfaccia di chiamata di sistema compatibile, si è sfortunati.
mattdm,

1
Aah, questo è eccellente. Questo è esattamente il tipo di correzione costruttiva che speravo. Grazie mille: D Potresti dirmi di più su queste presunte chiamate di sistema o reindirizzarmi verso un posto dove posso saperne di più su di loro?
zec,

3
Non sono "supposti", sono reali. :) Ecco un buon inizio: ibm.com/developerworks/linux/library/l-system-calls
mattdm

7
Detto questo, la tua idea "folle" non è del tutto impossibile. Solo molto lavoro. Il progetto Wine è essenzialmente questo per eseguire binari MS Windows su Linux (o OS X). Fornisce un livello di traduzione per le chiamate di sistema. wiki.winehq.org/…
mattdm

1
Bene, ho pensato che non sarebbe stato del tutto impossibile, ma non mi aspettavo che fosse così semplice come l'ho descritto. Ho scritto la domanda con l'intenzione di essere corretto. Questo a volte sembra un metodo più efficiente per arrivare al nocciolo della questione piuttosto che porre una domanda diretta come "Come faccio a convertire un binario Linux per funzionare su Mac OS". Inoltre, di tanto in tanto ho usato il vino, ma non avevo mai davvero riflettuto su come funzionasse prima, penso che ora andrò a esaminarlo.
zec,

17

Questo è fattibile se qualcuno vuole passare abbastanza tempo per farlo accadere. Il progetto Darling ci sta provando, anche se al momento della stesura di questo documento, è in uno stato piuttosto primitivo.

È stato fatto con successo in precedenza su altre piattaforme:

  • Solaris e UnixWare includono un programma di supporto chiamato lxrunche funziona in modo simile sudo: si passa il nome eseguibile e parametri all'helper e risolve le cose in modo dinamico in modo che l'eseguibile possa parlare con il sistema operativo. Il sito ufficiale (in basso, link all'archivio ) dice che è bitrate .

  • Il kernel di Linux una volta aveva una funzione chiamata iBCS che faceva il contrario, tranne per il fatto che non aveva bisogno di un aiuto perché il kernel riconosceva direttamente i binari "stranieri". E cadde in rovina durante la serie di sviluppo del kernel 2.3 , molto probabilmente perché la piccola battaglia di server Unix era in sostanza una volta 2.4 è venuto fuori.

  • Il kernel di FreeBSD può essere configurato per riconoscere i binari di Linux ed eseguirli come se fossero nativi. Questa funzione sembra essere in forma migliore rispetto alle due precedenti.

    OpenBSD e NetBSD hanno caratteristiche simili.

OS X ha molto FreeBSD , quindi il porting del suo supporto Linux potrebbe essere semplice.


2
Uno dei motivi per cui questo non è un grosso problema per i programmi Linux → altre piattaforme è: non esistono app significative solo per Linux per le quali la fonte non è disponibile. Volete eseguire il vostro programma su OS X o Solaris, ricompilarlo e il gioco è fatto. Potrebbe esserci un po 'di porting da fare in cui il codice è stato scritto in modi specifici di Linux, ma generalmente non è molto lavoro, soprattutto rispetto al mantenimento del livello di compatibilità. La compatibilità Linux di FreeBSD era molto importante quando Netscape era un binario distribuito solo per Linux, e probabilmente è ancora usato per Adobe Flash Player.
Mattdm,

@ Jörg W Mittag - inoltre, dovevi avere a disposizione le librerie di sistema dell'altra piattaforma. Questa potrebbe essere stata la base per la loro causa contro AutoZone. Ma onestamente dimentico i dettagli e non mi interessa più. :)
mattdm,

Quindi quello che dici è essenzialmente che se il sistema operativo X fornisce gli stessi servizi del sistema operativo Y, un binario può essere eseguito in entrambi. Questo è vero, ma richiede uno sforzo deliberato per il sistema X. Non sono a conoscenza di alcun sistema operativo compatibile in questo modo con OS X.
Thorbjørn Ravn Andersen,

bitrotten? Mi mostrerò.
GnP,

3

Sono praticamente d'accordo con tutti, ma voglio aggiungere che, sebbene ciò richiederebbe una notevole quantità di tempo e sforzi, non sarebbe quasi quanto ci è voluto per sviluppare Wine.

Gran parte del difficile sviluppo di Wine è che stanno eseguendo il porting di un formato binario da un sistema operativo di origine chiusa e MOLTE chiamate di sistema non sono documentate. Hanno dovuto essenzialmente decodificare il sistema operativo.

Se qualcuno dovesse farlo da un sistema operativo aperto a un altro sistema operativo aperto, potrebbe probabilmente farlo in 1/10 del tempo, poiché il livello di compatibilità potrebbe essere plausibilmente copiato / incollato dall'altro sistema operativo se un equivalente sistema nativo chiama non esiste. Naturalmente, nella maggior parte dei casi nel mondo POSIX, sarà disponibile una chiamata nativa.

Un altro progetto degno di nota è ReactOS, in cui stanno essenzialmente creando una versione completa di Windows compatibile con i binari ... non c'è bisogno di Wine.


1

È tecnicamente fattibile in macOS ma non senza sforzi significativi, sebbene alcuni degli sforzi siano già stati fatti per noi.

  • Sia macOS che un Red Hat Enterprise Linux rinominato sono stati certificati UNIX 03. Ciò significa che in linea di principio le chiamate POSIX dovrebbero avere la stessa API.
  • Sia macOS che Linux utilizzano System V ABI per la piattaforma amd64. Ciò significa che per amd64 macOS e Linux dovrebbero avere ABI e API compatibili.
  • macOS utilizza Mach-O come formato eseguibile nativo mentre Linux utilizza ELF. Questo semplifica le cose, poiché il formato del file eseguibile può essere utilizzato per distinguere se il livello di compatibilità debba essere chiamato. Ciò richiederebbe qualcosa di simile binfmt_miscperò.
  • Esiste un'estensione del kernel macOS di terze parti che fornisce esattamente questo. Ora abbiamo un modo per caricare convincere macOS a caricare ELF, abbiamo bisogno del nostro speciale ld-linux.soche a sua volta è un eseguibile Mach-O che carica il nostro ELF e lo esegue.

Ora quello di cui abbiamo bisogno è almeno uno speciale ld-linux.soche possa fare quanto segue:

  • Essere un eseguibile Mach-O o dyldse stesso,
  • Può caricare file ELF di Linux in memoria all'indirizzo corretto,
  • Speriamo che abbia la possibilità di mappare il soname Linux su macOS (esempio /lib/libc.so.6a /lib/libSystem.B.dylib) e caricare il Mach-O corrispondente quando non viene trovato un ELF corrispondente, quindi possiamo riutilizzare le librerie macOS

Con solo quel caricatore sopra ELF che non crea syscalls diretti ha buone probabilità di funzionare, ma ELF con syscalls potrebbe non funzionare. Un secondo componente che potrebbe essere utile sarebbe un'estensione del kernel che cattura quelle syscalls Linux e le associa a quelle macOS. A partire dagli usi desktop, è necessaria un'implementazione speciale di mesa per mappare le chiamate grafiche Linux su OpenGL.frameworke Metal.framework.


0

Esistono diverse app Linux specializzate per le quali questo sarebbe di grande aiuto. Dal punto di vista dell'FPGA, Quartus e Vivado sono buoni esempi di programmi eseguiti su Linux ed è improbabile che ci sia un codice sorgente disponibile per loro o programmi simili destinati agli ultimi FPGA.

Penso che la semplice risposta alla tua domanda sia: ricompilare su MacOS dove hai la fonte e formare un gruppo per fornire la capacità se hai tempo - e sarà un compito che richiede tempo.

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.