xref: /haiku/data/develop/makefile-engine (revision a30a4a41f948ebb03b95dab065a27a584ac0c97a)
1##	BeOS and Haiku Generic Makefile Engine v2.5.1
2##	Does all the hard work for the Generic Makefile
3##	which simply defines the project parameters
4
5##	Supports Generic Makefile v2.0, 2.01, 2.1, 2.2, 2.3, 2.4, 2.5
6
7#	determine wheather running on x86 or ppc
8MACHINE=$(shell uname -m)
9ifeq ($(MACHINE), BePC)
10	CPU = x86
11else
12	CPU = $(MACHINE)
13endif
14
15#	create some default settings
16ifeq ($(NAME), )
17	NAME = NameThisApp
18endif
19
20ifeq ($(TYPE), )
21	TYPE = APP
22endif
23
24ifeq ($(APP_MIME_SIG), )
25	APP_MIME = x.vnd-Haiku-$(NAME)
26endif
27
28ifeq ($(DRIVER_PATH), )
29	DRIVER_PATH = misc
30endif
31
32#	specify the mimeset tool
33	MIMESET		:= mimeset
34
35#	specify the tools for adding and removing resources
36	XRES		:= xres
37
38#	specify the tools for compiling resource definition files
39	RESCOMP		:= rc
40
41#	set the compiler and compiler flags
42	CC			:=	gcc
43	C++			:=	g++
44
45#	SETTING: set the CFLAGS for each binary type
46	ifeq ($(strip $(TYPE)), DRIVER)
47		CFLAGS	+= -D_KERNEL_MODE=1 -fno-pic
48	else
49		CFLAGS +=
50	endif
51
52#	SETTING: set the proper optimization level
53	ifeq ($(strip $(OPTIMIZE)), FULL)
54		OPTIMIZER	= -O3
55	else
56	ifeq ($(strip $(OPTIMIZE)), SOME)
57		OPTIMIZER	= -O1
58	else
59	ifeq ($(strip $(OPTIMIZE)), NONE)
60		OPTIMIZER	= -O0
61	else
62#		OPTIMIZE not set so set to full
63		OPTIMIZER	= -O3
64	endif
65	endif
66	endif
67
68#	SETTING: set proper debugger flags
69	ifeq ($(strip $(DEBUGGER)), TRUE)
70		DEBUG += -g
71		OPTIMIZER = -O0
72	endif
73
74	CFLAGS += $(OPTIMIZER) $(DEBUG)
75
76#	SETTING: set warning level
77	ifeq ($(strip $(WARNINGS)), ALL)
78		CFLAGS += -Wall -Wno-multichar -Wno-ctor-dtor-privacy
79	else
80	ifeq ($(strip $(WARNINGS)), NONE)
81		CFLAGS += -w
82	endif
83	endif
84
85#	set the linker and linker flags
86ifeq ($(origin LD), default)
87	LD			:= gcc
88endif
89	LDFLAGS		+= $(DEBUG)
90
91#	SETTING: set linker flags for each binary type
92	ifeq ($(strip $(TYPE)), APP)
93		LDFLAGS += -Xlinker -soname=_APP_
94	else
95	ifeq ($(strip $(TYPE)), SHARED)
96		LDFLAGS += -shared -Xlinker -soname=$(NAME)
97	else
98	ifeq ($(strip $(TYPE)), DRIVER)
99		LDFLAGS += -nostdlib /boot/system/develop/lib/_KERNEL_ \
100					/boot/system/develop/lib/haiku_version_glue.o
101	endif
102	endif
103	endif
104
105#	guess compiler version
106	CC_VER = $(word 1, $(subst -, , $(subst ., , $(shell $(CC) -dumpversion))))
107
108#	set the directory where object files and binaries will be created
109	OBJ_DIR		:= objects.$(CPU)-$(CC)$(CC_VER)-$(if $(DEBUGGER),debug,release)
110
111# 	specify the directory the binary should be created in by default
112ifeq ($(TARGET_DIR), )
113	TARGET_DIR	:= $(OBJ_DIR)
114endif
115
116# NOTE: make doesn't find the target if its name is enclosed in
117#       quotation marks
118ifeq ($(strip $(TYPE)), STATIC)
119	TARGET		:= $(TARGET_DIR)/$(NAME).a
120else
121	TARGET		:= $(TARGET_DIR)/$(NAME)
122endif
123
124
125# psuedo-function for converting a list of source files in SRCS variable
126# to a corresponding list of object files in $(OBJ_DIR)/xxx.o
127# The "function" strips off the src file suffix (.ccp or .c or whatever)
128# and then strips of the directory name, leaving just the root file name.
129# It then appends the .o suffix and prepends the $(OBJ_DIR)/ path
130define SRCS_LIST_TO_OBJS
131	$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \
132	$(basename $(notdir $(file))))))
133endef
134
135define SRCS_LIST_TO_DEPENDS
136	$(addprefix $(OBJ_DIR)/, $(addsuffix .d, $(foreach file, $(SRCS), \
137	$(basename $(notdir $(file))))))
138endef
139
140OBJS = $(SRCS_LIST_TO_OBJS)
141DEPENDS = $(SRCS_LIST_TO_DEPENDS)
142
143# create a unique list of paths to our sourcefiles
144SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file))))
145
146# add source paths to VPATH if not already present
147VPATH :=
148VPATH += $(addprefix :, $(subst  ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS))))
149
150#	SETTING: build the local and system include paths, compose C++ libs
151ifneq (,$(filter $(CPU),x86 x86_64))
152	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
153 ifeq ($(CC_VER), 2)
154	INCLUDES = $(LOC_INCLUDES)
155	INCLUDES += -I-
156	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -I, $(path)))
157
158	STDCPPLIBS = stdc++.r4
159 else
160	INCLUDES = -iquote./
161	INCLUDES += $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -iquote, $(path)))
162	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -isystem, $(path)))
163
164	STDCPPLIBS = stdc++ supc++
165 endif
166else
167ifeq ($(CPU), ppc)
168	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
169	SYS_INCLUDES += -i-
170	SYS_INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -i , $(path)))
171
172	INCLUDES = $(LOC_INCLUDES) $(SYS_INCLUDES)
173endif
174endif
175
176
177# SETTING: add the -L prefix to all library paths to search
178LINK_PATHS = $(foreach path, $(SRC_PATHS) $(LIBPATHS), \
179	$(addprefix -L, $(path)))
180
181#	SETTING: specify the additional libraries to link against
182#	if the libraries have a .so or .a prefix, or if they are _APP_ or _KERNEL_
183#	simply add them to the list
184LINK_LIBS += $(filter %.so %.a _APP_ _KERNEL_, $(LIBS))
185#	if the libraries do not have suffixes and are not _APP_ or _KERNEL_
186#	prepend -l to each name: be becomes -lbe
187LINK_LIBS += $(foreach lib, $(filter-out %.so %.a _APP_ _KERNEL_, $(LIBS)), $(addprefix -l, $(lib)))
188
189# add to the linker flags
190LDFLAGS += $(LINK_PATHS)  $(LINK_LIBS)
191
192#	SETTING: add the defines to the compiler flags
193CFLAGS += $(foreach define, $(DEFINES), $(addprefix -D, $(define)))
194
195#	SETTING: add the additional compiler flags
196CFLAGS += $(COMPILER_FLAGS)
197
198#	SETTING: add the additional linker flags
199LDFLAGS += $(LINKER_FLAGS)
200
201#	SETTING: use the archive tools if building a static library
202#	otherwise use the linker
203ifeq ($(strip $(TYPE)), STATIC)
204	BUILD_LINE = ar -cru "$(TARGET)" $(OBJS)
205else
206	BUILD_LINE = $(LD) -o "$@" $(OBJS) $(LDFLAGS)
207endif
208
209# pseudo-function for converting a list of resource definition files in RDEFS
210# variable to a corresponding list of object files in $(OBJ_DIR)/xxx.rsrc
211# The "function" strips off the rdef file suffix (.rdef) and then strips
212# of the directory name, leaving just the root file name.
213# It then appends the .rsrc suffix and prepends the $(OBJ_DIR)/ path
214define RDEFS_LIST_TO_RSRCS
215	$(addprefix $(OBJ_DIR)/, $(addsuffix .rsrc, $(foreach file, $(RDEFS), \
216	$(basename $(notdir $(file))))))
217endef
218
219#	create the resource definitions instruction in case RDEFS is not empty
220	ifeq ($(RDEFS), )
221		RSRCS +=
222	else
223		RSRCS += $(RDEFS_LIST_TO_RSRCS)
224	endif
225
226#	create the resource instruction
227	ifeq ($(RSRCS), )
228		DO_RSRCS :=
229	else
230		DO_RSRCS := $(XRES) -o $(TARGET) $(RSRCS)
231	endif
232
233#	the directory for internationalization sources (catkeys)
234	CATKEYS_DIR	:= locales
235
236#	the directory for internationalization resource data (catalogs)
237	CATALOGS_DIR := $(OBJ_DIR)/$(APP_MIME_SIG)
238
239# pseudo-function for converting a list of language codes in CATALOGS variable
240# to a corresponding list of catkeys files in $(CATALOGS_DIR)/xx.catalog
241# The "function" appends the .catalog suffix and prepends the $(CATALOGS_DIR)/ path
242define LOCALES_LIST_TO_CATALOGS
243	$(addprefix $(CATALOGS_DIR)/, $(addsuffix .catalog, $(foreach lang, $(LOCALES), $(lang))))
244endef
245
246CATALOGS = $(LOCALES_LIST_TO_CATALOGS)
247
248#	define the actual work to be done
249default: $(TARGET)
250
251$(TARGET):	$(OBJ_DIR) $(OBJS) $(RSRCS)
252		$(BUILD_LINE)
253		$(DO_RSRCS)
254		$(MIMESET) -f "$@"
255
256
257#	rule to create the object file directory if needed
258$(OBJ_DIR)::
259	@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
260
261#	rule to create the localization sources directory if needed
262$(CATKEYS_DIR)::
263	@[ -d $(CATKEYS_DIR) ] || mkdir $(CATKEYS_DIR) > /dev/null 2>&1
264
265#	rule to create the localization data directory if needed
266$(CATALOGS_DIR):: $(OBJ_DIR)
267	@[ -d $(CATALOGS_DIR) ] || mkdir $(CATALOGS_DIR) > /dev/null 2>&1
268
269# rules to make the dependency files
270$(OBJ_DIR)/%.d : %.c
271	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
272	mkdepend $(LOC_INCLUDES) -p .c:$(OBJ_DIR)/%n.o -m -f "$@" $<
273$(OBJ_DIR)/%.d : %.cpp
274	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
275	mkdepend $(LOC_INCLUDES) -p .cpp:$(OBJ_DIR)/%n.o -m -f "$@" $<
276$(OBJ_DIR)/%.d : %.cp
277	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
278	mkdepend $(LOC_INCLUDES) -p .cp:$(OBJ_DIR)/%n.o -m -f "$@" $<
279$(OBJ_DIR)/%.d : %.cc
280	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
281	mkdepend $(LOC_INCLUDES) -p .cc:$(OBJ_DIR)/%n.o -m -f "$@" $<
282$(OBJ_DIR)/%.d : %.C
283	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
284	mkdepend $(LOC_INCLUDES) -p .C:$(OBJ_DIR)/%n.o -m -f "$@" $<
285$(OBJ_DIR)/%.d : %.CC
286	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
287	mkdepend $(LOC_INCLUDES) -p .CC:$(OBJ_DIR)/%n.o -m -f "$@" $<
288$(OBJ_DIR)/%.d : %.CPP
289	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
290	mkdepend $(LOC_INCLUDES) -p .CPP:$(OBJ_DIR)/%n.o -m -f "$@" $<
291
292-include $(DEPENDS)
293
294# rules to make the object files
295$(OBJ_DIR)/%.o : %.c
296	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
297$(OBJ_DIR)/%.o : %.cpp
298	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
299$(OBJ_DIR)/%.o : %.cp
300	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
301$(OBJ_DIR)/%.o : %.cc
302	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
303$(OBJ_DIR)/%.o : %.C
304	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
305$(OBJ_DIR)/%.o : %.CC
306	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
307$(OBJ_DIR)/%.o : %.CPP
308	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
309
310# rules to compile resource definition files
311$(OBJ_DIR)/%.rsrc : %.rdef
312	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
313$(OBJ_DIR)/%.rsrc : %.RDEF
314	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
315
316# rule to compile localization data catalogs
317$(CATALOGS_DIR)/%.catalog : $(CATKEYS_DIR)/%.catkeys
318	linkcatkeys -o "$@" -s $(APP_MIME_SIG) -l $(notdir $(basename $@)) $<
319
320# rule to preprocess program sources into file ready for collecting catkeys
321$(OBJ_DIR)/$(NAME).pre : $(SRCS)
322	-cat $(SRCS) | $(CC) -E -x c++ $(INCLUDES) $(CFLAGS) -DB_COLLECTING_CATKEYS - > $(OBJ_DIR)/$(NAME).pre
323
324# rules to collect localization catkeys
325catkeys : $(CATKEYS_DIR)/en.catkeys
326
327$(CATKEYS_DIR)/en.catkeys : $(CATKEYS_DIR) $(OBJ_DIR)/$(NAME).pre
328	collectcatkeys -s $(APP_MIME_SIG) $(OBJ_DIR)/$(NAME).pre -o $(CATKEYS_DIR)/en.catkeys
329
330# rule to create localization catalogs
331catalogs : $(CATALOGS_DIR) $(CATALOGS)
332
333#	rules to handle lex/flex and yacc/bison files
334
335$(OBJ_DIR)/%.o: %.l
336	flex $<
337	$(CC) -c $(INCLUDES) $(CFLAGS) lex.yy.c -o "$@"
338$(OBJ_DIR)/%.o: %.y
339	bison -d -y $<
340	$(CC) -c $(INCLUDES) $(CFLAGS) y.tab.c -o "$@"
341
342#	empty rule. Things that depend on this rule will always get triggered
343FORCE:
344
345#	The generic clean command. Delete everything in the object folder.
346clean :: FORCE
347	-rm -rf "$(OBJ_DIR)"
348
349#	remove just the application from the object folder
350rmapp ::
351	-rm -f $(TARGET)
352
353# make it easy to install drivers for testing
354USER_BIN_PATH = /boot/home/config/add-ons/kernel/drivers/bin
355USER_DEV_PATH = /boot/home/config/add-ons/kernel/drivers/dev
356
357driverinstall :: default
358ifeq ($(strip $(TYPE)), DRIVER)
359	copyattr --data $(TARGET) $(USER_BIN_PATH)/$(NAME)
360	mkdir -p $(USER_DEV_PATH)/$(DRIVER_PATH)
361	ln -sf $(USER_BIN_PATH)/$(NAME) $(USER_DEV_PATH)/$(DRIVER_PATH)/$(NAME)
362endif
363
364install :: default
365ifeq ($(INSTALL_DIR), )
366	@echo "No install directory specified for \"$(NAME)\" (INSTALL_DIR is empty)" >&2
367else
368	mkdir -p "$(INSTALL_DIR)"
369	cp $(TARGET) $(INSTALL_DIR)/$(NAME)
370endif
371
372#	rule to install localization resources catalogs
373catalogsinstall :: catalogs
374	mkdir -p "/boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)"
375	-cp $(CATALOGS_DIR)/*.catalog /boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)
376
377# alternative way of storing localization catalogs - bind into program executable's resources
378bindcatalogs :
379	for lc in $(LOCALES); do linkcatkeys -o $(TARGET) -s $(APP_MIME_SIG) -tr -l $$lc $(CATKEYS_DIR)/$$lc.catkeys; done
380
381