diff options
-rwxr-xr-x | gen_makefile.py | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/gen_makefile.py b/gen_makefile.py new file mode 100755 index 0000000..2dea146 --- /dev/null +++ b/gen_makefile.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python + +## Copyright (c) <2015> Olivier Gayot <duskcoder@gmail.com> +## +## +## Permission is hereby granted, free of charge, to any person obtaining a +## copy of this software and associated documentation files (the "Software"), to +## deal in the Software without restriction, including without limitation the +## rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +## sell copies of the Software, and to permit persons to whom the Software is +## furnished to do so, subject to the following conditions: +## +## The above copyright notice and this permission notice shall be included in +## all copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +## SOFTWARE. + + +class makefile_generator(): + def __init__(self): + self._binary = 'a.out' + self.phony = [] + + def append_variable(self, name, value=''): + print('%s%.*s= %s' % (name, 16 - len(name), ' ', value)) + + def append_separator(self): + print('') + + def append_rule(self, target, dep='', cmds={}): + print('%s: %s' % (target, dep)) + + for cmd in cmds: + print('\t%s' % (cmd)) + + self.append_separator() + + def append_static_rule(self, target, dep='', cmds={}): + self.append_rule(target, dep, cmds) + self.phony.append(target) + + def gen(self): + # mandatory input + self.append_variable('NAME', self._binary) + self.append_variable('SRC', '$(wildcard *.%s)' % (self._extension)) + self.append_separator() + + # optional input + self.append_variable('CPPFLAGS') + self.append_variable('LDFLAGS') + self.append_variable(self._compiler_flags_var, self._compiler_flags) + self.append_separator() + self.append_variable(self._compiler_var, self._compiler) + self.append_separator() + + # make use of implicit rules + self.append_variable('OBJ', '$(SRC:.%s=.o)' % (self._extension)) + self.append_variable('DEP', '$(SRC:.%s=.d)' % (self._extension)) + self.append_separator() + + # first rule to be evaluated + self.append_static_rule('all', '$(NAME)') + + # linkage + self.append_rule('$(NAME)', '$(OBJ)', { + '$(%s) -o "$@" $^ $(LDFLAGS)' % (self._compiler_var) + }) + + # include dependencies + print('-include $(DEP)') + self.append_separator() + + # rule to generate dependencies + self.append_rule('%.d', '%%.%s' % (self._extension), { + '$(%s) -MM $(CPPFLAGS) $(%s) $< -MF $@ -MT "$*.o $@"' % + (self._compiler_var, self._compiler_flags_var), + }) + + self.append_static_rule('clean', cmds={ + '$(RM) $(OBJ)', + '$(RM) $(NAME)', + }) + self.append_static_rule('mrproper', 'clean', { + '$(RM) $(DEP)', + }) + self.append_static_rule('distclean', 'mrproper', { + '$(RM) $(addsuffix ~,$(SRC))' + }) + + # phony rule + self.append_rule('.PHONY', ' '.join(self.phony)) + +class makefile_generator_c(makefile_generator): + def __init__(self): + self._compiler_var = 'CC' + self._compiler_flags_var = 'CFLAGS' + self._compiler = 'gcc' + self._compiler_flags = '-W -Wall -Wextra -std=gnu99' + self._extension = 'c' + + super().__init__() + +class makefile_generator_cpp(makefile_generator): + def __init__(self): + self._compiler_var = 'CXX' + self._compiler_flags_var = 'CXXFLAGS' + self._compiler = 'g++' + self._compiler_flags = '-W -Wall -Wextra -Weffc++' + self._extension = 'cpp' + + super().__init__() + +def main(): + generator = makefile_generator_c() + + generator.gen() + +if __name__ == '__main__': + main() |