Embed an arbitrary binary blob into an ELF or COFF object file.
 
 
Go to file
James T. Martin a922cb9912
Fixed file permissions for new ELF object files.
2022-05-18 13:56:58 -07:00
subprojects Fixed file permissions for new ELF object files. 2022-05-18 13:56:58 -07:00
.editorconfig Initial commit 2021-10-17 23:20:06 -07:00
LICENSE Initial commit 2021-10-17 23:20:06 -07:00
README.md Initial commit 2021-10-17 23:20:06 -07:00
meson.build Initial commit 2021-10-17 23:20:06 -07:00

README.md

Blob Object

A simple utility for embedding an arbitrary binary blob into an ELF or COFF object file. You can then link your program against that object file to be able to access the binary blob as a C array.

This project will only be updated rarely, if ever. This isn't because the project has been abandoned; it's just trivial enough that (other than the caveats described below) there are few reasons that an update would be necessary.

This project is public domain (see LICENSE), so feel free to use it however you'd like. Credit is optional.

Installation

This project has no dependencies and can be built with Meson: meson setup build && cd build && meson compile && sudo meson install

You can also compile it manually with your C compiler; meson is just for convenience:

cc -o blob-object-elf subprojects/blob-object-elf/src/main.c
cc -o blob-object-coff subprojects/blob-object-coff/src/main.c

Usage

blob-object-(elf|coff) <output file> <section name> <symbol name> <blob file>

You can include the generated blob object in C using these declarations:

// the size in bytes of the blob. can be uint64_t with ELF, but COFF is restricted to 32-bit.
extern uint32_t const <symbol name>_size;
// the address of this constant is the beginning of the blob
extern uint8_t const <symbol name>;

// get a reference to your data
uint8_t* my_data = &<symbol name>;

Example for compiling GLSL shaders to SPIR-V and into your Vulkan program

Here's an example of how you might use this to include compiled SPIR-V shaders in your executable:

  • glslangValidator -V100 -o "frag_shader.spv" "frag.glsl"
  • blob-object-elf frag_shader.o shaders frag_shader frag_shader.spv
  • gcc my-vulkan-program.c frag_shader.o

I wrote a hack to make shader compilation part of the build processess with meson:

compile_shader = find_program(meson.source_root() / 'compile-shader.sh')
shaders_gen = generator(
    compile_shader,
    output: '@PLAINNAME@.o',
    arguments: [
        '@BUILD_ROOT@',
        '@INPUT@',
        '@OUTPUT@',
        '@PLAINNAME@',
    ]
)

sources += [
    shaders_gen.process('shaders/shader.frag'),
    shaders_gen.process('shaders/shader.vert')
]

compile-shader.sh:

#!/bin/bash
build_root="$1"
src="$2"
obj="$3"
name="$4"

if [[ "$OSTYPE" == "msys" ]]; then
    make_blob="$build_root/subprojects/make-coff-blob/blob-object-coff.exe"
else
    make_blob="$build_root/subprojects/make-elf-blob/blob-object-elf"
fi

base_name="${name%.*}"
ext="${name#*.}"

spv="$obj.spv"

glslangValidator -V100 -o "$spv" "$src" && $make_blob "$obj" shaders "cg_${base_name}_${ext}" "$spv"

Caveats

  • blob-object-coff is restricted to <4GB blobs because COFF is a 32-bit format
  • blob-object-elf cannot be used on native Windows because it depends on POSIX (fix: this program should use standard library headers instead of POSIX and bundle its own elf.h)
  • both generators are hardcoded to generate object files flagged for x86_64 for their respective platforms (fix: add an argument to select which platform to build for)

Fixing these things would be pretty trivial; feel free to send a PR. I'd also be willing to do it myself if anyone ends up actually using this, so you could open an issue instead too.

It'd also be nice to support Mach-O (MacOS) and combine both blob-object commands into a single executable.