1

My question is focused on CMake C++ projects and separating out code into multiple repositories for re-usability, and somewhat mimicking a naive package management system. For now I would like to ignore any possible package managers like Conan or vcpkg.

Suppose I have a C++ repository PackageA that uses CMake and supplies its own find package file FindPackageA.cmake so that it can be used in another CMake package. This file may do some checking to see if PackageA is already installed locally on the system (like its headers and lib files exist in some known location) and if not it will compile PackageA and install it locally (ideally this package would be versioned so it could find version 1, 2, ect. if requested).

I know have another package PackageB which wishes to consume PackageA. In theory, if both of these projects lived in a version control system like Github, I assume PackageB would have a CMakeLists.txt file that contains

...
# Download PackageA locally so that we get FindPackageA.cmake file
include(ExternalProject)
ExternalProject_Add(ProjectA
 GIT_REPOSITORY MY_PACKAGE_A_GITHUB_REPO
 GIT_TAG origin/release/1
)
# Run the FindPackageA.cmake file to get the headers and libs to link and use against.
find_package(PackageA)
...

My one problem with this potential solution is that it requires downloading PackageA every time to get its find package file. Is there a more maintainable way to separate out multiple CMake projects so that they can be easily resued here? Would it be better to have a single respository/package that just contains all the find package files so that they are separate from their respective packages?

asked Dec 10, 2023 at 6:34
1
  • 1
    What is the expected common scenario for you? Is it that the exact version needed by PackageB already exists in compiled for on the user's computer or that it does not exist. Commented Dec 11, 2023 at 7:53

1 Answer 1

1

Well, If I may interject here a little bit, CMake's find_package and ExternalProject is great for reusability, but I believe that there are better ways to improve maintainability in your scenario.

There are three things I think could be of much more benefit.

  1. Git Submodules. This ensures both projects are version controlled together. There might be downside that it has the potential for One Definition Rule (ODR) violations if PackageB and another project have a common dependency on a different version.

  2. FetchContent. This avoids repetitive downloads and allows specifying desired versions. Not much of a downside to that, you'll just have to keep maintaining it.

  3. External Project with CMAKE_MODULE_PATH. Instead of relying on find_package(PackageA), set CMAKE_MODULE_PATH to include PackageA's directory containing FindPackageA.cmake

  4. use something like Conan or vcpkg.

I would simply just analyze your expected scenarios (pre-built vs. building PackageA) and the number of dependencies involved before deciding which to go with.

answered Jun 19, 2024 at 2:30

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.