57

クロス コンパイルされたプロジェクトのソース ツリーに静的ライブラリを含めるのではなく、ブーストを直接 cmake に追加してビルドしたいと考えています。これは利用できますか?

4

2 に答える 2

45

私の職場でも、これにはかなり苦労しました。「最善の」方法を知っているとは断言できませんが、私の経験から次のような考えを述べることができます。

最初は、開発者にブーストを個別にインストールするように要求し、CMake にfind_package(Boost...)呼び出しの形で通常のチェックを行わせました。これは簡単でしたが、自動化されておらず、古いバージョンのブーストが既にインストールされている開発者に問題を引き起こしました。

次に方針を変更し、上記のプロジェクトの 1 つから複製したブースト ソースのコピーを追加しました。詳細は思い出せませんが、Ryppl プロジェクトで現在取り組んでいるものの前身だったと思います。主なポイントは、CMake が既にサポートされていることです。ブースト ライブラリは、呼び出しによって追加された実際の CMake ターゲットadd_libraryであり、CMake コードでの作業が容易になりました。

これは、プロジェクトでのブーストの使用を自動化することで以前の問題を解決しましたが、最終的にはメンテナンスの悪夢になりました. 私たちが複製したブースト プロジェクトは根本的に変更され、現在は Ryppl 固有の CMake 関数に大きく依存しています。Ryppl を依存関係として追加したくなかったので、方針を変更しました。

質問で言及されたプロジェクトを調べましたが、同様に使用できるものはありませんでした。

現在のセットアップでは、CMake のExternalProjectモジュールを利用しています。これにより、ビルド ツリーにブーストをダウンロードしてビルドすることができます。

利点:

  • 低メンテナンス
  • 自動化されているため、すべての開発者が同じフラグでビルドされた同じバージョンを使用します
  • 独自のソース ツリーをサードパーティ コードから解放
  • boost の複数のコピーは問題なく共存できます (したがって、別のコンパイラ/stdlib の組み合わせでビルドされたコピーに誤ってリンクする可能性はありません)。

短所

  • ビルド ツリーを削除すると、最初からブーストをダウンロードしてビルドする必要があります。これは、たとえば固定の場所 (たとえば、システムの一時ディレクトリ) にダウンロードすることで改善される可能性があるため、ブースト ソースの既存のコピーが見つかった場合、ダウンロード/解凍の手順をスキップできます。
  • ブースト ライブラリは適切な CMake ターゲットではありません (つまり、add_library呼び出しによって追加されていません) 。

CMake コードへのリンクは次のとおりです。これを改善する必要があるいくつかの方法がありますが、現在のところ十分に機能しています。

すぐにこの回答が時代遅れになり、まともなモジュール化された CMake 互換のソリューションが利用可能になることを願っています。

于 2013-08-21T12:46:00.127 に答える
5

上記の Fraser の回答は良い出発点であることがわかりましたが、システムで Boost 1.55.0 を使用するといくつかの問題に遭遇しました。

まず、アプリケーション用の自己完結型のソース コード パッケージが必要だったので、CMake ExternalProject を使用しないことを選択しました。Boost の thread および date_time ライブラリのみを使用していたため、bcp を使用して、ビルド ツール、スレッド、およびその他の依存ライブラリを備えた Boost のサブセットを作成しました。

$ bcp tools/build thread system date_time ../boost_1_55_0_threads_only

これをsvnリポジトリにチェックインしました。

次に、Fraser の CMake ファイルを Linux でのビルドに適合させることができましたが、bootstrap.batWindows で CMake の execute_process コマンドを使用してファイルを実行すると問題が発生しました。bootstrap.bat を実行するには、まず関連する Visual Studiovcvarsall.batスクリプトを実行して環境変数を設定する必要がありました (設定する必要がある個々の変数を特定することはできますが、スクリプト全体を実行する方が簡単でした)。execult_process を使用して同じシェルで 2 つの .bat ファイルを実行するために、引数としてa でcmd /c区切られたファイルを使用してリストしました。&

またbootstrap.bat、失敗した場合に終了コードをゼロ以外に設定しなかったため、execute_process RESULT_VARIABLE を使用して成功を確認しても機能しませんでした。代わりに、コマンドの実行後に b2.exe 実行可能ファイルが作成されたことを確認しました。

