mkmfs: fix zone bitmap initialization.
[helenos.git] / tools / autotool.py
blob9825e39e83e165162c6f8f6cf03d86b8b53ca8cb
1 #!/usr/bin/env python
3 # Copyright (c) 2010 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.
30 """
31 Detect important prerequisites and parameters for building HelenOS
32 """
34 import sys
35 import os
36 import shutil
37 import re
38 import time
39 import subprocess
41 SANDBOX = 'autotool'
42 CONFIG = 'Makefile.config'
43 MAKEFILE = 'Makefile.common'
44 HEADER = 'common.h'
45 GUARD = 'AUTOTOOL_COMMON_H_'
47 PROBE_SOURCE = 'probe.c'
48 PROBE_OUTPUT = 'probe.s'
50 PACKAGE_BINUTILS = "usually part of binutils"
51 PACKAGE_GCC = "preferably version 4.7.0 or newer"
52 PACKAGE_CROSS = "use tools/toolchain.sh to build the cross-compiler toolchain"
54 COMPILER_FAIL = "The compiler is probably not capable to compile HelenOS."
55 COMPILER_WARNING = "The compilation of HelenOS might fail."
57 PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, strc, conc, value) \\
58 asm volatile ( \\
59 "AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t" strc "\\t" conc "\\t%[val]\\n" \\
60 : \\
61 : [val] "n" (value) \\
64 #define STRING(arg) STRING_ARG(arg)
65 #define STRING_ARG(arg) #arg
67 #define DECLARE_BUILTIN_TYPE(tag, type) \\
68 AUTOTOOL_DECLARE("builtin_size", "", tag, STRING(type), "", "", sizeof(type)); \\
69 AUTOTOOL_DECLARE("builtin_sign", "unsigned long long int", tag, STRING(type), "unsigned", "", __builtin_types_compatible_p(type, unsigned long long int)); \\
70 AUTOTOOL_DECLARE("builtin_sign", "unsigned long int", tag, STRING(type), "unsigned", "", __builtin_types_compatible_p(type, unsigned long int)); \\
71 AUTOTOOL_DECLARE("builtin_sign", "unsigned int", tag, STRING(type), "unsigned", "", __builtin_types_compatible_p(type, unsigned int)); \\
72 AUTOTOOL_DECLARE("builtin_sign", "unsigned short int", tag, STRING(type), "unsigned", "", __builtin_types_compatible_p(type, unsigned short int)); \\
73 AUTOTOOL_DECLARE("builtin_sign", "unsigned char", tag, STRING(type), "unsigned", "", __builtin_types_compatible_p(type, unsigned char)); \\
74 AUTOTOOL_DECLARE("builtin_sign", "signed long long int", tag, STRING(type), "signed", "", __builtin_types_compatible_p(type, signed long long int)); \\
75 AUTOTOOL_DECLARE("builtin_sign", "signed long int", tag, STRING(type), "signed", "", __builtin_types_compatible_p(type, signed long int)); \\
76 AUTOTOOL_DECLARE("builtin_sign", "signed int", tag, STRING(type), "signed", "", __builtin_types_compatible_p(type, signed int)); \\
77 AUTOTOOL_DECLARE("builtin_sign", "signed short int", tag, STRING(type), "signed", "", __builtin_types_compatible_p(type, signed short int)); \\
78 AUTOTOOL_DECLARE("builtin_sign", "signed char", tag, STRING(type), "signed", "", __builtin_types_compatible_p(type, signed char));
80 #define DECLARE_INTSIZE(tag, type, strc, conc) \\
81 AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, strc, conc, sizeof(unsigned type)); \\
82 AUTOTOOL_DECLARE("intsize", "signed", tag, #type, strc, conc, sizeof(signed type));
84 #define DECLARE_FLOATSIZE(tag, type) \\
85 AUTOTOOL_DECLARE("floatsize", "", tag, #type, "", "", sizeof(type));
87 int main(int argc, char *argv[])
89 #ifdef __SIZE_TYPE__
90 DECLARE_BUILTIN_TYPE("size", __SIZE_TYPE__);
91 #endif
92 #ifdef __WCHAR_TYPE__
93 DECLARE_BUILTIN_TYPE("wchar", __WCHAR_TYPE__);
94 #endif
95 #ifdef __WINT_TYPE__
96 DECLARE_BUILTIN_TYPE("wint", __WINT_TYPE__);
97 #endif
98 """
100 PROBE_TAIL = """}
103 def read_config(fname, config):
104 "Read HelenOS build configuration"
106 inf = open(fname, 'r')
108 for line in inf:
109 res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
110 if (res):
111 config[res.group(1)] = res.group(2)
113 inf.close()
115 def print_error(msg):
116 "Print a bold error message"
118 sys.stderr.write("\n")
119 sys.stderr.write("######################################################################\n")
120 sys.stderr.write("HelenOS build sanity check error:\n")
121 sys.stderr.write("\n")
122 sys.stderr.write("%s\n" % "\n".join(msg))
123 sys.stderr.write("######################################################################\n")
124 sys.stderr.write("\n")
126 sys.exit(1)
128 def print_warning(msg):
129 "Print a bold error message"
131 sys.stderr.write("\n")
132 sys.stderr.write("######################################################################\n")
133 sys.stderr.write("HelenOS build sanity check warning:\n")
134 sys.stderr.write("\n")
135 sys.stderr.write("%s\n" % "\n".join(msg))
136 sys.stderr.write("######################################################################\n")
137 sys.stderr.write("\n")
139 time.sleep(5)
141 def sandbox_enter():
142 "Create a temporal sandbox directory for running tests"
144 if (os.path.exists(SANDBOX)):
145 if (os.path.isdir(SANDBOX)):
146 try:
147 shutil.rmtree(SANDBOX)
148 except:
149 print_error(["Unable to cleanup the directory \"%s\"." % SANDBOX])
150 else:
151 print_error(["Please inspect and remove unexpected directory,",
152 "entry \"%s\"." % SANDBOX])
154 try:
155 os.mkdir(SANDBOX)
156 except:
157 print_error(["Unable to create sandbox directory \"%s\"." % SANDBOX])
159 owd = os.getcwd()
160 os.chdir(SANDBOX)
162 return owd
164 def sandbox_leave(owd):
165 "Leave the temporal sandbox directory"
167 os.chdir(owd)
169 def check_config(config, key):
170 "Check whether the configuration key exists"
172 if (not key in config):
173 print_error(["Build configuration of HelenOS does not contain %s." % key,
174 "Try running \"make config\" again.",
175 "If the problem persists, please contact the developers of HelenOS."])
177 def check_common(common, key):
178 "Check whether the common key exists"
180 if (not key in common):
181 print_error(["Failed to determine the value %s." % key,
182 "Please contact the developers of HelenOS."])
184 def get_target(config):
185 target = None
186 gnu_target = None
187 clang_target = None
188 cc_args = []
190 if (config['PLATFORM'] == "abs32le"):
191 check_config(config, "CROSS_TARGET")
192 target = config['CROSS_TARGET']
194 if (config['CROSS_TARGET'] == "arm32"):
195 gnu_target = "arm-linux-gnueabi"
196 clang_target = "arm-unknown-linux"
198 if (config['CROSS_TARGET'] == "ia32"):
199 gnu_target = "i686-pc-linux-gnu"
200 clang_target = "i386-unknown-linux"
202 if (config['CROSS_TARGET'] == "mips32"):
203 gnu_target = "mipsel-linux-gnu"
204 clang_target = "mipsel-unknown-linux"
205 common['CC_ARGS'].append("-mabi=32")
207 if (config['PLATFORM'] == "amd64"):
208 target = config['PLATFORM']
209 gnu_target = "amd64-linux-gnu"
210 clang_target = "x86_64-unknown-linux"
212 if (config['PLATFORM'] == "arm32"):
213 target = config['PLATFORM']
214 gnu_target = "arm-linux-gnueabi"
215 clang_target = "arm-unknown-linux"
217 if (config['PLATFORM'] == "ia32"):
218 target = config['PLATFORM']
219 gnu_target = "i686-pc-linux-gnu"
220 clang_target = "i386-unknown-linux"
222 if (config['PLATFORM'] == "ia64"):
223 target = config['PLATFORM']
224 gnu_target = "ia64-pc-linux-gnu"
226 if (config['PLATFORM'] == "mips32"):
227 check_config(config, "MACHINE")
228 cc_args.append("-mabi=32")
230 if ((config['MACHINE'] == "msim") or (config['MACHINE'] == "lmalta")):
231 target = config['PLATFORM']
232 gnu_target = "mipsel-linux-gnu"
233 clang_target = "mipsel-unknown-linux"
235 if ((config['MACHINE'] == "bmalta")):
236 target = "mips32eb"
237 gnu_target = "mips-linux-gnu"
238 clang_target = "mips-unknown-linux"
240 if (config['PLATFORM'] == "mips64"):
241 check_config(config, "MACHINE")
242 cc_args.append("-mabi=64")
244 if (config['MACHINE'] == "msim"):
245 target = config['PLATFORM']
246 gnu_target = "mips64el-linux-gnu"
247 clang_target = "mips64el-unknown-linux"
249 if (config['PLATFORM'] == "ppc32"):
250 target = config['PLATFORM']
251 gnu_target = "ppc-linux-gnu"
252 clang_target = "powerpc-unknown-linux"
254 if (config['PLATFORM'] == "sparc64"):
255 target = config['PLATFORM']
256 gnu_target = "sparc64-linux-gnu"
257 clang_target = "sparc-unknown-linux"
259 return (target, cc_args, gnu_target, clang_target)
261 def check_app(args, name, details):
262 "Check whether an application can be executed"
264 try:
265 sys.stderr.write("Checking for %s ... " % args[0])
266 subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE).wait()
267 except:
268 sys.stderr.write("failed\n")
269 print_error(["%s is missing." % name,
271 "Execution of \"%s\" has failed. Please make sure that it" % " ".join(args),
272 "is installed in your system (%s)." % details])
274 sys.stderr.write("ok\n")
276 def check_app_alternatives(alts, args, name, details):
277 "Check whether an application can be executed (use several alternatives)"
279 tried = []
280 found = None
282 for alt in alts:
283 working = True
284 cmdline = [alt] + args
285 tried.append(" ".join(cmdline))
287 try:
288 sys.stderr.write("Checking for %s ... " % alt)
289 subprocess.Popen(cmdline, stdout = subprocess.PIPE, stderr = subprocess.PIPE).wait()
290 except:
291 sys.stderr.write("failed\n")
292 working = False
294 if (working):
295 sys.stderr.write("ok\n")
296 found = alt
297 break
299 if (found is None):
300 print_error(["%s is missing." % name,
302 "Please make sure that it is installed in your",
303 "system (%s)." % details,
305 "The following alternatives were tried:"] + tried)
307 return found
309 def check_gcc(path, prefix, common, details):
310 "Check for GCC"
312 common['GCC'] = "%sgcc" % prefix
314 if (not path is None):
315 common['GCC'] = "%s/%s" % (path, common['GCC'])
317 check_app([common['GCC'], "--version"], "GNU GCC", details)
319 def check_binutils(path, prefix, common, details):
320 "Check for binutils toolchain"
322 common['AS'] = "%sas" % prefix
323 common['LD'] = "%sld" % prefix
324 common['AR'] = "%sar" % prefix
325 common['OBJCOPY'] = "%sobjcopy" % prefix
326 common['OBJDUMP'] = "%sobjdump" % prefix
327 common['STRIP'] = "%sstrip" % prefix
329 if (not path is None):
330 for key in ["AS", "LD", "AR", "OBJCOPY", "OBJDUMP", "STRIP"]:
331 common[key] = "%s/%s" % (path, common[key])
333 check_app([common['AS'], "--version"], "GNU Assembler", details)
334 check_app([common['LD'], "--version"], "GNU Linker", details)
335 check_app([common['AR'], "--version"], "GNU Archiver", details)
336 check_app([common['OBJCOPY'], "--version"], "GNU Objcopy utility", details)
337 check_app([common['OBJDUMP'], "--version"], "GNU Objdump utility", details)
338 check_app([common['STRIP'], "--version"], "GNU strip", details)
340 def decode_value(value):
341 "Decode integer value"
343 base = 10
345 if ((value.startswith('$')) or (value.startswith('#'))):
346 value = value[1:]
348 if (value.startswith('0x')):
349 value = value[2:]
350 base = 16
352 return int(value, base)
354 def probe_compiler(common, intsizes, floatsizes):
355 "Generate, compile and parse probing source"
357 check_common(common, "CC")
359 outf = open(PROBE_SOURCE, 'w')
360 outf.write(PROBE_HEAD)
362 for typedef in intsizes:
363 outf.write("\tDECLARE_INTSIZE(\"%s\", %s, %s, %s);\n" % (typedef['tag'], typedef['type'], typedef['strc'], typedef['conc']))
365 for typedef in floatsizes:
366 outf.write("\nDECLARE_FLOATSIZE(\"%s\", %s);\n" % (typedef['tag'], typedef['type']))
368 outf.write(PROBE_TAIL)
369 outf.close()
371 args = [common['CC']]
372 args.extend(common['CC_ARGS'])
373 args.extend(["-S", "-o", PROBE_OUTPUT, PROBE_SOURCE])
375 try:
376 sys.stderr.write("Checking compiler properties ... ")
377 output = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
378 except:
379 sys.stderr.write("failed\n")
380 print_error(["Error executing \"%s\"." % " ".join(args),
381 "Make sure that the compiler works properly."])
383 if (not os.path.isfile(PROBE_OUTPUT)):
384 sys.stderr.write("failed\n")
385 print(output[1])
386 print_error(["Error executing \"%s\"." % " ".join(args),
387 "The compiler did not produce the output file \"%s\"." % PROBE_OUTPUT,
389 output[0],
390 output[1]])
392 sys.stderr.write("ok\n")
394 inf = open(PROBE_OUTPUT, 'r')
395 lines = inf.readlines()
396 inf.close()
398 unsigned_sizes = {}
399 signed_sizes = {}
401 unsigned_tags = {}
402 signed_tags = {}
404 unsigned_strcs = {}
405 signed_strcs = {}
407 unsigned_concs = {}
408 signed_concs = {}
410 float_tags = {}
412 builtin_sizes = {}
413 builtin_signs = {}
415 for j in range(len(lines)):
416 tokens = lines[j].strip().split("\t")
418 if (len(tokens) > 0):
419 if (tokens[0] == "AUTOTOOL_DECLARE"):
420 if (len(tokens) < 7):
421 print_error(["Malformed declaration in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
423 category = tokens[1]
424 subcategory = tokens[2]
425 tag = tokens[3]
426 name = tokens[4]
427 strc = tokens[5]
428 conc = tokens[6]
429 value = tokens[7]
431 if (category == "intsize"):
432 try:
433 value_int = decode_value(value)
434 except:
435 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
437 if (subcategory == "unsigned"):
438 unsigned_sizes[value_int] = name
439 unsigned_tags[tag] = value_int
440 unsigned_strcs[value_int] = strc
441 unsigned_concs[value_int] = conc
442 elif (subcategory == "signed"):
443 signed_sizes[value_int] = name
444 signed_tags[tag] = value_int
445 signed_strcs[value_int] = strc
446 signed_concs[value_int] = conc
447 else:
448 print_error(["Unexpected keyword \"%s\" in \"%s\" on line %s." % (subcategory, PROBE_OUTPUT, j), COMPILER_FAIL])
450 if (category == "floatsize"):
451 try:
452 value_int = decode_value(value)
453 except:
454 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
456 float_tags[tag] = value_int
458 if (category == "builtin_size"):
459 try:
460 value_int = decode_value(value)
461 except:
462 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
464 builtin_sizes[tag] = {'name': name, 'value': value_int}
466 if (category == "builtin_sign"):
467 try:
468 value_int = decode_value(value)
469 except:
470 print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
472 if (value_int == 1):
473 if (not tag in builtin_signs):
474 builtin_signs[tag] = strc;
475 elif (builtin_signs[tag] != strc):
476 print_error(["Inconsistent builtin type detection in \"%s\" on line %s." % (PROBE_OUTPUT, j), COMPILER_FAIL])
478 return {'unsigned_sizes': unsigned_sizes, 'signed_sizes': signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags, 'unsigned_strcs': unsigned_strcs, 'signed_strcs': signed_strcs, 'unsigned_concs': unsigned_concs, 'signed_concs': signed_concs, 'float_tags': float_tags, 'builtin_sizes': builtin_sizes, 'builtin_signs': builtin_signs}
480 def detect_sizes(probe, bytes, inttags, floattags):
481 "Detect correct types for fixed-size types"
483 macros = []
484 typedefs = []
486 for b in bytes:
487 if (not b in probe['unsigned_sizes']):
488 print_error(['Unable to find appropriate unsigned integer type for %u bytes.' % b,
489 COMPILER_FAIL])
491 if (not b in probe['signed_sizes']):
492 print_error(['Unable to find appropriate signed integer type for %u bytes.' % b,
493 COMPILER_FAIL])
495 if (not b in probe['unsigned_strcs']):
496 print_error(['Unable to find appropriate unsigned printf formatter for %u bytes.' % b,
497 COMPILER_FAIL])
499 if (not b in probe['signed_strcs']):
500 print_error(['Unable to find appropriate signed printf formatter for %u bytes.' % b,
501 COMPILER_FAIL])
503 if (not b in probe['unsigned_concs']):
504 print_error(['Unable to find appropriate unsigned literal macro for %u bytes.' % b,
505 COMPILER_FAIL])
507 if (not b in probe['signed_concs']):
508 print_error(['Unable to find appropriate signed literal macro for %u bytes.' % b,
509 COMPILER_FAIL])
511 typedefs.append({'oldtype': "unsigned %s" % probe['unsigned_sizes'][b], 'newtype': "uint%u_t" % (b * 8)})
512 typedefs.append({'oldtype': "signed %s" % probe['signed_sizes'][b], 'newtype': "int%u_t" % (b * 8)})
514 macros.append({'oldmacro': "unsigned %s" % probe['unsigned_sizes'][b], 'newmacro': "UINT%u_T" % (b * 8)})
515 macros.append({'oldmacro': "signed %s" % probe['signed_sizes'][b], 'newmacro': "INT%u_T" % (b * 8)})
517 macros.append({'oldmacro': "\"%so\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIo%u" % (b * 8)})
518 macros.append({'oldmacro': "\"%su\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIu%u" % (b * 8)})
519 macros.append({'oldmacro': "\"%sx\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIx%u" % (b * 8)})
520 macros.append({'oldmacro': "\"%sX\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIX%u" % (b * 8)})
521 macros.append({'oldmacro': "\"%sd\"" % probe['signed_strcs'][b], 'newmacro': "PRId%u" % (b * 8)})
523 name = probe['unsigned_concs'][b]
524 if ((name.startswith('@')) or (name == "")):
525 macros.append({'oldmacro': "c ## U", 'newmacro': "UINT%u_C(c)" % (b * 8)})
526 else:
527 macros.append({'oldmacro': "c ## U%s" % name, 'newmacro': "UINT%u_C(c)" % (b * 8)})
529 name = probe['unsigned_concs'][b]
530 if ((name.startswith('@')) or (name == "")):
531 macros.append({'oldmacro': "c", 'newmacro': "INT%u_C(c)" % (b * 8)})
532 else:
533 macros.append({'oldmacro': "c ## %s" % name, 'newmacro': "INT%u_C(c)" % (b * 8)})
535 for tag in inttags:
536 newmacro = "U%s" % tag
537 if (not tag in probe['unsigned_tags']):
538 print_error(['Unable to find appropriate size macro for %s.' % newmacro,
539 COMPILER_FAIL])
541 oldmacro = "UINT%s" % (probe['unsigned_tags'][tag] * 8)
542 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
543 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
544 macros.append({'oldmacro': "1", 'newmacro': 'U%s_SIZE_%s' % (tag, probe['unsigned_tags'][tag] * 8)})
546 newmacro = tag
547 if (not tag in probe['signed_tags']):
548 print_error(['Unable to find appropriate size macro for %s' % newmacro,
549 COMPILER_FAIL])
551 oldmacro = "INT%s" % (probe['signed_tags'][tag] * 8)
552 macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
553 macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
554 macros.append({'oldmacro': "1", 'newmacro': '%s_SIZE_%s' % (tag, probe['signed_tags'][tag] * 8)})
556 for tag in floattags:
557 if (not tag in probe['float_tags']):
558 print_error(['Unable to find appropriate size macro for %s' % tag,
559 COMPILER_FAIL])
561 macros.append({'oldmacro': "1", 'newmacro': '%s_SIZE_%s' % (tag, probe['float_tags'][tag] * 8)})
563 if (not 'size' in probe['builtin_signs']):
564 print_error(['Unable to determine whether size_t is signed or unsigned.',
565 COMPILER_FAIL])
567 if (probe['builtin_signs']['size'] != 'unsigned'):
568 print_error(['The type size_t is not unsigned.',
569 COMPILER_FAIL])
571 fnd = True
573 if (not 'wchar' in probe['builtin_sizes']):
574 print_warning(['The compiler does not provide the macro __WCHAR_TYPE__',
575 'for defining the compiler-native type wchar_t. We are',
576 'forced to define wchar_t as a hardwired type int32_t.',
577 COMPILER_WARNING])
578 fnd = False
580 if (probe['builtin_sizes']['wchar']['value'] != 4):
581 print_warning(['The compiler provided macro __WCHAR_TYPE__ for defining',
582 'the compiler-native type wchar_t is not compliant with',
583 'HelenOS. We are forced to define wchar_t as a hardwired',
584 'type int32_t.',
585 COMPILER_WARNING])
586 fnd = False
588 if (not fnd):
589 macros.append({'oldmacro': "int32_t", 'newmacro': "wchar_t"})
590 else:
591 macros.append({'oldmacro': "__WCHAR_TYPE__", 'newmacro': "wchar_t"})
593 if (not 'wchar' in probe['builtin_signs']):
594 print_error(['Unable to determine whether wchar_t is signed or unsigned.',
595 COMPILER_FAIL])
597 if (probe['builtin_signs']['wchar'] == 'unsigned'):
598 macros.append({'oldmacro': "1", 'newmacro': 'WCHAR_IS_UNSIGNED'})
599 if (probe['builtin_signs']['wchar'] == 'signed'):
600 macros.append({'oldmacro': "1", 'newmacro': 'WCHAR_IS_SIGNED'})
602 fnd = True
604 if (not 'wint' in probe['builtin_sizes']):
605 print_warning(['The compiler does not provide the macro __WINT_TYPE__',
606 'for defining the compiler-native type wint_t. We are',
607 'forced to define wint_t as a hardwired type int32_t.',
608 COMPILER_WARNING])
609 fnd = False
611 if (probe['builtin_sizes']['wint']['value'] != 4):
612 print_warning(['The compiler provided macro __WINT_TYPE__ for defining',
613 'the compiler-native type wint_t is not compliant with',
614 'HelenOS. We are forced to define wint_t as a hardwired',
615 'type int32_t.',
616 COMPILER_WARNING])
617 fnd = False
619 if (not fnd):
620 macros.append({'oldmacro': "int32_t", 'newmacro': "wint_t"})
621 else:
622 macros.append({'oldmacro': "__WINT_TYPE__", 'newmacro': "wint_t"})
624 if (not 'wint' in probe['builtin_signs']):
625 print_error(['Unable to determine whether wint_t is signed or unsigned.',
626 COMPILER_FAIL])
628 if (probe['builtin_signs']['wint'] == 'unsigned'):
629 macros.append({'oldmacro': "1", 'newmacro': 'WINT_IS_UNSIGNED'})
630 if (probe['builtin_signs']['wint'] == 'signed'):
631 macros.append({'oldmacro': "1", 'newmacro': 'WINT_IS_SIGNED'})
633 return {'macros': macros, 'typedefs': typedefs}
635 def create_makefile(mkname, common):
636 "Create makefile output"
638 outmk = open(mkname, 'w')
640 outmk.write('#########################################\n')
641 outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
642 outmk.write('## Generated by: tools/autotool.py ##\n')
643 outmk.write('#########################################\n\n')
645 for key, value in common.items():
646 if (type(value) is list):
647 outmk.write('%s = %s\n' % (key, " ".join(value)))
648 else:
649 outmk.write('%s = %s\n' % (key, value))
651 outmk.close()
653 def create_header(hdname, maps):
654 "Create header output"
656 outhd = open(hdname, 'w')
658 outhd.write('/***************************************\n')
659 outhd.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
660 outhd.write(' * Generated by: tools/autotool.py *\n')
661 outhd.write(' ***************************************/\n\n')
663 outhd.write('#ifndef %s\n' % GUARD)
664 outhd.write('#define %s\n\n' % GUARD)
666 for macro in maps['macros']:
667 outhd.write('#define %s %s\n' % (macro['newmacro'], macro['oldmacro']))
669 outhd.write('\n')
671 for typedef in maps['typedefs']:
672 outhd.write('typedef %s %s;\n' % (typedef['oldtype'], typedef['newtype']))
674 outhd.write('\n#endif\n')
675 outhd.close()
677 def main():
678 config = {}
679 common = {}
681 # Read and check configuration
682 if os.path.exists(CONFIG):
683 read_config(CONFIG, config)
684 else:
685 print_error(["Configuration file %s not found! Make sure that the" % CONFIG,
686 "configuration phase of HelenOS build went OK. Try running",
687 "\"make config\" again."])
689 check_config(config, "PLATFORM")
690 check_config(config, "COMPILER")
691 check_config(config, "BARCH")
693 # Cross-compiler prefix
694 if ('CROSS_PREFIX' in os.environ):
695 cross_prefix = os.environ['CROSS_PREFIX']
696 else:
697 cross_prefix = "/usr/local/cross"
699 # Prefix binutils tools on Solaris
700 if (os.uname()[0] == "SunOS"):
701 binutils_prefix = "g"
702 else:
703 binutils_prefix = ""
705 owd = sandbox_enter()
707 try:
708 # Common utilities
709 check_app(["ln", "--version"], "Symlink utility", "usually part of coreutils")
710 check_app(["rm", "--version"], "File remove utility", "usually part of coreutils")
711 check_app(["mkdir", "--version"], "Directory creation utility", "usually part of coreutils")
712 check_app(["cp", "--version"], "Copy utility", "usually part of coreutils")
713 check_app(["find", "--version"], "Find utility", "usually part of findutils")
714 check_app(["diff", "--version"], "Diff utility", "usually part of diffutils")
715 check_app(["make", "--version"], "Make utility", "preferably GNU Make")
716 check_app(["makedepend", "-f", "-"], "Makedepend utility", "usually part of imake or xutils")
718 # Compiler
719 common['CC_ARGS'] = []
720 if (config['COMPILER'] == "gcc_cross"):
721 target, cc_args, gnu_target, clang_target = get_target(config)
723 if (target is None) or (gnu_target is None):
724 print_error(["Unsupported compiler target for GNU GCC.",
725 "Please contact the developers of HelenOS."])
727 path = "%s/%s/bin" % (cross_prefix, target)
728 prefix = "%s-" % gnu_target
730 check_gcc(path, prefix, common, PACKAGE_CROSS)
731 check_binutils(path, prefix, common, PACKAGE_CROSS)
733 check_common(common, "GCC")
734 common['CC'] = common['GCC']
735 common['CC_ARGS'].extend(cc_args)
737 if (config['COMPILER'] == "gcc_native"):
738 check_gcc(None, "", common, PACKAGE_GCC)
739 check_binutils(None, binutils_prefix, common, PACKAGE_BINUTILS)
741 check_common(common, "GCC")
742 common['CC'] = common['GCC']
744 if (config['COMPILER'] == "icc"):
745 common['CC'] = "icc"
746 check_app([common['CC'], "-V"], "Intel C++ Compiler", "support is experimental")
747 check_gcc(None, "", common, PACKAGE_GCC)
748 check_binutils(None, binutils_prefix, common, PACKAGE_BINUTILS)
750 if (config['COMPILER'] == "clang"):
751 target, cc_args, gnu_target, clang_target = get_target(config)
753 if (target is None) or (gnu_target is None) or (clang_target is None):
754 print_error(["Unsupported compiler target for clang.",
755 "Please contact the developers of HelenOS."])
757 path = "%s/%s/bin" % (cross_prefix, target)
758 prefix = "%s-" % gnu_target
760 check_app(["clang", "--version"], "clang compiler", "preferably version 1.0 or newer")
761 check_gcc(path, prefix, common, PACKAGE_GCC)
762 check_binutils(path, prefix, common, PACKAGE_BINUTILS)
764 check_common(common, "GCC")
765 common['CC'] = "clang"
766 common['CC_ARGS'].extend(cc_args)
767 common['CC_ARGS'].append("-target")
768 common['CC_ARGS'].append(clang_target)
769 common['CLANG_TARGET'] = clang_target
771 # Platform-specific utilities
772 if ((config['BARCH'] == "amd64") or (config['BARCH'] == "ia32") or (config['BARCH'] == "ppc32") or (config['BARCH'] == "sparc64")):
773 common['GENISOIMAGE'] = check_app_alternatives(["mkisofs", "genisoimage"], ["--version"], "ISO 9660 creation utility", "usually part of genisoimage")
775 probe = probe_compiler(common,
777 {'type': 'long long int', 'tag': 'LLONG', 'strc': '"ll"', 'conc': '"LL"'},
778 {'type': 'long int', 'tag': 'LONG', 'strc': '"l"', 'conc': '"L"'},
779 {'type': 'int', 'tag': 'INT', 'strc': '""', 'conc': '""'},
780 {'type': 'short int', 'tag': 'SHORT', 'strc': '"h"', 'conc': '"@"'},
781 {'type': 'char', 'tag': 'CHAR', 'strc': '"hh"', 'conc': '"@@"'}
784 {'type': 'long double', 'tag': 'LONG_DOUBLE'},
785 {'type': 'double', 'tag': 'DOUBLE'},
786 {'type': 'float', 'tag': 'FLOAT'}
790 maps = detect_sizes(probe, [1, 2, 4, 8], ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG'], ['LONG_DOUBLE', 'DOUBLE', 'FLOAT'])
792 finally:
793 sandbox_leave(owd)
795 create_makefile(MAKEFILE, common)
796 create_header(HEADER, maps)
798 return 0
800 if __name__ == '__main__':
801 sys.exit(main())