can I build CMakeLists.txt from a set of smaller f

2019-06-06 00:37发布

问题:

I am building a medium sized C++ library, and my CMakeLists.txt file is starting to get a bit long. I was reading Robert Martin's book The Clean Coder in which he discusses the elements of clean coding style for the sake of code maintenance and readability.

So I wanted to see if I could break up my CMakeLists.txt file into a set of smaller files--that would integrate when I ran a build command. I could then just manage these smaller files, just as I would break up classes into separate files. Now as a caveat, I am not building separate executables for different elements of the library. I am just building a single library with a set of classes and functions that I need for other projects.

Here is my current CMakeLists.txt file. Then I will show how I would like to break it up.

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)

Now I would like to create a separate file for the basic settings piece:

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

Then a separate piece for the finding the CGAL library:

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

And so forth.

回答1:

Split your CMakeLists.txt into:

Project's top file:

  • Contains all common settings of the project
  • Includes the external projects
  • Include the sub directories
  • Set the common compiler settings
  • Builds the targets

Reusable functions file:

  • Store your own CMake macros and functions into a separate file to reuse it in your different projects

Source files:

  • Place a CMakeList.txt in every subdirectory of source code
  • Add the sources here to the variable SOURCE and use PARENT SCOPE

Tests:

  • Use a extra CMakeLists.txt to build the unit tests
  • Reuse the previous structure of CMake files in case of large test environment

I have small projects with one CMakeLists.txt and large projects for a single library with up to 10 files.



标签: c++ cmake