-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakefile
More file actions
311 lines (259 loc) · 8.13 KB
/
makefile
File metadata and controls
311 lines (259 loc) · 8.13 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
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
#
# Autoconfig makefile
# Copyright by Piotr Styczyński (2017)
# MIT License
#
# Use:
# Create build.config file / file by default should look like this:
#
# PROJECT_DESCR := Some compilable project in C/C++
# PEFFERED_CC := GCPP
# SUPPORT_GCC := null
# SUPPORT_GCPP := -std=c++11 -O3 -w -I./include
# SUPPORT_CLANG := null
#
# For null keys compiler is marked as non-supporting project builds.
# For the rest SUPPORT_* flags are applied to the compiler autoconfigured path
#
# If you want to manipulate specific compile functions you can decalre
# also:
#
# CC_SEL_GEN_O := $$(CC) -c -o $$@ $$<
# CC_SEL_GEN_EXE := $$(CC) -o $$@ $$<
#
# The make file creates _autoconf_.config file with the autoconfigured flags and compiler path
# If this config don't work dor you, just edit _autoconf_ file.
#
#
ECHO := @
PREFFERED_CC_OVERRIDE:=
ifneq (,$(filter config,$(MAKECMDGOALS)))
PREFFERED_CC_OVERRIDE:=$(filter-out config,$(MAKECMDGOALS))
endif
PREFFERED_CC_OVERRIDE:=$(subst g++,GCPP,$(PREFFERED_CC_OVERRIDE))
PREFFERED_CC_OVERRIDE:=$(subst gcc,GCC,$(PREFFERED_CC_OVERRIDE))
PREFFERED_CC_OVERRIDE:=$(subst clang,CLANG,$(PREFFERED_CC_OVERRIDE))
include build.config
ifneq (,$(PREFFERED_CC_OVERRIDE))
PREFFERED_CC:=$(PREFFERED_CC_OVERRIDE)
endif
TGTCC_AVCC=
TGTCC_AVCC_SIZE=0
CC_GC_VERSION=$(shell gcc -dumpversion 2> /dev/null || echo "")
CC_GCPP_VERSION=$(shell g++ -dumpversion 2> /dev/null || echo "")
CC_CLANG_VERSION=$(shell g++ -dumpversion 2> /dev/null || echo "")
CC_SEL=null
CC_SEL_FLAGS=
CC_SEL_GEN_O=
CC_SEL_GEN_EXE=
CC_SUP_GCC=false
CC_SUP_GCPP=false
CC_SUP_CLANG=false
CC_SUP_ANY=
COM_AUTOCONF1=
COM_AUTOCONF2=
COM_AUTOCONF3=
COM_PREP_DIR1=
COM_PREP_DIR2=
RUN_AUTOCONF=false
ifneq (,$(filter config,$(MAKECMDGOALS)))
RUN_AUTOCONF=true
endif
ifeq (,$(wildcard _autoconf_.config))
RUN_AUTOCONF=true
endif
ifeq (true,$(RUN_AUTOCONF))
ifneq (,$(CC_GC_VERSION))
ifeq (,$(CC_SUP_ANY))
CC_SUP_ANY:=GCC
endif
ifneq (null,$(SUPPORT_GCC))
$(info [Compiler autoconf] gcc version detected $(CC_GC_VERSION) [SUPPORTED])
TGTCC_AVCC:=$(TGTCC_AVCC)$$(($(TGTCC_AVCC_SIZE)+1)).) gcc ($(CC_GC_VERSION))\\n
TGTCC_AVCC_SIZE:=$$(($(TGTCC_AVCC_SIZE)+1))
CC_SUP_GCC=true
else
$(info [Compiler autoconf] gcc version detected $(CC_GC_VERSION) [no support])
endif
endif
ifneq (,$(CC_GCPP_VERSION))
ifeq (,$(CC_SUP_ANY))
CC_SUP_ANY:=GCPP
endif
ifneq (null,$(SUPPORT_GCPP))
$(info [Compiler autoconf] g++ version detected $(CC_GCPP_VERSION) [SUPPORTED])
TGTCC_AVCC:=$(TGTCC_AVCC)$$(($(TGTCC_AVCC_SIZE)+1)).) g++ ($(CC_GCPP_VERSION)) \\n
TGTCC_AVCC_SIZE:=$$(($(TGTCC_AVCC_SIZE)+1))
CC_SUP_GCPP=true
else
$(info [Compiler autoconf] g++ version detected $(CC_GCPP_VERSION) [no support])
endif
endif
ifneq (,$(CC_CLANG_VERSION))
ifeq (,$(CC_SUP_ANY))
CC_SUP_ANY:=CLANG
endif
ifneq (null,$(SUPPORT_CLANG))
$(info [Compiler autoconf] clang version detected $(CC_CLANG_VERSION) [SUPPORTED])
TGTCC_AVCC:=$(TGTCC_AVCC)$$(($(TGTCC_AVCC_SIZE)+1)).) clang ($(CC_CLANG_VERSION))\\n
TGTCC_AVCC_SIZE:=$$(($(TGTCC_AVCC_SIZE)+1))
CC_SUP_CLANG=true
else
$(info [Compiler autoconf] clang version detected $(CC_CLANG_VERSION) [no support])
endif
endif
ifeq (true,$(CC_SUP_${PREFFERED_CC}))
$(info [Compiler autoconf] Selected preffered compiler: $(PREFFERED_CC))
CC_SEL:=$(PREFFERED_CC)
CC_SEL_FLAGS:=$()
else
$(info [Compiler autoconf] No preffered compiler available. Selecting any other.)
ifeq (true,$(CC_SUP_GCC))
$(info [Compiler autoconf] Selecting available compiler: gcc)
CC_SEL:=GCC
else
ifeq (true,$(CC_SUP_GCPP))
$(info [Compiler autoconf] Selecting available compiler: g++)
CC_SEL:=GCPP
else
ifeq (true,$(CC_SUP_CLANG))
$(info [Compiler autoconf] Selecting available compiler: clang)
CC_SEL:=CLANG
else
$(info [Compiler autoconf] No available compiler to compile the code!)
ifeq (,$(CC_SUP_ANY))
$(info Autoconf detected youve got no suitable compiler.)
$(info You have to compile the code manually.)
$(error No suitable compiler detected.)
else
$(info Autoconf detected youve got a suitable compiler.)
$(info Please change SUPPORT_$(CC_SUP_ANY) to flags for $(CC_SUP_ANY) compiler.)
$(info Then redo make command.)
$(error No support for $(CC_SUP_ANY) compiler.)
endif
endif
endif
endif
endif
ifeq (GCC,$(CC_SEL))
CC_SEL:=gcc
CC_SEL_FLAGS:=$(SUPPORT_GCC)
CC_SEL_GEN_O:=$(SUPPORT_GCC_GEN_O)
CC_SEL_GEN_EXE:=$(SUPPORT_GCC_GEN_EXE)
endif
ifeq (GCPP,$(CC_SEL))
CC_SEL:=g++
CC_SEL_FLAGS:=$(SUPPORT_GCPP)
CC_SEL_GEN_O:=$(SUPPORT_GCPP_GEN_O)
CC_SEL_GEN_EXE:=$(SUPPORT_GCPP_GEN_EXE)
endif
ifeq (CLANG,$(CC_SEL))
CC_SEL:=clang
CC_SEL_FLAGS:=$(SUPPORT_CLANG)
CC_SEL_GEN_O:=$(SUPPORT_CLANG_GEN_O)
CC_SEL_GEN_EXE:=$(SUPPORT_GCPP_GEN_EXE)
endif
ifeq (,$(CC_SEL_GEN_O))
CC_SEL_GEN_O:=\$$\$$(CC) -c -o \$$\$$@ \$$\$$<
endif
ifeq (,$(CC_SEL_GEN_EXE))
CC_SEL_GEN_EXE:=\$$\$$(CC) -o \$$\$$@ \$$\$$<
endif
COM_AUTOCONF1:=@printf "\#\n\# Autoconfig makefile\n\# Edit only if your compiler is not supported\n\#\n\n\n\# Compiler executable path:\nCC_SEL := $(CC_SEL)\n\n\# Compiler flags:\nCC_SEL_FLAGS := $(CC_SEL_FLAGS)\n\n\# Compiler intruction for building object files:\nCC_SEL_GEN_O := $(CC_SEL_GEN_O)\n\n\# Compiler intruction for building executable files:\nCC_SEL_GEN_EXE := $(CC_SEL_GEN_EXE)" > _autoconf_.config
COM_AUTOCONF2:=@echo Autoconf file was created.
COM_AUTOCONF3:=@printf "\n Configured using $(CC_SEL)\n\n"
CC_SEL_GEN_O:=$(subst \,,$(CC_SEL_GEN_O))
CC_SEL_GEN_EXE:=$(subst \,,$(CC_SEL_GEN_EXE))
CC_SEL_GEN_O:=$(subst $$$$,$$,$(CC_SEL_GEN_O))
CC_SEL_GEN_EXE:=$(subst $$$$,$$,$(CC_SEL_GEN_EXE))
else
include _autoconf_.config
ifeq (,$(findstring run,$(MAKECMDGOALS)))
ifeq (help,$(findstring run-example-,$(MAKECMDGOALS)))
$(info Using compiler from autoconfig file ($(CC_SEL)))
endif
endif
#$(error FY)
endif
CC := $(ECHO)$(CC_SEL) $(CC_SEL_FLAGS)
EXAMPLES_FILES := $(wildcard ./examples/src/*.cpp)
EXAMPLES_FILES_LIST := $(addprefix ,$(notdir $(EXAMPLES_FILES:.cpp=)))
EXAMPLES_OBJ_FILES := $(addprefix ./examples/bin/,$(notdir $(EXAMPLES_FILES:.cpp=.o)))
EXAMPLES_EXE_FILES := $(addprefix ./examples/bin/,$(notdir $(EXAMPLES_FILES:.cpp=.exe)))
EXAMPLES_BUILT_FILES := $(addprefix ./examples/bin/,$(notdir $(wildcard ./examples/bin/*)))
EXAMPLES_NUMBER := $(words $(EXAMPLES_FILES))
EXAMPLES_MADE_NUMBER := %
ifeq (,$(wildcard ./examples/bin))
COM_PREP_DIR1=@mkdir ./examples/bin
COM_PREP_DIR2=@echo Prepared needed directories.
endif
ifneq (,$(findstring run-example-,$(MAKECMDGOALS)))
RUN_EXAMPLE_NAME=$(subst run-example-,,$(MAKECMDGOALS))
RUN_EXAMPLE_PATH=./examples/bin/$(RUN_EXAMPLE_NAME).exe
ifneq ("$(wildcard $(RUN_EXAMPLE_PATH))","")
else
$(error Cannot run an example if the examples weren't built. Run 'make examples' command firstly)
endif
endif
ifneq (,$(filter clean clean-all,$(MAKECMDGOALS)))
ifeq (,$(EXAMPLES_BUILT_FILES))
$(error Directory is clean)
endif
endif
help:
$(info )
$(info )
$(info $(PROJECT_DESCR))
$(info )
$(info Autoconf makefile by Piotr Styczynski <MIT>)
$(info )
$(info To compile all examples use 'make all' or 'make examples' command)
$(info To get list of all available examples use 'make run-example' command)
$(info To run the specified example use 'make run-example-NAME' e.g. 'make run-example-demo')
$(info To clean project use 'make clean' command)
$(info )
$(info )
$(info )
$(info )
config: init
init:
$(COM_AUTOCONF1)
$(COM_AUTOCONF2)
$(COM_AUTOCONF3)
$(COM_PREP_DIR1)
$(COM_PREP_DIR2)
rebuild: init clean-all examples
clean: clean-all
$(info Project cleaned. Done)
clean-all: clean-examples
all: init examples
examples: examples_ $(EXAMPLES_OBJ_FILES) $(EXAMPLES_EXE_FILES) clean-examples-build
$(info Examples compiled. Done)
examples_:
$(info $(EXAMPLES_NUMBER) examples are available)
run-example:
$(info All available examples: $(EXAMPLES_FILES_LIST))
run-example-%:
$(ECHO)./examples/bin/$*.exe
clean-examples:
$(ECHO)rm $(EXAMPLES_BUILT_FILES)
clean-examples-build:
$(info Cleaning build)
$(ECHO)rm $(EXAMPLES_OBJ_FILES)
define make-tgt-o
./examples/bin/%.o: ./examples/src/%.cpp
$$(info Compiling example: $$<)
$(CC_SEL_GEN_O)
./examples/bin/%.o: ./examples/src/%.c
$$(info Compiling example: $$<)
$(CC_SEL_GEN_O)
endef
define make-tgt-exe
./examples/bin/%.exe: ./examples/bin/%.o
$(CC_SEL_GEN_EXE)
endef
gcc:
g++:
clang:
$(eval $(call make-tgt-o))
$(eval $(call make-tgt-exe))