2017-04-16 64 views
1

我正在构建一个中等大小的C++库,并且我的CMakeLists.txt文件开始变得有点长。我正在阅读Robert Martin的书Clean Coder,其中他讨论了干净的编码风格的元素,以维护代码和可读性。我可以从一组较小的文件构建CMakeLists.txt(以提高CMakeLists.txt的可读性和可维护性)

所以我想看看我是否可以将我的CMakeLists.txt文件分解为一组较小的文件 - 当我运行构建命令时这些文件就会集成在一起。然后,我可以管理这些较小的文件,就像我将课程分成单独的文件一样。现在作为一个警告,我没有为库的不同元素构建单独的可执行文件。我只是建立一个包含一系列我需要用于其他项目的类和函数的单个库。

这是我目前的CMakeLists.txt文件。然后我会展示我想如何分解它。

cmake_minimum_required(VERSION 3.7) 
project(tvastrCpp) 
set (tvastrCpp_VERSION_MAJOR 0) 
set (tvastrCpp_VERSION_MINOR 1) 


# Find CGAL 
find_package(CGAL REQUIRED COMPONENTS Core) # If the dependency is required, use REQUIRED option - if it's not found CMake will issue an error 
include(${CGAL_USE_FILE}) 
include(ExternalProject) 
set(CMAKE_CXX_STANDARD 14) 
find_package(Eigen3 3.1.0) 
if (EIGEN3_FOUND) 
    include(${EIGEN3_USE_FILE}) 
endif() 

find_package(Boost 1.58.0 REQUIRED COMPONENTS system filesystem program_options chrono timer date_time REQUIRED) 

if(NOT Boost_FOUND) 
    message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") 
endif() 

set(Boost_USE_STATIC_LIBS  ON) 
set(Boost_USE_MULTITHREADED  ON) 
set(Boost_USE_STATIC_RUNTIME OFF) 


INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) 
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 

ExternalProject_Add(
     catch 
     PREFIX ${CMAKE_BINARY_DIR}/catch 
     GIT_REPOSITORY https://github.com/philsquared/Catch.git 
     TIMEOUT 10 
     UPDATE_COMMAND ${GIT_EXECUTABLE} pull 
     CONFIGURE_COMMAND "" 
     BUILD_COMMAND "" 
     INSTALL_COMMAND "" 
     LOG_DOWNLOAD ON 
) 

ExternalProject_Get_Property(catch source_dir) 
set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch") 

INCLUDE_DIRECTORIES ("${EIGEN3_INCLUDE_DIR}") 

file(GLOB lib_SRC RELATIVE "lib" "*.h" "*.cpp") 
file(GLOB test_SRC RELATIVE "tests" "*.h" "*.cpp") 


# need to fix the instruction below to reference library 
set(SOURCE_FILES ${lib_SRC}) 
add_library(tvastrCpp SHARED ${SOURCE_FILES}) 

add_executable(${PROJECT_NAME} main.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp) 
add_executable(my_tests testcases.cpp RipsComplex.h RipsComplex.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp) 
add_executable(gd_validator gudhi_validator.cpp) 
TARGET_LINK_LIBRARIES(gd_validator ${Boost_LIBRARIES}) 

enable_testing(true) 
add_test(NAME cooltests COMMAND my_tests) 

现在我想创建一个单独的文件进行基本设置片:

find_cgal.txt: 
find_package(CGAL REQUIRED COMPONENTS Core) # If the dependency is required, use REQUIRED option - if it's not found CMake will issue an error 
include(${CGAL_USE_FILE}) 
include(ExternalProject) 
set(CMAKE_CXX_STANDARD 14) 
find_package(Eigen3 3.1.0) 
if (EIGEN3_FOUND) 
    include(${EIGEN3_USE_FILE}) 
endif() 

如此反复:

settings.txt: 
cmake_minimum_required(VERSION 3.7) 
project(tvastrCpp) 
set (tvastrCpp_VERSION_MAJOR 0) 
set (tvastrCpp_VERSION_MINOR 1) 

然后为寻找CGAL库的单独部件。

+2

移动这些部分到每个自己的文件,并把它们包含通过[包括(https://cmake.org/cmake/help/v3.7/command/include.html)。 – Tsyvarev

+0

@Tsyvarev哦,这是有道理的。是的,我可以试试。我想我假设'include'会保留代码的顺序,这样我就不会遇到任何问题,比如在赋值之前使用变量等。我会给它一个镜头。 – krishnab

回答

2

分裂您的CMakeLists.txt到:

项目的顶层文件:

  • 包含项目
  • 包括外部项目
  • 包括子目录的所有常用设置
  • 设置通用编译器设置
  • 构建目标

可重复使用的功能文件:

  • 存储自己的CMake宏和功能集成到一个单独的文件中重用它在不同的项目

源文件:

  • 放置一个CMakeList.txt在源代码中每一个子目录
  • 在此处添加源可变电源和使用父作用域

测试:

  • 使用额外CMakeLists。TXT构建单元测试
  • 重用的CMake的文件之前的结构在大型测试环境的情况下

我有多达10个文件一个库中的小项目,一个的CMakeLists.txt和大型项目。

+0

非常感谢。我环顾四周,发现了这个例子。这是你的建议吗? https://stackoverflow.com/questions/6352123/multiple-directories-under-cmake – krishnab

+0

啊,这是伟大的。是啊,我很担心打破了一切,但它似乎工作得很好。非常感谢。当我不通过文件寻找时,它会让生活变得更容易。 – krishnab

+0

请记住使用父作用域的情况下,一个子目录设置在根目录中使用的变量(如源文件的列表)。 –

相关问题