最後の 1 つの問題:オプションはbootstrap.shサポートされていますが、サポートされていません。また、Windowsではオプションを指定すると機能することもわかりましたが、Linux ではオプションを指定せずに使用すると、エラーが発生しました。(理由はまだわかりません)。--prefix=bootstrap.bat--prefixb2.exe--prefixb2bootstrap.sh

したがって、CMake ファイルの関連部分は次のようになります。

  #
  # run bootstrap
  #
  if(WIN32)
    if(MSVC10)
      set(VCVARS_CMD "C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 10.0\\VC\\vcvarsall.bat")
    elseif(MSVC11)
      set(VCVARS_CMD "C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 11.0\\VC\\vcvarsall.bat")
    elseif(MSVC12)
      set(VCVARS_CMD "C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat")
    # elseif(...)
     # add more options here
    endif(MSVC10)
    set(BOOTSTRAP_CMD "${VCVARS_CMD} & bootstrap.bat")
    message("Executing command: ${BOOTSTRAP_CMD}")
    execute_process(COMMAND cmd /c "${BOOTSTRAP_CMD}" WORKING_DIRECTORY ${APT_BOOST_SRC}
                  RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR)
    if(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
      message(FATAL_ERROR "Failed running cmd /c ${BOOTSTRAP_CMD} in ${APT_BOOST_SRC}:\n${BS_OUTPUT}\n${BS_ERROR}\n")
    else(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
      message("bootstrap output:\n${BS_OUTPUT}")
    endif(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
  else(WIN32)
    set(BOOTSTRAP_CMD "./bootstrap.sh")
    set(BOOTSTRAP_ARGS "--prefix=${APT_BOOST_BIN}")
    message("Executing command: ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS}")
    execute_process(COMMAND "${BOOTSTRAP_CMD}" ${BOOTSTRAP_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC}
                  RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR)
    if(NOT BS_RESULT EQUAL 0)
      message(FATAL_ERROR "Failed running ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS} in ${APT_BOOST_SRC}:\n${BS_OUTPUT}\n${BS_ERROR}\n")
    endif()
  endif(WIN32)
  #
  # run b2
  #
  set(B2_ARGS "link=static" "threading=multi" "runtime-link=static" "variant=release")
  foreach(COMP IN LISTS APT_BOOST_COMPONENTS)
    set(B2_ARGS "--with-${COMP}" ${B2_ARGS})
  endforeach(COMP IN LISTS APT_BOOST_COMPONENTS)
  if(WIN32)
    if(MSVC11)
      set(B2_ARGS "--toolset=msvc-11.0" ${B2_ARGS})
    elseif(MSVC12)
      set(B2_ARGS "--toolset=msvc-12.0" ${B2_ARGS})
    endif(MSVC11)
    file(TO_NATIVE_PATH ${APT_BOOST_BIN} APT_BOOST_BIN_WIN)
    set(B2_ARGS "--prefix=${APT_BOOST_BIN_WIN}" ${B2_ARGS} "architecture=x86" "address-model=64")
  endif(WIN32)
  set(B2_ARGS ${B2_ARGS} install)
  set(B2_CMD "./b2")
  message("Executing command: ${B2_CMD} ${B2_ARGS}")
  execute_process(COMMAND ${B2_CMD} ${B2_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC}
                  RESULT_VARIABLE B2_RESULT OUTPUT_VARIABLE B2_OUTPUT ERROR_VARIABLE B2_ERROR)
  if(NOT B2_RESULT EQUAL 0)
    message(FATAL_ERROR "Failed running ${B2_CMD} in ${APT_BOOST_SRC}:\n${B2_OUTPUT}\n${B2_ERROR}\n")
  endif()

上記APT_BOOST_SRCは、ソース ディレクトリ内の Boost サブディレクトリの場所です。APT_BOOST_BINは CMake ビルド ディレクトリにライブラリを格納するために使用する場所であり、使用してAPT_BOOST_COMPONENTSいる Boost ライブラリのリストです。

于 2014-07-28T19:42:06.687 に答える