CMakeを使用してプロジェクト(ソリューション全体ではない)の警告レベルを設定するにはどうすればよいですか?VisualStudioとGCCで動作するはずです。
さまざまなオプションを見つけましたが、ほとんどが機能しないか、ドキュメントと一致していないようです。
CMakeを使用してプロジェクト(ソリューション全体ではない)の警告レベルを設定するにはどうすればよいですか?VisualStudioとGCCで動作するはずです。
さまざまなオプションを見つけましたが、ほとんどが機能しないか、ドキュメントと一致していないようです。
最新のCMakeでは、以下が適切に機能します。
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
私の同僚は別のバージョンを提案しました:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
)
${TARGET_NAME}
実際のターゲット名に置き換えます。-Werror
オプションで、すべての警告をエラーに変えます。
またはadd_compile_options(...)
、コメントで@aldoによって提案されているように、すべてのターゲットに適用する場合に使用します。
また、との違いを必ず理解してPRIVATE
くださいPUBLIC
(パブリックオプションは、指定されたターゲットに依存するターゲットに継承されます)。
更新:この回答は、現代のCMake時代よりも前のものです。すべての正気なCMakeユーザーは、直接いじるのを控え、代わりにコマンドCMAKE_CXX_FLAGS
を呼び出す必要があります。推奨されるベストプラクティスを示すmrtsの回答target_compile_options
を確認してください。
あなたはこれに似た何かをすることができます:
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()
私が書いたいくつかの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_CONVERSION
ます(別名ビルド設定->警告->疑わしい暗黙の変換-> YES)-Werror
Makefile gccおよびclang:
-Wconversion
、-Werror
Visual Studio:
/WX
、/w14244
Cmake 3.23のドキュメントによると:
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つすべてをカバーする必要があります。
これが私がこれまでに見つけた最良の解決策です(コンパイラチェックを含む):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
GCCに相当するものは-Wall
(テストされていません)です。
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
target_compile_options
--cmakeを使用すると、doubleフラグを使用しようとします。/W*
これにより、コンパイラによって警告が表示されます。
CMakeを使用してプロジェクト(ソリューション全体ではない)の警告レベルを設定するにはどうすればよいですか?
(これは、CMakeプロジェクトではなく、 CMakeターゲットを意味すると思います。)
さまざまなオプションを見つけましたが、ほとんどが機能しないか、ドキュメントと一致していないようです。
KitwareのAPIは、ビルドシステムを脆弱でエラーが発生しやすいものにすることを思いとどまらせようとしている可能性があります。この質問に対する他の回答によって奨励された特別なケーシングは、最新のCMakeビルドシステムの少なくとも2つの重要な原則に違反しています...
まず、CMakeLists.txtファイルでツールチェーン固有の詳細を指定しないことをお勧めします。ビルドシステムがもろくなります。たとえば、ツールチェーンの将来のバージョンで新しい警告が表示された場合、コンパイラはエラーを発行し、ユーザーはターゲットをビルドするためにプロジェクトをハックする必要がある場合があります。
代わりに、ツールチェーンに依存しないCMakeLists.txtファイルを作成し、ユーザーが適切と思われるようにカスタマイズできるようにします。理想的には、プロジェクトはバニラツールチェーン構成でどこにでも構築する必要があります-それがデフォルトで優先警告を有効にしない場合でも。
次に、バイナリをリンクする場合は、フラグに一貫性を持たせる必要があります。これにより、プログラムの形式が正しくなくなる可能性のある非互換性のリスクが軽減されます。ただし、警告フラグがコード生成に影響を与える可能性は低いため、リンクするターゲット間で警告フラグを変更しても安全な場合があります。
したがって...ツールチェーンごとにフラグを指定する必要があり、ターゲットごとに異なるフラグが絶対に必要な場合は、カスタム変数を使用します。
# CMakeLists.txt
project(my_project)
add_executable(my_target source_file.cpp)
target_compile_options(my_target PRIVATE "${MY_PROJECT_ELEVATED_WARNING_FLAGS}")
これらの変数を設定するには、CMakeCache.txt、ツールチェーンファイル、およびを介して多くの方法がありますCMAKE_PROJECT_INCLUDE_BEFORE
。ただし、最も簡単な方法は、GCCの場合、構成中にコマンドラインを使用することです。
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="-Wall;-Wextra;-Wpedantic;-Werror" <path-to-project>
MSVCの場合
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="/W4;/WX" <path-to-project>