cpm-cmake / CPM.cmake

📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

right now it's not possible to add boost properly using CPM

Gerodote opened this issue · comments

I was disappointed when I saw a not working example with boost. I also was disappointed by the idea of using boost-cmake .

After sometime reading CMake code of boost I finally got it. it was ridiculous to find out that CPM...package() cannot add "option" with multiple values.

Then, It was interesting to find, that boost cmake code is actually good.

here's the working example: ( look at last messages at the issue to see maybe more updated script )

set(TRY_BOOST_VERSION "1.83.0")
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "thread")
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio")

set(IS_BOOST_LOCAL OFF)
if(${CPM_LOCAL_PACKAGES_ONLY})
  message(STATUS "Trying to find Boost...")
  find_package(Boost ${TRY_BOOST_VERSION} REQUIRED COMPONENTS
    ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
  set(IS_BOOST_LOCAL ON)
elseif(${CPM_USE_LOCAL_PACKAGES} OR NOT ${CPM_DOWNLOAD_ALL})
  message(STATUS "Trying to use local Boost...")
  find_package(Boost ${TRY_BOOST_VERSION} COMPONENTS ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
  if(${BOOST_FOUND})
    set(IS_BOOST_LOCAL ON)
    message(DEBUG "boost include dir: ${Boost_INCLUDE_DIRS}")
  endif()
endif()

if(NOT (${BOOST_FOUND}) OR (NOT DEFINED BOOST_FOUND))
  message(STATUS "Trying to download Boost...")
  set(BOOST_INCLUDE_LIBRARIES
    "${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED};${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}")
  CPMAddPackage(
    NAME Boost
    URL
    "https://github.com/boostorg/boost/releases/download/boost-${TRY_BOOST_VERSION}/boost-${TRY_BOOST_VERSION}.tar.xz"
  )
  set(IS_BOOST_LOCAL OFF)

endif()


if(${IS_BOOST_LOCAL})
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost)
else()
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::asio)
endif()
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::thread)

Thank you!
This code works for header only and non-header only boost libs!


set(BOOST_INCLUDE_LIBRARIES "thread;asio")

CPMAddPackage(
    NAME Boost
    URL "https://github.com/boostorg/boost/releases/download/boost-1.83.0/boost-1.83.0.tar.xz"
  )

target_link_libraries(${PROJECT_NAME}
 PUBLIC Boost::asio
 PUBLIC Boost::thread)

@US3RN2ME You are welcome. Though, your code won't work for local boost because there it's assumed that all header-only libs are under Boost::boost , not Boost::specific_header-only_lib . That's why there's a lot of mess in my code: I don't know how to properly add COMPONENTS keyword to CPM...Package .

a problem with the solution found.

Assume we have two projects and both use Boost of the same version: One use only one stuff and second another stuff from boost.

First project tries CPM...Package( second_project ) . We got a problem : Boost from first project is added, but only what first project needs, and when in second project CPMAddPackage( boost ) happens, it does nothing, because it thinks that the boost is added, but we know that yes, maybe it's added, but only different stuff from it we need.

Possible solutions:

  1. Patch CPM:
  • allow add not only options, but cache variable that is relevant to a project
  • modify CPMRegisterPackage to save not only package name and version, but also options and cache variables. Assuming, we can add variable that contains list, and after reading https://stackoverflow.com/questions/17862512/how-to-pass-a-list-of-lists-to-cmake-macro I got to assumption we should add not cache variables, but their names.
  • modify cpm_check_if_package_already_added to make it check by options and cache variables too. also, it should be able to throw error , if it's with another flags, that cannot be merged.
  • somehow re-add_subdirectory or force cmake reconfigure itself with additional variables.
  • test it
  1. in my solution make the check manually. Sounds hacky.
  2. Use CPM with another package manager in conjunction. For instance, use vcpkg + CPM or OS-specific manager + CPM . The solution works, though I wouldn't do it because I like the possibility of cmake to compile all my dependency from cmake with cmake's flags and chosen compiler from cmake. E.g. vcpkg usually compiles everything with gcc on linux. Yes, it's possible to replace triplet to make it compile using clang and specific flags, though it's a little bit hard.

at first glance I see a problem I cannot solve: IDK how to remove result of add_subdirectory and then add_subdirectory again.

