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.txt
、factorial/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)
ここで多くの問題:
add_executable(fact fact.cpp)
実行可能ファイルではなく階乗関数のみを定義しているため、呼び出しではadd_library
(STATIC
または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ファイルでのみ必要です)
CMakeのドキュメントを見ると、_PROJECT_SOURCE_DIR
_変数は次のように定義されています。
現在のプロジェクトの最上位のソースディレクトリ。
これは、最新のproject()コマンドのソースディレクトリです。
project
を何度も呼び出したので、その変数は常に変化します。プロジェクトディレクティブを削除するか、プロジェクト全体のソースディレクトリを常に指す_CMAKE_SOURCE_DIR
_を使用することをお勧めします。
補足として、_add_definition
_の代わりにset(CMAKE_CXX_STANDARD 11)
を使用することをお勧めします