diff --git a/etc/makemake.py b/etc/makemake.py index 9519743..30e59fe 100755 --- a/etc/makemake.py +++ b/etc/makemake.py @@ -41,12 +41,12 @@ There are special strings that are replaced in the template file: # http://www.cs.umd.edu/~nspring/software/style-check-readme.html import sys -import getopt import re import os import subprocess from os import pathsep import os.path +from optparse import OptionParser def unique (list): @@ -77,7 +77,7 @@ def file_search (filename, search_path, debug): return None -def hfiles_get (cfile, filedeps, mopts): +def hfiles_get (cfile, filedeps, options): deps = filedeps[cfile] @@ -89,12 +89,12 @@ def hfiles_get (cfile, filedeps, mopts): for hfile in filedeps[cfile]: if hfile[-2:] == '.h': - if mopts['relpath']: + if options.relpath: hfile = os.path.relpath (hfile) hfilelist.append (hfile) for hfile in filedeps[cfile]: - hfilelist.extend (hfiles_get (hfile, filedeps, mopts)) + hfilelist.extend (hfiles_get (hfile, filedeps, options)) return unique (hfilelist) @@ -127,17 +127,12 @@ def file_parse (pathname, indent, debug): return hfilelist -def makefile_print (mopts, template, maincfilename, filedeps, - search_list, debug): +def makefile_print (options, template, maincfilename, filedeps, + search_list): - basecfilelist = [] - cfilelist = [] - for target in filedeps: - if target[-2:] == '.c': - cfilelist.append (target) - basecfilelist.append (os.path.basename (target)) - basecfilelist.sort () + cfilelist = cfiles_get (filedeps) cfilelist.sort () + basecfilelist = [os.path.basename (cfile) for cfile in cfilelist] project = os.path.splitext (os.path.basename (maincfilename)) project = project[0] @@ -152,13 +147,13 @@ def makefile_print (mopts, template, maincfilename, filedeps, src = ' '.join (basecfilelist) obj = src - if mopts['builddir'] != '': - objfilelist = [os.path.join (mopts['builddir'], obj1) for obj1 in basecfilelist] + if options.builddir != '': + objfilelist = [os.path.join (options.builddir, obj1) for obj1 in basecfilelist] objfilelist.sort () obj = ' '.join (objfilelist) - project = os.path.join (mopts['builddir'], project) + project = os.path.join (options.builddir, project) - obj = re.sub (r'([a-zA-Z0-9/.-_]*)[.]c', r'\1' + mopts['objext'], obj) + obj = re.sub (r'([a-zA-Z0-9/.-_]*)[.]c', r'\1' + options.objext, obj) text = re.sub (r'@PROJECT@', project, text) text = re.sub (r'@VPATH@', vpath, text) @@ -175,21 +170,21 @@ def makefile_print (mopts, template, maincfilename, filedeps, for cfile in cfilelist: cfilebase = os.path.basename (cfile) - if mopts['relpath']: + if options.relpath: cfile1 = os.path.relpath (cfile) else: cfile1 = cfilebase - if mopts['builddir'] != '': - rules = rules + os.path.join (mopts['builddir'], '') + if options.builddir != '': + rules = rules + os.path.join (options.builddir, '') - rules = rules + re.sub ('([a-zA-Z0-9/.-_]*)[.]c', r'\1' + mopts['objext'], cfilebase) + ': ' + cfile1 + rules = rules + re.sub ('([a-zA-Z0-9/.-_]*)[.]c', r'\1' + options.objext, cfilebase) + ': ' + cfile1 - hfilelist = hfiles_get (cfile, filedeps, mopts) + hfilelist = hfiles_get (cfile, filedeps, options) hfilelist.sort () - if debug: + if options.debug: print >> sys.stderr, 'Need hfiles', hfilelist, 'for', cfile for hfile in hfilelist: @@ -308,23 +303,23 @@ def files_find (gcc, filepath, search_path, filedeps, moduledeps, indent, debug) files_find (gcc, file, search_path, filedeps, moduledeps, indent + ' ', debug) -def alldeps_print (depsdir, mopts): +def alldeps_print (depsdir, options): for target in depsdir.keys (): targetbase = os.path.basename (target) - if targetbase in mopts['exclude']: + if targetbase in options.exclude: continue deps = depsdir[target] - deps = [dep for dep in deps if os.path.basename (dep) not in mopts['exclude']] - if mopts['relpath']: + deps = [dep for dep in deps if os.path.basename (dep) not in options.exclude] + if options.relpath: deps = [os.path.relpath (dep) for dep in deps] print os.path.relpath (target) + ': ' + ' '.join (deps) + '\n' -def deps_print (target, depsdir, mopts, record = {}): +def deps_print (target, depsdir, options, record = {}): if record.has_key (target): return @@ -332,11 +327,11 @@ def deps_print (target, depsdir, mopts, record = {}): return deps = depsdir[target] - deps = [dep for dep in deps if os.path.basename (dep) not in mopts['exclude']] + deps = [dep for dep in deps if os.path.basename (dep) not in options.exclude] for dep in deps: - deps_print (dep, depsdir, mopts, record) + deps_print (dep, depsdir, options, record) - if mopts['relpath']: + if options.relpath: deps = [os.path.relpath (dep) for dep in deps] record[target] = True @@ -353,136 +348,139 @@ class Usage (Exception): def main(argv = None): if argv is None: argv = sys.argv - try: - try: - opts, args = getopt.gnu_getopt (argv[1:], "?h", \ - ["help", "builddir=", "objext=", - "exeext=", - "relpath", "debug", "template=", - "files", "modules", "exclude=", - "calls"]) - except getopt.error, msg: - raise Usage (msg) - - if not opts and not args: - print __doc__ - sys.exit (0) - - if len (args) < 1: - print __doc__ - sys.exit (0) - - mopts = {} - mopts['builddir'] = '' - mopts['objext'] = '.o' - mopts['exeext'] = '.out' - mopts['relpath'] = False - mopts['template'] = None - mopts['files'] = False - mopts['modules'] = False - mopts['calls'] = False - mopts['exclude'] = [] - debug = False - - # Process options - for o, a in opts: - if o in ("-?", "-h", "--help"): - print __doc__ - sys.exit (0) - elif o == "--builddir": - mopts['builddir'] = a - elif o == "--objext": - mopts['objext'] = a - elif o == "--exeext": - mopts['exeext'] = a - elif o == "--relpath": - mopts['relpath'] = True - elif o == "--debug": - debug = True - elif o == "--template": - mopts['template'] = a - elif o == "--files": - mopts['files'] = True - elif o == "--modules": - mopts['modules'] = True - elif o == "--calls": - mopts['calls'] = True - elif o == "--exclude": - mopts['exclude'] = a.split (' ') - - maincfilename = args[0] - - search_list = [] - if len (args) > 1: - search_list.extend (args[1:len (args)]) - - if debug: - print >> sys.stderr, search_list - search_path = pathsep.join (search_list) - if debug: - print >> sys.stderr, 'template', mopts['template'] - print >> sys.stderr, 'cfile', maincfilename - print >> sys.stderr, 'search_path', search_path - print >> sys.stderr, 'CWD = ', os.getcwd() - - if os.path.isdir (maincfilename): - if debug: - print >> sys.stderr, 'Searching ' + maincfilename - maincfilename = maincfilename_find (maincfilename) - if not maincfilename: - sys.exit (1) - - if debug: - print >> sys.stderr, 'Found C file ' + maincfilename - - includes = '-I' + ' -I'.join (search_list) - cflags = '-mmcu=atmega32u2' - opts = '-Os' - gcc = 'avr-gcc' + ' ' + cflags + ' ' + opts + ' ' + includes - - # Search main c file looking for header files included with #include - # and any header files included by the header files - - filedeps = {} - moduledeps = {} - functiondeps = {} - files_find (gcc, maincfilename, search_path, filedeps, moduledeps, '', debug) - - cfilelist = cfiles_get (filedeps) - ofilelist = [cfile[:-2] + mopts['objext'] for cfile in cfilelist] - outfile = maincfilename[:-2] + mopts['exeext'] - filedeps[outfile] = ofilelist - for ofile in ofilelist: - deps = [] - deps.append (ofile[:-2] + '.c') - filedeps[ofile] = deps - - # print >> sys.stderr, moduledeps - # print >> sys.stderr, filedeps - - if mopts['calls']: - for cfile in cfilelist: - functions_find (gcc, cfile, functiondeps) - deps_print ('main', functiondeps, mopts) - - if mopts['files']: - deps_print (outfile, filedeps, mopts) - - if mopts['modules']: - target, ext = os.path.splitext (os.path.basename (maincfilename)) - deps_print (target, moduledeps, mopts) - - if mopts['template']: - makefile_print (mopts, mopts['template'], maincfilename, filedeps, - search_list, debug) - - return 0 - - - except Usage, err: - print >> sys.stderr, err.msg - print >> sys.stderr, "for help use --help" - return 2 + + version = __doc__.split ('\n')[0] + + parser = OptionParser (usage = '%prog', version = version, + description = __doc__) + + parser.add_option('--showops', action = 'store_true', + dest = 'showops', default = False, + help = 'show operations') + + parser.add_option('--modules', action = 'store_true', + dest = 'modules', default = False, + help = 'generate module dependencies') + + parser.add_option('--calls', action = 'store_true', + dest = 'calls', default = False, + help = 'generate callgraph') + + parser.add_option('--files', action = 'store_true', + dest = 'files', default = False, + help = 'generate file dependencies') + + parser.add_option('--debug', action = 'store_true', + dest = 'debug', default = False, + help = 'enable debugging') + + parser.add_option('--exclude', dest = 'exclude', + default = '', + help = 'files to exclude') + + parser.add_option('--objext', dest = 'objext', + default = '.o', + help = 'object file extension') + + parser.add_option('--exeext', dest = 'exeext', + default = '.out', + help = 'executable file extension') + + parser.add_option('--relpath', action = 'store_true', + dest = 'relpath', default = False, + help = 'use relative paths') + + parser.add_option('--outfile', dest = 'outfilename', + default = None, + help = 'output filename') + + parser.add_option('--builddir', dest = 'builddir', + default = '', + help = 'build dirname') + + parser.add_option('--template', dest = 'template', + default = None, + help = 'template filename') + + (options, args) = parser.parse_args () + + if len (args) < 1: + print __doc__ + sys.exit (0) + + + if ',' in options.exclude: + options.exclude = options.exclude.split(',') + else: + options.exclude = options.exclude.split() + + maincfilename = args[0] + + search_list = [] + if len (args) > 1: + search_list.extend (args[1:len (args)]) + + if options.debug: + print >> sys.stderr, search_list + search_path = pathsep.join (search_list) + if options.debug: + print >> sys.stderr, 'template', options.template + print >> sys.stderr, 'cfile', maincfilename + print >> sys.stderr, 'search_path', search_path + print >> sys.stderr, 'CWD = ', os.getcwd() + + if os.path.isdir (maincfilename): + if options.debug: + print >> sys.stderr, 'Searching ' + maincfilename + maincfilename = maincfilename_find (maincfilename) + if not maincfilename: + sys.exit (1) + + if options.debug: + print >> sys.stderr, 'Found C file ' + maincfilename + + includes = '-I' + ' -I'.join (search_list) + cflags = '-mmcu=atmega32u2' + opts = '-Os' + gcc = 'avr-gcc' + ' ' + cflags + ' ' + opts + ' ' + includes + + # Search main c file looking for header files included with #include + # and any header files included by the header files + + filedeps = {} + moduledeps = {} + functiondeps = {} + files_find (gcc, maincfilename, search_path, filedeps, moduledeps, '', options.debug) + + cfilelist = cfiles_get (filedeps) + ofilelist = [cfile[:-2] + options.objext for cfile in cfilelist] + outfile = maincfilename[:-2] + options.exeext + filedeps[outfile] = ofilelist + for ofile in ofilelist: + deps = [] + deps.append (ofile[:-2] + '.c') + filedeps[ofile] = deps + + # print >> sys.stderr, moduledeps + # print >> sys.stderr, filedeps + + if options.calls: + for cfile in cfilelist: + functions_find (gcc, cfile, functiondeps) + deps_print ('main', functiondeps, options) + + if options.files: + deps_print (outfile, filedeps, options) + + if options.modules: + target, ext = os.path.splitext (os.path.basename (maincfilename)) + deps_print (target, moduledeps, options) + + if options.template: + makefile_print (options, options.template, maincfilename, filedeps, + search_list) + + return 0 if __name__ == "__main__":