18

On the Boost library documentation page, there are two categories named "Header Only Libraries" and "Automatic Linking".

I suppose "Header Only Libraries" means you don't have to link against Boost libraries in order to use them, and "Automatic Linking" means you have to link.

But when I use Boost.Timer, I have to link a static or dynamic library named timer (libboost_timer.a and libboost_timer.so.1.48.0 and various soft links to these under Linux library path), which is apparently the exact library file of Boost.Timer. I even need to link against Boost.System and Boost.Chrono, though it is understandable that the library itself uses some other libraries that need to be linked.

On the other side, Boost has clearly stated that Boost.Asio belongs to "Automatic Linking", but there aren't any library files named anything like asio.

So what does it actually mean to be a "header-only library" or "automatic linking"? Or is it purely a mistake?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
WiSaGaN
  • 46,887
  • 10
  • 54
  • 88
  • Someone in comments asked why not all is header-only: http://stackoverflow.com/questions/11363011/why-all-lib-in-boost-are-not-headers-only/11363269#11363269 – Sebastian Mach Aug 06 '12 at 15:08
  • Wouldn't it be possible to chart all self-sufficient Boost libraries by using something like https://stackoverflow.com/questions/42308/tool-to-track-include-dependencies – rwst Apr 23 '18 at 13:29

2 Answers2

11

As you said, "Header only library" means that the whole library is in header files, so one (or several) #include lines is enough to use it. No linking is necessary.

"Automatic linking" means that, although the library needs some linking (either directly or as a dependency), you don't need to specify it in the compiler line, because the #include'd files will do some magic to bring in the appropriate libraries automatically, if supported by the compiler.

For example, in MSVC compilers, they use #pragman comment(lib, "..."); in Borland compilers they use #pragma defineoptions;, etc.

And most notably, "automatic linking" is not supported by the GNU compiler.

Automatic linking can be troublesome sometimes (for example, mixing debug and release versions), and you can selectively disable them by defining some preprocessor macros: BOOST_<libname>_NO_LIB. In that case you will have to do the linking manually.

UPDATE: About your comment below:

Boost.Timer claims to be a "Header only library" but it has lib files in the lib directory.

It looks like there is an error in the Boost documentation. Actually there are two different libraries named timer: The old, deprecated, header-only <boost/timer.hpp> and the new, improved, cooler, automatically linkable <boost/timer/timer.hpp>.

But for some reason, the main documentation page lists the properties of the old one.

There's no Boost.Asio lib files.

In the main Boost library documentation page library documentation page, you can see that Asio is listed as Automatic linking due to dependency. The specific dependencies are listed elsewhere: Boost.System and Boost.Regex, and both present automatic linking.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Could you explain why `Boost.Timer` when claims to be a "Header Only Library" has lib files in the lib directory? And there's no `Boost.Asio` lib files. – WiSaGaN Aug 07 '12 at 08:40
  • The info about Asio's dependency status can no longer be found on that library doc page. Is there any page at all now with that information? – rwst Apr 23 '18 at 13:18
  • @rwst: I don't know what you mean. The latest [docs](https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/using.html) contains that updated information. – rodrigo Apr 23 '18 at 13:39
9

You've pretty much nailed it -- a header only library is one where all the code for that library is contained in the header(s), so you only have to include them, not link against a library to use them.

