Kapan kita harus menggunakan "binari tertanam" daripada "Kerangka Tertaut" di Xcode?


141

Ada pertanyaan bagus tentang perbedaan antara kedua opsi tersebut seperti yang dijelaskan di Link Binary with libraries VS Embed Frameworks .

Sepertinya kita memiliki opsi untuk menggunakan keduanya, hanya ingin tahu kasus mana yang sebaiknya kita gunakan binari tertanam lebih baik, atau daripada kerangka kerja tertaut?

Adakah contoh yang solid untuk mengatasi hal ini dengan lebih jelas? Terima kasih


Jawaban:


241

Pertanyaan yang Anda tautkan merujuk pada fungsi "Link Binary With Libraries", yang agak berbeda dari biner yang disematkan.

"Link Binary With Libraries" berarti apa yang Anda harapkan sehubungan dengan linkage: Terlepas dari apakah biner tersebut adalah library statis, library dinamis, atau framework, biner tersebut akan ditautkan ke kode objek Anda pada waktu link setelah kompilasi.

Ketika Anda memikirkan keterkaitan dengan pustaka statis, yang terjadi cukup jelas: penaut menyalin kode dari pustaka (misalnya libFoo.a) ke dalam biner keluaran Anda. File keluaran Anda bertambah besar tetapi tidak perlu menyelesaikan dependensi eksternal apa pun pada waktu proses. Semua yang dibutuhkan program Anda untuk dijalankan (sehubungan dengan pustaka statis) ada setelah program dibuat.

Dengan pustaka dinamis (.dylib, atau kerangka kerja yang dipasok sistem), diharapkan pustaka yang Anda tautkan akan ada di suatu tempat di jalur pemuat pustaka dinamis sistem saat Anda menjalankan program. Dengan cara ini Anda tidak memiliki overhead untuk menyalin semua pustaka eksternal pihak ketiga ke biner Anda, dan semua program berbeda di komputer yang juga ditautkan ke pustaka itu akan dapat menemukannya, yang menghemat ruang disk minimal, tetapi juga kemungkinan ruang memori, tergantung pada bagaimana dan di mana perpustakaan cache sistem.

Framework mirip dengan library dinamis, tetapi dapat berisi resource dalam struktur direktorinya (gambar, audio, framework lain, dll.). Dalam hal ini statis-perpustakaan atau .dylib file sederhana tidak akan dipotong sehingga Anda mungkin harus link ke sebuah kerangka kerja hanya begitu itu dapat menemukan apa yang dibutuhkan untuk berjalan dengan baik.

Saat Anda menautkan ke kerangka pihak ketiga (katakanlah sesuatu yang Anda unduh dari github dan buat sendiri), kerangka itu mungkin tidak ada di sistem yang ingin Anda jalankan. Dalam kasus ini, Anda tidak hanya akan menautkan ke kerangka kerja, tetapi juga menyematkannya di dalam bundel aplikasi Anda menggunakan fase "Salin Kerangka Kerja". Saat program Anda berjalan, runtime-linker (alias resolver) akan melihat ke dalam bundel Anda selain ke jalur pemuat sistem, menemukan kerangka kerja yang disematkan, dan menautkannya sehingga aplikasi Anda akan memiliki kode yang diperlukan untuk menjalankannya.

Terakhir, apa yang disebut sebagai "biner tertanam" adalah file yang dapat dieksekusi yang Anda berdua sematkan dalam bundel aplikasi Anda melalui Fase File Salin, dan yang Anda jalankan sendiri, mungkin dengan panggilan ke popen()atau serupa. Biner yang disematkan dapat dipanggil oleh program Anda, tetapi tidak terkait dengannya. Ini adalah entitas yang sepenuhnya eksternal (seperti program di /bindirektori).

Dalam praktiknya, untuk pustaka dan kerangka kerja yang disediakan sistem Anda akan menautkannya dan hanya itu yang perlu Anda lakukan.

