web-dev-qa-db-ja.com

Catch2でCMakeを使用する方法は?

Catch2の例 から、この例をcmakeで実行しようとしました。ここで、プロジェクトの構造は次のようになります。

/factorial
    +-- CMakeLists.txt
    +-- /bin
    +-- /include
    |     +-- catch.hpp
    |     +-- fact.hpp 
    +-- /src
    |     +-- CMakeLists.txt
    |    +-- fact.cpp
    +-- /test
         +-- CMakeLists.txt
         +-- test_fact.cpp

fact.cpp

unsigned int factorial( unsigned int number ) {
    return number <= 1 ? number : factorial(number-1)*number;
}

fact.hpp

#ifndef FACT_H
#define FACT_H

unsigned int factorial(unsigned int);

#endif

test_fact.cpp

#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "fact.hpp"

TEST_CASE( "factorials are computed", "[factorial]" ) {
    REQUIRE( factorial(1) == 1 );
    REQUIRE( factorial(2) == 2 );
    REQUIRE( factorial(3) == 6 );
    REQUIRE( factorial(10) == 3628800 );
}

cmakeを使用してこのプロジェクトをビルドする方法をいくつか試しましたが、失敗しました。時々エラーが発生しました:

cpp:X:XX: fatal error: 'fact.hpp' file not found
...

そして時々私は得ました:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
...

makeを実行すると。

実行ファイルをfactorial/CMakeLists.txtに置きたい場合、factorial/src/CMakeLists.txtfactorial/test/CMakeLists.txtおよびfactorial/binには何が必要ですか?

追加:これは私のCMakeLists.txtです(完全に間違っていると思います)。

factorial/CMakeLists.txt

project(factorial)
cmake_minimum_required(VERSION 2.8.12)

add_definitions("-std=c++11")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

add_subdirectory(src)
add_subdirectory(test)

factorial/src/CMakeLists.txt

project(factorial)
cmake_minimum_required(VERSION 2.8.12)

add_executable(fact fact.cpp)

factorial/test/CMakeLists.txt

project(factorial)
cmake_minimum_required(VERSION 2.8.12)

add_executable(test_fact test_fact.cpp)
target_include_directories(test_fact PRIVATE ${CMAKE_SOURCE_DIR}/include)
5
fronthem

ここで多くの問題:

add_executable(fact fact.cpp)

実行可能ファイルではなく階乗関数のみを定義しているため、呼び出しではadd_librarySTATICまたはSHAREDを指定することもできます)を使用する必要がありますmain function

add_executable(fact fact.cpp)

ファイルはtest_fact.cppである必要があり、ターゲットは、以前に作成したライブラリとの競合を避けるために別の名前である必要があります。また、fact.cppにはfact.hppが含まれていません。最後になりましたが、target_include_directoriesを実行する代わりに、トップレベルのCMakeLists.txtに次のように記述します。

include_directories(include)

これで、すべてのサブディレクトリがヘッダーファイルにアクセスできるようになります。これにより、ヘッダーファイルのスコープの制御が削除され(PRIVATE vs PUBLIC vs INTERFACE)、allサブディレクトリがヘッダーファイルにアクセスできるようになることに注意してください。 。この動作を制限する場合は、すべてのターゲット(ライブラリとテスト実行可能ファイル)にtarget_include_direcoriesを使用します。この例では、すべてがヘッダーファイルにアクセスする必要があるため、上記のステートメントに問題はありません。

その他の問題:

project(factorial)
cmake_minimum_required(VERSION 2.8.12)

これらのステートメントの順序を切り替えるか、両方を削除してください。 (トップレベルのCMakeファイルでのみ必要です)

3
Arnav Borborah

CMakeのドキュメントを見ると、_PROJECT_SOURCE_DIR_変数は次のように定義されています。

現在のプロジェクトの最上位のソースディレクトリ。

これは、最新のproject()コマンドのソースディレクトリです。

projectを何度も呼び出したので、その変数は常に変化します。プロジェクトディレクティブを削除するか、プロジェクト全体のソースディレクトリを常に指す_CMAKE_SOURCE_DIR_を使用することをお勧めします。


補足として、_add_definition_の代わりにset(CMAKE_CXX_STANDARD 11)を使用することをお勧めします

4