web-dev-qa-db-ja.com

CMakeLists.txtへのコンパイラフラグの追加

Boostライブラリの最新バージョンを使用し、CMakeLists.txtファイルの内容を以下のようにしたい:

cmake_minimum_required (VERSION 3.0)
project (foo)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread")
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")

add_executable (first first.cpp)

これにより、次のリンカーエラーが発生し続けます。

`pthread_detachへの未定義の参照

ただし、CMakeを使用せずにコードをコンパイルする場合は、次のコマンドを使用します。

g++ foo.cpp -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread

正常に動作します。

問題は、CMakeを使用してそれを機能させる方法です。 CMAKE_CXX_FLAGSを設定してコンパイラフラグを指定すると機能しないのはなぜですか?代わりにCMAKE_EXE_LINKER_FLAGSを指定する必要があるかもしれないと思いましたが、それを行うことはまったく役に立ちません。

4
user6646922

CMakeは、明示的なフラグ指定によって解決しようとしているすべてのことをネイティブでサポートしているため、代わりにそれを使用する必要があります。

cmake_minimum_required (VERSION 3.0)
project (foo)

add_executable (first first.cpp)
target_compile_options (first PRIVATE -std=c++11)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

CMakeの最小バージョン要件を3.1に増やすことができる場合は、ハードコードされたstdフラグをネイティブのCMakeに置き換えることもできます。

cmake_minimum_required (VERSION 3.1)
project (foo)

add_executable (first first.cpp)
set_target_properties (first PROPERTIES
  CXX_STANDARD 11
  CXX_STANDARD_REQUIRED TRUE
  CXX_EXTENSIONS FALSE
)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

すべてのコンパイラが「拡張機能なしでC++ 11を使用する」と同じように表現しているわけではありません。CMakeが要件を正しいフラグに変換します。

多くの実行可能ファイルに同じC++ 11セットアップが必要な場合は、代わりに、プロパティを事前設定するCMake変数を設定できます。変数を設定する必要があることに注意してくださいbefore実行可能ファイルが作成されます。

set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED TRUE)
set (CMAKE_CXX_EXTENSIONS FALSE)

add_executable (first first.cpp)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

add_executable (second second.cpp)
target_compile_definitions (second PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (second pthread)

# ... and so on

一般に、リンカーフラグを直接オーバーライドする代わりに、target_link_librariesを使用してライブラリを指定する必要があります。


この場合、別の方法で行うことができます。

add_executable (first first.cpp)

find_package(Threads REQUIRED)
target_link_libraries(first PRIVATE Threads::Threads)

上記のThreads::Threadsは、システムのスレッドライブラリを表します。これには、クロスプラットフォームであるという利点があります。たとえば、プロジェクトをコンパイルする場合などです。 g。 Windowsでは、リンカーは不明なpthreadライブラリについて文句を言いません。

同じ理由で、C++バージョンを@Angewがその答えで行うように設定することをお勧めします。これは、コンパイラごとにフラグを手動で調整する必要がなく、機能するだけです。

2
joe_chip