ビルド システムとして CMake を使用する C++ プロジェクトがあります。次の動作を実現したいと考えています。
cmakeが として呼び出された場合cmake ..
、CMAKE_CXX_FLAGS
は-O3 -Wall -Wextra
cmakeが として呼び出された場合cmake .. -DCMAKE_BUILD_TYPE=Debug
、CMAKE_CXX_FLAGS
は-g -Wall -Wextra
私は次のことを試しました
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra")
しかし、これには大きな問題があります。まず、2 番目の呼び出しを使用すると、フラグ-O3
と-g
フラグの両方がコンパイラに渡されます。さらに、2 番目の呼び出しを使用し、その後に最初の呼び出しを使用すると、明示的に順序付けされていないにもかかわらず、CMAKE_BUILD_TYPE
が残りますDebug
。そのため、最適化されたビルドが必要なのに、デバッグ ビルドが取得されます。
なぜですか? 望ましい動作を得るにはどうすればいいですか?
ベストアンサー1
まず、CMake の推奨される使用方法は、常にCMAKE_BUILD_TYPE
コマンド ラインで明示的に指定することです (単一構成ジェネレーターを使用している場合のみ)。あなたのユース ケースはこのベスト プラクティスから外れているため、この回答を「実行方法」として扱い、「実行すべき方法」として扱う必要はありません。
最初の問題に対処するには、CMakeList の早い段階でこれを実行できるはずです。
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
これにより、ビルド タイプをまったく指定しない場合は、デフォルトで「リリース」が使用され、それがCMAKE_CXX_FLAGS_RELEASE
使用されるようになります。
2番目は対処が難しいです。コマンドラインから渡される変数(などCMAKE_BUILD_TYPE=Debug
)はキャッシュされたCMake によって実行され、後続の呼び出しで再利用されます (ビルド間で入力を変更すると CMake が自身を再トリガーする可能性があるため、これは必要です)。
唯一の解決策は、 を使用して、ユーザーがビルド タイプを再度明示的に切り替えるようにすることですcmake .. -DCMAKE_BUILD_TYPE=Release
。
なぜこれが必要なのか考えてみましょう。前述したように、CMake の入力 (CMakeLists.txt
ファイルまたはその依存関係) が前回の CMake の実行以降に変更された場合、CMake はビルドの一部として自身を再トリガーできます。このような場合、 などのコマンドライン引数なしでも実行され-DCMAKE_BUILD_TYPE=whatever
、前回と同じ値を提供するためにキャッシュに依存します。このシナリオは、追加の引数なしで手動で実行した場合と区別がつきませんcmake ..
。
CMAKE_BUILD_TYPE
コマンドラインで明示的に指定されていない場合は常にリセットするというハッキーな解決策を提供することもできます。ただし、これは、次のように生成されたビルドシステムが次のように再生成されることRelease
も意味します。Debug
Release
自動再生成が起こった場合。それはあなたが望んでいることではないと確信しています。