Saya mengembangkan aplikasi menggunakan set alat Unix yang biasa: compiler make
,, dan shared library. Prosedurnya biasanya seperti itu
./configure
, yang menyesuaikan sumber untuk fitur mesin yang dijalankan,make
, yang sebenarnya mengkompilasi lib, shared executable, dll.,make check
, yang menjalankan tes sebelum kami menginstal paket,make install
, jika paket berperilaku baik, dan akhirnya, secara opsional,make installcheck
, untuk memastikan instalasi bekerja.
Selama make
, lib dan shared executable yang dikompilasi dalam bentuk akhir mereka: executable dikompilasi dengan ketergantungan pada lib yang dibagikan di tujuan akhir mereka (yaitu, mereka bergantung pada perpustakaan di /usr/local/lib
meskipun mereka belum ada di sana, mereka masih dalam pembuatan pohon). Kemudian make install
, kira-kira, hanya menggunakan cp
untuk menginstal lib dan executables dari build tree ke tempat terakhir.
Selama make check
fase ini, kami menjalankan program yang dihapus: libs yang dibagikan, file yang dapat dieksekusi, dan file tambahan masih dalam struktur pohon. Untuk menjalankan tes, Anda harus menyiapkan beberapa variabel lingkungan kustom (misalnya untuk memberi tahu program Anda bahwa file data tambahan Anda tidak ada dalam /usr/local/share
tetapi di pohon sumber), dan beberapa variabel lingkungan sistem, untuk memberitahu lib loader Anda agar terlihat untuk lib yang dibagikan. Variabel lingkungan pada Unices tradisional adalah LD_LIBRARY_PATH
, pada OS X itu DYLD_LIBRARY_PATH
. Ini telah bekerja selama (puluhan) tahun.
Tapi sekarang, El Capitan memecahkan ini.
$ (export FOO=foo; env) | grep foo
FOO=foo
$ (export DYLDFOO=foo; env) | grep foo
DYLDFOO=foo
$ (export DYLD_FOO=foo; env) | grep foo
$
sekarang, ketika SIP diaktifkan, tidak ada DYLD_*
yang diekspor dari suatu proses ke anak-anaknya.
Jadi pertanyaan saya adalah: Bagaimana kita bisa menjalankan program yang tidak diinstal? Bagaimana prosedur yang harus diikuti untuk dapat menjalankan urutan Unix tradisional ./configure && make && make check
?
Tolong , tidak ada jawaban seperti "jalankan make install
dulu". Itu bukan intinya. Saya seorang pengembang, dan menjalankan "make check" (dan lebih umum menjalankan versi program yang tidak diinstal) adalah sesuatu yang sangat sering saya lakukan. Bahkan menginstal ke tempat boneka adalah memakan waktu. Saya butuh sesuatu yang efektif, dan efisien. Dan menonaktifkan SIP tidak akan memperbaiki masalah bagi pengguna paket saya yang ingin menjalankan make check
.
DYLD_INSERT_LIBRARIES=$HOME/.bin/lib/Apple80211 /Applications/Utilities/AirPort\ Utility\ 5.6.app/Contents/MacOS/AirPort\ Utility\ 5.6
untuk menjalankan APU lama (dengan perpustakaan lama) di bawah 10.11 (meskipun variabel tidak muncul dienv
). Aneh (tapi berhasil).Jawaban:
Sepertinya DYLD_ * hanya akan dihapus untuk binari "terlindungi" (Saya tidak yakin persis apa artinya, tetapi tampaknya apa pun di / bin dan / usr / bin sebagai permulaan) Namun, jika Anda menyalin / usr / bin / env ke tempat lain, ia bisa menyimpan barang-barang DYLD_ * nya:
Saya pikir make selalu menjalankan perintah melalui / bin / sh, jadi Anda tidak bisa mengatur variabel "berbahaya" di makefile dan membuatnya memengaruhi perintah, tapi mungkin Anda bisa memindahkan tes ke skrip shell, mengatur variabel lingkungan di dalam skrip, lalu aktifkan skrip dari make. Meskipun jelas, ini tidak akan membantu Anda jika tes, pada gilirannya, bergantung pada skrip shell (atau jika hal-hal yang diuji adalah skrip shell!) Karena dengan begitu mereka akan memanggil / bin / sh dan kehilangan variabel lagi .. .
sumber
cp
/bin/sh
, dan menggunakan shell itu daripada yang asli. Symlink tidak akan berfungsi, dan tautan keras adalah "Operasi tidak diizinkan", jadi saya rasa saya harus hidup dengannyacp
.