Quantcast
Channel: Анал со зрелой
Viewing all articles
Browse latest Browse all 47

Single File Libraries – bundle.pl | incbin.pl

$
0
0

Sean T. Barrett makes a lot of very cool single-file libraries in C. Recently he’s also been making another big list of other single-file (or two files with src/header) that he likes.

The great thing about Sean’s libraries is that they contain functions that do exactly what they intend to accomplish, without doing anything more or less. They don’t contain any extra complexity other than specifically what is needed to get the job done. This helps when preventing his libraries from creating external dependencies, meaning his libs can be deployed as a single file inclusion into a pre-existing project, without linking to external libraries or requiring additional headers.

These qualities make libraries like Sean’s extremely easy to hookup and get going. If you want to learn how to make quality libraries just look at any of the STB libraries.

Writing Libraries

Sean writes libraries in an old version of Visual Studio (I think VC6?), and codes in C. He also keeps all of his code inside of a single file while writing it — I’ve seen this on Twitch.tv. For the rest of us that aren’t as crazy or hardcore as Sean we can just use bundle.pl.

Bundle.pl is a Perl script written by an unknown author (probably written by Richard Mitton). I found the file inside of Mitton’s single-file library “tigr”, which stands for Tiny Graphics Library. Mitton uses bundle.pl to recursively include a bunch of files into one larger c file. Check out the script yourself:

#!/usr/bin/perl

use File::Spec;

my $out = shift @ARGV or die;
my $root = shift @ARGV or die;
($volume,$dir,$file) = File::Spec->splitpath($root);

open OUT, ">$out" or die "$out: $!\n";
my %done;

sub inline
{
	my ($name) = @_;
	return 0 if ($done{$name});
	$done{$name} = 1;
	print " - $name\n";
	print OUT "//////// Start of inlined file: $name ////////\n\n";
	open my $IN, $name or die "$name: $!\n";
	while (<$IN>) {
		if (/^#include \"(.+)\"/ && -f $1 && !inline($1)) {
			print OUT "//$_";
		} else {
			print OUT "$_";
		}
	}
	close $IN;
	print OUT "\n//////// End of inlined file: $name ////////\n\n";
	return 1;
}

chdir $volume.$dir;
inline($file);

close OUT;

The idea is to make a dummy C file that includes other source files, like this:

#include "anneal.cpp"
#include "gen.cpp"
#include "cg.cpp"
#include "nn.cpp"

Then bundle.pl can be run from the command line (assuming you have Perl installed) like so:

bundle.pl output.file input.file

The script outputs some nice and quick text to stdout displaying which files were visited and packages the entire source tree into a single source file. The output file contains nice comments indicated the beginning and ending of files, like this excerpt from one of my own single-file libraries:

//////// Start of inlined file: cg.h ////////

// ... lots of code in here

//////// End of inlined file: nn.cpp ////////

incbin

Mitton writes about the old joys of using the incbin command in assembly, where the assembler would embed the binary contents of a file straight into your program. It sounds like this gets dubious when dealing with linkers nowadays (I’ve had some really long link times by including large files into source code…), though it still happens from time to time in small single-file libraries.

An example is in Mitton’s tigr library where he uses a makeshift perl script “incbin.pl” to embed shaders and a png file (containing raster font glyphs) straight into C source code. This concept can also be seen in Omar Ocornut’s imgui library where some font files are embedded into the source. Omar seems to have used a small C program to generate the binary data as C source.

Again, I’m not sure who originally wrote this incbin.pl script but it was probably Mitton himself.

TwitterRedditFacebookShare


Viewing all articles
Browse latest Browse all 47

Trending Articles