After some time googling, I cannot found a solution.

I assume, the idea of registering options and merging options and then re-add_subdirectory is not possible because of the bottleneck of cmake itself.

If someone can tell me how to do that, I can add modification and write smth that will work using re add_subdirectory or make CMake reconfigure from cmake code with new options.

boost-specific solutions:
1.hacky check what libs in boost are included, what are not, and then add_subdirectory at those libs which are not added.
2. add the all needed stuff from boost for all sub-projects and a project once at top level. Sounds like a crutch.

for anyone who want to use Boost::mpi:

you need to add an OPTION:

    CPMAddPackage(
      NAME Boost
      URL
      "https://github.com/boostorg/boost/releases/download/boost-${TRY_BOOST_VERSION}/boost-${TRY_BOOST_VERSION}.tar.xz"
      OPTIONS "BOOST_ENABLE_MPI ON"
    )

Ref: upstream cmake file: https://github.com/boostorg/mpi/blob/347595c77379ac5cbfc6e4474fe315398fef355e/CMakeLists.txt#L63

Do you know Why you should NOT use Boost git repo with CPM.cmake

It works, but you can't easily install any boost library!

See too https://discourse.cmake.org/t/fetchcontent-with-boost/6596

@Gerodote Q: Assume we have two projects and both use Boost of the same version: One use only one stuff and second another stuff from boost.

This is no Problem, because every library linked is build from boost:

cmake_minimum_required(VERSION 3.14...3.28 FATAL_ERROR)

project(CPMExampleBoost)

# ---- Create binary ----

add_executable(CPMExampleBoost main.cpp)
target_compile_features(CPMExampleBoost PRIVATE cxx_std_17)

# ---- Dependencies ----

include(../../cmake/CPM.cmake)
include(FetchContent)

option(BUILD_SHARED_LIBS "yes/no" YES)

CPMAddPackage(
  NAME Boost
  URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz
  URL_MD5 893b5203b862eb9bbd08553e24ff146a
  EXCLUDE_FROM_ALL ON
  SYSTEM ON
)

add_library(scoped_lock scoped_lock.cpp scoped_lock.hpp)
target_link_libraries(scoped_lock PUBLIC Boost::core)
install(FILES scoped_lock.hpp TYPE INCLUDE)
install(TARGETS scoped_lock boost_core)

target_link_libraries(CPMExampleBoost PRIVATE Boost::asio)
install(TARGETS CPMExampleBoost boost_asio)

set(CPACK_GENERATOR TBZ2)
include(CPack)

The real problem is that no headers and not all libs are installed without a warning from cmake!

dyld_info /Users/clausklein/cmake/TheLartians/CPM.cmake/examples/boost/build/_CPack_Packages/Darwin/TBZ2/CPMExampleBoost-0.1.1-Darwin/bin/CPMExampleBoost
/Users/clausklein/cmake/TheLartians/CPM.cmake/examples/boost/build/_CPack_Packages/Darwin/TBZ2/CPMExampleBoost-0.1.1-Darwin/bin/CPMExampleBoost [x86_64]:
    -platform:
        platform     minOS      sdk
           macOS     13.6      14.2   
    -segments:
        load-offset   segment section        sect-size  seg-size perm
        0x00000000    __TEXT                                80KB r.x
        0x00005DC0             __text            46663
        0x00011407             __stubs             468
        0x000115DC             __init_offsets       32
        0x000115FC             __gcc_except_tab   4424
        0x00012750             __const            2183
        0x00012FD7             __cstring          1406
        0x00013558             __unwind_info      2728
        0x00014000    __DATA_CONST                          16KB rw.
        0x00014000             __got              1088
        0x00014440             __const            4120
        0x00018000    __DATA                                16KB rw.
        0x00018000             __data              136
        0x00018088             __thread_vars        24
        0x000180A0             __thread_ptrs         8
        0x000180A8             __thread_bss          8
    -dependents:
        attributes     load path
                       @rpath/libboost_coroutine.1.84.0.dylib
                       @rpath/libboost_context.1.84.0.dylib
                       @rpath/libboost_date_time.1.84.0.dylib
                       @rpath/libboost_container.1.84.0.dylib
                       /usr/lib/libc++.1.dylib
                       /usr/lib/libSystem.B.dylib
