単一ファイルのコンパイルフラグを上書きする


109

プロジェクトをコンパイルするためにフラグのグローバルセットを使用したいと思います。つまり、最上位の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 、それは助けにはなりませんでした。

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


1
待って、最後の試みがうまくいったなら、それが構築された後でないと、これはキャッシングの問題ではないのでしょうか?変更後にCMakeCacheを削除してみてください。
Cameron

関連、CMakeで1つの実行可能ファイルのコンパイラフラグを変更する方法を参照してくださいアンドレの答えは、既存のオプションを新しいオプションで置き換える方法のように見えるものを示しています。
jww 2017

回答:


126

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

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

あなたは-Weffc++foo.cpp のフラグを打ち消すことができるはずです

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

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

make VERBOSE=1

さておき、GNU C ++標準ライブラリのメンテナの1は上かなり否定的意見を提示したよう-Weffc++、この答え

別のポイントは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_OPTIONS1COMPILE_FLAGSそのターゲットのが適用されるが、これらはそのソースファイルのプロパティのいずれかに表示されません。

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

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

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

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

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


1:COMPILE_FLAGSソースファイルのプロパティとは異なり、COMPILE_FLAGSターゲットのプロパティは非推奨です。


6
しかし、実際にファイルを追加せずにファイルのコンパイルフラグを個別に設定するにはどうすればよいですか。たとえば、結果のターゲットにはファイルとは異なるコンパイルフラグを使用したいのですが、それらが追加されているため、手動で削除する必要があります。追加されないが、実際には指定されたファイル/ターゲットに対してのみ設定されるプロパティはありませんか?
Baradé

2
-fno-flagが使用できない(および-fflagが設定されている)場合、どうすればよいですか?
gnzlbg 2015

@バラデあなたはできません-ソースファイルではありません。
Fraser

@gnzlbg繰り返しになりますが、かなり行き詰まっています。回答を更新して、もう少し情報を追加しました(およびいくつかのシナリオでおそらく機能する可能性のある回避策)。
Fraser

単一ファイルのコンパイルオプション設定の回避策は本当にありませんか?gcovをクラッシュさせるいくつかのファイルのgccカバレッジ生成を無効にする必要があります。
Lothar 2017年

5

@Fraserの正解に追加するだけです。

特定のフォルダに特別なフラグを追加したい場合は、次のようにします。

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

または

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

ここで説明されているようにGLOBを使用することはお勧めしません。


0

@Fraserの回答を使用して、変数にセミコロンで区切られた複数のパスが含まれているため、Qtインクルードを処理するために以下を作成しました。つまり、最初にforeach()ループを追加し、手動で includeフラグを作成する必要がありました。ただし、これにより、foo.cppという1 つの例外を設けることができます(この1つのファイルは現在のところ Qtを使用していますが、長期的にはその依存関係を削除し、Qtが他の場所に侵入しないようにしたい)。

find_package(Qt5Core REQUIRED)
set(QT_INCLUDE_PROPERTIES "")
foreach(DIR ${Qt5Core_INCLUDE_DIRS})
    set(QT_INCLUDE_PROPERTIES "${QT_INCLUDE_PROPERTIES} -isystem ${DIR}")
endforeach()
set_source_files_properties(foo.cpp PROPERTIES
    COMPILE_FLAGS
        ${QT_INCLUDE_PROPERTIES}
)

-isystem代わりに-IQtヘッダーが生成する警告を回避するためにを使用していることにも注意してください(大量の警告がオンになっています)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.