forked from lzh9102/makegen
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_gen.py
More file actions
149 lines (121 loc) · 5.73 KB
/
Copy pathmake_gen.py
File metadata and controls
149 lines (121 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
from rule_generator import RULE_GENERATORS
from rule_generator import get_c_rule_generator
from rule_generator import get_cpp_rule_generator
from rule_generator import get_header_rule_generator
from rule_generator import get_as_rule_generator
class MakeGen:
def __init__(self):
self.rule_generator = {}
for generator in RULE_GENERATORS:
for ext in generator.handled_extensions():
self.rule_generator[ext] = generator
def generate(self, options):
c_compiler = None
cpp_compiler = None
as_compiler = None
object_files = []
link_libraries = options.link_libraries
compiler_flags = self.__compiler_flags(options)
for f in options.sources:
filename, ext = self.__split_extension(f)
base = os.path.basename(filename)
base = os.path.join(options.objdir, base+".o")
if ext in get_c_rule_generator().handled_extensions():
c_compiler = options.c_compiler
object_files.append(base)
elif ext in get_cpp_rule_generator().handled_extensions():
cpp_compiler = options.cpp_compiler
object_files.append(base)
elif ext in get_as_rule_generator().handled_extensions():
as_compiler = options.as_compiler
object_files.append(base)
with open("Makefile", "w") as output_file:
# variables
if c_compiler:
output_file.write("CC=%s\n" % (c_compiler))
output_file.write("CFLAGS=%(CFLAGS)s %(FLAGS)s\n"
% {"FLAGS": compiler_flags,
"CFLAGS": options.cflags})
if cpp_compiler:
output_file.write("CXX=%s\n" % (cpp_compiler))
output_file.write("CXXFLAGS=%(CXXFLAGS)s %(FLAGS)s\n"
% {"FLAGS": compiler_flags,
"CXXFLAGS": options.cxxflags})
if as_compiler:
output_file.write("AS=%s\n" % (as_compiler))
output_file.write("ASFLAGS=%(ASFLAGS)s\n"
% { "ASFLAGS": options.asflags})
if object_files:
output_file.write("OBJS=%s\n" % (' '.join(object_files)))
output_file.write("LDFLAGS=%(LDFLAGS)s %(FLAGS)s\n"
% {"FLAGS": self.__linker_flags(options),
"LDFLAGS": options.ldflags})
output_file.write("\n\n")
# check if something changed since last time makegen was run
output_file.write("HASH := %s\n\n" % (options.hash))
name_string = ""
for gen in RULE_GENERATORS:
for ext in gen.handled_extensions():
if name_string == "":
name_string += "-name \"*.%s\" " % ext
else:
name_string += "-o -name \"*.%s\" " % ext
output_file.write("HASH_SRCS := $(shell find \"%1s\" -type f %2s | sed 's|^./||' | tr -d '[:space:]')\n" % (options.root_dir, name_string))
output_file.write("COMP_HASH := $(shell echo -n \"$(HASH_SRCS)\" | md5sum | cut -d' ' -f1)\n\n")
output_file.write("\n\n")
# all
if object_files:
output_file.write("all: %1s\n" % options.output)
else:
output_file.write("all:\n")
output_file.write("ifneq ($(HASH), $(COMP_HASH))\n")
output_file.write("\t$(shell makegen -f make \"%s\")\n" % (options.root_dir))
output_file.write("endif\n\n")
# executable
if object_files:
output_file.write("%1s: $(OBJS)\n" % (options.output))
linker = "$(CC)"
if cpp_compiler:
linker = "$(CXX)"
output_file.write("\t%1s -o %2s $(LDFLAGS) $(OBJS)\n\n"
% (linker, options.output))
# object files
for f in options.sources:
self.__generate_rule(f, output_file, options.sources, output_dir=options.objdir)
# clean
output_file.write("clean:\n")
for f in object_files:
output_file.write("\trm -f %s\n" % (f)) # remove *.o
if object_files:
output_file.write("\trm -f %s\n" % (options.output))
output_file.write("\n\n")
output_file.write(options.custom_section)
def __linker_flags(self, options):
flags = []
for lib in options.link_libraries:
flags.append("-l%s" % (lib))
for path in options.library_paths:
flags.append("-L%s" % (path))
return ' '.join(flags)
def __compiler_flags(self, options):
flags = []
for d in options.defines:
flags.append("-D%s" % (d))
for path in options.include_paths:
flags.append("-I%s" % (path))
return ' '.join(flags)
def __split_extension(self, filename):
name, ext = os.path.splitext(filename)
ext = ext[1:] # remove leading '.'
return (name, ext)
def __generate_rule(self, filename, output_file, sources, output_dir=""):
name, ext = self.__split_extension(filename)
if ext not in self.rule_generator:
print("warning: don't know how to generate rule for \"%s\"" % (filename))
return
generator = self.rule_generator[ext]
rule = generator.generate_rule(filename, output_dir, sources)
output_file.write(rule)