bash-5.2$ cat install_manifest.txt
/Users/clausklein/cmake/TheLartians/CPM.cmake/examples/boost/build/_CPack_Packages/Darwin/TBZ2/CPMExampleBoost-0.1.1-Darwin/include/scoped_lock.hpp
/Users/clausklein/cmake/TheLartians/CPM.cmake/examples/boost/build/_CPack_Packages/Darwin/TBZ2/CPMExampleBoost-0.1.1-Darwin/lib/libscoped_lock.dylib
/Users/clausklein/cmake/TheLartians/CPM.cmake/examples/boost/build/_CPack_Packages/Darwin/TBZ2/CPMExampleBoost-0.1.1-Darwin/bin/CPMExampleBoost
bash-5.2$ 
``

Is this the same issue?

# Download CPM.cmake                                                                                                                             
file(                                                                                                                                            
  DOWNLOAD      https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.38.3/CPM.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake           
  EXPECTED_HASH SHA256=cc155ce02e7945e7b8967ddfaff0b050e958a723ef7aad3766d368940cb15494                                                          
)                                                                                                                                                
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)        

# Boost libraries                                                                                                                                
CPMAddPackage(                      
  NAME Boost                               
  VERSION  1.84.0    
  URL      https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz   
  URL_HASH SHA256=2e64e5d79a738d0fa6fb546c6e5c2bd28f88d268a2a080546f74e5ff98f29d0e
  OPTIONS   
    "BOOST_ENABLE_CMAKE ON"  
    # This doesn't work: boost thinks this is one library called  "system container".  
    "BOOST_INCLUDE_LIBRARIES system container"                                                             
)                                                                                                                                  

And the relevant output from cmake:

-- Boost: libraries included: system container
CMake Warning at Build/_deps/boost-src/tools/cmake/include/BoostRoot.cmake:223 (message):
  Library 'system container' given in BOOST_INCLUDE_LIBRARIES has not been
  found.

Or should I check for/write a new issue?

No, it is an CPM.cmake Interface Problem

"BOOST_INCLUDE_LIBRARIES system\;container"

it must be a quotend list!

But you don't need to set this options

I don't need to set this option, but I want to!

The following line works for me:

 "BOOST_INCLUDE_LIBRARIES system\\\;container"  # Note the escapes! 

Multiple escapes are required. This is the ONLY thing that worked for me, but it works well. CPM does a nice job. :-)

I wrote #531 to add multiple escapes to the boost example.

@ClausKlein

@Gerodote Q: Assume we have two projects and both use Boost of the same version: One use only one stuff and second another stuff from boost.
...

I've done next to understand is it possible to make an option in cmake and have installable boost and not rewrite their cmake script:

  1. I took ModernCppStarter
  2. Removed header and replaced code of greater.cpp with an example of boost-asio for tcp echo server.
  3. Placed my script
  4. Added in packageProject boost-1.84.0
  5. Got fail because there were no target boost_asio and so on
  6. Checked boost/tools/cmake/include/BoostRoot.cmake and boost/tools/cmake/include/BoostInstall.cmake
  7. I found smth related to installing: BOOST_SKIP_INSTALL_RULES
  8. Tried to change it at user level. Fail.
  9. Tried to "patch" the place where it sets the variable to TRUE manually by editing CPM's cache.
  10. Successfully compiled
  11. Tried to install it in a folder with cmake --install ./path/to/build/folder --prefix ./a_folder/
  12. In a folder there's a lot of boost stuff, including headers
  13. Made a patch, using common method described here
  14. Checked if applying the patch works. It seemed, I had patch command but not apply.
  15. It compiles successfully.
  16. cmake --install ./path/to/build/folder --prefix ./a_folder/ installs a lot of boost related stuff in the a_folder.

So, please check if this actually works.

Here's the repo with working example: link to my repo with working example

The CMake script:

set(TRY_BOOST_VERSION "1.84.0")
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "thread")
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio")

set(IS_BOOST_LOCAL OFF)
if(${CPM_LOCAL_PACKAGES_ONLY})
  message(STATUS "Trying to find Boost...")
  find_package(Boost ${TRY_BOOST_VERSION} REQUIRED COMPONENTS
    ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
  set(IS_BOOST_LOCAL ON)
elseif(${CPM_USE_LOCAL_PACKAGES} OR NOT ${CPM_DOWNLOAD_ALL})
  message(STATUS "Trying to use local Boost...")
  find_package(Boost ${TRY_BOOST_VERSION} COMPONENTS ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
  if(${BOOST_FOUND})
    set(IS_BOOST_LOCAL ON)
    message(DEBUG "boost include dir: ${Boost_INCLUDE_DIRS}")
  endif()
endif()

if(NOT (${BOOST_FOUND}) OR (NOT DEFINED BOOST_FOUND))
  message(STATUS "Trying to download Boost...")
  set(BOOST_INCLUDE_LIBRARIES
    "${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED};${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}")
  CPMAddPackage(
    NAME Boost
    URL
    "https://github.com/boostorg/boost/releases/download/boost-${TRY_BOOST_VERSION}/boost-${TRY_BOOST_VERSION}.tar.xz"
    DOWNLOAD_ONLY YES
  )
  message(DEBUG "It's gonna execute next: patch -rnN -p1 -d ${Boost_SOURCE_DIR} -i ${CMAKE_CURRENT_SOURCE_DIR}/patches/boost/boost_cmake_enable_install_rules_for_add_subdirectory_case.patch  ")
  execute_process(COMMAND patch -rnN -p1 -d ${Boost_SOURCE_DIR} -i ${CMAKE_CURRENT_SOURCE_DIR}/patches/boost/boost_cmake_enable_install_rules_for_add_subdirectory_case.patch  ) # -N is essential. it won't allow patch twice.
  add_subdirectory(${Boost_SOURCE_DIR})
  set(IS_BOOST_LOCAL OFF)
endif()

...

add_library(${PROJECT_NAME} ${headers} ${sources})

...

if(${IS_BOOST_LOCAL})
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost)
else()
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::asio)
endif()
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::thread)

...
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}-${PROJECT_VERSION}
  VERSION_HEADER "${VERSION_HEADER_LOCATION}"
  COMPATIBILITY SameMajorVersion
  DEPENDENCIES "Boost 1.84.0"
)

The patch:

diff --git a/tools/cmake/include/BoostRoot.cmake b/tools/cmake/include/BoostRoot.cmake
index e93f9071..f0380b39 100644
--- a/tools/cmake/include/BoostRoot.cmake
+++ b/tools/cmake/include/BoostRoot.cmake
@@ -108,7 +108,7 @@ else()
   endif()
 
   set(BUILD_TESTING OFF)
-  set(BOOST_SKIP_INSTALL_RULES ON)
+  set(BOOST_SKIP_INSTALL_RULES OFF)
 
 endif()
 

You build an excecutable and linked it against the shared boost libs, right?

It seems I've built a lib with static boost libs.

I don't get now how to use packageProject with executable ( why it should be ? )

With shared libs you get errors like this:

CMake Error: install(EXPORT "tftpdTargets" ...) includes target "boost_asio" which requires target "boost_align" that is not in any export set.

To test installed version: cd test; cmake -D TEST_INSTALLED_VESION=1 ....

not gonna lie, but the solution that closes the issue, still has the problem with installing smth with boost. I mean there's no shared libs, if BUILD_SHARED_LIBS=ON was given to boost.

Currently, I have no idea how to solve by not rewriting current boost's cmake. We need further investigation in this.

even more, the shared libs in installed stuff links to nowhere, so lddtree ./a_binary_that_depends_on_a_boost_shared_libs shows smth like boost_chrono -> [None]

Though building something with boost worked correctly, and with proposed "solution" works too.

without patching boost's cmake it's impossible to use TheLartians's packageProject script because of inexistence install(TARGET ...) in the case of add_subdirectory in boost's cmake of similar stuff.

Maybe I can find some time to look at this next week. It would be nice if this was simple.

@Gerodote I think what you may want to do in YOUR project is to install the Boost libraries YOU depend on. See here for a very basic example.

Modifying Boost's CMake files to install only the libraries that you need seems like too much work, and I can't imagine the Boost maintainers would take that pull request seriously (but maybe?). They are already overworked as it is.

If your project depends on multiple sub-projects that also depend on Boost, I think this works fine as long as you analyze what they use and make sure your CPM tells boost what to build. But there is always a possibility you will need to add patches to them. If your project is complicated is very probable. (You will, of course, want to provide these patches back to the maintainers if it makes sense.)

