2 # -*- coding: utf-8 -*-
3 # Tool to embed file into objects
5 __author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
6 __copyright__ = "Jérôme Carretero, 2014"
10 This tool allows to embed file contents in object files (.o).
11 It is not exactly portable, and the file contents are reachable
12 using various non-portable fashions.
13 The goal here is to provide a functional interface to the embedding
14 of file data in objects.
15 See the ``playground/embedded_resources`` example for an example.
21 # ^ Reference this in use="..." for things using the generated code
22 features='file_to_object',
24 # ^ Name of the file to embed in binary section.
29 - Destination is named like source, with extension renamed to .o
30 eg. some.file -> some.o
35 from waflib import Task, TaskGen, Errors
37 def filename_c_escape(x):
38 return x.replace("\\", "\\\\")
40 class file_to_object_s(Task.Task):
42 vars = ['DEST_CPU', 'DEST_BINFMT']
46 for i, x in enumerate(self.inputs[0].name):
51 file = self.inputs[0].abspath()
52 size = os.path.getsize(file)
53 if self.env.DEST_CPU in ('x86_64', 'ia', 'aarch64'):
56 elif self.env.DEST_CPU in ('x86','arm', 'thumb', 'm68k'):
60 raise Errors.WafError("Unsupported DEST_CPU, please report bug!")
62 file = filename_c_escape(file)
63 name = "_binary_" + "".join(name)
64 rodata = ".section .rodata"
65 if self.env.DEST_BINFMT == "mac-o":
67 rodata = ".section __TEXT,__const"
69 with open(self.outputs[0].abspath(), 'w') as f:
72 .global %(name)s_start
84 class file_to_object_c(Task.Task):
88 for i, x in enumerate(self.inputs[0].name):
93 file = self.inputs[0].abspath()
94 size = os.path.getsize(file)
96 name = "_binary_" + "".join(name)
99 if sys.version_info[0] < 3:
103 data = self.inputs[0].read('rb')
105 for idx_byte, byte in enumerate(data):
107 if len(line) > 15 or idx_byte == size-1:
108 lines.append(", ".join(("0x%02x" % char_to_num(x)) for x in line))
110 data = ",\n ".join(lines)
112 self.outputs[0].write(\
114 unsigned long %(name)s_size = %(size)dL;
115 char const %(name)s_start[] = {
118 char const %(name)s_end[] = {};
121 @TaskGen.feature('file_to_object')
122 @TaskGen.before_method('process_source')
123 def tg_file_to_object(self):
125 sources = self.to_nodes(self.source)
128 if bld.env.F2O_METHOD == ["asm"]:
129 tgt = src.parent.find_or_declare(src.name + '.f2o.s')
130 tsk = self.create_task('file_to_object_s', src, tgt)
131 tsk.cwd = src.parent.abspath() # verify
133 tgt = src.parent.find_or_declare(src.name + '.f2o.c')
134 tsk = self.create_task('file_to_object_c', src, tgt)
135 tsk.cwd = src.parent.abspath() # verify
137 self.source = targets
141 conf.env.F2O_METHOD = ["c"]