A C API for C++ and Python ones — or making of libh2o

Lately I spent a lot of time working on a small project of mine called libh2o. Its goal is to provide a library of routines implementing IAPWS IF97 equations for water and steam properties. With the core written in C, and providing a nice-to-use API for C++ and Python.

At first, I thought about not providing a «high level» C API at all. It was like: if you want to use plain C, you’ve gotta glue all the low-level equations yourself. However, after some thinking I decided to provide one, and built the two remaining APIs (C++ and Python) on top of it.

The main reason for doing this was that Python (well, CPython) is written in C. Although I’ve seen people writing Python extensions in C++, and even using some of C++ features to make them a little nicer, that’s still a bunch of ugly C hacks and pointer casts. I don’t see a really good reason to write a Python extension in C++, nor to make it depend on a C++ compiler when it’s all limited to C-based CPython API anyway.

And that means that I have either to duplicate all the high-level logic in the Python extension, or just create a C API first and reuse that. Since the whole logic was simple enough to be covered completely and clearly in C, I have chosen this way.

As it happens when people choose C, I had to implement some kind of poor man’s objectivity. Not something as wide (and ugly) as GObject (someone, please kill it!) but a few bits necessary to keep the state. In other words, a structure keeping the «object» and a bunch of nicely named functions taking it as their first argument.

Before I learnt C++, I would assume that the object structure should be a private (and obscured) blob, and the object type should be an incomplete pointer to it. User should just grab that pointer from a «constructor», pass it around and finally free it through a «destructor». Advantage: the exact struct contents are not the part of ABI.

But now I’ve decided to go the other way; way similar to how C++ classes work. I’ve created a structure with explicitly listed private fields (and a very simple /*private:*/ comment), and used that as the public type. It doesn’t need to keep any memory allocated, and is simple enough to be allocated on stack. Advantages: no need for a destructor, and an ability to pack that struct in the C++ class which will wrap it.

Then the usual stuff: a bunch of functions with common prefixes. One prefix for the «namespace», another one for the function (new, get…). All in nice and clear fashion, either to be used directly or wrapped in the C++ or Python APIs.

Five commandments for XML format designers

If you’re designing an XML-based data format, then I beg you, please read the few following rules and obey them. XML may look easy, and even is easy but that doesn’t mean that writing a good one is. And if you’re going to invent second HTML, then please, just use JSON or any other random container. That will be easier for you, and easier for us.

Continue reading “Five commandments for XML format designers”

Moving systemd into /usr — the technical side

Now that I think of it, I really regret I didn’t make systemd ebuild install it to /usr from the very beginning. But the harm has been done already, and I’d like to move it ASAP and that’s why I’d like to sum up problems with that and possible ways of proceeding with it.

The idea

The idea is simple as it is: move systemd install to /usr prefix completely. Right now, there are no technical benefits from keeping it in rootfs. It already depends on libdbus, which is installed in /usr, and I expect more dependencies over time. There’s no reason to move all those packages into rootfs.

Most importantly, the above information allows me to assume that such move won’t hurt our split-/usr users — because they already had to have /usr mounted for systemd to run.

Continue reading “Moving systemd into /usr — the technical side”

Why there’s no IUSE=systemd, logrotate, bash-completion…

Next tides of users slowly notice that a number of unneeded files is installed on their systems. They enumerate systemd unit files, logrotate files, take their pitchforks and start their cruciates against Gentoo developers wasting their precious disk space.

Let me tell you a story. The story starts when Uncle Scarabeus wants to add bash-completion support into libreoffice ebuild. He considers this a minor addon, not worth the half a day necessary to rebuild libreoffice, so he doesn’t revbump it. He simply assumes the change will be propagated nicely when users upgrade to the next version.

Of course, some users will already come shouting here: that’s against the policy! Yes, indeed it is. But is it worth the hassle? Should all libreoffice users be forced to rebuild that huge package just to get a single tiny file installed? He could wait and add that along with the next version. Well, if he wouldn’t forget about it.

But that’s not really important part here. Because, to his surprise, many users have actually noticed the change. That’s because the use of bash-completion.eclass has caused the ebuild to have IUSE=bash-completion; and many of the --newuse Portage option users have rebuilt the package. A few others, like me, just stopped using that option.

That’s when the discussion started. We — the few devs actually caring about discussing — decided that it is quite pointless to control installing tiny files through USEflags. Of course, the libreoffice is an elephant-case here but so-called regular packages aren’t much better here. Is there really a reason to rebuild even 10 C files when the only thing going to change is a single, tiny text file being installed or not?

Another solution is to split those files into separate ebuilds. But that’s usually inconvenient both for users and devs. Users have to notice that they need to emerge an additional package to get the particular file installed, and devs need to maintain that additional package. That starts to become really ridiculous with files like systemd units which are often generated during build-time and store installation paths.

So what to use? INSTALL_MASK, obviously. It’s an ancient Portage magic which allows you to control which files will be punted from installed files. You can use app-portage/install-mask to quickly set it for the files you don’t want. It’s as simple as:

# install-mask -a systemd logrotate