Small update: Version 1.9.4 now includes
libpar2! Also, a fresh installer for Windows is available here!
I write a tool that makes so-called forward error correction of file trees easy to manage, par2deep. At least, I think it makes it easy, you can (and do!) send me your own opinions on that, I’m always looking for improvements!
One such improvement I have been looking at today and yesterday is seeing if I can create a Python library out of the par2cmdline project, because right now I just generate the commandline options with which to run
par2, the compiled executable of the
par2cmdline project. It works, but it requires the user to ensure the executable is in their PATH or point
par2deep to wherever they have it. Not the best or most robust way to do things, right?
So, a library is what I need, but alas, there wasn’t really one. Although the
par2cmdline (auto)makefile creates a static library of (nearly) all of its sources, and then links them up with the
par2cmdline.cpp, the interface to that library is not explicitly defined anywhere. At first I thought exposing the functions in
pybind11 would be a good idea, but it takes a whole bunch of arguments of which I have no idea, and I also don’t really want to have an idea. I want the commandline interface, I understand its switches because they are defined and documented in the manpage.
commandline.h converts your arguments into the right input for
libpar.h. So, I must reuse
cpp to interface with the functions in
libpar.h. Not hard, turn
extern "C" par2cmdline() and presto! Woah woah woah, not so fast! I spent the night educating myself on automake, trying to modify
Makefile.am into doing what I want, but after some time it because clear, for shared libraries, automake needs external tooling, libtool. Okay…
sudo apt install libtool. Nope. No
sudo apt install libtool-bin. Still nope. Hmm, must run
libtoolize in the source dir. Oh and add
configure. O, and no LDADD, but LIBADD to link
libpar2.a. The generate
makefile still did not specify a LIBTOOL, so manually adding it seemed to generate something. Nope, it didn’t, more errors in the generated
makefile. Well, here I gave up. I’m not interested in build scripts much, I never quite understand them, and they seem to have as much ceremony as using PGP with its 6 trust levels. I just want a shared library, why is that so tricky?
I then tried to make the static library work, but that does not play well with Pythons ctypes CDDL interface. It must be a shared library. It is what I’m used to as well, I’ve written libraries with C interfaces before (medimage and dosia feature them), so what other options do I have? Cutting out the build script. That of course means cutting out the linking of the various seperately compiled object files that the build script generated for each source file in
Include all the things! The main challenge here was figuring out the right order, because the
par2cmdline coding style does not feature a consistent include for every dependency, it lets the linker make sure all the symbols are present. The function signature fortunately is already C-proof (argc,argv), so all I need to do is prepend a fake executable name that the
CommandLine class scans for. Presto, libpar2!
I chose not to edit any
par2cmdline/src code, such that it will remain straightforward to follow upstream updates. Building does not really require any script anymore, and the interface is just the commandline interface we already know and love.
Have fun! Would be interesting if anyone likes or even uses it! I’ll see to the integration into