xref: /haiku/data/develop/makefile-engine (revision bf243977ffd34197ad7c0820c2da5d21abea0402)
1##	BeOS and Haiku Generic Makefile Engine v2.2.0
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
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 ($(DRIVER_PATH), )
25	DRIVER_PATH = misc
26endif
27
28#	specify the mimeset tool
29	MIMESET		:= mimeset
30
31#	specify the tools for adding and removing resources
32	XRES		:= xres
33
34#	specify the tools for compiling resource definition files
35	RESCOMP		:= rc
36
37#	set the compiler and compiler flags
38	CC			:=	gcc
39	C++			:=	g++
40
41#	SETTING: set the CFLAGS for each binary type
42	ifeq ($(TYPE), DRIVER)
43		CFLAGS	+= -D_KERNEL_MODE=1 -no-fpic
44	else
45		CFLAGS +=
46	endif
47
48#	SETTING: set the proper optimization level
49	ifeq ($(OPTIMIZE), FULL)
50		OPTIMIZER	= -O3
51	else
52	ifeq ($(OPTIMIZE), SOME)
53		OPTIMIZER	= -O1
54	else
55	ifeq ($(OPTIMIZE), NONE)
56		OPTIMIZER	= -O0
57	else
58#		OPTIMIZE not set so set to full
59		OPTIMIZER	= -O3
60	endif
61	endif
62	endif
63
64#	SETTING: set proper debugger flags
65	ifeq ($(DEBUGGER), TRUE)
66		DEBUG += -g
67		OPTIMIZER = -O0
68	endif
69
70	CFLAGS += $(OPTIMIZER) $(DEBUG)
71
72#	SETTING: set warning level
73	ifeq ($(WARNINGS), ALL)
74		CFLAGS += -Wall -Wno-multichar -Wno-ctor-dtor-privacy
75	else
76	ifeq ($(WARNINGS), NONE)
77		CFLAGS += -w
78	endif
79	endif
80
81#	set the linker and linker flags
82	LD			:= gcc
83	LDFLAGS		+= $(DEBUG)
84
85#	SETTING: set linker flags for each binary type
86	ifeq ($(TYPE), APP)
87		LDFLAGS += -Xlinker -soname=_APP_
88	else
89	ifeq ($(TYPE), SHARED)
90		LDFLAGS += -nostart -Xlinker -soname=$(NAME)
91	else
92	ifeq ($(TYPE), DRIVER)
93		LDFLAGS += -nostdlib /boot/develop/lib/x86/_KERNEL_ \
94					/boot/develop/lib/x86/haiku_version_glue.o
95	endif
96	endif
97	endif
98
99#	guess compiler version
100	CC_VER = $(word 1, $(subst -, , $(subst ., , $(shell $(CC) -dumpversion))))
101
102#	set the directory where object files and binaries will be created
103	OBJ_DIR		:= objects.$(CPU)-$(CC)$(CC_VER)-$(if $(DEBUGGER),debug,release)
104
105# 	specify the directory the binary should be created in by default
106ifeq ($(TARGET_DIR), )
107	TARGET_DIR	:= $(OBJ_DIR)
108endif
109
110# NOTE: make doesn't find the target if its name is enclosed in
111#       quotation marks
112	TARGET		:= $(TARGET_DIR)/$(NAME)
113
114# psuedo-function for converting a list of source files in SRCS variable
115# to a corresponding list of object files in $(OBJ_DIR)/xxx.o
116# The "function" strips off the src file suffix (.ccp or .c or whatever)
117# and then strips of the directory name, leaving just the root file name.
118# It then appends the .o suffix and prepends the $(OBJ_DIR)/ path
119define SRCS_LIST_TO_OBJS
120	$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \
121	$(basename $(notdir $(file))))))
122endef
123
124define SRCS_LIST_TO_DEPENDS
125	$(addprefix $(OBJ_DIR)/, $(addsuffix .d, $(foreach file, $(SRCS), \
126	$(basename $(notdir $(file))))))
127endef
128
129OBJS = $(SRCS_LIST_TO_OBJS)
130DEPENDS = $(SRCS_LIST_TO_DEPENDS)
131
132# create a unique list of paths to our sourcefiles
133SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file))))
134
135# add source paths to VPATH if not already present
136VPATH :=
137VPATH += $(addprefix :, $(subst  ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS))))
138
139#	SETTING: build the local and system include paths
140ifeq ($(CPU), x86)
141	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
142 ifeq ($(CC_VER), 2)
143	INCLUDES = $(LOC_INCLUDES)
144	INCLUDES += -I-
145	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -I, $(path)))
146 else
147	INCLUDES = -iquote./
148	INCLUDES += $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -iquote, $(path)))
149	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -isystem, $(path)))
150 endif
151else
152ifeq ($(CPU), ppc)
153	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
154	SYS_INCLUDES += -i-
155	SYS_INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -i , $(path)))
156
157	INCLUDES = $(LOC_INCLUDES) $(SYS_INCLUDES)
158endif
159endif
160
161
162# SETTING: add the -L prefix to all library paths to search
163LINK_PATHS = $(foreach path, $(SRC_PATHS) $(LIBPATHS), \
164	$(addprefix -L, $(path)))
165
166#	SETTING: specify the additional libraries to link against
167#	if the libraries have a .so or .a prefix, or if they are _APP_ or _KERNEL_
168#	simply add them to the list
169LINK_LIBS += $(filter %.so %.a _APP_ _KERNEL_, $(LIBS))
170#	if the libraries do not have suffixes and are not _APP_ or _KERNEL_
171#	prepend -l to each name: be becomes -lbe
172LINK_LIBS += $(foreach lib, $(filter-out %.so %.a _APP_ _KERNEL_, $(LIBS)), $(addprefix -l, $(lib)))
173
174# add to the linker flags
175LDFLAGS += $(LINK_PATHS)  $(LINK_LIBS)
176
177#	SETTING: add the defines to the compiler flags
178CFLAGS += $(foreach define, $(DEFINES), $(addprefix -D, $(define)))
179
180#	SETTING: add the additional compiler flags
181CFLAGS += $(COMPILER_FLAGS)
182
183#	SETTING: add the additional linker flags
184LDFLAGS += $(LINKER_FLAGS)
185
186#	SETTING: use the archive tools if building a static library
187#	otherwise use the linker
188ifeq ($(TYPE), STATIC)
189	BUILD_LINE = ar -cru "$(TARGET)" $(OBJS)
190else
191	BUILD_LINE = $(LD) -o "$@" $(OBJS) $(LDFLAGS)
192endif
193
194# pseudo-function for converting a list of resource definition files in RDEFS
195# variable to a corresponding list of object files in $(OBJ_DIR)/xxx.rsrc
196# The "function" strips off the rdef file suffix (.rdef) and then strips
197# of the directory name, leaving just the root file name.
198# It then appends the .rsrc suffix and prepends the $(OBJ_DIR)/ path
199define RDEFS_LIST_TO_RSRCS
200	$(addprefix $(OBJ_DIR)/, $(addsuffix .rsrc, $(foreach file, $(RDEFS), \
201	$(basename $(notdir $(file))))))
202endef
203
204#	create the resource definitions instruction in case RDEFS is not empty
205	ifeq ($(RDEFS), )
206		RSRCS +=
207	else
208		RSRCS += $(RDEFS_LIST_TO_RSRCS)
209	endif
210
211#	create the resource instruction
212	ifeq ($(RSRCS), )
213		DO_RSRCS :=
214	else
215		DO_RSRCS := $(XRES) -o $(TARGET) $(RSRCS)
216	endif
217
218
219#	define the actual work to be done
220default: $(TARGET)
221
222$(TARGET):	$(OBJ_DIR) $(OBJS) $(RSRCS)
223		$(BUILD_LINE)
224		$(DO_RSRCS)
225		$(MIMESET) -f "$@"
226
227
228#	rule to create the object file directory if needed
229$(OBJ_DIR)::
230	@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
231
232# rules to make the dependency files
233$(OBJ_DIR)/%.d : %.c
234	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
235	mkdepend $(LOC_INCLUDES) -p .c:$(OBJ_DIR)/%n.o -m -f "$@" $<
236$(OBJ_DIR)/%.d : %.cpp
237	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
238	mkdepend $(LOC_INCLUDES) -p .cpp:$(OBJ_DIR)/%n.o -m -f "$@" $<
239$(OBJ_DIR)/%.d : %.cp
240	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
241	mkdepend $(LOC_INCLUDES) -p .cp:$(OBJ_DIR)/%n.o -m -f "$@" $<
242$(OBJ_DIR)/%.d : %.cc
243	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
244	mkdepend $(LOC_INCLUDES) -p .cc:$(OBJ_DIR)/%n.o -m -f "$@" $<
245$(OBJ_DIR)/%.d : %.C
246	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
247	mkdepend $(LOC_INCLUDES) -p .C:$(OBJ_DIR)/%n.o -m -f "$@" $<
248$(OBJ_DIR)/%.d : %.CC
249	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
250	mkdepend $(LOC_INCLUDES) -p .CC:$(OBJ_DIR)/%n.o -m -f "$@" $<
251$(OBJ_DIR)/%.d : %.CPP
252	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
253	mkdepend $(LOC_INCLUDES) -p .CPP:$(OBJ_DIR)/%n.o -m -f "$@" $<
254
255-include $(DEPENDS)
256
257# rules to make the object files
258$(OBJ_DIR)/%.o : %.c
259	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
260$(OBJ_DIR)/%.o : %.cpp
261	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
262$(OBJ_DIR)/%.o : %.cp
263	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
264$(OBJ_DIR)/%.o : %.cc
265	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
266$(OBJ_DIR)/%.o : %.C
267	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
268$(OBJ_DIR)/%.o : %.CC
269	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
270$(OBJ_DIR)/%.o : %.CPP
271	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
272
273# rules to compile resource definition files
274$(OBJ_DIR)/%.rsrc : %.rdef
275	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
276$(OBJ_DIR)/%.rsrc : %.RDEF
277	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
278
279#	rules to handle lex/flex and yacc/bison files
280
281$(OBJ_DIR)/%.o: %.l
282	flex $<
283	$(CC) -c $(INCLUDES) $(CFLAGS) lex.yy.c -o "$@"
284$(OBJ_DIR)/%.o: %.y
285	bison -d -y $<
286	$(CC) -c $(INCLUDES) $(CFLAGS) y.tab.c -o "$@"
287
288#	empty rule. Things that depend on this rule will always get triggered
289FORCE:
290
291#	The generic clean command. Delete everything in the object folder.
292clean :: FORCE
293	-rm -rf "$(OBJ_DIR)"
294
295#	remove just the application from the object folder
296rmapp ::
297	-rm -f $(TARGET)
298
299# make it easy to install drivers for testing
300USER_BIN_PATH = /boot/home/config/add-ons/kernel/drivers/bin
301USER_DEV_PATH = /boot/home/config/add-ons/kernel/drivers/dev
302
303driverinstall :: default
304ifeq ($(TYPE), DRIVER)
305	copyattr --data $(TARGET) $(USER_BIN_PATH)/$(NAME)
306	mkdir -p $(USER_DEV_PATH)/$(DRIVER_PATH)
307	ln -sf $(USER_BIN_PATH)/$(NAME) $(USER_DEV_PATH)/$(DRIVER_PATH)/$(NAME)
308endif
309
310install :: default
311ifeq ($(INSTALL_DIR), )
312	@echo "No install directory specified for \"$(NAME)\" (INSTALL_DIR is empty)" >&2
313else
314	mkdir -p "$(INSTALL_DIR)"
315	cp $(TARGET) $(INSTALL_DIR)/$(NAME)
316endif
317