I just don't understand one stuff:

I see at cmake debugger that cmake goes through boost's script and "does" install(TARGET ... ) install(FILE ... ) for libs, headers and scripts.

BUT NOTHING installs.

And yeah, your idea to rewrite install script is good actually, but I genuinly have no idea why this happens.

Also, I made a patch that correctly (including all dependencies) install boost_*.so , boost_*.a libs .
No headers installed, no boost's cmake script files

Here's semi-working repo

you can test it all by
docker build . (look at logs carefully)
docker run -it container_id bash ( to do some testing by yourself )

oh

I got it

boost puts its install rules not to ./build/cmake_install.cmake
but to ./build/_deps/boost-build/cmake_install.cmake

How I got this:

  1. remove install rules from my cmake for boost libs
  2. get it all rebuilt
  3. cmake --install ./build/_deps/boost-build --prefix ./install_dir
  4. Got what I need from boost + headers + cmake scripts installed

Now we just need to figure out why this happens

Check out magic_enum. I don't have a public project, but I was able to install magic_enum's files when I added it to a private as follows:

CPMAddPackage(
  NAME magic_enum
  URL      https://github.com/Neargye/magic_enum/archive/refs/tags/v0.9.5.tar.gz
  URL_HASH SHA256=44ad80db5a72f5047e01d90e18315751d9ac90c0ab42cbea7a6f9ec66a4cd679
  SYSTEM   True
  OPTIONS
    MAGIC_ENUM_OPT_INSTALL True
)  

It's only the header files, but it works in the way you want. Plus it's just a cool library. :-)

In boost, maybe the function to look at is boost_install_target? Maybe this line is messing you up?

I guess the problem was that somehow CPM...(DOWNLOAD_ONLY) + add_subdirectory(${Boost_SOURCE_DIR} ${Boost_BINARY_DIR} SYSTEM EXCLUDE_FROM_ALL) wasn't working well.

Right now it works !

The example at https://github.com/Gerodote/ModernCppStarterExampleBoostCmake

Generally speaking, it requires one patch to boost's cmake:

diff --git a/tools/cmake/include/BoostRoot.cmake b/tools/cmake/include/BoostRoot.cmake
index e93f9071..f0380b39 100644
--- a/tools/cmake/include/BoostRoot.cmake
+++ b/tools/cmake/include/BoostRoot.cmake
@@ -108,7 +108,7 @@ else()
   endif()
 
   set(BUILD_TESTING OFF)
-  set(BOOST_SKIP_INSTALL_RULES ON)
+  set(BOOST_SKIP_INSTALL_RULES OFF)
 
 endif()
 

and such lines:

set(TRY_BOOST_VERSION "1.84.0")
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "thread")
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio")

option(BUILD_SHARED_LIBS "yes/no" YES)

set(IS_BOOST_LOCAL OFF)
if(${CPM_LOCAL_PACKAGES_ONLY})
  message(STATUS "Trying to find Boost...")
  find_package(
    Boost ${TRY_BOOST_VERSION} REQUIRED
    COMPONENTS ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}
  )
  set(IS_BOOST_LOCAL ON)
elseif(${CPM_USE_LOCAL_PACKAGES} OR NOT ${CPM_DOWNLOAD_ALL})
  message(STATUS "Trying to use local Boost...")
  find_package(
    Boost ${TRY_BOOST_VERSION} COMPONENTS ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}
  )
  if(${BOOST_FOUND})
    set(IS_BOOST_LOCAL ON)
    message(DEBUG "boost include dir: ${Boost_INCLUDE_DIRS}")
  endif()
endif()

