xref: /haiku/data/develop/makefile-engine (revision 0044a8c39ab5721051b6279506d1a8c511e20453)
1##	BeOS and Haiku Generic Makefile Engine v2.5.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, 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 -no-fpic
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 += -nostart -Xlinker -soname=$(NAME)
97	else
98	ifeq ($(strip $(TYPE)), DRIVER)
99		LDFLAGS += -nostdlib /boot/develop/lib/x86/_KERNEL_ \
100					/boot/develop/lib/x86/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
118	TARGET		:= $(TARGET_DIR)/$(NAME)
119
120# psuedo-function for converting a list of source files in SRCS variable
121# to a corresponding list of object files in $(OBJ_DIR)/xxx.o
122# The "function" strips off the src file suffix (.ccp or .c or whatever)
123# and then strips of the directory name, leaving just the root file name.
124# It then appends the .o suffix and prepends the $(OBJ_DIR)/ path
125define SRCS_LIST_TO_OBJS
126	$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \
127	$(basename $(notdir $(file))))))
128endef
129
130define SRCS_LIST_TO_DEPENDS
131	$(addprefix $(OBJ_DIR)/, $(addsuffix .d, $(foreach file, $(SRCS), \
132	$(basename $(notdir $(file))))))
133endef
134
135OBJS = $(SRCS_LIST_TO_OBJS)
136DEPENDS = $(SRCS_LIST_TO_DEPENDS)
137
138# create a unique list of paths to our sourcefiles
139SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file))))
140
141# add source paths to VPATH if not already present
142VPATH :=
143VPATH += $(addprefix :, $(subst  ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS))))
144
145#	SETTING: build the local and system include paths, compose C++ libs
146ifeq ($(CPU), x86)
147	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
148 ifeq ($(CC_VER), 2)
149	INCLUDES = $(LOC_INCLUDES)
150	INCLUDES += -I-
151	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -I, $(path)))
152
153	STDCPPLIBS = stdc++.r4
154 else
155	INCLUDES = -iquote./
156	INCLUDES += $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -iquote, $(path)))
157	INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -isystem, $(path)))
158
159	STDCPPLIBS = stdc++ supc++
160 endif
161else
162ifeq ($(CPU), ppc)
163	LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path)))
164	SYS_INCLUDES += -i-
165	SYS_INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -i , $(path)))
166
167	INCLUDES = $(LOC_INCLUDES) $(SYS_INCLUDES)
168endif
169endif
170
171
172# SETTING: add the -L prefix to all library paths to search
173LINK_PATHS = $(foreach path, $(SRC_PATHS) $(LIBPATHS), \
174	$(addprefix -L, $(path)))
175
176#	SETTING: specify the additional libraries to link against
177#	if the libraries have a .so or .a prefix, or if they are _APP_ or _KERNEL_
178#	simply add them to the list
179LINK_LIBS += $(filter %.so %.a _APP_ _KERNEL_, $(LIBS))
180#	if the libraries do not have suffixes and are not _APP_ or _KERNEL_
181#	prepend -l to each name: be becomes -lbe
182LINK_LIBS += $(foreach lib, $(filter-out %.so %.a _APP_ _KERNEL_, $(LIBS)), $(addprefix -l, $(lib)))
183
184# add to the linker flags
185LDFLAGS += $(LINK_PATHS)  $(LINK_LIBS)
186
187#	SETTING: add the defines to the compiler flags
188CFLAGS += $(foreach define, $(DEFINES), $(addprefix -D, $(define)))
189
190#	SETTING: add the additional compiler flags
191CFLAGS += $(COMPILER_FLAGS)
192
193#	SETTING: add the additional linker flags
194LDFLAGS += $(LINKER_FLAGS)
195
196#	SETTING: use the archive tools if building a static library
197#	otherwise use the linker
198ifeq ($(strip $(TYPE)), STATIC)
199	BUILD_LINE = ar -cru "$(TARGET)" $(OBJS)
200else
201	BUILD_LINE = $(LD) -o "$@" $(OBJS) $(LDFLAGS)
202endif
203
204# pseudo-function for converting a list of resource definition files in RDEFS
205# variable to a corresponding list of object files in $(OBJ_DIR)/xxx.rsrc
206# The "function" strips off the rdef file suffix (.rdef) and then strips
207# of the directory name, leaving just the root file name.
208# It then appends the .rsrc suffix and prepends the $(OBJ_DIR)/ path
209define RDEFS_LIST_TO_RSRCS
210	$(addprefix $(OBJ_DIR)/, $(addsuffix .rsrc, $(foreach file, $(RDEFS), \
211	$(basename $(notdir $(file))))))
212endef
213
214#	create the resource definitions instruction in case RDEFS is not empty
215	ifeq ($(RDEFS), )
216		RSRCS +=
217	else
218		RSRCS += $(RDEFS_LIST_TO_RSRCS)
219	endif
220
221#	create the resource instruction
222	ifeq ($(RSRCS), )
223		DO_RSRCS :=
224	else
225		DO_RSRCS := $(XRES) -o $(TARGET) $(RSRCS)
226	endif
227
228#	the directory for internationalization sources (catkeys)
229	CATKEYS_DIR	:= locales
230
231#	the directory for internationalization resource data (catalogs)
232	CATALOGS_DIR := $(OBJ_DIR)/$(APP_MIME_SIG)
233
234# pseudo-function for converting a list of language codes in CATALOGS variable
235# to a corresponding list of catkeys files in $(CATALOGS_DIR)/xx.catalog
236# The "function" appends the .catalog suffix and prepends the $(CATALOGS_DIR)/ path
237define LOCALES_LIST_TO_CATALOGS
238	$(addprefix $(CATALOGS_DIR)/, $(addsuffix .catalog, $(foreach lang, $(LOCALES), $(lang))))
239endef
240
241CATALOGS = $(LOCALES_LIST_TO_CATALOGS)
242
243#	define the actual work to be done
244default: $(TARGET)
245
246$(TARGET):	$(OBJ_DIR) $(OBJS) $(RSRCS)
247		$(BUILD_LINE)
248		$(DO_RSRCS)
249		$(MIMESET) -f "$@"
250
251
252#	rule to create the object file directory if needed
253$(OBJ_DIR)::
254	@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
255
256#	rule to create the localization sources directory if needed
257$(CATKEYS_DIR)::
258	@[ -d $(CATKEYS_DIR) ] || mkdir $(CATKEYS_DIR) > /dev/null 2>&1
259
260#	rule to create the localization data directory if needed
261$(CATALOGS_DIR):: $(OBJ_DIR)
262	@[ -d $(CATALOGS_DIR) ] || mkdir $(CATALOGS_DIR) > /dev/null 2>&1
263
264# rules to make the dependency files
265$(OBJ_DIR)/%.d : %.c
266	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
267	mkdepend $(LOC_INCLUDES) -p .c:$(OBJ_DIR)/%n.o -m -f "$@" $<
268$(OBJ_DIR)/%.d : %.cpp
269	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
270	mkdepend $(LOC_INCLUDES) -p .cpp:$(OBJ_DIR)/%n.o -m -f "$@" $<
271$(OBJ_DIR)/%.d : %.cp
272	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
273	mkdepend $(LOC_INCLUDES) -p .cp:$(OBJ_DIR)/%n.o -m -f "$@" $<
274$(OBJ_DIR)/%.d : %.cc
275	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
276	mkdepend $(LOC_INCLUDES) -p .cc:$(OBJ_DIR)/%n.o -m -f "$@" $<
277$(OBJ_DIR)/%.d : %.C
278	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
279	mkdepend $(LOC_INCLUDES) -p .C:$(OBJ_DIR)/%n.o -m -f "$@" $<
280$(OBJ_DIR)/%.d : %.CC
281	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
282	mkdepend $(LOC_INCLUDES) -p .CC:$(OBJ_DIR)/%n.o -m -f "$@" $<
283$(OBJ_DIR)/%.d : %.CPP
284	[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1; \
285	mkdepend $(LOC_INCLUDES) -p .CPP:$(OBJ_DIR)/%n.o -m -f "$@" $<
286
287-include $(DEPENDS)
288
289# rules to make the object files
290$(OBJ_DIR)/%.o : %.c
291	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
292$(OBJ_DIR)/%.o : %.cpp
293	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
294$(OBJ_DIR)/%.o : %.cp
295	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
296$(OBJ_DIR)/%.o : %.cc
297	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
298$(OBJ_DIR)/%.o : %.C
299	$(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
300$(OBJ_DIR)/%.o : %.CC
301	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
302$(OBJ_DIR)/%.o : %.CPP
303	$(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@"
304
305# rules to compile resource definition files
306$(OBJ_DIR)/%.rsrc : %.rdef
307	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
308$(OBJ_DIR)/%.rsrc : %.RDEF
309	cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -v '^#' | $(RESCOMP) -I $(dir $<) -o "$@" -
310
311# rule to compile localization data catalogs
312$(CATALOGS_DIR)/%.catalog : $(CATKEYS_DIR)/%.catkeys
313	linkcatkeys -o "$@" -s $(APP_MIME_SIG) -l $(notdir $(basename $@)) $<
314
315# rule to preprocess program sources into file ready for collecting catkeys
316$(OBJ_DIR)/$(NAME).pre : $(SRCS)
317	-cat $(SRCS) | $(CC) -E -x c++ $(INCLUDES) $(CFLAGS) -DB_COLLECTING_CATKEYS - > $(OBJ_DIR)/$(NAME).pre
318
319# rules to collect localization catkeys
320catkeys : $(CATKEYS_DIR)/en.catkeys
321
322$(CATKEYS_DIR)/en.catkeys : $(CATKEYS_DIR) $(OBJ_DIR)/$(NAME).pre
323	collectcatkeys -s $(APP_MIME_SIG) $(OBJ_DIR)/$(NAME).pre -o $(CATKEYS_DIR)/en.catkeys
324
325# rule to create localization catalogs
326catalogs : $(CATALOGS_DIR) $(CATALOGS)
327
328#	rules to handle lex/flex and yacc/bison files
329
330$(OBJ_DIR)/%.o: %.l
331	flex $<
332	$(CC) -c $(INCLUDES) $(CFLAGS) lex.yy.c -o "$@"
333$(OBJ_DIR)/%.o: %.y
334	bison -d -y $<
335	$(CC) -c $(INCLUDES) $(CFLAGS) y.tab.c -o "$@"
336
337#	empty rule. Things that depend on this rule will always get triggered
338FORCE:
339
340#	The generic clean command. Delete everything in the object folder.
341clean :: FORCE
342	-rm -rf "$(OBJ_DIR)"
343
344#	remove just the application from the object folder
345rmapp ::
346	-rm -f $(TARGET)
347
348# make it easy to install drivers for testing
349USER_BIN_PATH = /boot/home/config/add-ons/kernel/drivers/bin
350USER_DEV_PATH = /boot/home/config/add-ons/kernel/drivers/dev
351
352driverinstall :: default
353ifeq ($(strip $(TYPE)), DRIVER)
354	copyattr --data $(TARGET) $(USER_BIN_PATH)/$(NAME)
355	mkdir -p $(USER_DEV_PATH)/$(DRIVER_PATH)
356	ln -sf $(USER_BIN_PATH)/$(NAME) $(USER_DEV_PATH)/$(DRIVER_PATH)/$(NAME)
357endif
358
359install :: default
360ifeq ($(INSTALL_DIR), )
361	@echo "No install directory specified for \"$(NAME)\" (INSTALL_DIR is empty)" >&2
362else
363	mkdir -p "$(INSTALL_DIR)"
364	cp $(TARGET) $(INSTALL_DIR)/$(NAME)
365endif
366
367#	rule to install localization resources catalogs
368catalogsinstall :: catalogs
369	mkdir -p "/boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)"
370	-cp $(CATALOGS_DIR)/*.catalog /boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)
371
372