Hacker News new | ask | show | jobs
by flohofwoe 3045 days ago
Some advantages of header-only vs .h/.c pair:

- you can build simple tools contained in a single .c file, and you dont't need a build system for this (e.g. just call "cc tool.c -o tool" instead of mucking around with Makefiles or cmake)

- the library can be configured with macros before including the implementation (e.g. provide your own malloc, assert, etc...), with the implementation in a .c file, these config macros must be provided via command line args, which implies a build system

- you can put the implementations for all header-only libs used in a project into a single .c file instead of compiling the multiple .c implementation files, this might speed up compilation

Single-header libs have some of the advantages that a proper module system would bring to C and C++ (e.g. extremely simple integration into own project and increased compile speed), but without all the complexity of implanting a module system into C or C++.

2 comments

For #1: you already have multiple files in your source so nothing stops you from including the .c file if you feel like compiling a single c file from the command line without a build tool is needed (although when it comes to make usually you can have a single generic makefile that does the same job)

For #3: the #1 applies here too (although beware for static stuff conflicts) but in practice C code compiles fast enough for this to not be a problem

I can see #2 being an advantage, but TBH i think the case where you both need a custom malloc, assert, etc and not need a build tool where you can pass the configuration macros is kinda rare.

Make is so simple that it can actually build you single file project without a makefile with less characters to type:

make tool

Et voilà.

Errr, I actually have to spend 5 minutes googling how to install make on Windows, then getting mingw and hating myself. So no, no it's really not that simple in general.
https://github.com/tom-seddon/b2/blob/master/snmake.exe - standalone build of GNU Make 3.80. Has a couple of hacks in it to better support Windows-style paths with colons in it. I think this came from the SN Systems Playstation2 SDK. Thanks to the GPL, you can have it too.

(I have no idea whether this will successfully run a C compiler for you on Windows, though. I mostly use it to run Makefiles with phony targets as a cross-platform replacement for shell scripts.)

Oh no, Make 3.80...

Why not build a more recent version? This thing is 15 years old!

This sounds like something one should ask people who do not write portable makefiles, rather than porters of Make, which has been standardised for quite a while now.
They added some useful stuff in subsequent versions... my recollection (though this is going back a while now) is that even only 3.81 was a worthwhile upgrade over 3.80!

However I have better things to do than try to figure out how to build GNUstuff myself on Windows.

Good idea! Let me know when you’ve done it... I could do with an updated copy.
Not really fair to blame make for your daft OS.
1) A new dependency to install on every build server and dev's machine unless you're a 'nix only shop (e.g. not in gamedev) and sometimes even then (yes, I've had to apt-get install make) - at the very least this is a boatload of new setup/install instructions, in practice this also involves coordinating with IT, and heaven help you if you let your less programmery coworkers build from source too.

2) Which version of make? I have detailed instructions at work about which make to use with which makefiles such that all the stars align and the OS vars and other gnu tools line up such that our upstream Makefiles work without modifications (well, usually.)

3) Given the complexity of 2, what I'm actually going to do is automatically invoke make from whatever build system we're using internally.

4) Now that I have two sets of build configuration, I have a continual maintenance burden as conflicting dependencies and incompatible build settings need to be resolved. Since I deal with C++ libs and tools, sneezing too hard will cause incompatible libs. In practice, the Makefile will hardcode CCFLAGs, sometimes CC itself, and things like building with/without RTTI will cause incompatible libs I can't link without more Makefile tweaks.

5) When I get sufficiently fed up with the state of affairs in point 4, I'll integrate the tool into our own build system such that we have a single unified build system again and I don't have to make the same change in 5 places (our codebase + a measly 4 dependencies in this example.)

At this point I'm no longer using make and wondering why I didn't just skip directly to step 5 in the first place. Make is simple - so simple it doesn't address my needs nor solve my problems.