It might not be well known, but there is a feature used by many packages, also in Portage, that is called “multicall binary”. A multicall binary is an executable that runs different code depending on the name used to invoke it. This usually brings the package to install a single executable and then a series of symbolic links with the various alternative names (sometimes called applets), pointing to the one. Two very common examples of this trick are busybox and portage-utils.
The reason why you might want to use multicall binaries is that sometimes you end up having lots of shared code between two programs, and shared libraries are not an option but you still want to avoid wasting space, maybe because the size of the shared code trumps the size of the programs themselves.
It is of course a matter of compromises: the size of the singe program will increase and that means that it might take more memory when running for a long period of time; on the other hand, if you have multiple instances, running for long time, of that family of programs, they will, overall, use less memory, because their shared code will already be loaded in memory. And since they are not using shared objects the PIC effect will be avoided, saving even more space.
How do you implement multicall binaries? Well, it’s not really hard: you just have to implement different entrypoints for the applets (in place of one main()
function each), and then, in your main, check the value of argv[0]
to call the right one. For completeness, you often also add a generic applet name, with argv[1]
to explicitly choose one applet (portage-utils does that when you call the q
command).
The only notice you have to take here is that sometimes it is far from trivial to properly transform the name string into a value computable by the C code, and thus you might have an heavy slow-down for that parsing in particular. My suggestion there is to use something like Ragel which makes the translation much faster than a chain of if … else if …
statements would.