summaryrefslogtreecommitdiff
path: root/gen_makefile.py
diff options
context:
space:
mode:
authorOlivier Gayot <duskcoder@gmail.com>2015-02-26 18:58:21 +0000
committerOlivier Gayot <duskcoder@gmail.com>2015-02-26 18:58:21 +0000
commitecf99c25dc676cdf74567c942a8388572efce17b (patch)
treeb176f8a1e1ca2906c6cec2385e25eff32a55c9f7 /gen_makefile.py
first commit
Signed-off-by: Olivier Gayot <duskcoder@gmail.com>
Diffstat (limited to 'gen_makefile.py')
-rwxr-xr-xgen_makefile.py125
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()