Fakeroot、Xcode、およびPackageMaker

Xcodeと組み合わせてMacで使用するためにfakerootを適合させた経験を共有したいと思います。 Fakerootは、スーパーユーザーセッションをエミュレートする特別な環境でプログラムを実行します。 PackageMakerを使用してインストーラーをビルドする場合、ルート権限が必要になる場合があります。



歴史的に、Mac OS Xを含むUNIXライクなシステムでは、ソフトウェアの配布に対して特定のアプローチがあります。 パッケージの中心にあるのは、deb、rpm、またはpakosovy pkgのいずれであっても、ターゲットファイルシステムに直接展開されるアーカイブです。 たとえば、パッケージlitware.pkgが/ usr / local / binフォルダーに展開され、アーカイブにアクセスマスク0755と所有者/グループroot:wheelで実行される実行可能ファイルが含まれている場合、プログラム/ usr / local / bin / litがシステムに表示されます(マスクアクセス0755、所有者/グループルート:wheel、つまりアーカイブ内と同じ)。



パッケージは特別なユーティリティを使用して作成されます(Mac OS Xではコンソールパッケージメーカーです )。 ユーティリティは、起動時に指定されたフォルダーの内容をパッケージに入れます。 フォルダーの内容は、パッケージにそのまま含まれています。 特に、正しいlitware.pkgを作成するには、litファイルをroot:wheelの所有者にする必要があります。 残念ながら、この操作を成功させるにはスーパーユーザーの権利が必要です。



Linuxでは、この問題はfakerootで回避されます。 実際、プログラムは現在のユーザーに代わって実行されますが、多くのシステムコールをインターセプトすることにより、rootとして動作しているように見えます。 たとえば、chownとstatは傍受されます。 Chownはファイルのowner:グループを正常に変更し、ファイルシステム上のこれらのフィールド(実際のルートが必要)を実際に変更する代わりに、偽造デーモンは情報を記憶します。 インターセプトされたstatは、以前のchown呼び出しに関する保存情報に基づいて、ファイルシステムから受信したファイルパラメーターを静かに変更します。



フェイクルートミニ



Fakerootは、バージョン10.7までのMacOS Xをサポートしています。 残念ながら、fakerootはMac OS Xのポピュラーなポートマネージャー( MacPortsFink )の両方から欠落しています。 正常に動作させるには、インストールが必要です。 さらに、fakerootを必要とするすべてのスクリプトを1つのfakerootセッションに結合する方法がないため、従来のfakerootはXcodeと併用すると不便です。 異なるfakerootセッションは完全に独立しています。あるセッションで行われた変更は、別のセッションでは見えません。



fakerootコードに基づいて、次の主要機能を備えたfakeroot-miniの修正バージョンを作成しました。

  1. インストールは必要ありません。 唯一の動的ライブラリが配布されます。 このライブラリはリポジトリに直接配置でき、プロジェクトをビルドするために追加のソフトウェアをインストールする必要がなくなります。
  2. 拡張ファイルシステム属性に情報を保存します。 このソリューションは、独立したfakerootセッションの問題を修正します。


動作原理は変更されていません-システムコールをインターセプトする動的ライブラリが、起動されるプログラムに実装されています。 プロセスでのライブラリの実装は、ダイナミックローダーの通常の機能であり、環境変数DYLD_INSERT_LIBRARIESを使用してアクティブ化されます。



/usr/bin/env DYLD_INSERT_LIBRARIES=<-> command [args]
      
      







Xcodeデモプロジェクト



リンクからXcodeのデモプロジェクトをダウンロードできます。 プロジェクトは、シンプルなコンソールアプリケーションとインストーラーをビルドします。







プロジェクト設定:



 DEPLOYMENT_LOCATION=YES DEPLOYMENT_POSTPROCESSING=YES INSTALL_OWNER=root INSTALL_GROUP=wheel STRIP_INSTALLED_PRODUCT=NO CHOWN=$(SRCROOT)/chown LIBFAKER=$(SRCROOT)/libfakermini-1.0.0.dylib PACKAGE=$(BUILT_PRODUCTS_DIR)/litware.pkg
      
      





DEPLOYMENT_LOCATION=YES



Xcodeはインストールパスに沿ってファイルをレイアウトします。 たとえば、litの場合、インストールパスは/ usr / local / bin / litです。 DEPLOYMENT_LOCATION設定を有効にすると、Xcodeはパス$(DSTROOT)/ usr / local / bin / litに沿って点灯します。 $(DSTROOT)の値は構成可能です。デフォルトでは、/ tmp / <project-name> .dstです。 次のファイルツリーが一時フォルダーに構築されます。



 /tmp/litware.dst/ └── usr    ├── local    │   └── bin    │       └── lit    └── share        └── man            └── man1                └── lit.1
      
      





DEPLOYMENT_POSTPROCESSING=YES



は、$(DSTROOT)での追加のファイル処理が含まれます。 特に、$(INSTALL_OWNER)の所有者と$(INSTALL_GROUP)ファイルのグループが設定されます。



STRIP_INSTALLED_PRODUCT=NO



は、収集されたバイナリのデバッグ情報の削除を無効にします。 Xcodeのエラーにより、場合によってはプロジェクトを再構築するときに、ストリップが機能してすべてを削除した後にデバッグ情報がコピーされます。



CHOWN=$(SRCROOT)/chown



は、標準ユーティリティ/ usr / sbin / chownではなく、プロジェクトソースフォルダー内のスクリプトを使用するようXcodeに指示します。 このスクリプトは、fakeroot環境をセットアップし、標準chownを呼び出します。



LIBFAKER変数とPACKAGE変数は便宜上定義されており、Xcodeの動作の影響を受けません。



インストーラーは、次のスクリプトを使用して作成されます。



 /usr/bin/env "DYLD_INSERT_LIBRARIES=${LIBFAKER}" \    /usr/sbin/mtree -f "${SRCROOT}/mtree.spec" -p "${DSTROOT}" -U && \ rm -f "${PACKAGE}" && \ /usr/bin/env "DYLD_INSERT_LIBRARIES=${LIBFAKER}" \    /Developer/usr/bin/packagemaker --id org.example.litware \    --root "${DSTROOT}" --no-recommend --target 10.5 \    --out "${PACKAGE}"
      
      





まず、 mtreeを fakeroot環境で起動して、$(DSTROOT)内のフォルダーのアクセスマスクと所有者/グループを構成します。 Xcodeは$(DSTROOT)/ usr / local / bin / litのアクセスマスクと所有者/グループを設定しますが、中間フォルダー(例:$(DSTROOT)/ usr / local / bin)は処理されないため、これが必要です



不明な理由により、packagemakerはインストーラーの生成時に既存のファイルを上書きしません。 そのため、fakeroot環境でpackagemakerを実行する前に、既存のインストーラーファイルが存在する場合は、明示的に削除します。



おわりに



説明されているテクノロジーにより、最小限の設定で、追加のソフトウェアをインストールせずに、Xcodeで直接インストーラーを作成できます。 インストーラーの製造における多くのタスクには、スーパーユーザー権限が必要です。 Fakerootを使用すると、非特権ユーザーに対してこれらのタスクを正常に完了することができます。



この情報は、MacOSのシステムユーティリティとデーモンの開発者にとって有用です。 通常、カスタムアプリケーションのインストーラーは、fakerootなしでビルドできます。



参照資料
  1. Xcodeのデモプロジェクト
  2. オリジナルの偽ルート
  3. フェイクルートミニ
  4. Xcodeでxcconfigファイルを使用する
  5. Mac OS Xでのシステムコールのインターセプト





All Articles