Non-trivial build hang due to CONFIGURE_DEPENDS in CMake files
Hi, I was recently diagnosing a small build hang and traced it back to the use of CMake GLOB + CONFIGURE_DEPENDS in a handful of Boost libraries. Most of the use cases seem to be specifically for Visual Studio project generation which most libraries handle conditionally, but some do not. One use case (Boost.Url) is GLOBing sources. In my opinion CMake GLOB should not be used at all; instead explicitly listing all sources, including headers, should be the preferred pattern. Since that's a large change probably requiring some discussion, for now I've gone ahead and submitted the following PRs that just continue the pattern used elsewhere. https://github.com/boostorg/assert/pull/49 https://github.com/boostorg/unordered/pull/357 https://github.com/boostorg/openmethod/pull/138 https://github.com/boostorg/static_string/pull/83 https://github.com/boostorg/json/pull/1217 https://github.com/boostorg/url/pull/1015 Thank you, -- chris
Chris Glover wrote:
Hi,
I was recently diagnosing a small build hang and traced it back to the use of CMake GLOB + CONFIGURE_DEPENDS in a handful of Boost libraries.
Most of the use cases seem to be specifically for Visual Studio project generation which most libraries handle conditionally, but some do not.
One use case (Boost.Url) is GLOBing sources.
At the moment we don't need the headers except for IDE projects, but if/when we transition to modules, we'll also have to transition to handling headers with CMake file sets.
In my opinion CMake GLOB should not be used at all; instead explicitly listing all sources, including headers, should be the preferred pattern.
Not sure that maintainers will find it convenient to list headers explicitly. :-)
At the moment we don't need the headers except for IDE projects, but if/when we transition to modules, we'll also have to transition to handling headers with CMake file sets.
In my opinion CMake GLOB should not be used at all; instead explicitly listing all sources, including headers, should be the preferred pattern.
Not sure that maintainers will find it convenient to list headers explicitly. :-)
No, I'm sure. I certainly didn't at first, but I got used to it using Bazel and found the upside to be worth it. The modules case you mention, for example, should be explicit file sets in my opinion. -- chris
Chris Glover wrote:
At the moment we don't need the headers except for IDE projects, but if/when we transition to modules, we'll also have to transition to handling headers with CMake file sets.
In my opinion CMake GLOB should not be used at all; instead explicitly listing all sources, including headers, should be the preferred pattern.
Not sure that maintainers will find it convenient to list headers explicitly. :-)
No, I'm sure. I certainly didn't at first, but I got used to it using Bazel and found the upside to be worth it.
There are also downsides. If you add a header, but forget to add it to the CMakeLists.txt file (not an uncommon occurrence), everything will appear to work fine, but the header will not be installed. This may go undetected for a long time if the test suite does not exercise every header (or does not test installation at all, also not an uncommon occurrence) and if the header is only needed rarely.
On Fri, 30 Oct 2026 at 15:30, Peter Dimov <pdimov@gmail.com> wrote:
There are also downsides. If you add a header, but forget to add it to the CMakeLists.txt file (not an uncommon occurrence), everything will appear to work fine, but the header will not be installed.
This may go undetected for a long time if the test suite does not exercise every header (or does not test installation at all, also not an uncommon occurrence) and if the header is only needed rarely.
I agree. Bazel handles this by explicitly forbidding includes of unlisted files. We can't exactly do what Bazel does but we could get close by copying or symlinking the declared headers somewhere and only including from there. My instincts are telling me that's not a good idea, but it could be done.
Chris Glover wrote:
On Fri, 30 Oct 2026 at 15:30, Peter Dimov <pdimov@gmail.com <mailto:pdimov@gmail.com> > wrote:
There are also downsides. If you add a header, but forget to add it to the CMakeLists.txt file (not an uncommon occurrence), everything will appear to work fine, but the header will not be installed.
This may go undetected for a long time if the test suite does not exercise every header (or does not test installation at all, also not an uncommon occurrence) and if the header is only needed rarely.
I agree. Bazel handles this by explicitly forbidding includes of unlisted files. We can't exactly do what Bazel does but we could get close by copying or symlinking the declared headers somewhere and only including from there. My instincts are telling me that's not a good idea, but it could be done.
At the moment my preferred solution would be to retain the globs, but only use CONFIGURE_DEPENDS for them if Boost is not a subproject. This feels like a reasonable compromise; people who FetchContent Boost don't need to rescan because the Boost sources are static. This can be accomplished by setting a variable BOOST_CONFIGURE_DEPENDS in the superproject to either empty or "CONFIGURE_DEPENDS" appropriately, then using file(GLOB_RECURSE headers ${BOOST_CONFIGURE_DEPENDS} include/*.hpp) instead of file(GLOB_RECURSE headers CONFIGURE_DEPENDS include/*.hpp)
On Fri, 30 Oct 2026 at 16:40, Peter Dimov <pdimov@gmail.com> wrote:
At the moment my preferred solution would be to retain the globs, but only use CONFIGURE_DEPENDS for them if Boost is not a subproject. This feels like a reasonable compromise; people who FetchContent Boost don't need to rescan because the Boost sources are static.
This can be accomplished by setting a variable BOOST_CONFIGURE_DEPENDS in the superproject to either empty or "CONFIGURE_DEPENDS" appropriately, then using
file(GLOB_RECURSE headers ${BOOST_CONFIGURE_DEPENDS} include/*.hpp)
instead of
file(GLOB_RECURSE headers CONFIGURE_DEPENDS include/*.hpp)
That sounds reasonable. Do you want me to update all of the call sites at the same time (ie: remove the AND CMAKE_GENERATOR MATCHES "Visual Studio" from the existing places), or just the ones I'm affected by? -- chris
On Fri, 30 Oct 2026 at 18:27, Chris Glover <c.d.glover@gmail.com> wrote:
That sounds reasonable. Do you want me to update all of the call sites at the same time (ie: remove the AND CMAKE_GENERATOR MATCHES "Visual Studio" from the existing places), or just the ones I'm affected by?
I've added the concept of BOOST_CONFIGURE_DEPENDS in the PR below and updated the other PRs to use this variable instead. https://github.com/boostorg/cmake/pull/108 -- chris
participants (2)
-
Chris Glover -
Peter Dimov