Design in general is always "the art to balance contradicting goals".
Here, you have these goals:
- The framework should be simple to use. If your API is 15 header files, then users will always struggle which ones to include and which ones to omit.
- All common functionality should be in a single header file. So file I/O shouldn't be in
string.h but you also don't want 3
string.h header files.
- Dependencies are bad, so you want to reduce them to the smallest amount possible
- Reading huge (amounts of) header files is slow
- Each feature in your header file will raise the risk that you need to include another header file to make it compile.
gtk.h makes sense since you want to build a user interface for your application (point #2). You could argue that people should include each widget individually but then, your framework will become slightly harder to use (point #1).
If you look at old X11/Motif code, you will see dozens of
#include statements at the top of each C source file. It compiles a little bit faster but it takes hours of manual work to maintain these lists.
OTOH, if you put too many features in your header files, you will have too many dependencies in there and one of them might kill you (for example, when this dependency requires another framework with a certain version -> dependency hell).
I hope you understand by now that there is no solution; the problem is too complex and needs to be addressed again every time a new framework is started.
But then there must be a pretty good reason that GTK+ actively prevents including single headers via macro checks. – matthias
For GTK, the
#include statements are part of the public API. With these macros, they are free to rearrange the header files, their content, names and include order, in any way they like at any time without breaking a single existing project.