[Capy review] On peer dependencies
I'd like to bring up the issue of peer dependencies in Boost, taking Capy's review as an occasion. Running boostdep --brief capy yields: # Primary dependencies asio # Secondary dependencies align assert # and half of Boost, omitted for brevity This is not a hard dependency - Asio is included in an optional header (capy/buffers/asio.hpp) to facilitate integration. I think this is the right choice, but we lack a way to represent this. Every Boost library depending on Capy and using boostdep will now install Asio and half of Boost (when they likely don't need it). I don't know if this has implications for package managers or not (the b2 people probably know the answer). What's everyone's opinion on this? Should we try to do something to represent the concept of "peer dependency"? (maybe a field in meta.json?) Best, Ruben.
On Tue, Jun 23, 2026 at 10:19 AM Ruben Perez via Boost < boost@lists.boost.org> wrote:
Asio is included in an optional header (capy/buffers/asio.hpp) to facilitate integration.
I would prefer if this was #include <capy/asio/asio.hpp> And then the repository directory include/boost/capy/asio was added to an "ignore" or "optional" list that Boostdep could understand. Thanks
Asio is included in an optional header (capy/buffers/asio.hpp) to facilitate integration.
I would prefer if this was
#include <capy/asio/asio.hpp>
And then the repository directory include/boost/capy/asio was added to an "ignore" or "optional" list that Boostdep could understand.
Thanks
To add data points here, this same thing happens with: * Asio and Boost.Context (via asio/spawn.hpp) * MySQL and Boost.Pfr (via mysql/pfr.hpp) The only problem with an "ignore directory" is that these components may have an implementation header counterpart (mysql/impl/pfr.hpp). Best, Ruben.
On Tue, Jun 23, 2026 at 10:26 AM Ruben Perez <rubenperez038@gmail.com> wrote:
The only problem with an "ignore directory" is that these components may have an implementation header counterpart (mysql/impl/pfr.hpp).
That's OK. Boostdep only promises to show you stock dependencies. If you include an optional header then you get what you get. Thanks
On Tue, 23 Jun 2026 at 19:28, Vinnie Falco <vinnie.falco@gmail.com> wrote:
On Tue, Jun 23, 2026 at 10:26 AM Ruben Perez <rubenperez038@gmail.com> wrote:
The only problem with an "ignore directory" is that these components may have an implementation header counterpart (mysql/impl/pfr.hpp).
That's OK. Boostdep only promises to show you stock dependencies. If you include an optional header then you get what you get.
I may have explained myself incorrectly. You've got an optional header, mysql/pfr.hpp. This header includes mysql/impl/pfr.hpp for the implementation of its template functions (the same way as you've got in Beast). These two are the only places where Boost.Pfr is included, and together form the peer dependency. The user does not include the impl header at all. They just happen to not be in a separate directory.
On Tue, Jun 23, 2026 at 10:45 AM Ruben Perez <rubenperez038@gmail.com> wrote:
I may have explained myself incorrectly. You've got an optional header, mysql/pfr.hpp. This header includes mysql/impl/pfr.hpp for the implementation of its template functions
What I am proposing is that if you have #include <boost/capy/asio/asio.hpp> And we somehow inform boostdep that a directory should be ignored: ./include/boost/capy/asio/ Then the directory will simply not be scanned. If it contains impl/asio.hpp or impl/pfr.hpp, those will similarly be not scanned since they are in a not-scanned directory. I realize this is not how boostdep works today but if we want to support optional dependencies this seems the only rational way to do it without boostdep thinking that we depend on the world. Thanks
On Tue, 23 Jun 2026 at 19:48, Vinnie Falco <vinnie.falco@gmail.com> wrote:
On Tue, Jun 23, 2026 at 10:45 AM Ruben Perez <rubenperez038@gmail.com> wrote:
I may have explained myself incorrectly. You've got an optional header, mysql/pfr.hpp. This header includes mysql/impl/pfr.hpp for the implementation of its template functions
What I am proposing is that if you have
#include <boost/capy/asio/asio.hpp>
And we somehow inform boostdep that a directory should be ignored:
./include/boost/capy/asio/
Then the directory will simply not be scanned. If it contains impl/asio.hpp or impl/pfr.hpp, those will similarly be not scanned since they are in a not-scanned directory.
I realize this is not how boostdep works today but if we want to support optional dependencies this seems the only rational way to do it without boostdep thinking that we depend on the world.
I had thought of adding the individual headers. It reflects the current state of the art better (i.e. I don't see Asio now moving spawn.hpp to a separate directory out of nowhere). We're likely bikeshedding at this point though.
El 23/06/2026 a las 19:47, Vinnie Falco via Boost escribió:
On Tue, Jun 23, 2026 at 10:45 AM Ruben Perez <rubenperez038@gmail.com> wrote:
I may have explained myself incorrectly. You've got an optional header, mysql/pfr.hpp. This header includes mysql/impl/pfr.hpp for the implementation of its template functions
What I am proposing is that if you have
#include <boost/capy/asio/asio.hpp>
And we somehow inform boostdep that a directory should be ignored:
./include/boost/capy/asio/
Then the directory will simply not be scanned. If it contains impl/asio.hpp or impl/pfr.hpp, those will similarly be not scanned since they are in a not-scanned directory.
I realize this is not how boostdep works today but if we want to support optional dependencies this seems the only rational way to do it without boostdep thinking that we depend on the world.
boostdep can be blocked this way: https://github.com/boostorg/multi_index/blob/develop/include/boost/multi_ind... The trick seems quite reasonable to me, as it does what it says and the intent is clear. Joaquín M López Muñoz
boostdep can be blocked this way:
https://github.com/boostorg/multi_index/blob/develop/include/boost/multi_ind...
The trick seems quite reasonable to me, as it does what it says and the intent is clear.
Wow, that's creative. It looks a bit ugly to me, but if it works, it works. Thanks for sharing.
В письме от вторник, 23 июня 2026 г. 20:47:53 MSK пользователь Vinnie Falco via Boost написал:
What I am proposing is that if you have
#include <boost/capy/asio/asio.hpp>
And we somehow inform boostdep that a directory should be ignored:
./include/boost/capy/asio/
boostdep works the way it does because a user's mind also works that way. A user installs a Boost library with its dependencies (using boostdep). The user puts #include <boost/capy/asio/asio.hpp> into his code. Suddenly the user gets compilation errors. The user is now very confused, because he was under impression that he installed required dependencies. So, just creating an exception for boostdep is not enough, there should be some way to clearly signal to users that the header only works if *additional* requirements are satisfied. I was thinking about this for some time, and maybe we could agree upon header naming scheme for such optionally working headers. E.g. boost/copy/ext/asio.hpp. This signals the "extra" nature of the header to the user. We could then teach boostdep to ignore these headers by default (or vice versa, only ignore them optionally).
Dmitry Arkhipov wrote:
В письме от вторник, 23 июня 2026 г. 20:47:53 MSK пользователь Vinnie Falco via Boost написал:
What I am proposing is that if you have
#include <boost/capy/asio/asio.hpp>
And we somehow inform boostdep that a directory should be ignored:
./include/boost/capy/asio/
boostdep works the way it does because a user's mind also works that way. A user installs a Boost library with its dependencies (using boostdep). The user puts #include <boost/capy/asio/asio.hpp> into his code. Suddenly the user gets compilation errors. The user is now very confused, because he was under impression that he installed required dependencies.
So, just creating an exception for boostdep is not enough, there should be some way to clearly signal to users that the header only works if *additional* requirements are satisfied. I was thinking about this for some time, and maybe we could agree upon header naming scheme for such optionally working headers. E.g. boost/copy/ext/asio.hpp. This signals the "extra" nature of the header to the user. We could then teach boostdep to ignore these headers by default (or vice versa, only ignore them optionally).
The way package managers such as vcpkg handle these cases is by having "optional features" that can be installed separately. If you install `capy`, you don't get Asio support, but if you install `capy[asio]` or `capy+asio` or whatever, you do get it. This is also useful for things like bzip2 or zstd support. Actually, if you install `capy`, you get the default features, which may or may not include `asio`. So you might need to install `capy[]` or `capy-asio` or `capy-core` or whatever to not get Asio support. I'm not at all sure that we need all that complexity.
В письме от воскресенье, 28 июня 2026 г. 17:53:40 MSK пользователь Peter Dimov via Boost написал:
The way package managers such as vcpkg handle these cases is by having "optional features" that can be installed separately. If you install `capy`, you don't get Asio support, but if you install `capy[asio]` or `capy+asio` or whatever, you do get it.
This is also useful for things like bzip2 or zstd support.
Actually, if you install `capy`, you get the default features, which may or may not include `asio`. So you might need to install `capy[]` or `capy-asio` or `capy-core` or whatever to not get Asio support.
Piggybacking on my suggestion. boost/capy/ext/asio.hpp and boost/capy/ext/asio/foo.hpp would map to `asio` option/feature of Capy. This would allow packagers to programmatically determine which options a library has. Boost libraries already have a lot of optional features. E.g. Asio itself _optionally_ depends on OpenSSL.
I'm not at all sure that we need all that complexity.
This is indeed a big question.
Dmitry Arkhipov wrote:
В письме от воскресенье, 28 июня 2026 г. 17:53:40 MSK пользователь Peter Dimov via Boost написал:
The way package managers such as vcpkg handle these cases is by having "optional features" that can be installed separately. If you install `capy`, you don't get Asio support, but if you install `capy[asio]` or `capy+asio` or whatever, you do get it.
This is also useful for things like bzip2 or zstd support.
Actually, if you install `capy`, you get the default features, which may or may not include `asio`. So you might need to install `capy[]` or `capy-asio` or `capy-core` or whatever to not get Asio support.
Piggybacking on my suggestion. boost/capy/ext/asio.hpp and boost/capy/ext/asio/foo.hpp would map to `asio` option/feature of Capy. This would allow packagers to programmatically determine which options a library has. Boost libraries already have a lot of optional features. E.g. Asio itself _optionally_ depends on OpenSSL.
Since those are options, maybe opt/ would be a better choice than ext/.
I have a similar problem with OpenMethod. I have optional interop of virtual_ptr with standard smart pointers (OK, they come with the std lib), but I recently added one for boost::intrusive_ptr. More are coming (std::any, boost::any, TypeErasure).
participants (6)
-
Dmitry Arkhipov -
Jean-Louis Leroy -
Joaquin M López Muñoz -
Peter Dimov -
Ruben Perez -
Vinnie Falco