web-dev-qa-db-ja.com

CMakeでBoostをビルドすることは可能ですか?

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

47
dzada

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

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

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

これにより、プロジェクトでブーストの使用を自動化することで以前の問題を解決しましたが、最終的にはメンテナンスの悪夢になりました。クローンを作成したブーストプロジェクトは根本的に変更され、Ryppl固有のCMake関数に大きく依存しています。 Rypplを依存関係として追加したくなかったため、再度タックを変更しました!

私たちはあなたの質問で言及したプロジェクトを見て、同様にそれらのどれも使用可能ではないと見つけました。

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

利点:

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

欠点

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

CMakeコード へのリンクです。このニーズを改善するにはいくつかの方法がありますが、現在のところ私たちにとっては十分に機能しています。

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

40
Fraser

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

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

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

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

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

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

最後の問題:bootstrap.sh--prefix=オプションをサポートしますが、bootstrap.batはサポートしません。また、Windowsで--prefixb2.exeオプションを指定することはできましたが、--prefixに指定せずに、Linuxでb2bootstrap.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ライブラリ。

5
user1735629