While this works, I would recommend using a real package manager like Conan, Gentoo's or Nix's ones, or vcpkg in a worse case. You should not use CPM or FetchContent. Why? Because these two are not package managers. CPM, while has letters PM that stands for "package manager", is not a package manager. It is a wrapper of FetchContent with better interface. And FetchContent should not be used as primary way of getting dependencies. Why? Because it uses rule "first declaration of dependencies is the way we'll do it" and it's impossible to override this totally incorrect behaviour without insane overengineering.
So, yeah, this project somehow works, but please, use a package manager instead, and not CPM, FetchContent or Hunter.
Versions tested: from 1.79.0 upto 1.88.0.beta1 .
- Add CPM.cmake in your project.
- Download
AddBoost.cmakevia CPM: (or install AddBoost.cmake system-wide, check Features section of the document)
set(AddBoost.cmake_VERSION 3.7.3)
CPMAddPackage(
NAME AddBoost.cmake
VERSION "${AddBoost.cmake_VERSION}"
URL "https://github.com/Arniiiii/AddBoost.cmake/archive/refs/tags/${AddBoost.cmake_VERSION}.tar.gz"
)- Use the
add_boostmacro. Notice NOT wrapping variables like TRY_BOOST_VERSION and so on in"${}"when sending arguments to the macro
set(TRY_BOOST_VERSION "1.88.0.beta1")
set(BOOST_MY_OPTIONS "BOOST_ENABLE_PYTHON ON;")
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "thread;system")
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio;beast;uuid;container;cobalt")
add_boost(
TRY_BOOST_VERSION BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED
BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED your_target_name your_target_name2 your_target_name...
)- Add Boost's install target (notice
${ADDBOOSTCMAKE_PACKAGEPROJECT_INSTALL_TARGETS}): (Assumed that your target is named${PROJECT_NAME})
string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION)
string(TOLOWER ${PROJECT_NAME}/export.h EXPORT_HEADER_LOCATION)
set_property(TARGET ${PROJECT_NAME} PROPERTY VERSION ${PROJECT_VERSION})
set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION ${PROJECT_VERSION})
CPMAddPackage(
NAME PackageProject.cmake
VERSION 1.12.0
GITHUB_REPOSITORY "TheLartians/PackageProject.cmake"
)
packageProject(
NAME ${PROJECT_NAME}
VERSION ${PROJECT_VERSION}
NAMESPACE ${PROJECT_NAME}
BINARY_DIR ${PROJECT_BINARY_DIR}
INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
INCLUDE_DESTINATION include/${PROJECT_NAME}
VERSION_HEADER "${VERSION_HEADER_LOCATION}"
EXPORT_HEADER "${EXPORT_HEADER_LOCATION}"
COMPATIBILITY "AnyNewerVersion" DISABLE_VERSION_SUFFIX ON
DEPENDENCIES "${ADDBOOSTCMAKE_PACKAGEPROJECT_INSTALL_TARGETS}"
)
- Finds local Boost ( you can set
-DCPM_USE_LOCAL_PACKAGES=1for "looking for local Boost. if failed: download" mode. Set-DCPM_LOCAL_PACKAGES_ONLY=1to only look for installed Boost and emit error if failed to find) - Downloads boost, if
-DCPM_USE_LOCAL_PACKAGES=1and there's installed Boost with lower version than needed or if installed Boost doesn't exist on the system or if-DCPM_DOWNLOAD_ALL=1is set. - Links Boost to what targets you need by itself
- If you don't want to download Boost multiple times (when you deleted
buildfolder and going to reconfigure), set-DCPM_SOURCE_CACHE=./.cache/cpmor something like. - Gives appropriate string for you to add to
PackageProject.cmake - Makes Boost generate appropriate install targets
- If you download Boost, you can add additional configuring options just by either setting them before calling
functionmacroadd_boost(...)or by settingBOOST_MY_OPTIONSto something like"OPTION value;OPTION2 value;"for exampleBOOST_ENABLE_PYTHON ON;. - Little bit tested at Arniiiii/ModernCppStarterExampleBoostCmake and at some of my projects.
- If you have your own Boost directory, set
BOOST_USE_MY_BOOST_DIRECTORYto be the path with your Boost before calling thefunctionmacroadd_boost(...). - If you want, you can link Boost libs yourself, since the code is macro, not a function: copy and paste some last parts of the main CMakeLists.txt of the project and adjust for yourself.
- You can link Boost libs automagically to multiple targets just by adding them to the end of the
add_boost(...)macro. - You can use
ADDBOOSTCMAKE_LINK_TYPEto override default behaviour of linking: if target is INTERFACE, use INTERFACE, if else: PUBLIC - Correctly handles attempts to get beta versions like
boost-1.88.0.beta1, sincefind_packageconsiders such version as incorrect, but we understand what you mean ^_^ - You can install the AddBoost.cmake on your SYSTEM !!! Use
-DAddBoost.cmake_INSTALL=ONcommand line option at configuring and install as a usual CMake package. And yes, it supports versioning!find_package(AddBoost.cmake 3.7.2) - Internally, this uses my fork of CPM with better logging handling. Waiting until PRs for CPM are going to be reviewed...
- Cannot check existence of header only components of installed Boost, since it relies on functionality of
find_package(Boost ${VERSION} ${COMPONENTS}). Therefore, set version of Boost you need so that it have the library. - (CPM's problem) Almost impossible to get a reason why it failed to use an installed Boost if
-DCPM_USE_LOCAL_PACKAGES=1. Temporary solution:-DCPN_LOCAL_PACKAGES_ONLY=1will show the reason, but it has a problem too: it will make all CPM to only find packages, not add. But it works, trust me. - (CPM's problem) To use patches or any version of Boost before 1.85.0, consider specifing any folder for caching downloaded sources via
-DCPM_SOURCE_CACHE=/path/to/a/folder/for/downloaded/sources/. On Linux, you may use~/.cache/cpm(per user) ,./.cache/cpm(per work folder) or whatever else. - You can apply your patches to Boost. Before calling the
functionmacroadd_boost(...), define variableBOOST_ADD_MY_PATCHESto be a path to folder in which there's*.patchin such layout:
patches/
└── boost
├── 1.80.0
│ ├── a.patch
│ └── b.patch
├── 1.80.0.beta1
│ └── c.patch
├── 1.81.0
│ └── d.patch
├── 1.81.0.beta1
│ └── d.patch
├── 1.82.0
│ └── e.patch
├── 1.83.0
│ └── f.patch
├── 1.84.0
│ └── g.patch
├── patch_for_all_versions1.patch
└── i_dont_care_to_what_boost_version_itll_apply.patch
Where in folder with specific version will be patches, that will apply only to this version, if it's specified.
MIT