98

Xcode を使用せずに osX アプリを作成したとします。GCC でコンパイルした後、他のいくつかのライブラリにリンクされている実行可能ファイルを取得します。これらのライブラリの一部は、他の非標準システム ライブラリに再び動的にリンクされる可能性があります。

最初に必要なディレクトリ構造を作成し、次にリンクを再帰的にコピー/チェック/修正して、すべての動的依存関係がアプリバンドルにも含まれていることを確認することにより、OSX アプリバンドルを作成するツールはありますか?

私はこのようなものを書いてみることができると思いますが、このようなものがすでに存在するのだろうかと思っていました.

4

7 に答える 7

155

MacOSX でアプリ バンドルを作成するには、Easy と Ugly の 2 つの方法があります。

簡単な方法は、XCode を使用することです。終わり。

問題は、できない場合があることです。

私の場合、他のアプリを構築するアプリを構築しています。ユーザーが XCode をインストールしているとは思えません。また、 MacPortsを使用して、アプリが依存するライブラリを構築しています。アプリを配布する前に、これらの dylib がアプリにバンドルされていることを確認する必要があります。

免責事項:私はこの投稿を書く資格がまったくありません。記載されている内容はすべて、既存のアプリを分解して試行錯誤しながら Apple のドキュメントから集めたものです。それは私にとってはうまくいきますが、おそらく間違っています。訂正等ありましたらメールください。

最初に知っておくべきことは、アプリ バンドルは単なるディレクトリであることです。
架空の foo.app の構造を調べてみましょう。

foo.app/
    コンテンツ/
        Info.plist
        マックOS/
            ふー
        資力/
            foo.icns

Info.plist はプレーンな XML ファイルです。テキスト エディターまたは XCode にバンドルされているプロパティ リスト エディター アプリで編集できます。(/Developer/Applications/Utilities/ ディレクトリにあります)。

含める必要がある主なものは次のとおりです。

CFBundleName - アプリの名前。

CFBundleIcon - Contents/Resources ディレクトリにあると想定されるアイコン ファイル。Icon Composer アプリを使用してアイコンを作成します。(/Developer/Applications/Utilities/ ディレクトリにもあります) png をそのウィンドウにドラッグ アンド ドロップするだけで、ミップ レベルが自動的に生成されます。

CFBundleExecutable - Contents/MacOS/ サブフォルダーにあると想定される実行可能ファイルの名前。

他にもたくさんのオプションがありますが、上に挙げたものは最低限のものです。Info.plist ファイルと アプリ バンドル構造に関する Apple のドキュメントを次に示し ます。

また、Info.plist のサンプルを次に示します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist バージョン="1.0">
<辞書>
  <key>CFBundleGetInfoString</key>
  <string>ふー</string>
  <key>CFBundleExecutable</key>
  <string>フー</string>
  <key>CFBundleIdentifier</key>
  <string>com.your-company-name.www</string>
  <key>CFBundleName</key>
  <string>フー</string>
  <key>CFBundleIconFile</key>
  <string>foo.icns</string>
  <key>CFBundleShortVersionString</key>
  <string>0.01</string>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundlePackageType</key>
  <string>APPL</string>
  <key>IFMajorVersion</key>
  <整数>0</整数>
  <key>IFMinorVersion</key>
  <整数>1</整数>
</dict>
</plist>

完璧な世界では、実行可能ファイルを Contents/MacOS/ ディレクトリにドロップするだけで完了です。ただし、アプリに非標準の dylib 依存関係がある場合、アプリは機能しません。Windows と同様に、MacOS には独自の特別な種類のDLL Hellが付属しています。

リンク先のライブラリをビルドするためにMacPortsを 使用している場合、dylib の場所が実行可能ファイルにハードコードされます。まったく同じ場所に dylib があるマシンでアプリを実行すると、正常に実行されます。ただし、ほとんどのユーザーはそれらをインストールしていません。アプリをダブルクリックすると、クラッシュするだけです。

実行可能ファイルを配布する前に、読み込まれるすべての dylib を収集し、それらをアプリ バンドルにコピーする必要があります。また、実行可能ファイルを編集して、dylib が正しい場所で検索されるようにする必要があります。つまり、それらをコピーした場所です。

実行可能ファイルを手動で編集するのは危険に聞こえますよね? 幸いなことに、役立つコマンド ライン ツールがあります。

otool -L 実行可能ファイル名

このコマンドは、アプリが依存するすべての dylib を一覧表示します。System/Library または usr/lib フォルダーにないものがある場合は、それらをアプリ バンドルにコピーする必要があります。それらを /Contents/MacOS/ フォルダーにコピーします。次に、実行可能ファイルを編集して、新しい dylib を使用する必要があります。

まず、-headerpad_max_install_names フラグを使用してリンクしていることを確認する必要があります。これにより、新しい dylib パスが以前のものよりも長い場合に、そのためのスペースが確保されます。

次に、install_name_tool を使用して各 dylib パスを変更します。

install_name_tool -change existing_path_to_dylib @executable_path/blah.dylib executable_name

実際の例として、アプリがlibSDLを使用していて、otool がその場所を "/opt/local/lib/libSDL-1.2.0.dylib" としてリストしているとします。

