# how to make cmake reconfigure itself from cmakelists, or how to re-addsubdirectory ?

**URL:** https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858
**Category:** Code
**Created:** [September 1, 2023, 9:35am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858 "2023-09-01T09:35:35Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Gerodote](https://discourse.cmake.org/user_avatar/discourse.cmake.org/gerodote/32/3770_2.png) [@Gerodote](https://discourse.cmake.org/u/Gerodote)
#### Post date: [September 1, 2023, 9:35am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/1 "2023-09-01T09:35:35Z")

</div>

I thought to use CPM for my project. I got to problem that if CPM adds smth, then it’s cannot be readded.

Example : boost. one package adds only one library from it ( and the dependencies ) , but another package uses some other libs from boost.  
Then

1. package1 adds boost with some options via CPM
2. package1 adds package2 via CPM
3. when package2 is trying to add boost with other options via CPM it does nothing, because it assumes that a package with specific version doesn’t need to be reconfigured, if it’s already added.
4. boost components for package2 aren’t added.
5. at generating : Boost::component\_library is not found.

Let’s assume I can somehow write logic for merging options. But how I can readd smth ? Or , at least, how can I make cmake reconfigure itself with cache variables?

If someone know how to do so, it would be great to share, I can try write the logic and make a PR.

If it’s possible, we can make CPM be automatic in merging options and make it a really great package manager.

all my thoughts about the problem also there are at [github](https://github.com/cpm-cmake/CPM.cmake/issues/501)

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [September 1, 2023, 10:37am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/2 "2023-09-01T10:37:18Z")

</div>

You cannot “undo” an `add_subdirectory`. You can do it again with a different builddir (`add_subdirectory(boost "${CMAKE_CURRENT_BINARY_DIR}/boost-again")`, but that will get you 2 Boost builds.

I think you need to gather your requirements first and set up `BOOST_INCLUDE_LIBRARIES` suitably before ever including Boost.

---

<div class="post-metadata">

### Author: ![Gerodote](https://discourse.cmake.org/user_avatar/discourse.cmake.org/gerodote/32/3770_2.png) [@Gerodote](https://discourse.cmake.org/u/Gerodote)
#### Post date: [September 1, 2023, 10:49am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/3 "2023-09-01T10:49:22Z")

</div>

yea, I can do that. though, I think, I’ll get problem if one project adds a boost lib, another adds it too. then we will have two same targets. It’s prohibited by CMP0002, AFAIK.

About gathering requirements. That’s why I don’t want to gather them manually. I would like to make CPM it do instead of me: getting same lib, merging needed options and cache variables and then reconfigure the lib. That’s why I’m asking about any such capabilities of cmake.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [September 1, 2023, 11:05am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/4 "2023-09-01T11:05:09Z")

</div>

The closest I’m aware of that CMake provides is `FetchContent` (which I believe is more-or-less mutually exclusive to CPM in practice). @craig.scott knows far more about this module’s coverage of this use case than I do.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [September 1, 2023, 1:15pm UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/5 "2023-09-01T13:15:10Z")

</div>

My understanding is that CPM is implemented using FetchContent internally, but it’s been a while since I’ve taken a look at it.

As long as you use the same name to refer to a given dependency in calls to `FetchContent_Declare()`, FetchContent will take care of only adding that dependency to the build once, regardless of how many times `FetchContent_MakeAvailable()` is called for that dependency. The first such call adds the dependency, subsequent calls re-use that one. Assuming CPM is still implemented in terms of FetchContent, I would expect it to do the same.

FetchContent’s philosophy is “first to declare, wins”. The first `FetchContent_Declare()` call for a dependency controls how that dependency will be populated. If you’re encountering a situation where two dependencies are pulling in boost and the first one to pull it in isn’t enabling all the options you need, then your main project needs to make its own call to `FetchContent_Declare()` before pulling in either dependency. Then the first call from your main project will be in control of how boost is brought in.

I suggest you take a look through the FetchContent docs. They go through the way these things work.

[https://cmake.org/cmake/help/latest/module/FetchContent.html](https://cmake.org/cmake/help/latest/module/FetchContent.html)

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [September 2, 2023, 4:27am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/6 "2023-09-02T04:27:16Z")

</div>

> **[Why you should NOT use Boost git repo with CPM.cmake · cpm-cmake/CPM.cmake ·...](https://github.com/cpm-cmake/CPM.cmake/discussions/448)**
>
> the clone of the git repo takes to long time! and the boost CMake files are not really designed as modern CMake project! there is no central include directory! the boost CMake system is designed fo...

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [September 2, 2023, 6:24am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/7 "2023-09-02T06:24:07Z")

</div>

### With `CMP.cmake` and/or `FetchContents`, projects may end with create complexity!

```cmake
include(cmake/CPM.cmake)

cpmusepackagelock(package-lock.cmake)

# Done as a function so that updates to variables like
# CMAKE_CXX_FLAGS don't propagate out to other
# targets
function(myproject_setup_dependencies)

  # For each dependency, see if it's
  # already been provided to us by a parent project
  # NOTE: The order is also important! CK
  # i.e.: spdlog may use catch2 and fmtlib too

  # NOTE: needed in test/CMakelinst.txt: include(${Catch2_SOURCE_DIR}/extras/Catch.cmake)
  cpmaddpackage("gh:catchorg/Catch2@3.4.0")

  if(NOT TARGET fmtlib::fmtlib)
    # A git package with both version and tag provided
    cpmaddpackage("gh:fmtlib/fmt@9.1.0#9.1.0")
    # FIXME(CK): this does not work! No idea why?
    # cpmfindpackage("gh:fmtlib/fmt@9.1.0#9.1.0")
  endif()

  if(NOT TARGET spdlog::spdlog)
    # NOTE: you may find an installed version compiled with differrent options!
    # TODO(CK) this does not work! cpmfindpackage(
    cpmaddpackage(
      NAME
      spdlog
      VERSION
      1.12.0
      GITHUB_REPOSITORY
      "gabime/spdlog"
      OPTIONS
      "SPDLOG_FMT_EXTERNAL ON")
  endif()

  if(NOT TARGET CLI11::CLI11)
    cpmaddpackage("gh:CLIUtils/CLI11@2.3.2")
  endif()

  if(NOT TARGET ftxui::screen)
    # A git package with both version and tag provided
    cpmfindpackage(
      NAME
      FTXUI
      VERSION
      5.0.0
      GIT_TAG
      dd6a5d371fd7a3e2937bb579955003c54b727233
      GITHUB_REPOSITORY
      "ArthurSonzogni/FTXUI"
      OPTIONS
      "FTXUI_BUILD_EXAMPLES OFF;FTXUI_BUILD_DOCS OFF")
  endif()

  if(NOT TARGET tools::tools)
    cpmaddpackage("gh:lefticus/tools#update_build_system")
  endif()

endfunction()

```

```bash
bash-5.2$ cmake --preset unixlike-gcc-release --fresh | grep -w CPM
-- CPM: Adding package Catch2@3.4.0 (v3.4.0 at /Users/clausklein/.cache/CPM/catch2/fc2d6e70e6b1b691860849b5eeca5a7b84d30f6f)
-- CPM: Adding package fmt@9.1.0 (9.1.0 at /Users/clausklein/.cache/CPM/fmt/5c4bc51f3df5bb907a0028facff05ba4978aa6e5)
-- CPM: Adding package spdlog@1.12.0 (v1.12.0 at -- CPM: Adding package CLI11@2.3.2 (v2.3.2 at /Users/clausklein/.cache/CPM/cli11/9e6fd3fcb946a91f4a10e874dc9d09753d96ed7f)
-- CPM: Using local package FTXUI@5.0.0
-- CPM: Adding package tools@ (update_build_system at /Users/clausklein/.cache/CPM/tools/8c8c55a914858ebfc250a90e65f4f4a988a4e20e)
bash-5.2$ 

```

**cat build/cpm-package-lock.cmake**

```json
# CPM Package Lock
# This file should be committed to version control

# Catch2
CPMDeclarePackage(Catch2
  VERSION 3.4.0
  GITHUB_REPOSITORY catchorg/Catch2
  SYSTEM YES
  EXCLUDE_FROM_ALL YES
)
# fmt
CPMDeclarePackage(fmt
  VERSION 9.1.0
  GIT_TAG 9.1.0
  GITHUB_REPOSITORY fmtlib/fmt
  SYSTEM YES
  EXCLUDE_FROM_ALL YES
)
# spdlog
CPMDeclarePackage(spdlog
  NAME spdlog
  VERSION 1.12.0
  GITHUB_REPOSITORY gabime/spdlog
  OPTIONS
    "SPDLOG_FMT_EXTERNAL ON"
)
# CLI11
CPMDeclarePackage(CLI11
  VERSION 2.3.2
  GITHUB_REPOSITORY CLIUtils/CLI11
  SYSTEM YES
  EXCLUDE_FROM_ALL YES
)
# tools (unversioned)
# CPMDeclarePackage(tools
# GIT_TAG update_build_system
# GITHUB_REPOSITORY lefticus/tools
# SYSTEM YES
# EXCLUDE_FROM_ALL YES
#)

```

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [September 2, 2023, 6:34am UTC](https://discourse.cmake.org/t/how-to-make-cmake-reconfigure-itself-from-cmakelists-or-how-to-re-addsubdirectory/8858/8 "2023-09-02T06:34:58Z")

</div>

> [@Gerodote](#):
>
> I thought to use CPM for my project. I got to problem that if CPM adds smth, then it’s cannot be readded.

some hints:  
1.) try ` cmake --fresh ...`  
2.) try `cpmusepackagelock(package-lock.cmake)`  
3.) for `complex projects with many dependencies` or big libraries like **boost** :

### install it on your build environment!
