How to build cmake ExternalProject while configurating main one?
Asked Answered
C

1

10

It can be a pain to refrence ExternalProjects when their install targets are messed up. So one may want to build and install ExternalProjects once before generating main project files for given project. Is it possible with CMake and how to do it?

Crescentic answered 31/5, 2016 at 18:39 Comment(0)
P
16

You may use cmake call within execute_process for configure and build CMake project, which contains ExternalProject:

other_project/CMakeLists.txt:

project(other_project)
include(ExternalProject)

ExternalProject_Add(<project_name> <options...>)

CMakeLists.txt:

# Configure external project
execute_process(
    COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}/other_project
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/other_project
)

# Build external project
execute_process(
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/other_project
)

Such a way other_project will be configured and built in directory ${CMAKE_BINARY_DIR}/other_project. If you do not disable installation in ExternalProject_Add call, then it will performed when building other_project.

Normally, you want some options to ExternalProject, like SOURCE_DIR, BINARY_DIR, INSTALL_DIR, to be deduced from variables in the main project. You have two ways for achive that:

  1. Create CMakeLists.txt for other_project with configure_file, called from main project (before execute_process command).

  2. Pass variables from main project as -D parameters to ${CMAKE_COMMAND}.


Having separated execute_process calls for sequential COMMANDS is important. Otherwise, if use single execute_process with several COMMANDS, these commands will be just "piped" (executed concurrently but with output of the first command being treated as input for the second).

Pendragon answered 31/5, 2016 at 19:38 Comment(6)
What if one does not want to tie other_project to the project by altering its CMakeLists?Rocray
The script other_project/CMakeLists.txt is NOT the part of the other project: this script is developed solely for the main (your) project. The other project is entirely in its repo, and it isn't altered in the given approach.Pendragon
I see I misunderstood; I was confused as other_project could be a git submodule, which is my current use case.Rocray
@Pendragon Great answer, thanks. What if I want the build directory be different from the source directory? I tried it modifying the WORKING_DIRECTORY path to the place I want it to be built, but it forces me to run the script twice to start the download and build process.Mcbryde
@Camilo: "I want the build directory be different from the source directory" - Which project's build and source directory you are talking about? Do you talk about the main project? Its source directory is fixed and you choose its build directory when run cmake. Do you talk about other_project (auxiliary) project? In the example its build and source directories are definitely different (${CMAKE_BINARY_DIR}/other_project and ${CMAKE_SOURCE_DIR}/other_project). As for ExternalProject, its source and build directories could be specified in ExternalProject_Add call.Pendragon
@malat: Specifying CMake generator and its options for execute_process could be useful, but making this cross-platform requires more actions than just adding -T and -A options. E.g. some generators do not support toolset or platform. I don't want to concentrate on these aspects, this is why I have rolled back your edit. As for -S and -B options, settings of source and build directories are already included in the current code: source directory is given in the command line, and build directory is deduced from the current directory (WORKING_DIRECTORY).Pendragon

© 2022 - 2024 — McMap. All rights reserved.