google / oboe

Oboe is a C++ library that makes it easy to build high-performance audio apps on Android.
Apache License 2.0
3.71k stars 569 forks source link

Please build oboe as a single-header library #1101

Open jwatte opened 3 years ago

jwatte commented 3 years ago

Issue #1072 was closed, but didn't actually address the feature request, seemingly from a mis-understanding of what a "single-header library" is.

A "single-header library" is a library that is trivial to integrate in any system or build system, because all the code, and all the declarations, are available in a single physical header file. When using a single-header library, the only physical file necessary is a single header file, which contains both interface and implementation.

For any file/module that uses the library, you simply

include "library.h"

In one translation unit, you do:

define LIBRARY_IMPLEMENTATION

#include "library.h"

This enables all global symbols to be defined, and they all still come from that single header. Including a library like this in a project is as easy as dropping in the header file, and creating a .cpp file that defines the appropriate symbol and includes the header file. This means that integrating in build systems is trivial, no matter what the build system. From "build.bat" to "IDE specifics" to "automake" to "ninja" -- doesn't matter; integration is trivial! Shared libraries? Static libraries? Debug configurations? Memory checker macros? Doesn't matter; a single file is compiled with the settings I control, and It Just Works (tm.)

To take a look at how one includes and uses a library like "stb_image.h" to see how to make adoption and integration into arbitrary projects a zero-effort proposition!

https://github.com/nothings/stb/blob/master/stb_image.h

jwatte commented 3 years ago

Adding some context: The instructions for how to use a pre-built library start "Add the oboe dependency to your app's build.gradle file." That doesn't help me if I use makefiles, or Visual Studio for Android, or some other build tool that's not gradle.

philburk commented 3 years ago

Thanks for the clarification. By the way, we close issues if we think they are done. We just don't want inactive issues lingering forever. But if they need more work you could reopen them. Or do you not have permission from GitHub to reopen?

I can see now the benefits to providing a single header library. Thanks.

I assume that header is generated from multiple files using a tool. @jwatte - Do you recommend any of these?

https://www.google.com/search?q=tool+for+creating+single+header+library

dturner commented 3 years ago

Thanks for the suggestion and extra context @jwatte.

Is it difficult to include the Oboe pre-built binaries and headers into your project? These can be obtained by:

image

If you want to build the library yourself you can always take a look at https://github.com/google/oboe/blob/master/build_all_android.sh.

I'd like to understand why these methods of integrating Oboe aren't feasible before we modify our build process to create a single header file (which feels like it could be quite a bit of work).

(note to @philburk, public users don't have the ability to re-open issues)

jwatte commented 3 years ago

In general, having source is better when I need to debug. That being said: How would I, as a user, discover the instructions you suggest here?

Downloading the latest AAR file from the releases page: https://github.com/google/oboe/releases Rename the .aar to .zip and extract everything

So, an incremental improvement to documentation would be to add this at the front: "If you're not using gradle, download the latest AAR file ..." Then, continue with "If you're using gradle, add the dependency ..."

It's not as good as a single-file library, because if I use a compiler with a different ABI (mangled symbol names, etc,) I can't use pre-built C++ libraries unless they are compiled with the same compiler.

I have not used a tool to generate a single-header library, when I do it myself, I just have a rule that does "cat" in the makefile :-) (One way of viewing it: If your library needs more build smarts than that, then that, in itself, is probably a sign that building the library needs to be simplified!)

The cmake method might work, too, depending on what specific tools are required by the dependent cmake files.

philburk commented 3 years ago

I have not used a tool to generate a single-header library, when I do it myself, I just have a rule that does "cat" in the makefile

But wouldn't you have to strip off the #include statements for the files that are not shipped? You could probably do that by piping it through "grep -v".

Anyway, building the header seems easy. It seems useful. Let's keep this Issue open as a reminder to try it some day.

dturner commented 3 years ago

This isn't a priority right now but if other oboe users want this feature please give it a thumbs up 👍

eliasku commented 3 years ago

I have no success with new Prefab because liboboe.so is not found and I have runtime error, so I don't understand how PREFABS solve the problem, if I need to copy so files manually. After that I just include source-code files. One thing I add is "oboe_all.cpp" with including all cpp files (from the common to the AAudio / OpenSLES backends implementation) which turns all TUs into the single TU with nice build time boost when you build not only Oboe library source-code. I think instead of multiple cpp files it could be splitted into the private and public headers with 1 TU. After that you could easily provide Headers-only implementation just by concatenating sources in theory :)