-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakefile-gen
executable file
·175 lines (152 loc) · 4.71 KB
/
makefile-gen
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#! /usr/bin/env ruby
require 'optparse'
require 'ostruct'
require 'find'
require 'pp'
class ParseArgs
def self.parse(args)
# The options specified on the command line will be collected in *options*.
# We set default values here.
options = OpenStruct.new
options.flags = []
options.restrictive = false
options.outputType = "executable";
options.outputName = "program"
options.libPath = ""
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: makefile-gen [options]"
opts.separator ""
opts.separator "Options:"
# output name
opts.on("-o NAME", "--output Name", "Choose output name. Default = program") do |name|
options.outputName = name
end
# custom compilation flags
opts.on("-f", "--flags {FLAG1,FLAG2}", "Custom flags to add to compilation") do |lib|
options.flags.concat lib.split(',')
end
# lib path
opts.on("-l PATH", "--library PATH", "Choose library path. Default = autofind") do |path|
options.libPath = path
end
# restrictive
opts.on("-r", "--[no-]restrictive", "Add restrictive flags") do |v|
options.restrictive = v
end
# Output executable type
opts.on("-t", "--type [TYPE]", [:lib, :executable],
"Select output type (lib, executable)") do |t|
options.outputType = t
end
# Print usage
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end
opt_parser.parse!(args)
options
end # parse()
end # class ParseArgs
class ParseFolder
def self.parse
# define defaults
@pathes = []
@compilator = ""
@libPath = ""
extension = ""
# Find source files and define compilator
Find.find('.') do |path|
# Get sources paths
if ((path.end_with? ".c") || (path.end_with? ".cpp"))
if ((path.end_with? ".c") && extension == "")
extension = ".c"
@compilator = "gcc"
else
if (extension == "")
extension = ".cpp"
@compilator = "g++"
end
end
@pathes << path unless FileTest.directory?(path)
end
# Get lib paths
if (((path.end_with? ".h") || (path.end_with? ".hpp")) && @libPath == "")
@libPath = path.gsub(/\w*\.h/, "")
end
end # find
end # parse()
def self.getCompilator()
return @compilator
end
def self.getPaths()
return @pathes
end
def self.getLibPath()
return @libPath
end
end # class ParseFolder
def write_makefile(options, parsed_folder)
if (parsed_folder.getCompilator == "g++")
compile_flag_name = "CPPFLAGS"
else
compile_flag_name = "CFLAGS"
end
text = ""
text << "NAME\t= #{options.outputName}\n\n"
text << "CC\t= #{parsed_folder.getCompilator}\n\n"
text << "RM\t= rm -f\n\n"
text << "CURDIR = ./\n\n"
text << "TODO = -@fgrep --color --exclude=.git --exclude=*.o --exclude=Makefile --exclude=tags --exclude=cscope* -H -e TODO -e FIXME -r $(CURDIR) || true\n\n"
text << "SRCS\t= "
parsed_folder.getPaths().each do |path|
text << path + " \\\n\t "
end
text << "\n\n"
text = text.gsub("\\\n\t \n", "\n")
if (parsed_folder.getCompilator == "g++")
text << "OBJS\t= $(SRCS:.cpp=.o)\n\n"
else
text << "OBJS\t= $(SRCS:.c=.o)\n\n"
end
libPath = options.libPath
if (libPath == "")
text << "#{compile_flag_name} = -I#{parsed_folder.getLibPath}\n"
else
text << "#{compile_flag_name} = -I#{libPath}\n"
end
options.flags.each do |flag|
text << "#{compile_flag_name} += -#{flag}\n"
end
text << "#{compile_flag_name} += -W -Wall -Wextra\n"
if (options.restrictive)
text << "#{compile_flag_name} += -Werror\n"
end
if (options.outputType == "lib")
text << "#{compile_flag_name} += -fpic -shared"
end
text << "LDLIBS = "
text << "\n\nall: $(NAME)\n\n"
text << "$(NAME): $(OBJS)\n"
text << "\t@$(CC) $(CFLAGS) -o $(NAME) $(OBJS) $(LDLIBS)\n"
text << "\t@$(TODO)\n\n"
text << "#changer le '#' de place pour les couleur ou non\n\n"
text << "clean:\n"
text << "\t@\#@echo \"clean OK\"\n"
text << "\t@echo -e \"\\e[1;46m clean OK \\e[0m\"\n"
text << "\t@$(RM) $(OBJS)\n\n"
text << "fclean:\n"
text << "\t@\#@echo \"fclean OK\"\n"
text << "\t@echo -e \"\\e[1;46m fclean OK \\e[0m\"\n"
text << "\t@$(RM) $(OBJS)\n"
text << "\t@$(RM) $(NAME)\n\n"
text << "re: fclean all\n\n"
text << "%.o: %.c\n\t@gcc -c -o $@ $(CFLAGS) $<\n"
text << "\t@echo -e \"[\\e[0;32m OK \\e[0m] built '$@'\"\n\n"
text << ".PHONY: all clean fclean re\n"
File.open("Makefile", 'w') { |file| file.write(text) }
end
options = ParseArgs.parse(ARGV)
parsed_folder = ParseFolder
parsed_folder.parse
write_makefile(options, parsed_folder)