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 -fno-pic 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 96endif 97endif 98endif 99 100# Get the compiler version. 101CC_VER = $(word 1, $(subst -, , $(subst ., , $(shell $(CC) -dumpversion)))) 102 103# Set the object directory if it isn't already. 104OBJ_DIR := objects.$(CPU)-$(CC)$(CC_VER)-$(if $(DEBUGGER),debug,release) 105 106# Output the binary alongside the objects unless another directory is specified. 107ifeq ($(TARGET_DIR), ) 108 TARGET_DIR := $(OBJ_DIR) 109endif 110 111# NOTE: make doesn't find the target if its name is enclosed in quotes. 112ifeq ($(strip $(TYPE)), STATIC) 113 TARGET := $(TARGET_DIR)/$(NAME).a 114else 115 TARGET := $(TARGET_DIR)/$(NAME) 116endif 117 118# Psuedo-function for converting a list of source files in SRCS variable to a 119# corresponding list of object files in $(OBJ_DIR)/xxx.o. The "function" strips 120# off the src file suffix (.ccp or .c or whatever) and then strips off the 121# off the directory name, leaving just the root file name. It then appends the 122# .o suffix and prepends the $(OBJ_DIR)/ path 123define SRCS_LIST_TO_OBJS 124 $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \ 125 $(basename $(notdir $(file)))))) 126endef 127 128define SRCS_LIST_TO_DEPENDS 129 $(addprefix $(OBJ_DIR)/, $(addsuffix .d, $(foreach file, $(SRCS), \ 130 $(basename $(notdir $(file)))))) 131endef 132 133OBJS = $(SRCS_LIST_TO_OBJS) 134DEPENDS = $(SRCS_LIST_TO_DEPENDS) 135 136# Create a unique list of paths to our sourcefiles and resources. 137SRC_PATHS += $(sort $(foreach file, $(SRCS) $(RSRCS) $(RDEFS), $(dir $(file)))) 138 139# Add source paths to VPATH if not already present. 140VPATH := 141VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) 142 143# Set up the local & system include paths and C++ stdlibs. 144ifneq (,$(filter $(CPU),x86 x86_64)) 145 LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path))) 146 ifeq ($(CC_VER), 2) 147 INCLUDES = $(LOC_INCLUDES) 148 INCLUDES += -I- 149 INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -I, $(path))) 150 151 STDCPPLIBS = stdc++.r4 152 else 153 INCLUDES = -iquote./ 154 INCLUDES += $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -iquote, $(path))) 155 INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -isystem, $(path))) 156 157 STDCPPLIBS = stdc++ supc++ 158 endif 159else 160ifeq ($(CPU), ppc) 161 LOC_INCLUDES = $(foreach path, $(SRC_PATHS) $(LOCAL_INCLUDE_PATHS), $(addprefix -I, $(path))) 162 SYS_INCLUDES += -i- 163 SYS_INCLUDES += $(foreach path, $(SYSTEM_INCLUDE_PATHS), $(addprefix -i , $(path))) 164 165 INCLUDES = $(LOC_INCLUDES) $(SYS_INCLUDES) 166endif 167endif 168 169# Add the -L prefix to all of the library paths. 170LINK_PATHS = $(foreach path, $(SRC_PATHS) $(LIBPATHS), \ 171 $(addprefix -L, $(path))) 172 173# Handle the additional libraries specified. If the libraries have a .so or 174# a .a prefix, or if they are _APP_ or _KERNEL_, simply add them to the list. 175LINK_LIBS += $(filter %.so %.a _APP_ _KERNEL_, $(LIBS)) 176# If the libraries do not have suffixes and are not _APP_ or _KERNEL_, 177# prepend -l to each name:(e.g. "be" becomes "-lbe"). 178LINK_LIBS += $(foreach lib, $(filter-out %.so %.a _APP_ _KERNEL_, $(LIBS)), $(addprefix -l, $(lib))) 179 180# Add the linkpaths and linklibs to LDFLAGS. 181LDFLAGS += $(LINK_PATHS) $(LINK_LIBS) 182 183# Add the defines to CFLAGS. 184CFLAGS += $(foreach define, $(DEFINES), $(addprefix -D, $(define))) 185 186# Add the additional compiler flags to CFLAGS. 187CFLAGS += $(COMPILER_FLAGS) 188 189# Add the additional linkflags to LDFLAGS 190LDFLAGS += $(LINKER_FLAGS) 191 192# Use the archiving tools to create an an archive if we're building a static 193# library, otherwise use the linker. 194ifeq ($(strip $(TYPE)), STATIC) 195 BUILD_LINE = ar -cru "$(TARGET)" $(OBJS) 196else 197 BUILD_LINE = $(LD) -o "$@" $(OBJS) $(LDFLAGS) 198endif 199 200# Pseudo-function for converting a list of resource definition files in RDEFS 201# variable to a corresponding list of object files in $(OBJ_DIR)/xxx.rsrc. 202# The "function" strips off the rdef file suffix (.rdef) and then strips 203# of the directory name, leaving just the root file name. It then appends the 204# the .rsrc suffix and prepends the $(OBJ_DIR)/ path. 205define RDEFS_LIST_TO_RSRCS 206 $(addprefix $(OBJ_DIR)/, $(addsuffix .rsrc, $(foreach file, $(RDEFS), \ 207 $(basename $(notdir $(file)))))) 208endef 209 210# Create the resource definitions instruction in case RDEFS is not empty. 211ifeq ($(RDEFS), ) 212 RSRCS += 213else 214 RSRCS += $(RDEFS_LIST_TO_RSRCS) 215endif 216 217# Create the resource instruction. 218ifeq ($(RSRCS), ) 219 DO_RSRCS := 220else 221 DO_RSRCS := $(XRES) -o $(TARGET) $(RSRCS) 222endif 223 224# Set the directory for internationalization sources (catkeys) if it isn't 225# already. 226CATKEYS_DIR := locales 227 228# Set the directory for internationalization resource data (catalogs) if it 229# isn't already. 230CATALOGS_DIR := $(OBJ_DIR)/$(APP_MIME_SIG) 231 232# Pseudo-function for converting a list of language codes in CATALOGS variable 233# to a corresponding list of catkeys files in $(CATALOGS_DIR)/xx.catalog 234# The "function" appends the .catalog suffix and prepends the 235# $(CATALOGS_DIR)/ path. 236define LOCALES_LIST_TO_CATALOGS 237 $(addprefix $(CATALOGS_DIR)/, $(addsuffix .catalog, $(foreach lang, $(LOCALES), $(lang)))) 238endef 239 240CATALOGS = $(LOCALES_LIST_TO_CATALOGS) 241 242# Define the actual work to be done. 243default: $(TARGET) 244 245$(TARGET): $(OBJ_DIR) $(OBJS) $(RSRCS) 246 $(BUILD_LINE) 247 $(DO_RSRCS) 248 $(MIMESET) -f "$@" 249 250# Create OBJ_DIR if it doesn't exist. 251$(OBJ_DIR):: 252 @[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) >/dev/null 2>&1 253 254# Create the localization sources directory if it doesn't exist. 255$(CATKEYS_DIR):: 256 @[ -d $(CATKEYS_DIR) ] || mkdir $(CATKEYS_DIR) >/dev/null 2>&1 257 258# Create the localization data directory if it doesn't exist. 259$(CATALOGS_DIR):: $(OBJ_DIR) 260 @[ -d $(CATALOGS_DIR) ] || mkdir $(CATALOGS_DIR) >/dev/null 2>&1 261 262# Rules to create the dependency files. 263$(OBJ_DIR)/%.d : %.c 264 mkdir -p $(OBJ_DIR); \ 265 mkdepend $(LOC_INCLUDES) -p .c:$(OBJ_DIR)/%n.o -m -f "$@" $< 266$(OBJ_DIR)/%.d : %.cpp 267 mkdir -p $(OBJ_DIR); \ 268 mkdepend $(LOC_INCLUDES) -p .cpp:$(OBJ_DIR)/%n.o -m -f "$@" $< 269$(OBJ_DIR)/%.d : %.cp 270 mkdir -p $(OBJ_DIR); \ 271 mkdepend $(LOC_INCLUDES) -p .cp:$(OBJ_DIR)/%n.o -m -f "$@" $< 272$(OBJ_DIR)/%.d : %.cc 273 mkdir -p $(OBJ_DIR); \ 274 mkdepend $(LOC_INCLUDES) -p .cc:$(OBJ_DIR)/%n.o -m -f "$@" $< 275$(OBJ_DIR)/%.d : %.cxx 276 mkdir -p $(OBJ_DIR); \ 277 mkdepend $(LOC_INCLUDES) -p .cxx:$(OBJ_DIR)/%n.o -m -f "$@" $< 278$(OBJ_DIR)/%.d : %.C 279 mkdir -p $(OBJ_DIR); \ 280 mkdepend $(LOC_INCLUDES) -p .C:$(OBJ_DIR)/%n.o -m -f "$@" $< 281$(OBJ_DIR)/%.d : %.CC 282 mkdir -p $(OBJ_DIR); \ 283 mkdepend $(LOC_INCLUDES) -p .CC:$(OBJ_DIR)/%n.o -m -f "$@" $< 284$(OBJ_DIR)/%.d : %.CPP 285 mkdir -p $(OBJ_DIR); \ 286 mkdepend $(LOC_INCLUDES) -p .CPP:$(OBJ_DIR)/%n.o -m -f "$@" $< 287$(OBJ_DIR)/%.d : %.CXX 288 mkdir -p $(OBJ_DIR); \ 289 mkdepend $(LOC_INCLUDES) -p .CXX:$(OBJ_DIR)/%n.o -m -f "$@" $< 290 291-include $(DEPENDS) 292 293# Rules to make the object files. 294$(OBJ_DIR)/%.o : %.c 295 $(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 296$(OBJ_DIR)/%.o : %.cpp 297 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 298$(OBJ_DIR)/%.o : %.cp 299 $(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 300$(OBJ_DIR)/%.o : %.cc 301 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 302$(OBJ_DIR)/%.o : %.cxx 303 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 304$(OBJ_DIR)/%.o : %.C 305 $(CC) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 306$(OBJ_DIR)/%.o : %.CC 307 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 308$(OBJ_DIR)/%.o : %.CPP 309 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 310$(OBJ_DIR)/%.o : %.CXX 311 $(C++) -c $< $(INCLUDES) $(CFLAGS) -o "$@" 312 313# Rules to compile the resource definition files. 314$(OBJ_DIR)/%.rsrc : %.rdef 315 cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -av '^#' | $(RESCOMP) -I $(dir $<) -o "$@" - 316$(OBJ_DIR)/%.rsrc : %.RDEF 317 cat $< | $(CC) -E $(INCLUDES) $(CFLAGS) - | grep -av '^#' | $(RESCOMP) -I $(dir $<) -o "$@" - 318 319# Rule to compile localization data catalogs. 320$(CATALOGS_DIR)/%.catalog : $(CATKEYS_DIR)/%.catkeys 321 linkcatkeys -o "$@" -s $(APP_MIME_SIG) -l $(notdir $(basename $@)) $< 322 323# Rule to preprocess program sources into file ready for collecting catkeys. 324$(OBJ_DIR)/$(NAME).pre : $(SRCS) 325 -cat $(SRCS) | $(CC) -E -x c++ $(INCLUDES) $(CFLAGS) -DB_COLLECTING_CATKEYS - | grep -av '^#' > $(OBJ_DIR)/$(NAME).pre 326 327# Rules to collect localization catkeys. 328catkeys : $(CATKEYS_DIR)/en.catkeys 329 330$(CATKEYS_DIR)/en.catkeys : $(CATKEYS_DIR) $(OBJ_DIR)/$(NAME).pre 331 collectcatkeys -s $(APP_MIME_SIG) $(OBJ_DIR)/$(NAME).pre -o $(CATKEYS_DIR)/en.catkeys 332 333# Rule to create localization catalogs. 334catalogs : $(CATALOGS_DIR) $(CATALOGS) 335 336# Rules to handle lex/flex and yacc/bison files. 337$(OBJ_DIR)/%.o: %.l 338 flex $< 339 $(CC) -c $(INCLUDES) $(CFLAGS) lex.yy.c -o "$@" 340$(OBJ_DIR)/%.o: %.y 341 bison -d -y $< 342 $(CC) -c $(INCLUDES) $(CFLAGS) y.tab.c -o "$@" 343 344# The generic "clean" command. (Deletes everything in the object folder.) 345.PHONY: clean 346clean: 347 -rm -rf "$(OBJ_DIR)" 348 349# Remove just the application from the object folder. 350rmapp :: 351 -rm -f $(TARGET) 352 353# Make it easy to install drivers for testing. 354USER_BIN_PATH := $(shell finddir B_USER_NONPACKAGED_ADDONS_DIRECTORY)/kernel/drivers/bin 355USER_DEV_PATH := $(shell finddir B_USER_NONPACKAGED_ADDONS_DIRECTORY)/kernel/drivers/dev 356 357driverinstall :: default 358ifeq ($(strip $(TYPE)), DRIVER) 359 copyattr --data $(TARGET) $(USER_BIN_PATH)/$(NAME) 360 mkdir -p $(USER_DEV_PATH)/$(DRIVER_PATH) 361 ln -sf $(USER_BIN_PATH)/$(NAME) $(USER_DEV_PATH)/$(DRIVER_PATH)/$(NAME) 362endif 363 364install :: default 365ifeq ($(INSTALL_DIR), ) 366 @echo "No install directory specified for \"$(NAME)\" (INSTALL_DIR is empty)" >&2 367else 368 mkdir -p "$(INSTALL_DIR)" 369 cp $(TARGET) $(INSTALL_DIR)/$(NAME) 370endif 371 372# Set the catalog installation directory if it isn't already. 373CATALOG_INSTALL_DIR := $(shell finddir B_USER_NONPACKAGED_DATA_DIRECTORY)/locale/catalogs 374 375# Rule to install localization resources catalogs. 376catalogsinstall :: catalogs 377 mkdir -p "$(CATALOG_INSTALL_DIR)/$(APP_MIME_SIG)" 378 -cp $(CATALOGS_DIR)/*.catalog "$(CATALOG_INSTALL_DIR)/$(APP_MIME_SIG)" 379 380# Alternate way of storing localization catalogs: bind them into the program 381# executable's resources. 382bindcatalogs : 383 for lc in $(LOCALES); do linkcatkeys -o $(TARGET) -s $(APP_MIME_SIG) -tr -l $$lc $(CATKEYS_DIR)/$$lc.catkeys; done 384