Commit da7b73be authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner

Support to embed files in C programs

parent 16a36c61
......@@ -17,6 +17,6 @@ endif
all: $(TARGETS)
clean:
rm -rf $(O)/bin $(O)/lib $(O)/docs $(O)/.objs $(O)/.deps $(O)/lua_lib $(O)/lua_plugins $(TARGETS)
rm -rf $(O)/bin $(O)/lib $(O)/docs $(O)/.objs $(O)/.deps $(O)/lua_lib $(O)/lua_plugins $(O)/.gen $(TARGETS)
.PHONY: all clean
......@@ -176,6 +176,24 @@ $(O)/.objs/%.o: $(S)/%.c
$(Q)$(CC) $(CFLAGS_ALL) -c $< -o $@ -MD -MF $(patsubst %.o,%.pre,$(subst .objs/,.deps/,$@))
$(Q)$(S)/build/normalize_dep_file.pl $(O) $(patsubst %.o,%.pre,$(subst .objs/,.deps/,$@)) >$(patsubst %.o,%.d,$(subst .objs/,.deps/,$@))
$(O)/.objs/%.o: $(O)/.gen/%.c
$(M) CC $@
$(Q)mkdir -p $(dir $@ $(subst .objs/,.deps/,$@))
$(Q)$(CC) $(CFLAGS_ALL) -c $< -o $@ -MD -MF $(patsubst %.o,%.pre,$(subst .objs/,.deps/,$@))
$(Q)$(S)/build/normalize_dep_file.pl $(O) $(patsubst %.o,%.pre,$(subst .objs/,.deps/,$@)) >$(patsubst %.o,%.d,$(subst .objs/,.deps/,$@))
$(O)/.gen/%.embed.c: $(O)/.gen/%.embedlist
$(M) EMBED $@
$(Q)mkdir -p $(dir $@ $(subst .gen/,.deps/,$@))
$(Q)$(S)/build/embed_gen.pl -i $< -o $@ -d $(patsubst %.c,%.pre,$(subst .gen/,.deps/,$@))
$(Q)$(S)/build/normalize_dep_file.pl $(abspath $(O)) $(patsubst %.c,%.pre,$(subst .gen/,.deps/,$@)) >$(patsubst %.c,%.d,$(subst .gen/,.deps/,$@))
$(O)/.gen/%.embed.c: $(S)/%.embedlist
$(M) EMBED $@
$(Q)mkdir -p $(dir $@ $(subst .gen/,.deps/,$@))
$(Q)$(S)/build/embed_gen.pl -i $< -o $@ -d $(patsubst %.c,%.pre,$(subst .gen/,.deps/,$@))
$(Q)$(S)/build/normalize_dep_file.pl $(abspath $(O)) $(patsubst %.c,%.pre,$(subst .gen/,.deps/,$@)) >$(patsubst %.c,%.d,$(subst .gen/,.deps/,$@))
$(O)/bin/%:
$(M) LD $@
$(Q)mkdir -p $(dir $@)
......
......@@ -213,6 +213,29 @@ the `S` variable there should be adjusted to point to the sources
directory. Optionally, other options can be tweaked there. The `O`
variable can be left intact.
Embedding files
---------------
The build system can generate c files (and compile them) that include
other files inside them (in an array of bytes). To do so, create a
`<x>.embedlist` file and include `<x>` into the list of modules for a
target.
Alternatively, you may provide a rule to generate
`.gen/<path_to_target>/<x>.embedlist`.
The file looks like this:
# These are passed through (without the leading |)
|passthrough line
|another passthrough line
# Generates an array name „name“, containing the file.
name file/path
# Generates an index, array of type „type“, each element having a
# string name, pointer to the array and size. The type must come
# from some passthrough lines.
idx index type
Defines passed to the compiler
------------------------------
......
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Cwd qw(abs_path);
use File::Basename qw(dirname);
my $output_path;
my $input_path;
my $dep_path;
GetOptions
'output=s' => \$output_path,
'input=s' => \$input_path,
'deps=s' => \$dep_path
or die "Bad arguments\n";
$output_path = abs_path $output_path;
open my $input, '<', $input_path or die "Couldn't read input $input_path: $!\n";
open my $output, '>', $output_path or die "Couldn't write output $output_path: $!\n";
$SIG{__DIE__} = sub {
unlink $output_path;
};
open my $deps, '>', $dep_path or die "Couldn't write deps $dep_path: $!\n";
print $output <<'ENDHEAD';
// This file is auto-generated. Do not edit.
#include <stdint.h>
ENDHEAD
sub dep($) {
my ($dep) = @_;
$dep = abs_path $dep;
print $deps "$output_path: $dep\n";
}
dep $input_path;
# The paths in the input might be relative. Resolve them relative to that file.
chdir dirname $input_path;
my %idx;
while (<$input>) {
chomp;
if (my ($idx, $type) = /^idx\s+(\w+)\s+(\w+)/) {
# Please generate an index into variable and type given
print $output "struct $type $idx\[\] = {\n";
print $output " { \"$_\", $_, $idx{$_} },\n" for sort keys %idx;
print $output " { NULL, 0 }\n";
print $output "};\n";
# And reset the index, so we can generate more than one.
%idx = ();
} elsif (my ($passthrough) = /^\|(.*)/) {
# Include a line
print $output "$passthrough\n";
} elsif (my ($name, $path) = /^(\w+)\s+(\S+)\s*$/) {
# Embed a file as an array
dep $path;
open my $f, '<', $path or die "Couldn't read file '$path': $!\n";
print $output "static uint8_t $name\[\] = {\n";
my $chunk;
my $len;
my $total = 0;
while ($len = read $f, $chunk, 16) {
# Read chunks of max 16 bytes, like hexdump does
# Convert each to hex
printf $output '0x%02X, ', ord($_) for split '', $chunk;
print $output "\n";
$total += $len;
}
# Terminates with 0 on EOF and undef on error.
die "Error reading from file '$path': $!" unless defined $chunk;
print $output "0};\n";
$idx{$name} = $total;
} else {
# Allow comments and empty lines, but nothing else
die "I don't understand line $_" unless /^\s*(|#.*)$/;
}
}
close $output;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment