web-dev-qa-db-ja.com

CMake_BUILD_TYPEはCMakeLists.txtで使用されていません

デフォルトのビルド構成をリリースに設定するのに問題があります。 CMakeLists.txtファイルで、ファイルの上部にCMAKE_BUILD_TYPEを設定します。

#enable Release ALWAYS, configure vars
set(CMAKE_BUILD_TYPE Release)
set(EXECUTABLE_NAME "ParticleSimulator")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)

しかし、プロジェクトをビルドしてソリューションを開くと、CMakeListsファイルで指定したものとは反対に、常にデバッグモードが表示されます。私は何を間違えていますか?

私はそこにある他の質問のいくつかを見ましたが、この質問に特有のことは何も見ませんでした。

CMakeLists.txt の要点。

53

ジェネレータには、シングル構成とマルチ構成の2種類があります。

単一構成

Make-likeジェネレーター: nix MakefilesNMake MakefilesMinGW Makefiles 、...

生成ステップで構成タイプを設定します。

cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"

この場合、ビルドステップはalwaysDebug

> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...

マルチ構成

IDEジェネレーター: Visual StudioXcode

生成ステップのCMAKE_BUILD_TYPEは無視されます。両方とも:

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"

そして

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"

同じ効果があります:

Enter image description here

これは、すべての構成が内部であるためです(つまり、_builds/msvc-opaque/Releaseおよび_builds/msvc-opaque/Debugなどが重要ではありません)。 --configオプションを使用して切り替えることができます:

> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...

コントロール (?)

はい、できます。定義するだけ CMAKE_CONFIGURATION_TYPES

# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

デフォルト出力:

-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done

書き直してください:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done

Enter image description here

独自の構成タイプを定義することもできます。

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"

Enter image description here

そしてビルド:

cmake --build _builds --config MyRelease

乱雑(?)

あなたがトリックを知っている場合はまったくありません:)これは、スクリプト/ CIサーバー/ドキュメントのビルド指示などで構成をビルド/テストする方法です:

> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile

悪いパターン

if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...

良いもの

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")

いいですね。

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")

ありがとうございました! :) 1人のプログラマーのために1日節約できます。

Makefileで動作します、うれしいです...

ナイスガイ の素敵な本からのいくつかの引用は、おそらくあなたが知っている(強調鉱山):

なぜ気にする必要がありますか?さまざまなシステムでプログラミングしたり、さまざまなコンパイラを使用したりする人々は、そうしないと不明瞭なバグを見つけて修正することを余儀なくされるため無駄な時間を強いられます。彼らが移植性を気にしないと主張する人々は、単一のシステムのみを使用し、「言語は私のコンパイラが実装するものである」という態度に余裕があると感じているため、通常そうします。これは、narrowおよびshortsightedビューです。プログラムが成功した場合、移植される可能性が高いため、実装依存機能に関連する問題を誰かが見つけて修正する必要があります。さらに、プログラムは同じシステムの他のコンパイラーでコンパイルする必要がある場合が多く、お気に入りのコンパイラーの将来のリリースでさえ、現在のものとは異なることを行う場合があります。後で混乱を解こうとするよりも、プログラムの作成時に実装の依存関係の影響を把握して制限する方がはるかに簡単です。

154
user2288008

発生する可能性の1つは、サブモジュールの1つがCMAKE_BUILD_TYPEキャッシュ内の値、つまり:

SET(CMAKE_BUILD_TYPE Debug CACHE) 

つまり、その値はその時点から構成実行の終わりまで永久に更新されます。

この値が変更された問題の場所を追跡する1つの素晴らしい方法は、 CMakeのvariable_watch を使用することです。メインCMakelists.txtファイル、次の行を追加します

variable_watch(CMAKE_BUILD_TYPE)

これにより、この変数にアクセスするたびに標準エラーに出力されます。そして、ファイルをログに記録するには、次のようにします:

cmake <your options> 2>variable_watch.log

次のようなものが表示される場合があります。

<...>/CMakeLists.txt:184(add_library)のCMakeデバッグログ:変数「CMAKE_BUILD_TYPE」は、値「Debug」でREAD_ACCESSを使用してアクセスされました。

その後、CMAKE_BUILD_TYPEが最初に変更されたポイントが表示される可能性があります。そして、ここから問題のあるCMakeラインをトレースするのにずっと近くなります。

1
Daniel Heilper