ludocode / mpack

MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]
MIT License
521 stars 82 forks source link

Support building with CMake or similar #77

Closed martingkelly closed 4 years ago

martingkelly commented 4 years ago

Hi,

It would be really handy to be able to build this with CMake or some other standard build system, as Visual Studio .sln files aren't readily usable on Linux. I can't see any way to compile this on Linux currently, which is a shame, as I'd otherwise love to use this library.

martingkelly commented 4 years ago

Related: It would also be really helpful to export a pkg-config .pc file for integration with other libraries.

ludocode commented 4 years ago

The Visual Studio .sln file doesn't build MPack into a library. It only builds and runs unit tests. The same is true for the Xcode project and all other build files. I've been meaning to move these into the test/ folder to make it less confusing. These project files are out of date anyway. MPack supports various platforms but it's entirely developed on Linux.

MPack is not meant to be built into a shared or static library. It's shipped as a single-file library, like the stb libraries and other single .c/.h libraries. It's amalgamated like SQLite. Just download the latest release and drop mpack.c and mpack.h into your project.

If you really want to compile it separately on Linux, it's not complicated.

To compile the source: cc -Os -c src/mpack/*.c To build into a static library: ar rcs libmpack.a *.o To install headers somewhere, just copy them, for example with rsync:

rsync -av --include='*.h' --include='*/' --exclude='*' src/mpack /your/include/path

These are plain one-line commands for building stuff. You don't need CMake or pkg-config or anything else. I don't plan to add any buildsystem to do this because building MPack separately is not how I recommend it to be used. It is much easier to just drop the files into your project, that way it automatically takes on your project's debug/release configuration, LTO optimization, etc.

martingkelly commented 4 years ago

This is similar to the decision about shared vs static libraries... your approach is effectively a static library that only changes versions by manual update of the code (downloading a new amalgamation and copying into your source tree). This is one way to structure the library, and totally valid and best for some use cases.

That said, do you have any problem with people using the mpack as a traditional shared or static library, discoverable by pkg-config and installable in a Linux distro, for instance? If not, would you object to this project having an optionally installable .pc file and being buildable with CMake / meson / similar? Just trying to get a sense for whether you view the amalgamation workflow as the only valid one, or if it's just the one you prefer.

ludocode commented 4 years ago

I'm not opposed to people installing a pre-built MPack. I could even see it being useful in some cases, for example pre-compiling and installing in buildroot for an embedded device. I don't want to support a buildsystem or pkg-config files to do this within the project though. MPack is so trivial to build that trying to maintain a buildsystem for it would cause more problems than it would solve.

(Also, I've been forced to use CMake at various companies and I am very much not a fan. I would like to keep it far away from my projects. Meson looks nice but I haven't used it.)

There is one complexity that I forgot to mention above when precompiling MPack though. MPack enables debugging code automatically if the DEBUG or _DEBUG macros are defined, and this affects struct sizes among other things. If you pre-build the library without DEBUG, and then build some code with DEBUG and link against it, it will crash.

You can override this by defining MPACK_DEBUG to 0 or 1. Probably if you are installing a non-debug version, you'll want to add #define MPACK_DEBUG 0 to the top of the header (mpack.h in the amalgamated version or mpack-platform.h in the original source.) You lose out on a lot of error-checking code if you do this though. For example with debug on, MPack checks that you read and write the correct number of elements in compound types.

(All of this is why it's much simpler to just include mpack.c in your project. It won't need to be built separately and it will pick up the debug configuration of your project automatically.)

martingkelly commented 4 years ago

I don't want to support a buildsystem or pkg-config files to do this within the project though. MPack is so trivial to build that trying to maintain a buildsystem for it would cause more problems than it would solve.

OK, thanks for the clarification. Unfortunately, not having a build system makes this library a lot harder to usefor those who don't want to bundle the library. For instance, if you wanted to debianize this project, build it into an embedded root filesystem (e.g. yocto/buildroot), these would be trivial with pkg-config and a build system but require a bunch of user effort to manually patch a build system in. All these build systems have logic for handling all the standard builders, so packaging a project using them is trivial, while manually coding in the right cross-compile logic has a number of gotchas.

Obviously it's your decision, but just my $0.02 is that some kind of build system, with pkg-config integration, would be really helpful for adoption. It doesn't have to be CMake; meson or even autotools (or SCons, or waf, or... there's many) could work fine too.