129

プロジェクトのコンパイルにグローバルなフラグ セットを使用したいと考えています。つまり、最上位の CMakeLists.txt ファイルで次のように指定しました。

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

ただし、サブディレクトリ内の特定のファイル (「foo.cpp」としましょう) については、コンパイル フラグを切り替えて -Weffc++ (変更できない商用ライブラリが含まれています) を適用しないようにしたいと考えています。-Wall のみを使用する状況を単純化するために、次のことを試しました。

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

、うまくいきませんでした。私も試しました

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

、どちらも機能しませんでした。

最後に、この定義を削除してみました:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

、これも機能しませんでした (つまり、商用ライブラリに関する多くのスタイル警告が表示されます)。(**注: 実行可能ファイルのビルド後に -Weffc++ ディレクティブを再インクルードしないと、警告は抑制されます。)

また、コンパイル フラグを一時的に削除しようとしました: http://www.cmake.org/pipermail/cmake/2007-June/014614.html 、しかしそれは役に立ちませんでした。

これに対するエレガントな解決策はありませんか?

4

3 に答える 3

144

上記の試みは、期待どおりに上書きするのではなく、ファイル/ターゲットにさらにフラグを追加しています。たとえば、ソース ファイルのプロパティのドキュメントから - COMPILE_FLAGS :

これらのフラグは、このソース ファイルのビルド時にコンパイル フラグのリストに追加されます。

-Weffc++次のようにして、 foo.cppのフラグを取り消すことができるはずです。

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

-Wno-effc++これは、コンパイラ コマンドにafterを追加する効果が-Weffc++あり、後者の設定が優先されます。完全なコマンドを表示し、これが実際に当てはまることを確認するには、次のようにします。

make VERBOSE=1

余談ですが、GNU C++ 標準ライブラリの管理者の 1 人が、この回答でかなり否定的な意見を示して-Weffc++ます

もう 1 つのポイントは、add_definitionsこれを意図したプリプロセッサ定義ではなく、コンパイラ フラグに使用しているという意味で誤用していることです。

使用することが好ましいでしょうadd_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

または CMake バージョン < 3.0 の場合は、次のようなことを行います。

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

以下のコメントでのさらなる質問に答えて、1 つのファイルのフラグを確実に削除することは不可能だと思います。その理由は、任意のソース ファイルに対して、そのターゲットのCOMPILE_OPTIONS1が適用されていますが、これらはそのソース ファイルのどのプロパティにも表示されないためです。COMPILE_FLAGS

ターゲットの から問題フラグを取り除き、COMPILE_OPTIONSそれをターゲットの各ソースに個別に適用し、必要に応じて特定のソース ファイルから除外することを検討できます。

ただし、これは多くのシナリオで機能しますが、いくつかの問題があります。

最初のソース ファイルのプロパティには が含まれずCOMPILE_OPTIONS、 のみが含まれCOMPILE_FLAGSます。COMPILE_OPTIONSターゲットの にはジェネレータ式を含めることができますが、COMPILE_FLAGSサポートされていないため、これは問題です。したがって、フラグを検索するときにジェネレーター式に対応する必要があり、実際、フラグが1つ以上に含まれている場合は、ジェネレーター式を「解析」して、残りに再適用する必要があるかどうかを確認する必要さえあります。ソースファイル。

2 つ目 - CMake v3.0 以降、ターゲットは を指定できますINTERFACE_COMPILE_OPTIONSCOMPILE_OPTIONSこれは、ターゲットの依存関係が、その を介してターゲットを追加またはオーバーライドできることを意味しますINTERFACE_COMPILE_OPTIONS。したがって、すべてのターゲットの依存関係を再帰的に繰り返し処理する必要があります (ターゲットのリストにLINK_LIBRARIESはジェネレーター式も含まれている可能性があるため、特に簡単な作業ではありません) 問題フラグを適用しているものを見つけ、それらからそれを削除してみてくださいターゲットINTERFACE_COMPILE_OPTIONSも。

この複雑な段階では、CMake にパッチを提出して、ソース ファイルから特定のフラグを無条件に削除する機能を提供したいと考えています。


COMPILE_FLAGS1:ソース ファイルのプロパティとは異なり、COMPILE_FLAGSターゲットのプロパティは非推奨であることに注意してください。

于 2012-11-30T05:19:46.773 に答える