2017-04-16 65 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

請記住使用父作用域的情況下,一個子目錄設置在根目錄中使用的變量(如源文件的列表)。 –

相關問題