if(NOT (${BOOST_FOUND}) OR (NOT DEFINED BOOST_FOUND))
  message(STATUS "Trying to download Boost...")

  set(BOOST_INCLUDE_LIBRARIES
      "${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED};${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}"
  )
  find_package(Patch REQUIRED)

  set(PATCH_COMMAND_ARGS "-rnN")

  file(GLOB_RECURSE patches_for_boost CONFIGURE_DEPENDS
       "${CMAKE_CURRENT_SOURCE_DIR}/patches/boost/*.patch"
  )

  set(PATCH_COMMAND_FOR_CPM_BASE "${Patch_EXECUTABLE}" ${PATCH_COMMAND_ARGS} -p1 <)

  set(PATCH_COMMAND_FOR_CPM "")
  foreach(patch_filename IN LISTS patches_for_boost)
    list(APPEND PATCH_COMMAND_FOR_CPM ${PATCH_COMMAND_FOR_CPM_BASE})
    list(APPEND PATCH_COMMAND_FOR_CPM ${patch_filename})
    list(APPEND PATCH_COMMAND_FOR_CPM &&)
  endforeach()
  list(POP_BACK PATCH_COMMAND_FOR_CPM)

  message(DEBUG "Patch command: ${PATCH_COMMAND_FOR_CPM}")

  CPMAddPackage(
    NAME Boost
    URL "https://github.com/boostorg/boost/releases/download/boost-${TRY_BOOST_VERSION}/boost-${TRY_BOOST_VERSION}.tar.xz"
        PATCH_COMMAND ${PATCH_COMMAND_FOR_CPM}
    OPTIONS "BOOST_ENABLE_CMAKE ON"
  )

  set(IS_BOOST_LOCAL OFF)
endif()

...



# Link dependencies 
if(${IS_BOOST_LOCAL})
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::boost)
else()
  foreach(a_lib ${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
    target_link_libraries(${PROJECT_NAME} PUBLIC Boost::${a_lib})
  endforeach()
endif()

foreach(a_lib ${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED})
  target_link_libraries(${PROJECT_NAME} PUBLIC Boost::${a_lib})
endforeach()

@ClausKlein Can you check it please? I guess it now works. I checked it with "new environment" like a docker with a linux without boost.

On the first view, it works

But you install an partial and unusable boost library!

Boost::boost, Boost::header are missing too!

cmake -S test -B build-x86_64-Debug/test -G Ninja -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/local/bin/ccache -D CMAKE_BUILD_TYPE=Debug -D CMAKE_PREFIX_PATH=/Users/clausklein/Workspace/cpp/stagedir -D BUILD_TESTING=YES -D BUILD_SHARED_LIBS=YES -D CMAKE_UNITY_BUILD=NO -D FMT_MODULE=NO -D CMAKE_CXX_STANDARD=23 -D TEST_INSTALLED_VERSION=1 -D CPM_USE_LOCAL_PACKAGES=YES
-- The CXX compiler identification is AppleClang 15.0.0.15000309
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/usr/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CPM: Using local package doctest@2.4.11
-- Found Git: /usr/local/bin/git (found version "2.44.0") 
-- Found Python: /usr/local/Frameworks/Python.framework/Versions/3.12/bin/python3.12 (found version "3.12.2") found components: Interpreter 
-- CPM: Adding package Format.cmake@1.7.3 (v1.7.3 at /Users/clausklein/.cache/CPM/format.cmake/17e103764947115e78d95ecc29c4bee54dc64e08)
-- Found Boost: /Users/clausklein/Workspace/cpp/stagedir/lib/cmake/Boost-1.84.0/BoostConfig.cmake (found suitable version "1.84.0", minimum required is "1.84.0")  
CMake Error at CMakeLists.txt:22 (find_package):
  Found package configuration file:

    /Users/clausklein/Workspace/cpp/stagedir/lib/cmake/Greeter/GreeterConfig.cmake

  but it set Greeter_FOUND to FALSE so package "Greeter" is considered to be
  NOT FOUND.  Reason given by package:

  The following imported targets are referenced, but are missing: Boost::asio
  Boost::thread



-- Configuring incomplete, errors occurred!
bash-5.2$ ```

On the first view, it works

But you install an partial and unusable boost library!

Boost::boost, Boost::header are missing too!

but it set Greeter_FOUND to FALSE so package "Greeter" is considered to be
NOT FOUND. Reason given by package:

The following imported targets are referenced, but are missing: Boost::asio
Boost::thread

I thought the idea is to install only needed boost libraries, Boost::boost and Boost::header, I guess, shouldn't exist. Aren't those targets exist only for full boost installed versions? Or you guess we should get install all header-only libs and some not header-only libs and get it installed as usually boost is with b2 ?

I'm more concerned that it haven't found Boost::asio and Boost::thread. I should test more about that.