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