3

I am using the Unity testing library in my project. Ideally, I would like to automatically download the source code from GitHub and put it in the external/ directory, build the library once, regardless of how many different CMake configurations I have (one Debug and one Release CMake configuration), and link the library with my application.

I have tried to use FetchContent, ExternalProject, and add_subdirectory but none of these seem to work quite right.

The issues I am currently facing right now are:

  • The library is installed in the _deps/ subdirectory of my build/ directory. I want it to be downloaded to a directory called external/ in the project root.
  • "cmake --build ." builds the library every time. I just want the library to be built once.
  • "cmake --install ." installs my application and the Unity library. I only want install to install my application when this command is run. The library would be installed in lib/ and include/ before my application is built.

This is my project structure:

project/             <-- Project root
|-- bin/             <-- Application executable
|-- build/           <-- CMake build files
|   |-- _deps/       <-- Where Unity is built
|-- doc/             <-- Documentation from Doxygen
|-- include/         <-- Unity header files
|-- lib/             <-- Unity library file
|-- module/          <-- Application source code
|-- CMakeLists.txt   <-- CMake configuration file

This is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(Project VERSION 1.0.0)
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/include)
add_subdirectory(module)

# Add Unity testing framework from GitHub
include(FetchContent)
FetchContent_Declare(
  unity
  GIT_REPOSITORY https://github.com/ThrowTheSwitch/Unity.git
  GIT_TAG        v2.5.1
)
FetchContent_MakeAvailable(unity)
FetchContent_GetProperties(unity)
if (NOT unity_POPULATED)
  FetchContent_Populate(unity)
  add_subdirectory(${unity_SOURCE_DIR} ${unity_BINARY_DIR})
endif()

enable_testing()
add_subdirectory(tests)

I really have no idea how to accomplish this. I looked at this other question and this link but it didn't seem to do everything I wanted it to do. Any help is appreciated.

FrostyTigerXP
  • 81
  • 1
  • 7
  • 1
    All your 3 questions are actually **unrelated** and should be asked as **separate** question posts. For setting download directory with FetchContent see [that question](https://stackoverflow.com/questions/60981812/how-can-i-get-fetchcontent-to-download-to-a-specific-location). `FetchContent` allows to build the subproject along with the main project. If you want to build subproject only once for several configuration of the main project, then use `ExternalProject` instead. Note also, that `FetchContent_MakeAvailable` does all the things in the following 5 lines, so they are not needed. – Tsyvarev Aug 16 '20 at 19:56
  • @Tsyvarev That helped, thanks. – FrostyTigerXP Aug 17 '20 at 00:31

1 Answers1

3

I was able to make it work using ExternalProject. This is what my CMakeLists.txt looks like now:

include(ExternalProject)
set(UNITY unity_project)
ExternalProject_Add(
    unity_project
    GIT_REPOSITORY https://github.com/ThrowTheSwitch/Unity.git
    GIT_TAG cf949f45ca6d172a177b00da21310607b97bc7a7
    PREFIX ${PROJECT_SOURCE_DIR}/external/${UNITY}
    CONFIGURE_COMMAND cmake ../${UNITY}
    BUILD_COMMAND cmake --build .
    INSTALL_COMMAND cmake --install . --prefix ${PROJECT_SOURCE_DIR}
    UPDATE_COMMAND ""
)
add_library(unity STATIC IMPORTED)
set_property(TARGET unity PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/lib/libunity.a)
add_dependencies(unity unity_project)

The first issue was solved by the line:

PREFIX ${PROJECT_SOURCE_DIR}/external/${UNITY}

The second issue was solved by the line:

UPDATE_COMMAND ""

The third issue was solved by the line:

INSTALL_COMMAND cmake --install . --prefix ${PROJECT_SOURCE_DIR}
FrostyTigerXP
  • 81
  • 1
  • 7