CMakeで警告レベルを設定する方法は?


116

どのように設定して警告レベルのためのプロジェクト使用して(全体ではなくソリューション)CMakeのをVisual StudioGCCで動作するはずです。

さまざまなオプションを見つけましたが、ほとんどが機能していないか、ドキュメントと一致していません。

回答:


96

更新:この回答は、モダンCMake時代以前のものです。すべての健全なCMakeユーザーは、CMAKE_CXX_FLAGS直接いじるのを控え、target_compile_options代わりにコマンドを呼び出す必要があります。推奨されるベストプラクティスを示すmrtsの回答を確認してください。

あなたはこれに似た何かをすることができます:

if(MSVC)
  # Force to always compile with W4
  if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
  endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
  # Update if necessary
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()

Visual Studioの新しいバージョン(少なくとも2013)が/Wallフラグ(という名前EnableAllWarnings)をサポートしていることに注意してください。よりも多くの警告が生成されます/W4。しかし、私の経験から、それはあまりにも多くの警告を出します。
Adam Badura 2016年

12
/Wallclangと同じように、警告に対して「減算」戦略を実行したい場合に使用できます-Weverything。有効にする警告を選択する代わりに、すべてを有効にしてから、無効にする特定の警告を選択します。
bames53 2016

86

最近のCMakeでは、以下がうまく機能します:

if(MSVC)
  target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
  target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()

私の同僚は別のバージョンを提案しました:

target_compile_options(${TARGET_NAME} PRIVATE
  $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)

${TARGET_NAME}実際のターゲット名に置き換えます。-Werrorオプションで、すべての警告をエラーに変えます。

またはadd_compile_options(...)、コメントの@aldoで提案されているように、すべてのターゲットに適用する場合に使用します。

また、違いを理解してくださいPRIVATEとのPUBLIC(公共のオプションが指定されたターゲットに依存ターゲットによって継承されます)。


19
または単にadd_compile_options(...)すべてのターゲットに適用したい場合。
アルド

1
FYIモダンCMakeでは、else()またはで条件を繰り返す必要はありませんendif()
Timmmm 2019

1
@Timmmm頭を上げてくれてありがとう!単なるメモですか、それとも条件を削除しますか?
mrts

1
@helmesjoいいえ、Timmmmは、4月9日の編集前に存在していたCMakeコードを参照していました。編集履歴を見て、削除されたビットを確認できます。これは、Timmmmが指摘していたものと同じです。
FeRD

2
@aldo問題add_compile_options()は、警告がを介して追加されたターゲットに伝播することadd_subdirectory()です。この方法で外部ライブラリを含める場合、そのライブラリが異なる警告レベルで設計されていると、多くの警告が表示される可能性があります。
trozen

24

私が書いたいくつかのCMakeモジュールには、実験的なクロスプラットフォームの警告抑制が含まれています。

sugar_generate_warning_flags(
    target_compile_options
    target_properties
    ENABLE conversion
    TREAT_AS_ERRORS ALL
)

set_target_properties(
    foo
    PROPERTIES
    ${target_properties}
    COMPILE_OPTIONS
    "${target_compile_options}"
)

Xcodeの結果:

  • CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSIONXcode属性を設定します(別名ビルド設定 -> 警告 -> 疑わしい暗黙の変換 -> YES
  • コンパイラフラグを追加します。 -Werror

Makefile gccおよびclang:

  • コンパイラフラグを追加:-Wconversion-Werror

ビジュアルスタジオ:

  • コンパイラフラグを追加:/WX/w14244

リンク集


1
cmakeがこの機能を提供しないのは残念です
スラバ

3
朗報です。cmakeメーリングリストではなく、ここに投稿して申し訳ありませんが、レベルがないと、これは役に立たないでしょう。警告をすべて明示的にリストするには、警告が多すぎます。それを1つの方法で統一したい場合は、2つの別個のcmake_levelです。たとえば、clangに基づく警告の統一されたセットと、コンパイラ固有の意味を持つnative_levelです。それらの1つは、おそらくレベルまで短縮できます。私が実際に会話をフォローせず、何か問題があった場合は申し訳ありません
スラバ

1
@ void.pointerは有効なポイントを発生させます。あなたの提案の答えを読み取ります:私はこの機能を追加する計画します」。あなたがおおざっぱな研究をして、今では誰かがあなたのために重い仕事をしてくれることを望んでいるとは言いません。実装(およびその進行状況に関する質問)に起因することを望まない場合は、回答を編集して、1年以上経過していない進捗状況から自分を切り離す必要があります。
IInspectable 2017

「1年以上経っても、まだ進歩はない。」-これ有効なポイントです。年以上はして、合格したゼロ進行。それは放棄されたプロジェクトの非常に強力な兆候です。私たちが間違っていることを証明したい場合は、いくつかの進歩を見せてください。それは起こっていませんが、提案された答えはまだ機能がCMakeに追加されようとしていることを示唆しています。数年後には利用できなくなる機能について、すべての大騒ぎをするのはなぜですか?それはまったく役に立ちません。進行状況を表示するか、誤解を招かないように回答を編集してください。
IInspectable 2017

5
あなたは理解していないようです。機能を実装することを提案した場合は、その機能を適時に実装する必要があります。それに失敗すると、提案された回答からその約束を削除するよう求められます。あなたはこの機能を実装するためのコミットメントをゼロに示したので、他に主張しないでください。大きいと思います。また、これを実現できない場合があることも理解しています。私は単にあなたの答えにそれを反映させるように求めています。
IInspectable 2017

6

これが私がこれまでに見つけた最良のソリューションです(コンパイラチェックを含む)。

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()

これにより、Visual Studioで警告レベル2が設定されます。私は-W2それがGCCでも機能するだろうと推測しています(テストされていません)。

@Williamsからの更新:-WallGCC向けのはずです。


6
GCCのための警告フラグは以下のようになり-Wall、多分と-Wextraで説明するようgcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Milliams

1
私が使用するリストは-W -Wall -Wextra -pedanticです。-WextraIIRC -WはGCCの新しいバージョンで置き換えられましたが、互換性のために両方とも残します。
Jimmio92、2016

2
これは、add_definitionsの本来の目的ではありません(「プリプロセッサ定義を追加することを目的としています」)。これは、単なるベストプラクティスの推奨事項ではありません。このコマンドに渡された引数は、それらを予期しないツール(リソースコンパイラなど)を呼び出す生成されたビルドスクリプトに表示されます。
IInspectable 2018年

これは「コンパイラチェック」ではなく、ビルドツールチェックです。
トーマス

3

あたりとしてcmakeの3.17.1ドキュメント

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

GCCとClangはこれらのフラグを共有しているため、3つすべてをカバーする必要があります。


これは使わないでください。代わりに、target_compile_options()を使用してください。最新のドキュメントを参照することは「正しい」ように見えますが、これは下位互換性のための古代のエントリです。
caoanan

1
@caoananドキュメントでは、これに対する下位互換性については何も言及されていません。add_compile_optionsディレクトリ全体target_compile_optionsですが、1つのターゲットのみです。
TehWan

2
if(MSVC)
    string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

target_compile_options- を使用すると、cmakeは二重/W*フラグを使用しようとします。これにより、コンパイラによって警告が表示されます。


これをありがとう。私は単純に、で上書きされるadd_compile_options大量の警告を取得するためにのみ使用/W3していました/W4。CMakeがこの基本的なオプション(警告レベルの設定)に対処していないという事実は、信じられないほどです。
復活
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.