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