Hi all, Boost.Container has needed separate compilation for about a decade due to two small utilities. The extended allocators (the dlmalloc-derived heap) needed it since late 2013, and the polymorphic memory resources (PMR) since they were added in 2015. On the develop branch for 1.93 I've found a way to make it header-only again, because I think it greatly improves the usability of the library. Since this might cause some problems to users, I'd like to explain a bit how this was done in case some problems are detected and users need some hints to debug it. The need for a compiled library came from globals that were needed for two reasons: * The dlmalloc heap used by the extended allocators. This includes its arena, data structures, mutex, and tuning parameters. Memory allocated through one module (DLL) must be freeable through another (across DLLs). * The polymorphic memory resource singletons. This includes the default-resource slot that set_default_resource() writes and get_default_resource() reads and the global new_delete_resource of null_memory_resource. A compiled library provides this automatically (when properly compiled an linked/loaded), but a header-only library has some problems. Every DLL (on Windows) compiles its own copy. boost::container::pmr::vector allocated in the DLL and destroyed would return its memory to the wrong heap. In Boost 1.93, a private new utility (detail/intermodule_globals.hpp) provides a class (dtl::intermodule_globals<T, Options>) that returns a reference to a single object of type T for each T/Options pair. The object is shared by every module in the process. It is constructed on zero-initialized storage by whichever module reaches it first with some configurable options (like a phoenix singleton for those globals that need to be available to the very end of the program, like a heap allocator). The dlmalloc globals and the PMR globals are the only two users inside the library. On ELF and Mach-O the global object is implemented as a static data member of a class template, with default visibility (so that the loader unifies all the instances from each .so and .elf). On windows and Cygwin, since PE/COFF has no equivalent symbol merging, a shared memory segment is created where a incremental (linear) hash map is built to find singletons by name and those singleton objects are also constructed in that shared memory segmented (accesible by all the DLLs that need access to globals). Boost.Interprocess has a similar utility but it relies on non-trivial Interprocess data structures), it's design is not optimal and I didn't want to make Boost.Container dependant on Boost.Interprocess (that would be a circular dependency). Probably Interprocess will use a similar utility for its module-shared globals in the future if the Boost.Container transition goes reasonably well. Some limitations: * On ELF, STB_GNU_UNIQUE makes the shared object that defines the symbol non-unloadable (e.g. to avoid crashes when calling virtual functions that live on that module). * On windows a similar mechanism (module pinning) is used to avoid unloading the module if the corresponding option is used. * The Windows registry is a fixed-size arena. It is sized (the minimum shared memory is 64KB) for far more singletons than the library uses, so there is some memory waste (in practice, only the virtual address space is reserved, only really used memory is committed). I hope most existing code should continue to work. * BOOST_CONTAINER_DECL still exists and expands to nothing. * BOOST_CONTAINER_DYN_LINK, BOOST_CONTAINER_STATIC_LINK, BOOST_CONTAINER_SOURCE and BOOST_CONTAINER_NO_LIB are still accepted. * BOOST_CONTAINER_HEADER_ONLY has been removed, both as a CMake option and as a macro. I did not add a stub library, not sure how useful is to have it, I think other Boost compiled to header transitions did not add the stub library (Boost.system, on the other hand, provided one for a long time). Some superproject changes will be needed due to this change, Peter Dimov has already identified some changes. If some other Boost libraries or tests are broken due to this header-only transition, let me know so I can help solving them. Thanks, Ion