merge libext4 fixes
[helenos.git] / tools / pack.py
blob6b0f6ba117433b6269c4b679227f46c1a1c9e786
1 #!/usr/bin/env python
3 # Copyright (c) 2008 Martin Decky
4 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
10 # - Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # - Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # - The name of the author may not be used to endorse or promote products
16 # derived from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 """
30 Binary package creator
31 """
33 import sys
34 import os
35 import subprocess
36 import zlib
37 import shutil
39 SANDBOX = 'pack'
40 LINK = '_link.ld'
41 COMPONENTS = '_components'
43 def usage(prname):
44 "Print usage syntax"
45 print("%s <OBJCOPY> <FORMAT> <ARCH> <ARCH_PATH> [COMPONENTS ...]" % prname)
47 def deflate(data):
48 "Compress using deflate algorithm (without any headers)"
49 return zlib.compress(data, 9)[2:-4]
51 def print_error(msg):
52 "Print a bold error message"
54 sys.stderr.write("\n")
55 sys.stderr.write("######################################################################\n")
56 sys.stderr.write("HelenOS build sanity check error:\n")
57 sys.stderr.write("\n")
58 sys.stderr.write("%s\n" % "\n".join(msg))
59 sys.stderr.write("######################################################################\n")
60 sys.stderr.write("\n")
62 sys.exit(1)
64 def sandbox_enter():
65 "Create a temporal sandbox directory for packing"
67 if (os.path.exists(SANDBOX)):
68 if (os.path.isdir(SANDBOX)):
69 try:
70 shutil.rmtree(SANDBOX)
71 except:
72 print_error(["Unable to cleanup the directory \"%s\"." % SANDBOX])
73 else:
74 print_error(["Please inspect and remove unexpected directory,",
75 "entry \"%s\"." % SANDBOX])
77 try:
78 os.mkdir(SANDBOX)
79 except:
80 print_error(["Unable to create sandbox directory \"%s\"." % SANDBOX])
82 owd = os.getcwd()
83 os.chdir(SANDBOX)
85 return owd
87 def sandbox_leave(owd):
88 "Leave the temporal sandbox directory"
90 os.chdir(owd)
92 def main():
93 if (len(sys.argv) < 5):
94 usage(sys.argv[0])
95 return
97 objcopy = sys.argv[1]
98 format = sys.argv[2]
99 arch = sys.argv[3]
100 arch_path = sys.argv[4]
102 header_ctx = []
103 data_ctx = []
104 link_ctx = []
105 cnt = 0
106 for component in sys.argv[5:]:
107 basename = os.path.basename(component)
108 plainname = os.path.splitext(basename)[0]
109 obj = "%s.co" % plainname
110 symbol = "_binary_%s" % basename.replace(".", "_")
112 print("%s -> %s" % (component, obj))
114 comp_in = open(component, "rb")
115 comp_data = comp_in.read()
116 comp_in.close()
118 comp_deflate = deflate(comp_data)
120 owd = sandbox_enter()
122 try:
123 comp_out = open(basename, "wb")
124 comp_out.write(comp_deflate)
125 comp_out.close()
127 subprocess.call([objcopy,
128 "-I", "binary",
129 "-O", format,
130 "-B", arch,
131 "--rename-section", ".data=.%s_image" % plainname,
132 basename, os.path.join(owd, obj)])
134 finally:
135 sandbox_leave(owd)
137 link_ctx.append("\t\t*(.%s_image);" % plainname)
139 header_rec = "extern int %s_start;\n" % symbol
140 header_rec += "extern int %s_size;\n" % symbol
141 header_ctx.append(header_rec)
143 data_rec = "\t{\n"
144 data_rec += "\t\t.name = \"%s\",\n" % plainname
145 data_rec += "\t\t.start = (void *) &%s_start,\n" % symbol
146 data_rec += "\t\t.size = (size_t) &%s_size,\n" % symbol
147 data_rec += "\t\t.inflated = %d\n" % len(comp_data)
148 data_rec += "\t}"
149 data_ctx.append(data_rec)
151 cnt += 1
153 header = open(os.path.join(arch_path, "include", "%s.h" % COMPONENTS), "w")
155 header.write('/***************************************\n')
156 header.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
157 header.write(' * Generated by: tools/pack.py *\n')
158 header.write(' ***************************************/\n\n')
159 header.write("#ifndef BOOT_COMPONENTS_H_\n")
160 header.write("#define BOOT_COMPONENTS_H_\n\n")
161 header.write("#include <typedefs.h>\n\n")
162 header.write("#define COMPONENTS %d\n\n" % cnt)
163 header.write("typedef struct {\n")
164 header.write("\tconst char *name;\n")
165 header.write("\tvoid *start;\n")
166 header.write("\tsize_t size;\n")
167 header.write("\tsize_t inflated;\n")
168 header.write("} component_t;\n\n")
169 header.write("extern component_t components[];\n\n")
170 header.write("\n".join(header_ctx))
171 header.write("\n")
172 header.write("#endif\n")
174 header.close()
176 data = open(os.path.join(arch_path, "src", "%s.c" % COMPONENTS), "w")
178 data.write('/***************************************\n')
179 data.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
180 data.write(' * Generated by: tools/pack.py *\n')
181 data.write(' ***************************************/\n\n')
182 data.write("#include <typedefs.h>\n")
183 data.write("#include <arch/%s.h>\n\n" % COMPONENTS)
184 data.write("component_t components[] = {\n")
185 data.write(",\n".join(data_ctx))
186 data.write("\n")
187 data.write("};\n")
189 data.close()
191 link_in = open(os.path.join(arch_path, "%s.in" % LINK), "r")
192 template = link_in.read()
193 link_in.close()
195 link_out = open(os.path.join(arch_path, "%s.comp" % LINK), "w")
196 link_out.write(template.replace("[[COMPONENTS]]", "\n".join(link_ctx)))
197 link_out.close()
199 if __name__ == '__main__':
200 main()