Jika Anda perlu menautkan pustaka yang Anda buat yang tidak memerlukan sumber daya yang disematkan (yaitu, tidak memerlukan kerangka kerja), Anda dapat menautkan ke pustaka statis. Jika Anda menemukan Anda memiliki beberapa modul dalam program Anda yang ingin menggunakan kode perpustakaan yang sama, maka mengubahnya menjadi kerangka kerja atau perpustakaan dinamis dan menautkannya dapat menghemat ruang dan mungkin nyaman (terutama jika penggunaan memori menjadi perhatian).

Terakhir, kerangka kerja tidak hanya dapat menyertakan sumber daya, tetapi file header dan / atau lisensi. Menggunakan kerangka kerja untuk menyampaikan file-file ini sebenarnya adalah mekanisme distribusi yang mudah sehingga sering kali Anda mungkin ingin memasukkan kerangka kerja agar hal-hal ini dapat mengikuti biner Anda (yaitu persyaratan lisensi mungkin membuat ini wajib).

--- EDIT ---

Adam Johns memposting pertanyaan berikut sebagai komentar:

Ini jawaban yang bagus. Namun, ada sesuatu yang masih membuat saya bingung. Apa artinya mengeksekusi biner sendiri? Apakah yang Anda maksud hanya menggunakan kode kerangka tertanam? Saya tahu Anda menyebutkan popen (), tetapi maksud Anda aplikasi saya memanggil popen ()? Saya tidak begitu tahu apa artinya.

Saya mengatakan biner yang disematkan hanyalah file sumber daya lain dalam bundel Anda, seperti file audio atau gambar, meskipun file tersebut adalah alat baris perintah yang dapat dieksekusi. The popen()function ( man popendari terminal Anda untuk membaca lebih lanjut tentang hal itu) memungkinkan Anda menjalankan program yang sewenang-wenang dari program lain berjalan. The system()Fungsi adalah cara lain. Ada yang lain, dan saya akan memberikan contoh historis di sini yang mungkin membuat pemahaman tentang penggunaan biner tersemat menjadi sedikit lebih jelas:

Seperti yang mungkin Anda sadari, saat Anda meluncurkan aplikasi di Mac OS X, aplikasi diluncurkan dengan id pengguna dari pengguna saat ini. Di bawah penginstalan yang paling umum, itulah pengguna default di pengguna Desktop admin, yang diberi id pengguna 501.

Pada sistem operasi berbasis Unix hanya rootpengguna (id pengguna 0) yang memiliki akses penuh ke seluruh sistem file. Terkadang program penginstal yang diluncurkan oleh pengguna Desktop perlu menginstal file di direktori yang memiliki hak istimewa (misalnya driver). Dalam hal ini, program aplikasi perlu meningkatkan hak istimewanya kepada rootpengguna sehingga dapat menulis di direktori yang dibatasi ini.

Untuk memfasilitasi hal ini dalam sistem operasi melalui OS X 10.7, Apple menyediakan fungsi AuthorizationExecuteWithPrivileges () dalam API Layanan Otorisasi (ini sekarang sudah usang, tetapi masih menjadi contoh yang berguna).

AuthorizationExecuteWithPrivileges()mengambil argumen jalur ke alat baris perintah untuk dieksekusi sebagai root. Alat baris perintah adalah skrip shell yang dapat dieksekusi atau biner terkompilasi yang Anda tulis untuk menjalankan logika penginstalan. Alat ini dipasang di dalam bundel aplikasi Anda seperti file sumber daya lainnya.

Saat dipanggil, OS memasang dialog otorisasi yang meminta kata sandi pengguna (Anda pernah melihat ini sebelumnya!) Dan ketika dimasukkan akan menjalankan program seperti rootatas nama aplikasi Anda. Proses ini mirip dengan hanya menjalankan program dengan popen()diri Anda sendiri, meskipun popen()tidak memberi Anda keuntungan dari peningkatan hak istimewa.


63
Bagaimana Anda mengetahui hal-hal ini?
Ian Warburton

57
@IanWarburton Saya telah memprogram sistem operasi Apple selama lebih dari 20 tahun dan mendapatkan beberapa informasi menarik di sana-sini. :)
par

1
@JustAMartin Maksud saya link, tetapi Anda benar bahwa Anda juga harus menyematkannya melalui fase salin-file (jika tidak, bagaimana Anda akan menggunakannya?). Tujuan menggunakan kerangka pihak ketiga atau biner tersemat adalah untuk mengeksekusi kode yang disediakan entitas. Dengan biner tertanam, tidak ada tautan yang terlibat. Saat runtime, Anda membuat jalur ke biner lalu menjalankannya secara manual. Dengan kerangka kerja, penghubung waktu kompilasi akan menautkannya saat Anda membangun aplikasi, kemudian (jika kerangka kerja pihak ketiga) Anda menyematkannya melalui fase salin-file, dan terakhir penghubung waktu proses menautkannya lagi saat Anda menjalankan aplikasi. .
par

1
Hal-hal agak tidak jelas seperti apa jawaban Anda ke @JustAMartin. Tujuan menggunakan kerangka pihak ketiga atau biner tersemat adalah untuk mengeksekusi kode yang disediakan entitas. Saat ini, Embedded binari juga bisa menjadi framework pihak ketiga. Saya mencoba memahami apa yang Anda maksud di sini ... AFA Saya mengerti, arti biner yang disematkan, biner terpisah dari kerangka yang disematkan akan diperkenalkan ke dalam bundel Aplikasi, Dan Jika Anda hanya menautkan kerangka yang sama, itu akan dimasukkan ke dalam biner yang sama seperti itu dari aplikasi. Harap perbaiki saya Jika saya salah ...
hariszaman

1
Mungkin ada keajaiban Xcode baru yang akan memuat kerangka kerja tertanam. Sudah lama saya tidak membutuhkan fungsi itu. Jika Anda ingin menjelajahi apa yang terjadi lebih lanjut, silakan kirim pertanyaan baru di sini di SO.
par

35

Pendeknya,

  • perpustakaan sistem, tautkan mereka;
  • Perpustakaan pihak ketiga, sematkan.

Mengapa?

  • jika Anda mencoba menyematkan pustaka sistem, Anda tidak akan menemukannya di daftar munculan;
  • jika Anda menautkan pustaka pihak ketiga, Anda mungkin akan mengalami crash.

10

Ini adalah bagian dari Dependencymanajemen [Tentang]

Harap dicatat bahwa Xcode 11hanya berisi Frameworks, Libraries, and Embedded Contentbagian di Generaltab

[Xcode v11]

Tautkan Biner

General -> Linked Frameworks and Librariesadalah cermin dari Build Phases -> Link Binary With Libraries.

Perpustakaan dan Kerangka Statis

Jika Anda menambahkan a Static Library or Static Frameworkke bagian ini, itu akan muncul di Frameworks grup [About] ( Project Navigator -> <workspace/project> -> Frameworks) dan akan ada referensi yang ditambahkan ke proyek Anda untuk itu. Kemudian akan digunakan oleh Static Linker. Static Linkerpada waktu kompilasi akan menyertakan / menyalin semua kode dari perpustakaan ke dalam file objek yang dapat dieksekusi. Static linkerbekerja berpasangan denganBuild Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths. Jika Anda tidak menambahkan a static frameworkke bagian ini, Anda akan mendapatkan kesalahan kompilasi [Tidak ada modul seperti itu]

Sematkan biner

Perpustakaan Statis dan Kerangka Statis

Penyematan tidak akan masuk akal untuk Static Librarydan Static Frameworkkarena simbol darinya dikompilasi ke dalam biner yang dapat dieksekusi. Xcode tidak akan membiarkan Anda meletakkan di static librarybawah bagian Sematkan.

Kerangka Dinamis

General -> Embedded Binariesadalah cermin dari Build Phases -> Embed Frameworks.

Menyematkan sebenarnya menambahkan salinan kerangka kerja ke dalam bundel aplikasi Anda.

Secara default folder bundel adalah Frameworkstetapi Anda dapat mengubahnya menggunakan Destinationfield. Selain itu, Anda dapat menentukan file Subpath.

Dynamic linker :dyldpada saat memuat atau menjalankan akan mencoba menemukan kerangka tertanam menggunakan @rpath[About] Jika tidak ditemukan kesalahan akan terjadi [dyld: Library tidak dimuat]

Hasil:

  • Static Library - Link
  • Static Framework - Link
  • Dynamic Framework - Embed

[Saat menggunakan Tautan dan Sematkan]

[Kosa kata]

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.