#!/usr/bin/python # # Makefile generator by Unavowed (unavowed at vexillium org) # This code is public domain. # import sys, os, stat class Language: def __init__(self, suffixes): self.files = [] self.suffixes = suffixes self.suffixes_present = {} def add_file(self, fname): for s in self.suffixes: if fname.endswith('.' + s): self.files.append(fname) self.suffixes_present[s] = True return True return False def is_present(self): return (len(self.files) > 0) def get_suffixes(self): return [s for s in self.suffixes_present.keys()] def get_files(self): return self.files def print_list(lst, out): if len(lst) == 0: return out.write(lst[0]) if len(lst) == 1: return for l in lst[1:]: out.write(' ' + l) def print_files(lang, out): if not lang.is_present(): return files = [f for f in lang.get_files()] files.sort() print_list(files, out) lang_c = Language(['c']) lang_cpp = Language(['cpp', 'cc']) languages = { 'C' : lang_c, 'C++' : lang_cpp } target = 'a.out' if len(sys.argv) > 1: target = sys.argv[1] for f in os.listdir('.'): st = os.stat(f) if not stat.S_ISREG(st.st_mode): continue for lang in languages.itervalues(): if lang.add_file(f): break is_c = lang_c.is_present() is_cpp = lang_cpp.is_present() if not (is_c or is_cpp): sys.exit(0) suffixes = [] for lang in languages.itervalues(): if lang.is_present(): ls = lang.get_suffixes() if len(ls) > 1: sys.stderr.write( 'No more than one suffix is permitted per language.\n') sys.stderr.write('Ensure there is only one of: ') print_list(ls, sys.stderr) sys.stderr.write('.\n') sys.exit(1) suffixes.append('.' + ls[0]) if is_c: c_suffix = lang_c.get_suffixes()[0] if is_cpp: cpp_suffix = lang_cpp.get_suffixes()[0] print 'CC = gcc' if is_cpp: print 'CXX = g++' if is_c: print 'CFLAGS =' if is_cpp: print 'CXXFLAGS =' print 'LDFLAGS =' if is_cpp: print 'LIBS = -lstdc++' else: print 'LIBS =' print 'TARGET = ' + target print sys.stdout.write('.SUFFIXES: ') suffixes.sort() print_list(suffixes, sys.stdout) print print if is_c and is_cpp: sys.stdout.write('CSRC = ') print_files(lang_c, sys.stdout) print sys.stdout.write('CXXSRC = ') print_files(lang_cpp, sys.stdout) print else: sys.stdout.write('SRC = ') for lang in languages.itervalues(): if lang.is_present(): print_files(lang, sys.stdout) break print print sys.stdout.write('OBJ = ') if is_c and is_cpp: print '$(CSRC:.%s=.o) $(CXXSRC:.%s=.o)' % (c_suffix, cpp_suffix) elif is_c: print '$(SRC:.%s=.o)' % c_suffix else: print '$(SRC:.%s=.o)' % cpp_suffix print print 'all: $(TARGET)' print print '$(TARGET): $(OBJ)' print '\t$(CC) $(LDFLAGS) -o $(TARGET) $(OBJ) $(LIBS)' print if is_c: print '.%s.o:' % c_suffix print '\t$(CC) -c $(CFLAGS) -o $@ $<' print if is_cpp: print '.%s.o:' % cpp_suffix print '\t$(CXX) -c $(CXXFLAGS) -o $@ $<' print print 'clean:' print '\trm -f $(OBJ) $(TARGET) core'