12

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.txtfactorial/bin

附加:这是我的 CMakeLists.txts(我认为它们完全错误)。

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)
4

2 回答 2

6

这里有很多问题:

add_executable(fact fact.cpp)

调用应该使用add_library(您也可以指定STATICor SHARED),因为您只定义了一个阶乘函数,而不是一个带有mainfunction的可执行文件。

add_executable(fact fact.cpp)

该文件应该test_fact.cpp和目标应该有不同的名称,以避免与您创建的先前库冲突。另外,您的fact.cpp不包括fact.hpp. 最后但同样重要的是,不要做target_include_directories,只需在顶层写下以下内容CMakeLists.txt

include_directories(include)

现在,所有子目录都应该能够访问头文件。PRIVATE请注意,这会删除对头文件( vs PUBLICvs )范围的控制,INTERFACE并允许所有子目录访问头文件。如果您想限制此行为,请使用target_include_direcories所有目标(您的库和测试可执行文件)。对于这个例子,由于一切都需要访问头文件,所以上面的语句没有问题。

更多问题:

project(factorial)
cmake_minimum_required(VERSION 2.8.12)

要么切换这些语句的顺序,要么同时删除它们。(您只需要在顶级 CMake 文件中使用它们)

于 2018-03-21T18:48:46.727 回答
5

如果您查看 CMake 文档,该PROJECT_SOURCE_DIR变量的定义如下:

当前项目的顶级源目录。

这是最新的 project() 命令的源目录。

由于您project多次调用,该变量将不断变化。我建议你删除你的项目指令,或者使用CMAKE_SOURCE_DIR,它总是指向整个项目的源目录。


作为旁注,我建议使用set(CMAKE_CXX_STANDARD 11)而不是add_definition

于 2018-03-21T18:48:29.907 回答