最初にアプリ バンドルにコピーします。

cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/

次に、新しい場所を使用するように実行可能ファイルを編集します (注: -headerpad_max_install_names フラグを使用してビルドしたことを確認してください)。

install_name_tool -change /opt/local/lib/libSDL-1.2.0.dylib @executable_path/libSDL-1.2.0.dylib foo.app/Contents/MacOS/foo

ほら、もうすぐ完成です。現在の作業ディレクトリに小さな問題があります。

アプリを起動すると、現在のディレクトリは、アプリケーションが配置されている場所の上のディレクトリになります。例: foo.app を /Applcations フォルダーに配置すると、アプリを起動したときの現在のディレクトリは /Applications フォルダーになります。ご想像のとおり、/Applications/foo.app/Contents/MacOS/ ではありません。

これを考慮してアプリを変更するか、現在のディレクトリを変更してアプリを起動するこの魔法の小さなランチャー スクリプトを使用できます。

#!/ビン/バッシュ
CD「${0%/*}」
./フー

Info.plist ファイルを調整して、CFBundleExecutableが以前の実行可能ファイルではなく起動スクリプトを指すようにしてください。

わかりました、すべて完了しました。幸いなことに、これらすべてのことを理解したら、ビルド スクリプトに埋めてしまいます。

于 2010-07-14T23:15:50.940 に答える
20

私は実際に、いくらかの信用に値する非常に便利なツールを見つけました...いいえ-私はこれを開発しませんでした;)

https://github.com/auriamg/macdylibbundler/

すべての依存関係を解決し、実行可能ファイルと dylib ファイルを "修正" して、アプリ バンドルでスムーズに動作するようにします。

...依存する動的ライブラリの依存関係もチェックします:D

于 2011-02-19T20:25:13.250 に答える
10

これを Makefile で使用しています... アプリ バンドルを作成します。ここに含まれる PkgInfo および Info.plist ファイルとともに macosx/ フォルダーに png アイコンファイルが必要になるため、それを読んで理解してください...

「私のコンピューターで動作します」...これをマーベリックスの複数のアプリに使用しています...

APPNAME=MyApp
APPBUNDLE=$(APPNAME).app
APPBUNDLECONTENTS=$(APPBUNDLE)/Contents
APPBUNDLEEXE=$(APPBUNDLECONTENTS)/MacOS
APPBUNDLERESOURCES=$(APPBUNDLECONTENTS)/Resources
APPBUNDLEICON=$(APPBUNDLECONTENTS)/Resources
appbundle: macosx/$(APPNAME).icns
    rm -rf $(APPBUNDLE)
    mkdir $(APPBUNDLE)
    mkdir $(APPBUNDLE)/Contents
    mkdir $(APPBUNDLE)/Contents/MacOS
    mkdir $(APPBUNDLE)/Contents/Resources
    cp macosx/Info.plist $(APPBUNDLECONTENTS)/
    cp macosx/PkgInfo $(APPBUNDLECONTENTS)/
    cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/
    cp $(OUTFILE) $(APPBUNDLEEXE)/$(APPNAME)

macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
    rm -rf macosx/$(APPNAME).iconset
    mkdir macosx/$(APPNAME).iconset
    sips -z 16 16     macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16.png
    sips -z 32 32     macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16@2x.png
    sips -z 32 32     macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32.png
    sips -z 64 64     macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32@2x.png
    sips -z 128 128   macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128.png
    sips -z 256 256   macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128@2x.png
    sips -z 256 256   macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256.png
    sips -z 512 512   macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256@2x.png
    sips -z 512 512   macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_512x512.png
    cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png
    iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset
    rm -r macosx/$(APPNAME).iconset

Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>MyApp</string>
    <key>CFBundleGetInfoString</key>
    <string>0.48.2, Copyright 2013 my company</string>
    <key>CFBundleIconFile</key>
    <string>MyApp.icns</string>
    <key>CFBundleIdentifier</key>
    <string>com.mycompany.MyApp</string>
    <key>CFBundleDocumentTypes</key>
    <array>
    </array>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>0.48.2</string>
    <key>CFBundleSignature</key>
    <string>MyAp</string>
    <key>CFBundleVersion</key>
    <string>0.48.2</string>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright 2013 my company.</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.3</string>
</dict>
</plist>

パッケージ情報

APPLMyAp
于 2014-05-27T20:16:51.130 に答える
8

最も簡単な解決策は、何も変更せずに Xcode プロジェクトを作成し (つまり、Xcode が作成する単純な 1 ウィンドウのアプリを保持する)、それをビルドし、作成されたバンドルをコピーすることです。次に、コンテンツに合わせてファイル (特に Info.plist) を編集し、独自のバイナリを Contents/MacOS/ ディレクトリに配置します。

于 2010-03-10T15:34:38.513 に答える
3

Python ベースのアプリケーション用のpy2appなど、特定の環境用の依存ライブラリを使用してアプリ バンドルを構築するのに役立つオープン ソース ツールがいくつかあります。より一般的なものが見つからない場合は、おそらくニーズに合わせて調整できます。

于 2009-10-20T20:50:14.107 に答える