Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libboost-headers CMake 3.30 compatibility #226

Open
mgovers opened this issue Jan 15, 2025 · 4 comments
Open

libboost-headers CMake 3.30 compatibility #226

mgovers opened this issue Jan 15, 2025 · 4 comments
Labels

Comments

@mgovers
Copy link

mgovers commented Jan 15, 2025

Comment:

Is there a way to get libboost-headers (or equivalent; i.e. without any binaries) as well as a BoostConfig.cmake file?

We develop tooling with a header-only core and use conda-forge/libboost-headers to install the installed Boost headers as a dependency (for Windows). Up until recently, that has worked just fine. Recently, however, CMake has decided to phase out FindBoost.cmake. That means that we are unfortunately forced to either:

It would be great if we could have a libboost-headers-devel (or similar), that's compatible with both the most recent CMake policy and the smaller dependency size.

I am willing to contribute myself if needed.

@h-vetinari
Copy link
Member

The problem is that we cannot split a single file (like BoostConfig.cmake) across several packages. If we put it in libboost-headers-devel, then CMake will contain that it cannot find the binaries. If we package a header-only version in such an output, then the BoostConfig.cmake in libboost-devel will clobber that file (with undetermined rules which file wins).

So unfortunately, I don't think there's a realistic alternative to using the full libboost-devel if you want to have CMake metadata (or you cross your fingers that CMake will not remove the old policy for a while yet).

@mgovers
Copy link
Author

mgovers commented Jan 22, 2025

Wouldn't the COMPONENTS and OPTIONAL_COMPONENTS allow for such a solution?

In particular, Boost::headers is a required COMPONENT. Other components are not required, unless ALL is specified, or the user requests specific COMPONENTS in the find_package command.

I.e. find_package(Boost CONFIG COMPONENTS Boost::headers) may pass regardless of whether the currently investigated installation of Boost is header-only or not. On the other hand, find_package(Boost CONFIG COMPONENTS ALL) (or plainly find_package(Boost CONFIG) by default) will fail on a header-only installation, and instead try to look for the next one that does in fact result in an installation with all libs installed.

[for reference] Citing the BoostConfig.cmake from libboost-devel version 1.87.0:

# Find boost_headers

boost_find_component(headers 1 0)

if(NOT boost_headers_FOUND)

  set(Boost_FOUND 0)
  set(Boost_NOT_FOUND_MESSAGE "A required dependency, boost_headers, has not been found.")

  return()

endif()

# Compatibility variables

set(Boost_MAJOR_VERSION ${Boost_VERSION_MAJOR})
set(Boost_MINOR_VERSION ${Boost_VERSION_MINOR})
set(Boost_SUBMINOR_VERSION ${Boost_VERSION_PATCH})

set(Boost_VERSION_STRING ${Boost_VERSION})
set(Boost_VERSION_MACRO ${Boost_VERSION_MAJOR}0${Boost_VERSION_MINOR}0${Boost_VERSION_PATCH})

get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
set(Boost_LIBRARIES "")

# Find components

if("ALL" IN_LIST Boost_FIND_COMPONENTS)

  # Make sure "ALL" is the only requested component.
  list(LENGTH Boost_FIND_COMPONENTS __boost_find_components_count)
  if(NOT ${__boost_find_components_count} EQUAL 1)
    message(AUTHOR_WARNING "ALL cannot be combined with named components; the named components will be ignored.")
  endif()

  unset(__boost_find_components_count)

  set(Boost_ALL_TARGETS Boost::headers)

  boost_find_all_components()

else()

  foreach(__boost_comp IN LISTS Boost_FIND_COMPONENTS)

    boost_find_component(${__boost_comp} ${Boost_FIND_REQUIRED_${__boost_comp}} 0)

  endforeach()

endif()

@h-vetinari
Copy link
Member

find_package(Boost CONFIG) [...] will fail on a header-only installation

That's the main issue, because a lot of packages are not specifying explicit components.

@mgovers
Copy link
Author

mgovers commented Jan 23, 2025

find_package(Boost CONFIG) [...] will fail on a header-only installation

That's the main issue, because a lot of packages are not specifying explicit components.

I understand. What about the following?

  • Making ALL components the default (on find_package(Boost CONFIG))
  • Only on find_package(Boost CONFIG COMPONENTS headers) be OK with the lesser

I get that it requires a change to the CMakeLists but maybe this is a sustainable solution.

Alternatively, maybe it's possible to do something along the lines of

set(Boost_HEADER_ONLY TRUE)  # or maybe even as a CACHE entry
find_package(Boost CONFIG)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants