1

I have been working on a CPP project but was using configuration on visual studio IDE. Now, I wanted to use a build system generator CMake. It is a little difficult to getting started with this.

I am trying to add cppunit third-party tool for my testing. For that, I have added include and lib file in a folder third_party. But not sure how to include it in the CMakeLists.txt.

Please find CMakeList.txt

# CMake version setting
cmake_minimum_required(VERSION 3.8)
if(${CMAKE_VERSION} VERSION_LESS 3.19)
    cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
    cmake_policy(VERSION 3.19)
endif()

# Set project name and version
project(myproject
    VERSION 1.0
    DESCRIPTION "Setup cmake build system"
    LANGUAGES CXX
)

# Third party dependencies
set(THIRD_PARTY_DIR "${PROJECT_SOURCE_DIR}/third_party")

# CPP unit
set(CPP_UNIT_LIB_NAME "cppunit")
set(CPP_UNIT_VERSION "1.13.2")
set(CPP_UNIT_DIR "${THIRD_PARTY_DIR}/${CPP_UNIT_LIB_NAME}/${CPP_UNIT_VERSION}")

# NOT sure what to do here
# add_subdirectory(${CPP_UNIT_DIR})
# target_include_directories(${PROJECT_NAME} PRIVATE "${CPP_UNIT_DIR}/include/cppunit")
# target_link_libraries(${PROJECT_NAME}  ${CPP_UNIT_LIB_NAME} ${CPP_UNIT_LIBRARIES})
# target_compile_definitions(${PROJECT_NAME}  PRIVATE "CPP_UNIT_INCLUDE_NONE")

add_subdirectory(src)

Please find the snap-shot of the folder structure

enter image description here

Avi
  • 310
  • 2
  • 4
  • 16
  • I also read that we shouldn't use a file (GLOB), include_directories, link_directories, etc. in the projects. – Avi Dec 25 '20 at 18:04

1 Answers1

3

add_subdirectory(${CPP_UNIT_DIR}) will look in the directory specificied for a CMakeLists.txt and since CppUnit has a CMakeLists.txt file (https://github.com/Ultimaker/CppUnit/blob/master/CMakeLists.txt) it will build the library specified add_library(cppunit STATIC ${Sources}) which is cppunit.

And then when you specify your target to build, you can link in cppunit using target_link_libraries(your_target cppunit). But you need to create your target such as by using add_executable(one two.cpp three.h) which creates the target one.

https://cliutils.gitlab.io/modern-cmake/ is a good introductory resource for CMake. And there are different ways to bring in external projects such as through a git submodule.

If you have a CMakeLists.txt file in the src subdirectory, where you create a target you can link in cppunit.

As for the comment about include_directories, it is generally considered good practice to use target_include_directories instead, see What is the difference between include_directories and target_include_directories in CMake? and the above linked resource for more.

0RR
  • 1,538
  • 10
  • 21
  • 1
    Thanks, @ORR. This is really helpful. One more question here. If I have a few 3rd party party tools which has only header files and don't have their CMakeLists.txt. And, if I don't want to keep source files of cppunit in my project directory. What is the way to link with my project target? If you could share right reference for this specific topic. That'd also helpful. – Avi Dec 25 '20 at 20:44
  • 1
    @Avi you are welcome. You can create an `INTERFACE` library target for header only files see http://mariobadr.com/creating-a-header-only-library-with-cmake.html. If you use git, then adding your external project as a git submodule will mean git only has to track which external projects you use, so you won't hold the source but the source will be pulled in when you build the project e.g. `git submodule add` https://iscinumpy.gitlab.io/post/gtest-submodule/ https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html and then as you did before call `add_subdirectory(submodule_name)` – 0RR Dec 25 '20 at 21:59
  • 1
    @Avi will bring in the submodule at build time and your src folder shouldn't contain any clutter because your external project will be named in the gitmodules file. Or you can try using `ExternalProject_add` e.g. https://stackoverflow.com/questions/15175318/cmake-how-to-build-external-projects-and-include-their-targets And if you find your build get's cluttered with different targets e.g. in Visual studio you can set `set_property( GLOBAL PROPERTY USE_FOLDERS ON)` to use a folder structure and put specific targets in certain folders. – 0RR Dec 25 '20 at 22:02