16 # Key is the rule name. Value is a mkrule object.
19 # List of targets in the order defined by makerule commands.
27 # make these a hash so they will be unique.
33 globalvars = {} # We will globals here
37 # options in order defined. These will be unique due to use of hash
46 local_path = re.compile(r'^\.')
48 # -----------------------------------------------------------------------------
50 # -----------------------------------------------------------------------------
54 def __init__(self, file, line, command):
57 self.command = command
58 def next_line(self, command):
59 self.line = self.line + 1
60 self.command = command
62 return "%s:%d" % (self.file, self.line)
68 return self.stack[-1].file
70 return self.stack[-1].line
72 return self.stack[-1].command
74 def push_file(self, file):
75 self.stack.append(self.place(file, 0, ""))
78 def next_line(self, command):
79 self.stack[-1].next_line(command)
81 return self.stack[-1].at()
85 def __init__ (self, target):
90 def addaction(self, action):
91 self.actions.append(action)
93 def adddependency(self, dependency):
94 self.dependency.append(dependency)
99 def gdependency(self):
100 return self.dependency
106 def __init__ (self, name):
113 def setvalue(self, value, loc):
115 print "Option %s: \n" % self.name
116 print "Attempt to set %s at %s\n" % (value, loc.at())
117 print "Already set to %s at %s\n" % \
118 (self.value, self.loc.at())
129 def setdefault(self, value, loc):
131 print "%s: " % self.name
132 print "Attempt to default %s at %s\n" % (value, loc)
133 print "Already defaulted to %s at %s\n" % \
134 (self.value, self.loc.at())
135 print "Warning only\n"
137 print "%s: " % self.name
138 print "Attempt to default %s at %s\n" % (value, loc)
139 print "Already set to %s at %s\n" % \
140 (self.value, self.loc.at())
141 print "Warning only\n"
151 def __init__ (self, dir, parent, type):
153 print "partobj dir %s parent %s type %s" %(dir,parent,type)
156 self.registercode = []
162 self.instance = partinstance + 1
163 partinstance = partinstance + 1
167 print "add to parent"
169 parent.children.append(self)
173 def dumpme(self, lvl):
174 print "%d: type %s" % (lvl, self.type)
175 print "%d: dir %s" % (lvl,self.dir)
176 print "%d: parent %s" % (lvl,self.parent.type)
177 print "%d: parent dir %s" % (lvl,self.parent.dir)
178 print "%d: initcode " % lvl
179 for i in self.initcode:
181 print "%d: registercode " % lvl
182 for i in self.registercode:
186 print "struct cdev dev%d = {" % self.instance
187 print "/* %s %s */" % (self.type, self.dir)
188 print " .devfn = %d" % self.devfn
190 print " .next = &dev%d" % self.sibling.instance
192 print " .children = &dev%d" % \
193 self.children[0].instance
195 print " .private = private%d" % self.instance
202 def addinit(self, code):
203 self.initcode.append(code)
205 def addregister(self, code):
206 self.registercode.append(code)
213 def push(self, part):
214 self.stack.append(part)
217 return self.stack.pop()
220 return self.stack[-1]
221 pstack = partsstack()
225 size = len(loc.stack)
228 print loc.stack[i].at()
230 print "%s: %s"% (loc.at(), string)
235 print "===> Warning:"
236 size = len(loc.stack)
239 print loc.stack[i].at()
241 print "%s: %s"% (loc.at(), string)
244 # -----------------------------------------------------------------------------
246 # -----------------------------------------------------------------------------
248 def getvalue(dict, name):
249 if name not in dict.keys(): print 'Undefined:', name
250 v = dict.get(name, 0)
252 print "getvalue %s returning %s\n" % (name, v)
255 def setvalue(dict, name, value):
256 print "name %s value %s" % (name, value)
257 if name in dict.keys(): print "Warning, %s previously defined" % name
259 print "setvalue sets %s to %s\n" % (name, value)
263 # to create an option, it has to no exist.
264 # When an option value is fetched, the fact that it was used is
266 # Legal things to do:
267 # set a default value, then set a real value before the option is used.
268 # set a value, try to set a default, default silently fails.
270 # use the value, then try to set the value
273 print "getoption %s" % name
274 o = getvalue(options, name)
276 fatal( "Error. Option %s Undefined. Fix me.\n" % name)
278 print "returns %s" % o
279 print "%s" % o.where()
282 # stupid code, refactor later.
283 def setoption(name, value):
284 o = getvalue(options, name)
286 o.setvalue(value, loc)
289 o.setvalue(value, loc)
290 setvalue(options, name, o)
291 options_by_order.append(name)
293 def setdefault(name, value):
294 o = getvalue(options, name)
296 o.setdefault(value, loc)
298 print "setdefault: %s not here, setting to %s" % \
301 o.setdefault(value, loc)
302 setvalue(options, name, o)
303 options_by_order.append(name)
305 # we do the crt0include as a dictionary, so that if needed we
306 # can trace who added what when. Also it makes the keys
308 def addcrt0include(path):
310 #fullpath = os.path.join(curdir, path)
312 #setvalue(crt0includes, fullpath, loc)
313 # oh shoot. Order matters. All right, we'll worry about this
317 print "ADDCRT0: %s\n" % fullpath
318 crt0includes.append(fullpath)
320 def addldscript(path):
323 fullpath = treetop + '/src/' + path
325 fullpath = curdir + '/' + path
326 #fullpath = os.path.join(curdir, path)
327 #setvalue(ldscripts, fullpath, loc)
329 print "fullpath :%s: curdir :%s: path :%s:\n" % (fullpath, curdir, path)
330 ldscripts.append(fullpath)
334 adduserdefine("PAYLOAD:=%s"%path)
336 # adddep('payload', path)
337 # addaction('payload', 'cp $< $@')
339 # this is called with an an object name.
340 # the easiest thing to do is add this object to the current
342 # such kludgery. If the name starts with '.' then make the
343 # dependency be on ./thing.x gag me.
344 def addobjectdriver(dict, object_name):
345 print "add object object_name %s" % object_name
346 suffix = object_name[-2:]
349 base = object_name[:-2]
350 if (object_name[0] == '.'):
351 source = base + suffix
353 source = os.path.join(curdir, base + suffix)
355 print "addobject %s source %s\n" % (object, source)
356 setvalue(dict, base, [object, source])
358 def addobject(object_name):
359 addobjectdriver(objectrules, object_name)
361 def adddriver(driver_name):
362 addobjectdriver(driverrules, driver_name)
364 def target(targ_name):
367 print "TARGET loc.file is %s\n" % loc.file()
368 target_dir = os.path.join(os.path.dirname(loc.file()), targ_name)
369 print "TARGET dir.loc.file is %s\n" % os.path.dirname(loc.file())
370 if not os.path.isdir(target_dir):
371 print 'Creating directory', target_dir
372 os.makedirs(target_dir)
373 print 'Will place Makefile, crt0.S, etc. in ', target_dir
374 print '%s\n' % loc.file()
375 board = partobj(target_dir, 0, 'board')
380 def part(name, path, file):
381 global curpart,curdir
384 dirstack.append(curdir)
385 curdir = os.path.join(treetop, 'src', name, path)
386 newpart = partobj(curdir, curpart, name)
387 print "PUSH part " , curpart.dir
390 # option(parts, name, path)
391 # open the file, and parse it.
392 # curpart.option('MAINBOARD_PART_NUMBER',
393 # os.path.basename(lookup(parts, 'mainboard')))
394 # option(options, 'MAINBOARD_VENDOR', os.path.dirname(getvalue(parts, 'mainboard')))
396 doconfigfile(curdir, file)
399 global curpart,curdir
400 curpart = pstack.pop()
401 curdir = dirstack.pop()
402 print "POP PART %s\n" % curpart.dir
404 # dodir is like part but there is no new part
405 def dodir(path, file):
406 global curdir, treetop
407 # if the first char is '/', it is relative to treetop,
408 # else relative to curdir
409 # os.path.join screws up if the name starts with '/', sigh.
411 fullpath = treetop + '/src/' + path
413 fullpath = os.path.join(curdir, path)
415 print "DODIR: path %s, fullpath %s\n" % (path, fullpath)
416 print "DODIR: curdis %s treetop %s\n" % (curdir, treetop)
417 dirstack.append(curdir)
419 file = os.path.join(fullpath, file)
420 config_file_list.append(file)
421 doconfigfile(fullpath, file)
422 curdir = dirstack.pop()
424 def ternary(expr, yes, no):
425 print "ternary %s" % expr
426 a = tohex(expr) # expr # eval(expr)
427 print "expr %s a %d yes %d no %d\n"% (expr, a, yes, no)
429 print "Ternary returns %d\n" % yes
432 print "Ternary returns %d\n" % no
434 # atoi is in the python library, but not strtol? Weird!
436 return eval('int(%s)' % name)
439 """ Is the given string an integer?"""
448 setvalue(makebaserules, id, o)
450 def adduserdefine(str):
451 userdefines.append(str)
454 a = re.sub("^\"", "", str)
455 a = re.sub("\"$", "", a)
456 # highly un-intuitive, need four \!
457 a = re.sub("\\\\\"", "\"", a)
460 def addaction(id, str):
461 o = getvalue(makebaserules, id)
466 o = getvalue(makebaserules, id)
470 # If the first part of <path> matches treetop, replace that part with "$(TOP)"
473 if path[0:len(treetop)] == treetop:
474 path = path[len(treetop):len(path)]
475 if (path[0:1] == "/"):
476 path = path[1:len(path)]
477 path = "$(TOP)/" + path
480 # arch is 'different' ... darn it.
481 def set_arch(my_arch):
482 global arch, makebase
485 setdefault('ARCH', my_arch)
486 part('arch', my_arch, 'config/make.base.lb')
492 full_mainboard_dir = os.path.join(treetop, 'src/mainboard', path)
493 setdefault('MAINBOARD', full_mainboard_dir)
494 vendor = re.sub("/.*", "", path)
495 mainboard_part_number = re.sub("[^/]/", "", path)
496 setdefault('MAINBOARD_VENDOR', vendor)
497 setdefault('MAINBOARD_PART_NUMBER', mainboard_part_number)
498 part('mainboard', path, 'Config.lb')
499 #=============================================================================
501 #=============================================================================
502 def writemakefileheader(file, fname):
503 file.write("# File: %s\n" % fname)
504 file.write("# This file was generated by '%s %s %s'\n\n"
505 % (sys.argv[0], sys.argv[1], sys.argv[2]))
508 def writemakefilesettings(path):
509 global treetop, arch, mainboard_dir, target_dir, options
510 # Write Makefile.settings to seperate the settings
511 # from the actual makefile creation
512 # In practice you need to rerun NLBConfig.py to change
513 # these but in theory you shouldn't need to.
515 filename = os.path.join(path, "Makefile.settings")
516 print "Creating", filename
517 file = open(filename, 'w+')
518 writemakefileheader(file, filename)
519 file.write("TOP:=%s\n" % (treetop))
520 #file.write("ARCH:=%s\n" % (arch))
521 #file.write("MAINBOARD:=%s\n" % (mainboard_dir))
522 file.write("TARGET_DIR:=%s\n" % (target_dir))
523 for i in options_by_order:
525 # get the number in hex
529 s = "export %s:=0x%x\n"% (i, vi)
532 file.write("export %s:=%s\n" % (i, v))
533 file.write("export VARIABLES := ");
534 for i in options.keys():
535 file.write("%s " % i)
537 # file.write("CPUFLAGS := ");
538 # for i in options.keys():
540 # file.write("-D%s=%s " % (i, o.getvalue()))
546 # let's try the Makefile
547 # first, dump all the -D stuff
549 def writemakefile(path):
550 makefilepath = os.path.join(path, "Makefile")
551 print "Creating", makefilepath
552 file = open(makefilepath, 'w+')
553 writemakefileheader(file, makefilepath)
555 # file.write("include Makefile.settings\n")
556 # file.write("include cpuflags\n")
557 # Putting "include cpuflags" in the Makefile has the problem that the
558 # cpuflags file would be generated _after_ we want to include it.
559 # Instead, let make do the work of computing CPUFLAGS:
561 # Get the value of TOP, VARIABLES, and several other variables.
562 include Makefile.settings
564 # Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686
565 D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)
567 # Compute the value of CPUFLAGS here during make's first pass.
568 CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))
571 for i in userdefines:
572 file.write("%s\n" %i)
575 # print out all the object dependencies
576 file.write("\n# object dependencies (objectrules:)\n")
577 file.write("OBJECTS :=\n")
578 file.write("DRIVERS :=\n")
579 for objrule in objectrules.keys():
580 obj = objectrules[objrule]
583 file.write("OBJECTS-1 += %s\n" % (obj_name))
585 for driverrule in driverrules.keys():
586 driver = driverrules[driverrule]
588 obj_source = driver[1]
589 file.write("DRIVER += %s\n" % (obj_name))
591 # Print out all ldscript.ld dependencies.
592 file.write("\n# ldscript.ld dependencies:\n")
593 file.write("LDSUBSCRIPTS-1 := \n" )
594 for script in ldscripts:
595 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
597 # Print out the dependencies for crt0_includes.h
598 file.write("\n# Dependencies for crt0_includes.h\n")
599 file.write("CRT0_INCLUDES:=\n")
600 for i in crt0includes:
601 if (local_path.match(i)):
602 file.write("CRT0_INCLUDES += %s\n" % i)
604 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % i)
609 file.write("\nSOURCES=\n")
610 #for source in sources:
611 #file.write("SOURCES += %s\n" % source)
613 # Print out the user defines.
614 file.write("\n# userdefines:\n")
615 #for udef in userdefines:
616 #file.write("%s\n" % udef)
618 # Print out the base rules.
619 # Need to have a rule that counts on 'all'.
620 file.write("\n# mainrulelist:")
621 #file.write("\nmainrule: %s\n" % mainrulelist)
623 # Print out any user rules.
624 file.write("\n# From makerule or docipl commands:\n")
625 # Old way (hash order): for target in makebaserules.keys():
626 # New way (config file order):
627 #for target in makerule_targets:
628 #makebaserules[target].write(file)
630 file.write("\n# objectrules:\n")
631 for objrule in objectrules.keys():
632 obj = objectrules[objrule]
633 source = topify(obj[1])
634 file.write("%s: %s\n" % (obj[0], source))
635 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
636 #file.write("%s\n" % objrule[2])
638 for driverrule in driverrules.keys():
639 driver = driverrules[driverrule]
640 source = topify(driver[1])
641 file.write("%s: %s\n" % (driver[0], source))
642 #file.write("%s\n" % objrule[2])
644 # Print out the rules that will make cause the files
645 # generated by NLBConfig.py to be remade if any dependencies change.
647 file.write("\n# Remember the automatically generated files\n")
648 file.write("GENERATED:=\n")
649 for genfile in [ 'Makefile',
654 'LinuxBIOSDoc.config' ]:
655 file.write("GENERATED += %s\n" % genfile)
657 file.write("\n# Remake Makefile (and the other files generated by\n")
658 file.write("# NLBConfig.py) if any config dependencies change.\n")
660 for cfile in config_file_list:
661 file.write("$(GENERATED): %s\n" % topify(cfile))
663 for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
664 '$(TOP)/util/config/NLBConfig.py',
665 '$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
666 file.write("$(GENERATED): %s\n" % depfile)
668 file.write("$(GENERATED):\n")
669 file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
672 keys = makeoptions.keys()
674 file.write("\necho:\n")
676 file.write("\t@echo %s='$(%s)'\n"% (key,key))
679 for i in makebaserules.keys():
681 file.write("%s: " %i)
682 for i in m.dependency:
683 file.write("%s " % i)
686 file.write("\t%s\n" % i)
689 # Write out crt0_includes.h (top-level assembly language) include file.
690 def writecrt0_includes(path):
691 crt0filepath = os.path.join(path, "crt0_includes.h")
692 print "Creating", crt0filepath
693 file = open(crt0filepath, 'w+')
695 for i in crt0includes:
696 file.write("#include <%s>\n" % i)
706 token XNUM: r'0x[0-9a-fA-F]+'
707 # Why is path separate? Because paths to resources have to at least
708 # have a slash, we thinks
709 token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+'
710 # Dir's on the other hand are abitrary
711 # this may all be stupid.
712 token DIRPATH: r'[a-zA-Z0-9_$()./]+'
713 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
714 token STR: r'"([^\\"]+|\\.)*"'
716 token OPTION: 'option'
717 token MAINBOARD: 'mainboard'
718 token MAINBOARDINIT: 'mainboardinit'
721 token TARGET: 'target'
722 token OBJECT: 'object'
723 token DRIVER: 'driver'
724 token NORTHBRIDGE: 'northbridge'
725 token SOUTHBRIDGE: 'southbridge'
726 token SUPERIO: 'superio'
728 token MAKERULE: 'makerule'
731 token MAKEDEFINE: 'makedefine'
732 token ADDACTION: 'addaction'
733 token DEFAULT: 'default'
735 token REGISTER: 'register'
739 token LDSCRIPT: 'ldscript'
740 token PAYLOAD: 'payload'
742 # An expression is the sum and difference of factors
743 rule expr<<V>>: factor<<V>> {{ n = factor }}
744 ( "[+]" factor<<V>> {{ n = n+factor }}
745 | "-" factor<<V>> {{ n = n-factor }}
748 # A factor is the product and division of terms
749 rule factor<<V>>: term<<V>> {{ v = term }}
750 ( "[*]" term<<V>> {{ v = v*term }}
751 | "/" term<<V>> {{ v = v/term }}
752 | "<<" term<<V>> {{ v = v << term }}
753 | ">=" term<<V>> {{ v = (v < term)}}
756 rule unop<<V>>: "!" ID {{ return ternary(getoption(ID), 1, 0)}}
757 # A term is a number, variable, or an expression surrounded by parentheses
759 NUM {{ return atoi(NUM) }}
760 | XNUM {{ return tohex(XNUM) }}
761 | ID {{ return tohex(getoption(ID)) }}
762 | unop<<V>> {{ return unop }}
763 | "\\(" expr<<V>> "\\)" {{ return expr }}
765 rule option<<C>>: OPTION ID EQ
767 STR {{ if (C): setoption(ID, dequote(STR)) }}
768 | term<<[]>> {{ if (C): setoption(ID, term) }}
770 rule default<<C>>: DEFAULT ID EQ RAWTEXT {{ if (C): setdefault(ID, RAWTEXT) }}
772 rule partend<<C>>: partstmts<<C>> END
773 rule mainboard: MAINBOARD PATH {{mainboard(PATH) }}
776 rule northbridge<<C>>: NORTHBRIDGE PATH
777 {{if (C): part('northbridge', PATH, 'Config.lb')}} partend<<C>>
778 rule superio<<C>>: SUPERIO PATH
779 {{if (C): part('superio', PATH, 'Config.lb')}} partend<<C>>
780 rule cpu<<C>>: CPU ID
781 {{if (C): part('cpu', ID, 'Config.lb')}} partend<<C>>
782 rule arch<<C>>: ARCH ID
783 {{if (C): set_arch(ID) }} partend<<C>>
784 rule southbridge<<C>>: SOUTHBRIDGE PATH
785 {{if (C): part('southbridge', PATH, 'Config.lb')}} partend<<C>>
787 rule mainboardinit<<C>>:
788 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
790 rule object<<C>>: OBJECT DIRPATH {{if (C): addobject(DIRPATH)}}
791 rule driver<<C>>: DRIVER DIRPATH {{if (C): adddriver(DIRPATH)}}
792 rule dir<<C>>: DIR DIRPATH {{if (C): dodir(DIRPATH, 'Config.lb') }}
794 rule ldscript<<C>>: LDSCRIPT DIRPATH {{if (C): addldscript(DIRPATH) }}
795 rule payload<<C>>: PAYLOAD DIRPATH {{if (C): payload(DIRPATH) }}
796 # if is a bad id ....
798 # needs to be C and ID, but nested if's are, we hope, not going to
799 # happen. IF so, possibly ID && C could be used.
800 IF ID {{ c = tohex(getoption(ID)); print "IF %d\n" % c }} (stmt<<c>>)* END
802 rule depsacts<<ID, C>>: (
803 DEP STR {{ if (C): adddep(ID, STR) }}
804 | ACT STR {{ if (C): addaction(ID, STR) }}
806 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
807 depsacts<<DIRPATH, C>>
808 rule makedefine<<C>>: MAKEDEFINE RAWTEXT
809 {{ if (C): adduserdefine(RAWTEXT) }}
810 rule addaction<<C>>: ADDACTION ID STR
811 {{ if (C): addaction(ID, STR) }}
812 rule init<<C>>: INIT STR {{ if (C): curpart.addinit(STR) }}
813 rule register<<C>>: REGISTER STR {{ if (C): curpart.addregister(STR) }}
815 # to make if work without 2 passses, we use an old hack from SIMD, the
816 # context bit. If the bit is 1, then ops get done, otherwise
817 # ops don't get done. From the top level, context is always
818 # 1. In an if, context depends on eval of the if condition
820 option<<C>> {{ return option }}
821 | default<<C>> {{ return default }}
822 | cpu<<C>> {{ return cpu}}
823 | arch<<C>> {{ return arch}}
824 | northbridge<<C>> {{ return northbridge }}
825 | southbridge<<C>> {{ return southbridge }}
826 | superio<<C>> {{ return superio }}
827 | object<<C>> {{ return object }}
828 | driver<<C>> {{ return driver }}
829 | mainboardinit<<C>> {{ return mainboardinit }}
830 | makerule<<C>> {{ return makerule }}
831 | makedefine<<C>> {{ return makedefine }}
832 | addaction<<C>> {{ return addaction }}
833 | init<<C>> {{ return init }}
834 | register<<C>> {{ return register}}
835 | iif<<C>> {{ return iif }}
836 | dir<<C>> {{ return dir}}
837 | ldscript<<C>> {{ return ldscript}}
838 | payload<<C>> {{ return payload}}
840 rule stmts<<C>>: (stmt<<C>>)* {{ }}
842 rule partstmts<<C>>: (stmt<<C>>)* {{ partpop()}}
843 # need this to get from python to the rules, I think.
845 rule pstmts: stmts<<1>> {{ }}
846 rule target: TARGET DIRPATH {{target(DIRPATH)}}
847 rule board: target mainboard {{ }}
850 def dumptree(part, lvl):
851 print "DUMPTREE ME is"
853 # dump the siblings -- actually are there any? not sure
855 print "DUMPTREE KIDS are"
856 for kid in part.children:
858 print "DONE DUMPTREE"
861 print "GENCODE ME is"
863 # dump the siblings -- actually are there any? not sure
865 print "GENCODE KIDS are"
866 for kid in part.children:
871 def doconfigfile(path, file):
873 print "DOCONFIGFILE", path, " ", file
874 filename = os.path.join(path, file)
875 loc.push_file(filename);
876 parse('pstmts', open(filename, 'r').read())
878 if __name__=='__main__':
881 print 'Args: <file> <path to linuxbios>'
883 top_config_file = os.path.abspath(sys.argv[1])
885 treetop = os.path.abspath(sys.argv[2])
887 # Set the default locations for config files.
888 makebase = os.path.join(treetop, "util/config/make.base")
889 crt0base = os.path.join(treetop, "arch/i386/config/crt0.base")
890 doxyscriptbase = os.path.join(treetop, "src/config/doxyscript.base")
892 # Now read in the customizing script...
893 loc.push_file(argv[1]);
894 parse('board', open(argv[1], 'r').read())
897 for i in options.keys():
899 print "key %s @%s: val %s" % (i, o.where(), o.getvalue())
901 for i in crt0includes:
902 print "crt0include file %s \n" % (i)
903 for i in driverrules.keys():
904 print "driver file %s \n" % (i)
906 print "ldscript file %s\n" % (i)
907 for i in makebaserules.keys():
909 print " makerule %s dep %s act %s\n" % (i, m.dependency, m.actions)
910 writemakefilesettings(target_dir)
911 writecrt0_includes(target_dir)
912 writemakefile(target_dir)