That said, it's entirely possible to write a header-only library that depends on some other library, which may not be of the header-only variety. In this case, even though you don't have to tell the linker about the first library you're using, you still have to tell it about the second. Especially when/if all the code might be stuffed into one of what the linker thinks of as a library (e.g., one .lib or .a file), that may end up mostly a distinction without a difference (just to be clear: that isn't necessarily the case here, but it can and does arise anyway).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • The linux version of `boost` still has `libboost_timer.a` and `libboost_timer.so.1.48.0` and various soft links to these under lib path though. – WiSaGaN Aug 02 '12 at 01:15
  • 1
    @WiSaGaN: Yes. Boost is a *collection* of libraries, not a single library. Most Boost libraries are header-only. However, some Boost libraries such as Boost.Thread have separate source files that are compiled into object code you need to link to. – In silico Aug 02 '12 at 01:21
  • Why aren't all the files header-only? Bloat issue, or something else? – user541686 Aug 02 '12 at 01:30
  • 1
    @Insilico Yes, I understand that. What's strange is the apparent contradiction between the claim of `Header Only` and the lib file(and the contradiction between the claim of `Automatic Linking` and no lib files). – WiSaGaN Aug 02 '12 at 01:47
  • 1
    @WiSaGaN: Yes, portable open-source libraries tend to be like that... if you find one that's very user-friendly and has pre-built binaries, it's not "cool". You outta build them from scratch and go through the pain. Or at least that's the impression I've gotten from the ones I've used so far. – user541686 Aug 02 '12 at 02:02
  • Pre-built binaries for Windows are fairly common (e.g., for Boost you can download them from [BoostPro Consulting](http://www.boostpro.com/download/)). For Linux, the logistics become much more difficult, just because of the larger number of distros, different versions of gcc involved, etc. – Jerry Coffin Aug 02 '12 at 02:40
  • Pre-built binaries of a library are usually not provided because they would be compiler- (and possibly compiler version) specific. It's hard to see what the harm or trouble is in just compiling them yourself. – Cody Gray - on strike Aug 02 '12 at 02:48
  • 1
    The libraries for boost are built manually after the installation. So I guess it's not a compiler problem. – WiSaGaN Aug 02 '12 at 02:58
  • @CodyGray: I have a hard time imagining harm. The trouble is pretty simple: simple time and effort to build them. If memory serves, building Boost can take an hour or so (obviously depends on the computer though). – Jerry Coffin Aug 02 '12 at 02:59
  • @Mehrdad: I have never compiled boost myself, I have just installed some prepackaged version for the distribution I was running. As of why not always header only, there are multiple reasons, for example it might not be possible (say you have a static member, it has to be defined in exactly one translation unit). At the same time, if the code is complex enough (and not templated), there might be no reason to *recompile* all the functions in each translation unit just to have the linker discard them... – David Rodríguez - dribeas Aug 02 '12 at 03:30
  • @DavidRodríguez-dribeas: Ah, thanks. Yes, the compile time would be an issue, but the static-member part wouldn't, at least not for MSVC -- MSVC has `__declspec(selectany)` just for this. – user541686 Aug 02 '12 at 04:34
  • 1
    @CodyGray, JerryCoffin: Harm? Well, if you don't consider a waste of your time to be harm, then I guess maybe not. :\ Speaking of which -- it reminds me of how tools bcp aren't binary-distributed, either. There's really no point in making the client compile those. All it does is make the library become a user interface disaster. But I guess the assumption around portable open-source tools is that user interface is for end users, not programmers. :( – user541686 Aug 02 '12 at 04:37
  • @Mehrdad: If you are implying that as long as you only want your library to work with one compiler you can get away with it the answer is probably yes. But with C++ (as a language defined by a standard), you cannot do that. Also note that even if you limit your library to windows, not all compilers that target that platform will have that feature (g++, clang++, icpc, borland...) Claiming that something is not an issue because in exactly one compiler for exactly one platform it is not a problem is the same as claiming that running 100m under 10s is not a problem for humans. Now time yourself. – David Rodríguez - dribeas Aug 02 '12 at 12:57
  • @Mehrdad: It seems that you have had quite a bad experience with OSS, but the nice thing in OS is that **you** can get the project, and fix it to your needs. If you think it should be delivered as a binary, it is fairly simple to *compile* it yourself and distribute it, but beware, for libraries it is not so simple. Different compiler options will lead to ABI-incompatible binaries... What compiler options do you want to force into your users? – David Rodríguez - dribeas Aug 02 '12 at 13:03
  • 1
    @DavidRodríguez-dribeas: *"it is fairly simple..."* I wish! (I've only had trouble with portable OSS, not just any OSS.) When it's Windows-only, it's easy to compile, because the project files are already given to you... but when it's cross-platform, it is *not* "fairly simple" to compile it yourself to suit your needs. (Just as *one* example: How do you compile `bcp` with VS, linking statically to the CRT? I haven't figured it out, but I did waste time on trying to do that.) Anyway, providing precompiled binaries is ***not*** "forcing options" onto your users... I'm not sure what you mean. – user541686 Aug 02 '12 at 15:15
  • 1
    Regarding the library binary incompatibility issue: yes, but you can always provide a few different versions for one or more different major compilers... like Boost Pro does, for VS. That is not "limiting" in any way, but it does make your users' lives easier in many cases. – user541686 Aug 02 '12 at 15:33
  • @Mehrdad there's [a question on SO](http://stackoverflow.com/questions/440585/building-boost-bcp) about building bcp using Visual Studio – Sam Miller Aug 02 '12 at 16:57
  • @SamMiller: The answer from VGambit seemed to indicate the flow is different now. Does the old one still work? – user541686 Aug 02 '12 at 17:04
  • @Mehrdad: I don't have windows, so I cannot tell, but do you know what compiler *options* were used to build it? Building with different options can cause ODR violations, in particular if you mix secure vs. unsecure iterators, or multithreaded vs. non-multithreaded options... – David Rodríguez - dribeas Aug 02 '12 at 23:21
  • @DavidRodríguez-dribeas: I know at least *some* of the compiler options indeed (they're displayed somewhere, I remember), but the trouble is that when I try to build it manually, I get all sorts of things missing. It has to be done in a particular order... and while I *could* figure it out if I spend enough time on it, the bottom line is that figuring out the how to compile a meta-tool is just a waste of time, from a *user* perspective. It's not something I should have to deal with, but it seems to be something most portable OSS makes you have to deal with anyway, Boost being no exception. – user541686 Aug 03 '12 at 07:48
  • @Mehrdad: You misinterpreted my comment on the compiler options. The problem is that different compiler options will generate incompatible (at the ABI level) binaries. If you provide a library precompiled, the user cannot freely choose their compiler options, they have to match (to some extent) the options with which the library was built. That is what I meant by *forcing options* on the users. Say that I provide library A compiled without secure iterators for performance, and then you want to use it but with secure iterators (you want to debug something), you now don't have that option. – David Rodríguez - dribeas Aug 03 '12 at 12:48
  • @DavidRodríguez-dribeas: Oh, but you always have the option of recompiling it yourself anyway. Giving away precompiled binaries doesn't prevent that; it only helps make the lives of people who use the same compiler options as you easier. – user541686 Aug 03 '12 at 12:50
  • @Mehrdad: yes, and no. The problem is that ABI violations are not usually be picked up by the linker (I have seen this before many times), and that means that the user chooses the compiler options, usually unaware of what the options in the binary are, and then builds and links against the *simple* option: the precompiled version. And then things go haywire, the behavior of the program is undefined, in some cases it will seem to work, in others it will fail providing some helpful runtime error if you are lucky. And besides that, it is the problem of availability. – David Rodríguez - dribeas Aug 03 '12 at 12:54
  • ... I could not generate a windows binary even if I wanted. I just don't have the tools (I don't have any windows pc, much less all possible combinations of Windows 32/64, VS...) – David Rodríguez - dribeas Aug 03 '12 at 12:55
  • @DavidRodríguez-dribeas: I'm not sure I understand what you're saying here. You're saying it's beneficial *not* to provide binaries, if you're providing the source anyway? I always thought name mangling would pick up some stuff like secure iterators, but I mean, a clear comment right above the binary download link could easily say *"Must be used with projects compiled with `/GS /D_SECURE_SCL=0`"* or whatever, to prevent misuse. Besides, Boost Pro obviously provides binaries, and no one (apparently) has problems with that. I really don't see the problem with providing binaries here. – user541686 Aug 03 '12 at 13:00
  • @Mehrdad: *No one has problems with that* is a bit of an overstatement. We had that particular problem with boost 1.35 in the company I was working for (long enough that 1.35 had just been released). Name mangling does not change for secure/insecure iterators, as with most other compilation options. – David Rodríguez - dribeas Aug 03 '12 at 13:25
  • @DavidRodríguez-dribeas: Interesting... but that's exactly what Boost Pro does, and people seem to like it. Are you saying that's a bad idea? – user541686 Aug 03 '12 at 15:10
  • @Mehrdad: I am just saying that it is not always possible and it is not always the best idea. And it was you the first one to bash compiling boost. I can tell you that the projects I have compiled in linux have always compiled fine in one pass (download, configure, make && make install) – David Rodríguez - dribeas Aug 03 '12 at 15:23
  • Also, about "why are not all header-only": http://stackoverflow.com/questions/11363011/why-all-lib-in-boost-are-not-headers-only/11363269#11363269 – Sebastian Mach Aug 06 '12 at 15:07
  • @JerryCoffin I have a header only library linal. I was previously adding a rule to just copy over the headers to install location. It turns out that I am using boost_system in those headers. How do I add a Jamfile to his header only library directory and add a dependency on it so that when I am building an executable which uses this library, the linkflags are properly set? – Humble Debugger Apr 09 '17 at 12:52
  • @HumbleDebugger: Sounds like a fine thing to post as a question of its own. About the only time I use b2 is to build boost itself--for my own projects, I use other build tools (for what little it's worth, I'm pretty impressed with meson build). – Jerry Coffin Apr 09 '17 at 17:21