4

I am trying to use the CMake function FIXUP_BUNDLE to fix up an application bundle, but am getting install-time warnings and for lack of better terminology, not a fixed-up bundle.

The installed bundle has the right structure, but the frameworks it uses aren't correctly copied in. Only each framework's directory structure is copied in and not the actual shared library binary. For example, my bundle uses SFML 2.0's System framework. Note that all SFML frameworks I use are stored in /Library/Frameworks. Here is what I get in MyApp.app/Contents/Frameworks/ with respect to this SFML component:

sfml-system.framework/
    Versions/
        2.0.0/

And that's all I get, just the directories. The actual SFML System framework has a structure like this:

sfml-system.framework/
    Resources  (this is a symlink)
    sfml-system  (this is a symlink)
    Versions/
        2.0.0/
            Resources/
                Info.plist
            sfml-system  (this is the actual library binary)
        Current  (this is a symlink)

In my project, executables all have the same format so I have a small function to add them using this common format. The function just adds the executable, sets the libraries to link against, and at install time, installs the application bundle and calls FIXUP_BUNDLE on it. Here is that function:

FUNCTION(ADD_CUSTOM_EXECUTABLE TARGET HEADERS SOURCES DEPENDENCIES)
    ADD_EXECUTABLE(${TARGET} MACOSX_BUNDLE ${HEADERS} ${SOURCES} ${ARGN})
    TARGET_LINK_LIBRARIES(${TARGET} ${DEPENDENCIES})

    INSTALL(TARGETS ${TARGET} BUNDLE DESTINATION .)

    INSTALL(CODE "
        INCLUDE(BundleUtilities)
        FIXUP_BUNDLE(${CMAKE_INSTALL_PREFIX}/${TARGET}.app \"\" \"\") 
    ")
ENDFUNCTION(ADD_CUSTOM_EXECUTABLE)

I don't pass in anything for the LIBS or DIRS parameters of FIXUP_BUNDLE because I am currently not using any plugins. The ALL_BUILD project builds fine in Xcode, and the install project runs without failing, but produces many warnings like this for each library discovered via otool -L. Here's an example showing the start of the warnings for SFML's System framework, almost immediately after FIXUP_BUNDLE is called:

fixup_bundle
    app='/Users/user/Desktop/SFML_Testing_BUILD/dist/MyApp.app'
    libs=''
    dirs=''
fixup_bundle: preparing...
warning: embedded item does not exist 'Users/user/Desktop/SFML_Testing_BUILD/
dist/MyApp.app/Contents/Frameworks/sfml-system.framework/Versions/2.0.0/
sfml-system'
warning: cannot resolve item '@executable_path/../Frameworks/
sfml-system.framework/Versions/2.0.0/sfml-system'

possible problems:
    need more directories?
    need to use InstallRequiredSystemLibraries?
    run in install tree instead of build tree?

And a short bit later, stuff like this:

warning: target '@executable_path/../Frameworks/sfml-system.framework/Versions/
2.0.0/sfml-system' is not absolute...
warning: target '@executable_path/../Frameworks/sfml-system.framework/Versions/
2.0.0/sfml-system' does not exist...
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/
usr/bin/otool: can't open file: @executable_path/../Frameworks/
sfml-system.framework/Versions/2.0.0/sfml-system (No such file or directory)
otool: can't open file: @executable_path/../Frameworks/
sfml-system.framework/Versions/2.0.0/sfml-system
(No such file or directory)

Does anyone know how to resolve this issue? I scoured the internet for a solution, but had no luck.

4

1 に答える 1

2

取り込もうとしているフレームワークが「/Library/Frameworks」にある場合は、実際に取り込む必要のない「システム ライブラリ」であると見なされます...システム ライブラリ (自分で構築したものではなく) を使用すると、エンド ユーザーにも同じシステム ライブラリがインストールされます。(アプリをインストールする前に、SFML をインストールするように要求する必要があります。)

これは、法的に含めることが想定されていないシステム フレームワークを誤ってバンドルに含めることを思いとどまらせるために、意図的に行われます。SFML フレームワークをバンドルすることが合法かどうかは、厳密にあなたの負担です。

あなたの場合、この仮定が間違っていて、SFML を「非システム」と見なしたい場合は、BundleUtilities をカスタマイズして処理する必要があるかもしれません。

ただし、最初にこれを試す方が簡単です: 最初にそれらをビルド ツリー バンドルにコピーするスクリプトを作成し、次にバンドルをインストールして、次のカスタム オーバーライドを試みる前に fixup_bundle が動作するかどうかを確認します。

必要に応じて、次のようにカスタマイズできます。

まず、インライン コードを含む install(CODE スニペットを、構成/生成されたスクリプト ファイルを呼び出す install(SCRIPT 呼び出しに変更します。そうしないと、そのブロックに入れるコードが多すぎて、すべてのエスケープが厄介になります。

次に、スクリプトに BundleUtilities を含める前に、GetPrerequisites gp_resolved_file_type 関数のオーバーライド関数を追加します。これは、ライブラリが「システム」ライブラリであるかどうかを宣言するために BundleUtilities が使用するものです。BundleUtilities が必要とするすべてのファイル タイプの解決に対して、gp_resolved_file_type_override という名前のオーバーライド関数が呼び出されます。ライブラリ名を文字列「sfml」に単純に一致させるように記述できる場合があります。一致する場合は、タイプを「other」と宣言すると、宣言が勝ちます。

その後、上記の警告の一部は解消されますが、さらにカスタマイズが必要な他の問題が発生する可能性があります。

少し厄介で複雑ですが、既存の CMake で実行できるはずです...

でも:

BundleUtilities がシステム ライブラリに何かを取り込むという事実は誤りであり、CMake バグ トラッカーでバグとして報告する必要があります: http://www.cmake.org/Bug

于 2012-11-08T15:35:40.260 に答える