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