La domanda che hai collegato fa riferimento alla funzionalità "Collega binario con librerie", che è leggermente diversa da un binario incorporato.
"Collega binario con librerie" indica ciò che ti aspetteresti rispetto al collegamento: indipendentemente dal fatto che il binario sia una libreria statica, una libreria dinamica o un framework, sarà collegato al codice oggetto al momento del collegamento dopo la compilazione.
Quando pensi al collegamento con una libreria statica, ciò che accade è abbastanza chiaro: il linker copia il codice dalla libreria (ad es. libFoo.a
) Nel tuo binario di output. Le dimensioni del file di output aumentano ma non è necessario risolvere dipendenze esterne in fase di runtime. Tutto ciò che il tuo programma deve eseguire (rispetto alla libreria statica) è presente dopo che è stato creato.
Con una libreria dinamica (.dylib o framework fornito dal sistema), l'aspettativa è che la libreria a cui ci si collega sia presente da qualche parte nel percorso del caricatore della libreria dinamica del sistema quando si esegue il programma. In questo modo non hai il sovraccarico di copiare tutte le librerie esterne di terze parti nel tuo binario e tutti i diversi programmi su un computer che si collegano anche a quella libreria saranno in grado di trovarlo, risparmiando spazio su disco minimo, ma anche potenzialmente spazio di memoria, a seconda di come e dove il sistema memorizza nella cache le librerie.
Un framework è molto simile a una libreria dinamica, ma può contenere risorse nella sua struttura di directory (immagini, audio, altri framework, ecc.). In questo caso un file statico-libreria o .dylib semplice non è tagliato in modo potrebbe essere necessario collegamento a un quadro solo così si può trovare ciò di cui ha bisogno per funzionare correttamente.
Quando si collega a un framework di terze parti (ad esempio qualcosa scaricato da Github e creato dall'utente), potrebbe non essere presente sul sistema su cui si intende eseguire. In questo caso, non solo si collegherebbe al framework, ma lo si incorporerebbe anche nel bundle dell'applicazione utilizzando la fase "Copia frame". Quando il programma viene eseguito, il runtime-linker (noto anche come resolver) guarderà all'interno del bundle oltre al percorso del caricatore di sistema, troverà il framework incorporato e lo collegherà in modo che l'app disponga del codice necessario per l'esecuzione.
Infine, ciò che è propriamente un "binario incorporato" è un eseguibile che entrambi incorporate nel bundle dell'applicazione tramite una fase di copia dei file e che eseguite da soli, magari con una chiamata popen()
o simile. Il binario incorporato può essere chiamato dal tuo programma, ma non è collegato ad esso. È un'entità completamente esterna (come i programmi nella /bin
directory).
In pratica, per le librerie e i framework forniti dal sistema ti collegherai a loro e questo è tutto ciò che devi fare.
Se hai bisogno di collegare una libreria che hai creato che non ha bisogno di risorse incorporate (cioè non richiede l'esistenza di un framework), puoi semplicemente collegarti a una libreria statica. Se scopri di avere più moduli nel tuo programma che vogliono usare lo stesso codice di libreria, convertirlo in un framework o libreria dinamica e collegarlo può risparmiare spazio e può essere conveniente (in particolare se l'uso della memoria è un problema).
Infine, i framework possono includere non solo risorse, ma file di intestazione e / o licenza. L'utilizzo di un framework per trasmettere questi file è in realtà un comodo meccanismo di distribuzione, quindi spesso potresti voler incorporare un framework in modo che queste cose possano taggare insieme al tuo binario (cioè i requisiti di licenza potrebbero renderlo obbligatorio).
--- MODIFICARE ---
Adam Johns ha pubblicato la seguente domanda come commento:
Questa è un'ottima risposta C'è qualcosa su cui sono ancora un po 'confuso, comunque. Cosa significa eseguire il binario da soli? Vuoi dire semplicemente usando il codice del framework incorporato? So che hai menzionato popen (), ma stai dicendo che la mia app sta chiamando popen ()? Non so davvero cosa significhi.
Sto dicendo che un binario incorporato è solo un altro file di risorse nel tuo bundle, come un file audio o un'immagine, sebbene il file sia invece uno strumento da riga di comando eseguibile. La popen()
funzione ( man popen
dal tuo terminale per saperne di più) ti consente di eseguire programmi arbitrari da un altro programma in esecuzione. La system()
funzione è un altro modo. Ce ne sono altri, e qui darò un esempio storico che potrebbe rendere un po 'più chiaro la comprensione dell'uso di un binario incorporato:
Come probabilmente saprai, quando avvii un'app su Mac OS X questa viene avviata con un ID utente dell'utente corrente. Nelle installazioni più comuni è l'utente predefinito sul desktop admin
, a cui viene assegnato l'ID utente 501
.
Sui sistemi operativi basati su Unix solo l' root
utente (ID utente 0
) ha pieno accesso all'intero filesystem. A volte capita che un programma di installazione avviato dall'utente Desktop debba installare i file in una directory privilegiata (ad esempio i driver). In questo caso, il programma applicativo deve inoltrare i propri privilegi root
all'utente in modo da poter scrivere in queste directory riservate.
Per facilitare ciò nei sistemi operativi tramite OS X 10.7, Apple ha fornito nella sua API dei servizi di autorizzazione la funzione AuthorizationExecuteWithPrivileges () (ora è obsoleta, ma è ancora un esempio utile).
AuthorizationExecuteWithPrivileges()
ha preso come argomento un percorso a uno strumento da riga di comando per eseguire come root
. Lo strumento da riga di comando era uno script della shell eseguibile o un file binario compilato scritto per eseguire la logica di installazione. Questo strumento è stato installato nel pacchetto dell'applicazione come qualsiasi altro file di risorse.
Quando viene chiamato, il sistema operativo attiva una finestra di dialogo di autorizzazione che richiede la password dell'utente (l'hai già vista prima!) E una volta inserito eseguirà il programma come root
per conto della tua app. Questo processo è simile all'esecuzione di un programma con popen()
te stesso, anche se popen()
da solo non ti dà il vantaggio di escalation di privilegi.