diff options
Diffstat (limited to 'cyclone')
-rw-r--r-- | cyclone/Makefile.pdlibbuilder | 686 |
1 files changed, 404 insertions, 282 deletions
diff --git a/cyclone/Makefile.pdlibbuilder b/cyclone/Makefile.pdlibbuilder index 3bbea05..79f2d51 100644 --- a/cyclone/Makefile.pdlibbuilder +++ b/cyclone/Makefile.pdlibbuilder @@ -1,27 +1,27 @@ +# Makefile.pdlibbuilder version 0.0.0, dated 2015-06-25 # -# Makefile.pdlibbuilder dated 20150614-1 -# -# GNUmake-based helper makefile for Pure Data externals. -# Written by Katja Vetter March-May 2015 for the public domain. +# Helper makefile for Pure Data external libraries. +# Written by Katja Vetter March-June 2015 for the public domain. No warranties. # Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's # ShakeNMake. # +# GNU make version >= 3.81 required. +# # -#=== features ================================================================== +#=== characteristics =========================================================== # # -# - defines flags and extension according to autodetected platform -# - evaluates implicit dependencies for non-clean builds -# - defines rules to build from C or C++ sources -# - defines rules to build Pd class- or lib executables -# - defines rules for libdir installation -# - defines convenience targets for developer and user +# - defines build settings based on autodetected OS and architecture +# - defines rules to build Pd class- or lib executables from C or C++ sources +# - defines rules for libdir installation +# - defines convenience targets for developer and user +# - evaluates implicit dependencies for non-clean builds # # #=== basic usage =============================================================== # # -# In your Makefile, define your Pd lib name and class sources, and include +# In your Makefile, define your Pd lib name and class files, and include # Makefile.pdlibbuilder at the end of the Makefile. Like so: # # ________________________________________________________________________ @@ -32,92 +32,194 @@ # # class.sources = myclass1.c myclass2.c # -# include path/to/Makefile.pdlibbuilder +# datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt +# +# include Makefile.pdlibbuilder # ________________________________________________________________________ # # -# For files in class.sources it is assumed that class basename = source file -# basename. All other class sources must be specified in variables -# <classname>.class.sources. +# For files in class.sources it is assumed that class basename == source file +# basename. The default target builds all classes as individual executables +# with Pd's default extension for the platform. For anything more than the +# most basic usage, continue reading. +# +# +#=== list of Makefile.pdlibbuilder API variables =============================== +# # -# The default target builds all classes as indidividual executables with Pd's -# default extension for the platform. +# Variables available for definition in your library Makefile: +# +# - lib.name +# - lib.setup.sources +# - class.sources +# - common.sources +# - shared.sources +# - <classname>.class.sources +# - <classname>.class.ldflags +# - <classname>.class.ldlibs +# - cflags +# - ldflags +# - ldlibs +# - datafiles +# - datadirs +# - makefiles +# - makefiledirs +# - externalsdir # +# Variables avaialable for (re)definition via command arguments: # -#=== variables ================================================================= +# - pdbinpath (Windows only) +# - pdincludepath +# - DESTDIR +# - prefix +# - libdir +# - pkglibdir +# - CFLAGS +# - CC +# - CXX +# - INSTALL +# - INSTALL_PROGRAM +# - INSTALL_DATA +# - INSTALL_DIR +# +# Variables available for your makefile or as command argument: +# +# - objectsdir +# - make-lib-executable +# - suppress-wunused # # -# The following variables may be specified in your Makefile: +#=== descriptions of Makefile.pdlibbuilder API variables ======================= # -# - lib.name: name of the library -# - class.sources: sources files (C or C++), class name = source basename # -# - cflags: add preprocessor / compiler flags, notably -I or -D options -# - ldflags: add linker / loader flags -# - ldlibs: add flags for dynamic linking +# lib.name: +# Name of the library directory as it will be installed / distributed. Also the +# name of the lib executable in the case where all classes are linked into +# a single binary. # -# - <classname>.class.sources: list / add class-specific source files (C or C++) -# - <classname>.class.ldflags: add class-specific ld flags -# - <classname>.class.ldlibs: add class-specific dynamic link libs +# lib.setup.sources: +# Source file(s) (C or C++) which must be compiled only when linking all classes +# into a single lib binary. # -# - lib.setup.sources: source file(s) with routines to set up all classes -# - common.sources: sources to include in each class statically -# - shared.sources: source file(s) of dynamic lib shared by all classes +# class.sources: +# All sources files (C or C++) for which the condition holds that +# class name == source file basename. # -# - datafiles: non-executable files, including abstractions and help patches -# - datadirs: directories with data files +# <classname>.class.sources: +# Source file(s) (C or C++) specific to class <classname>. Use this for +# multiple-source classes or when class name != source file basename. # -# - externalsdir: relative path to 'externals' in pd SVN, default is '..' +# common.sources: +# Source file(s) which must be statically linked to each class in the library. # -# - makefiles: extra makefiles that should be made -# - makefiledirs: extra directories with makefiles that should be made +# shared.sources: +# Source file(s) (C or C++) to build a shared dynamic link lib, to be linked +# with all class executables. # +# cflags, ldflags, ldlibs: +# Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic +# link libs) for the whole library. These flags are added to platform-specific +# flags defined by Makefile.pdlibbuilder. # -#=== Pd-extended libdir concept ================================================ +# <classname>.class.ldflags and <classname>.class.ldlibs: +# Define ldflags resp. ldlibs specific to class <classname>. These flags are +# added to platform-specific flags defined by Makefile.pdlibbuilder, and flags +# defined in your Makefile for the whole library. Note: cflags can not be +# defined per class in the current implementation. # +# datafiles and datadirs: +# All extra files you want to include in binary distributions of the +# library: abstractions and help patches, example patches, meta patch, readme +# and license texts, manuals, sound files, etcetera. Use 'datafiles' for all +# files that should go into your lib rootdir and 'datadirs' for complete +# directories you want to copy from source to distribution. # -# For libdir layout as conceived by Hans-Christoph Steiner, see: +# externalsdir: +# Relative path to directory 'externals' in the context of pd-extended SVN, or +# any other centralized build layout for multiple libraries. Default value +# is '..', meaning the direct parent. The value is used in search paths for +# pd core components (header files, and executable in the case of Windows). # -# https://puredata.info/docs/developer/Libdir +# makefiles and makefiledirs: +# Extra makefiles or directories with makefiles that should be made in sub-make +# processes. # -# Files README.txt, LICENSE.txt and <lib.name>-meta.pd are part of the libdir -# convention. Help patches for each class and abstraction are supposed to be -# available. Makefile.pdlibbuilder does not force the presence of these files -# however, and it does not automatically include such files in libdir -# installations. +# pdbinpath: +# For Windows only. Directory where pd.dll can be found for linking. # +# pdincludepath: +# Directory where Pd API m_pd.h can be found, and other Pd header files. # -#=== search paths ============================================================== +# DESTDIR, prefix, libdir: +# Components of the path for installation as conventionally used on Linux. # +# pkglibdir: +# Base path for installation of Pd library directories. Default is specified +# per OS, see section about paths below. # -# Source file paths other than current working directory must be explicited in -# your Makefile. Executables are built in current working directory. Object (.o) -# files are built in the directory of their source files. +# objectsdir: +# Alias of pkglibdir. Can be defined in your makefile to enable project- +# dependent relative install locations. # -# Variable 'pdincludepath' stores the include path for Pd API headers. Default -# locations, searched in order of priority: -# -# any OS: $(externalsdir)../pd/include/pdextended -# $(externalsdir)../pd/include +# CFLAGS: +# Compiler (notably optimization) flags which are defined by +# Makefile.pdlibbuilder, but may be overriden via command argument. +# +# CC and CXX: +# C and C++ compiler programs as defined in your build environment. +# +# INSTALL, INSTALL_PROGRAM, INSTALL_DATA, INSTALL_DIR: +# Definitions of install program, may be overriden via command argument. # -# Linux: /usr/include/pdextended -# /usr/include/pd +# make-lib-executable: +# When this variable is defined 'yes' in your makefile or as command argument, +# Makefile.pdlibbuilder will try to build all classes into a single library +# executable (but it will force exit if lib.setup.sources is undefined). +# If your makefile defines 'make-lib-executable=yes' as the library default, +# this can still be overriden with 'make-lib-executable=no' as command argument +# to build individual class executables (the Makefile.pdlibbuilder default.) # -# OSX: /Applications/Pd-extended.app/Contents/Resources/include/pdextended -# /Applications/Pd.app/Contents/Resources/include +# suppress-wunused: +# When this variable is defined ('yes' or any other value), -Wunused-variable, +# -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed, +# but the other warnings from -Wall are retained. # -# Windows: c/PROGRA~1/pd/include -# c/PROGRA~2/pd/include # +#=== paths ===================================================================== # -# Overview of install paths per platform, taken from -# https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files. -# The rationale for a global install path (rather than in home) on Linux, -# is that some people share a home dir between 32 and 64 bit installations. # -# Linux: $(libdir)/pd-externals/$(lib.name) -# OSX: ~/Library/Pd/$(lib.name) -# Windows: c/PROGRA~1/COMMON~1/Pd/$(lib.name) +# Source files in directories other than current working directory must be +# prefixed with their relative path. Do not rely on VPATH or vpath. +# Object (.o) files are built in the directory of their source files. +# Executables are built in current working directory. +# +# Variable 'pdincludepath' stores the location where m_pd.h was found. +# Locations where Makefile.pdlibbuilder tries to find it, in order of priority: +# +# any OS: $(externalsdir)../pd/src/ +# +# Linux: /usr/include/pdextended/ +# /usr/include/pd/ +# +# OSX: /Applications/Pd-extended.app/Contents/Resources/include/pdextended/ +# /Applications/Pd.app/Contents/Resources/src/ +# +# Windows: %PROGRAMFILES%/pd/include/pdextended/ +# %PROGRAMFILES%/pd/src/ +# +# The path for installation of all library components is constructed as: +# +# installpath := $(DESTDIR)$(objectsdir)/$(lib.name) +# +# Default for 'objectsdir' is defined per platform and follows this convention: +# https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files +# +# Linux: /usr/local/lib/pd-externals +# OSX: ~/Library/Pd +# Windows: %APPDATA%/Pd +# +# The rationale for not installing to ~/pd-externals by default on Linux +# is that some people share the home dir between 32 and 64 bit installations. # # #=== targets =================================================================== @@ -125,19 +227,13 @@ # # all: build classes (default) or library blob (if make-lib-executable=true) # alldebug: build all with -g option turned on for debug symbols -# build-classes: build all class executables and optional shared lib -# build-lib: build all classes into a single lib executable # <classname>: force clean build of an individual class +# <sourcefile>.pre: make preprocessor output file in current working directory +# <sourcefile>.lst: make asm/source output file in current working directory # # install: install executables and data files -# dist: make source package for distribution (not yet implemented) -# dpkg-source: make debian source package (not yet implemented) -# # clean: remove build products from source tree -# distclean: not yet implemented # -# <sourcefile>.pre: make preprocessor output file in current working directory -# <sourcefile>.lst: make asm/source output file in current working directory # help: print help text # vars: print makefile variables # allvars: print all variables @@ -145,43 +241,56 @@ # coffee: dummy target # # -#=== syntax conventions ======================================================== +#=== Pd-extended libdir concept ================================================ +# +# +# For libdir layout as conceived by Hans-Christoph Steiner, see: +# +# https://puredata.info/docs/developer/Libdir +# +# Files README.txt, LICENSE.txt and <lib.name>-meta.pd are part of the libdir +# convention. Help patches for each class and abstraction are supposed to be +# available. Makefile.pdlibbuilder does not force the presence of these files +# however. It does not automatically include such files in libdir installations. +# Data files you want to include in distributions must be defined explicitly in +# your Makefile. +# +# +#=== Makefile.pdlibbuilder syntax conventions ================================== # # # Makefile.pdlibbuilder variable names are lower case. Default make variables, # environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR) # are upper case. Use target 'allvars' to print all variables and their values. # -# Words in 'function' names are separated by dashes, like in 'make-object-file'. -# Words in data variables may be separated by dots, like in 'foo.class.sources'. -# Make's 'basename' function is sometimes exploited to split such variable -# names. +# 'Fields' in data variables are separated by dots, like in 'foo.class.sources'. +# Words in variables expressing a function or command are separated by dashes, +# like in 'make-lib-executable'. # # #=== useful make options ======================================================= # # -# Use 'make -d <target>' to print debug details of the make process -# Use 'make -p <target>' to print make's database +# Use 'make -d <target>' to print debug details of the make process. +# Use 'make -p <target>' to print make's database. # # #=== TODO ====================================================================== # # -# - replace -DOSXFAT with specific architecture defines -# - document installpath -# - check if there's issues with & and $ in filenames -# - -static-libgcc or shared dll in MinGW? -# - fix Windows paths: can we allow spaces? then use env. var. paths -# - variables PD_PATH and PDINCLUDE for compatibility with pd-extended template -# - variable for external dependencies? +# - decide whether to use -static-libgcc or shared dll in MinGW # - cygwin support # - android support -# - makefile template targets dpkg-source dist libdir distclean tags and etags +# - Windows 64 bit support +# - figure out how to handle '$' in filenames +# - add makefile template targets dpkg-source dist libdir distclean tags? +# # +#=== end of documentation sections ============================================= # +# +################################################################################ ################################################################################ -### pre-flight checks ########################################################## ################################################################################ @@ -194,9 +303,10 @@ ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81) $(error GNU make version 3.81 or higher is required) endif -# Relative path to directory 'externals' in pd-extended SVN tree. Default is -# parent of current working directory. May be defined differently in including -# makefile. This variable is used to probe for paths. +# Relative path to externals root dir in multi-lib source tree like +# pd-extended SVN. Default is parent of current working directory. May be +# defined differently in including makefile. This variable is used to probe for +# paths. externalsdir ?= .. # variable you can use to check if Makefile.pdlibbuilder is already included @@ -204,6 +314,64 @@ Makefile.pdlibbuilder = true ################################################################################ +### variables: files ########################################################### +################################################################################ + + +# strip possibles spaces from lib.name, they mess up calculated file names +lib.name := $(strip $(lib.name)) + + +#=== sources =================================================================== + + +# (re)define <classname>.class.sources using file names in class.sources + +define add-class-source +$(notdir $(basename $v)).class.sources += $v +endef + +$(foreach v, $(class.sources), $(eval $(add-class-source))) + +# derive class names from <classname>.class.sources variables +sourcevariables := $(filter %.class.sources, $(.VARIABLES)) +classes := $(basename $(basename $(sourcevariables))) + +# accumulate all source files specified in makefile +classes.sources := $(sort $(foreach v, $(sourcevariables), $($v))) +all.sources := $(classes.sources) $(lib.setup.sources) \ + $(shared.sources) $(common.sources) + + +#=== object files ============================================================== + + +# construct object filenames from all C and C++ source file names +classes.objects := $(addsuffix .o, $(basename $(classes.sources))) +common.objects := $(addsuffix .o, $(basename $(common.sources))) +shared.objects := $(addsuffix .o, $(basename $(shared.sources))) +lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources))) +all.objects = $(classes.objects) $(common.objects) $(shared.objects) \ + $(lib.setup.objects) + + +#=== executables =============================================================== + + +# use recursive variables here because executable extension is not yet known + +# construct class executable names from class names +classes.executables = $(addsuffix .$(extension), $(classes)) + +# construct shared lib executable name if shared sources are defined +ifdef shared.sources + shared.lib = lib$(lib.name).$(shared.extension) +else + shared.lib = +endif + + +################################################################################ ### variables per platform ##################################################### ################################################################################ @@ -219,13 +387,11 @@ machine := $(shell uname -m) # Raspberry Pi 1st generation ifeq ($(machine), armv6l) arch.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard - CFLAGS += -fsingle-precision-constant endif # Beagle, Udoo, RPi2 etc. ifeq ($(machine), armv7l) arch.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard - CFLAGS += -fsingle-precision-constant endif # Intel 32 bit, build with SSE and SSE2 instructions @@ -239,24 +405,24 @@ ifeq ($(findstring $(machine), ia64 x86_64), $(machine)) endif -#=== platform ================================================================== +#=== operating system ========================================================== -# The following platforms are defined: Linux, Darwin, Windows. GNU and -# GNU/kFreeBSD are treated as Linux because they use the same options. +# The following systems are defined: Linux, Darwin, Windows. GNU and +# GNU/kFreeBSD are treated as Linux to get the same options. uname := $(shell uname) ifeq ($(findstring $(uname), Linux GNU GNU/kFreeBSD), $(uname)) - platform = Linux + system = Linux endif ifeq ($(uname), Darwin) - platform = Darwin + system = Darwin endif ifeq ($(findstring MINGW, $(uname)), MINGW) - platform = Windows + system = Windows endif # TODO: Cygwin, Android @@ -265,16 +431,14 @@ endif #=== flags and paths for Linux ================================================= -ifeq ($(platform), Linux) +ifeq ($(system), Linux) prefix = /usr/local libdir := $(prefix)/lib - pkglibdir ?= $(libdir)/pd-externals - mpdhsearchpaths := \ - $(externalsdir)/../pd/src/ \ - /usr/include/pdextended/ \ - /usr/include/pd/ - pdincludepath := \ - $(firstword $(dir $(wildcard $(addsuffix m_pd.h, $(mpdhsearchpaths))))) + pkglibdir = $(libdir)/pd-externals + pdincludepath := $(firstword $(dir $(wildcard \ + $(externalsdir)/../pd/src/m_pd.h \ + /usr/include/pdextended/m_pd.h \ + /usr/include/pd/m_pd.h))) extension = pd_linux cpp.flags := -DUNIX c.flags := -fpic @@ -284,7 +448,7 @@ ifeq ($(platform), Linux) cxx.ldflags := -rdynamic -shared -fpic -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags cxx.ldlibs := -lc -lm -lstdc++ shared.extension = so - shared.ldflags = -rdynamic -fpic -shared -Wl,-soname,$(shared.lib) + shared.ldflags := -rdynamic -fpic -shared -Wl,-soname,$(shared.lib) stripflags = --strip-unneeded -R .note -R .comment endif @@ -294,25 +458,18 @@ endif # On OSX we try to build fat binaries by default. It is assumed that OSX i386 # can build for ppc and OSX x86_64 can't. TODO: try to refine this condition. -# TODO: replace -DOSXFAT with more specific defines. # LLVM-clang doesn't support -fcheck-new, therefore this flag is omitted for # OSX x86_64. -ifeq ($(platform), Darwin) - pkglibdir ?= $(HOME)/Library/Pd - pdpath := $(firstword $(wildcard \ - $(externalsdir)/../pd \ - c/PROGRA~1/pd \ - c/PROGRA~2/pd)) - mpdhsearchpaths := \ - $(externalsdir)/../pd/src/ \ - /Applications/Pd-extended.app/Contents/Resources/include/pdextended/ \ - /Applications/Pd.app/Contents/Resources/src/ - pdincludepath := \ - $(firstword $(dir $(wildcard $(addsuffix m_pd.h, $(mpdhsearchpaths))))) +ifeq ($(system), Darwin) + pkglibdir = $(HOME)/Library/Pd + pdincludepath := $(firstword $(dir $(wildcard \ + $(externalsdir)/../pd/src/m_pd.h \ + /Applications/Pd-extended.app/Contents/Resources/include/pdextended/m_pd.h \ + /Applications/Pd.app/Contents/Resources/src/m_pd.h))) extension = pd_darwin arch.flags = - cpp.flags := -DUNIX -DMACOSX -I /sw/include + cpp.flags := -DUNIX -DMACOSX -I /sw/include c.flags := c.ldflags := -undefined suppress -flat_namespace -bundle c.ldlibs := -lc @@ -324,12 +481,10 @@ ifeq ($(platform), Darwin) -compatibility_version 1 -current_version 1.0 stripflags = -x ifeq ($(machine), i386) - cpp.flags += -DOSXFAT cxx.flags := -fcheck-new arch.flags := -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 endif ifeq ($(machine), x86_64) - cpp.flags += -DOSXFAT arch.flags := -arch i386 -arch x86_64 -mmacosx-version-min=10.5 endif endif @@ -338,20 +493,33 @@ endif #=== flags and paths for Windows =============================================== +# Standard paths on Windows contain spaces, and GNU make functions treat such +# paths as lists, with unintended effects. Therefore we must use shell function +# ls instead of make's wildcard, and probe for each standard path individually. +# Using double quotes around paths with spaces is obligatory. Since some path +# variables are assembled or re-expanded later, great care must be taken to put +# quotes at appropriate points throughout the makefile. Thanks, Bill. + +# paths for 32-bit executables on 64-bit Windows aren't yet defined here (TODO) +ifeq ($(system), Windows) + pkglibdir := $(APPDATA)/Pd + pdbinpath := $(wildcard $(externalsdir)/../pd/bin/) + pdincludepath := $(wildcard $(externalsdir)/../pd/src/) + ifndef pdbinpath + pdbinpath := $(shell ls -d "$(PROGRAMFILES)/pd/bin/") + endif + ifndef pdincludepath + pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/include/pdextended/") + endif + ifndef pdincludepath + pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/src/") + endif +endif + # On Windows we build 32 bit by default to match Pd(-extended) binary # distributions. This may change in the future. -# Paths shall not contain spaces, use 8.3 format instead. -# TODO: try to convert env vars %PROGRAMFILES% and %COMMONPROGRAMFILES% to -# 8.3 format. - -ifeq ($(platform), Windows) - pkglibdir ?= c/PROGRA~1/COMMON~1/Pd - mpdhsearchpaths := \ - $(externalsdir)/../pd/src \ - c/PROGRA~1/pd/src \ - c/PROGRA~2/pd/src - pdincludepath := \ - $(firstword $(dir $(wildcard $(addsuffix m_pd.h, $(mpdhsearchpaths))))) +# TODO: decide whether -mms-bitfields should be specified. +ifeq ($(system), Windows) extension = dll CC = gcc CXX = g++ @@ -359,63 +527,56 @@ ifeq ($(platform), Windows) cpp.flags := -DMSW -DNT c.flags := c.ldflags := -static-libgcc -shared \ - -Wl,--enable-auto-import $(pdpath)/bin/pd.dll + -Wl,--enable-auto-import "$(pdbinpath)pd.dll" c.ldlibs := cxx.flags := -fcheck-new cxx.ldflags := -static-libstdc++ -shared \ - -Wl,--enable-auto-import $(pdpath)/bin/pd.dll + -Wl,--enable-auto-import "$(pdbinpath)pd.dll" cxx.ldlibs := shared.extension = dll - shared.ldflags := -static-libgcc -shared \ - $(pdpath)/bin/pd.dll + shared.ldflags := -static-libgcc -shared "$(pdbinpath)pd.dll" stripflags = --strip-unneeded -R .note -R .comment endif -# TODO: should we set -mms-bitfields or not? -#=== platform-independent flags ================================================ +#=== paths ===================================================================== -# From GNU make docs: 'Users expect to be able to specify CFLAGS freely -# themselves.' So we use CFLAGS to define platform-independent options which -# are not strictly required for compilation: optimizations and warnings. - -CFLAGS = -O3 -ffast-math -funroll-loops -fomit-frame-pointer - -# warnings are enabled by default, but may be suppressed -ifneq ($(suppress-warnings),yes) - CFLAGS += -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -endif - - -#=== paths for installation ==================================================== - - -# Default pkglibdir is specified above per platform. It is aliased as -# 'objectsdir' to retain compatibility with pd-extended template. -objectsdir := $(pkglibdir) +# Default pkglibdir is specified above per operating system. It is aliased as +# 'objectsdir' to retain compatibility with pd-extended template. Assignment +# operator '?=' is used to enable a project-relative path definition in the +# including makefile. +objectsdir ?= $(pkglibdir) # base path where all components of the lib will be installed by default installpath := $(DESTDIR)$(objectsdir)/$(lib.name) +# check if pdincludepath contains spaces (as is often the case on Windows) +# if so, store the path so we can later do checks with it +pdincludepathwithspaces := $(if $(word 2, $(pdincludepath)), $(pdincludepath)) -#=== Makefile.config =========================================================== +#=== accumulated build flags =================================================== -# Optionally include Makefile.config, which can be used to override default -# paths or extensions. - --include Makefile.config +# From GNU make docs: 'Users expect to be able to specify CFLAGS freely +# themselves.' So we use CFLAGS to define platform-independent options which +# are not strictly required for compilation: optimizations and warnings. CFLAGS +# can be safely overriden using a make command argument. +# Variables cflags, ldflags and ldlibs may be defined in including makefile. -#=== accumulated build flags =================================================== +optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer +warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing +# suppress -Wunused-variable & Co if you don't want to clutter a build log +ifdef suppress-wunused + warn.flags += $(addprefix -Wno-unused-, function parameter value variable) +endif -# Variables cflags, ldflags and ldlibs may be defined in including makefile. -# Variable CFLAGS may be defined as command line argument. +CFLAGS = $(warn.flags) $(optimization.flags) # preprocessor flags -cpp.flags += -DPD -I $(pdincludepath) +cpp.flags += -DPD -I "$(pdincludepath)" # flags for C compiler / linker c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS) @@ -429,79 +590,22 @@ cxx.ldlibs := $(cxx.ldlibs) $(ldlibs) ################################################################################ -### variables: files ########################################################### -################################################################################ - - -# strip possibles spaces from lib.name, they mess up calculated file names -lib.name := $(strip $(lib.name)) - - -#=== sources =================================================================== - - -# Based on file names in class.sources, (re)define <classname>.class.sources - -define add-class-source -$(notdir $(basename $v)).class.sources += $v -endef - -$(foreach v, $(class.sources), $(eval $(add-class-source))) - -# derive class names from .class.sources variables -sourcevariables := $(filter %.class.sources, $(.VARIABLES)) -classes := $(basename $(basename $(sourcevariables))) - -# accumulate all source files specified in makefile -classes.sources := $(sort $(foreach v, $(sourcevariables), $($v))) -all.sources := $(classes.sources) $(lib.setup.sources) \ - $(shared.sources) $(common.sources) - -# construct shared lib name if shared sources are defined -ifdef shared.sources - shared.lib := lib$(lib.name).$(shared.extension) -else - shared.lib = -endif - - -#=== build products ============================================================ - - -# construct object filenames from all C and C++ source file names -classes.objects := $(addsuffix .o, $(basename $(classes.sources))) -common.objects := $(addsuffix .o, $(basename $(common.sources))) -shared.objects := $(addsuffix .o, $(basename $(shared.sources))) -lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources))) -all.objects = $(classes.objects) $(common.objects) $(shared.objects) \ - $(lib.setup.objects) - -# construct class executable names from class names -classes.executables := $(addsuffix .$(extension), $(classes)) - - -################################################################################ ### variables: tools ########################################################### ################################################################################ -# aliases so we can define 'compile-$1' and give 'c' or 'cxx' as argument +# aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument compile-c := $(CC) compile-cxx := $(CXX) -# install executables, data and directories while preserving time stamps -INSTALL = install -INSTALL_PROGRAM := $(INSTALL) -p -m 644 -INSTALL_DATA := $(INSTALL) -p -m 644 -INSTALL_DIR := $(INSTALL) -p -m 755 -d - ################################################################################ ### checks ##################################################################### ################################################################################ -# At this point most variables are defined. Time to do some checks and info's. +# At this point most variables are defined. Now do some checks and info's +# before rules begin. # 'forward declaration' of default target, needed to do checks all: @@ -520,14 +624,12 @@ else endif # check if m_pd.h is found and print info about it -$(if $(wildcard $(pdincludepath)m_pd.h), \ +$(if $(shell ls "$(pdincludepath)m_pd.h"), \ $(info ++++ info: using Pd API $(pdincludepath)m_pd.h), \ - $(warning Where is your m_pd.h? It was searched but not found on one of the \ - following locations: $(mpdhsearchpaths). Alternatively you can specify \ - variable pdincludepath as argument.)) + $(warning Where is your m_pd.h? Do 'make help' for info.)) # print target info -$(info ++++ info: making target $(goals) in lib $(lib.name)) +$(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name))) # when installing, print installpath info $(if $(filter install install-lib, $(goals)), $(info ++++ info: \ @@ -553,7 +655,7 @@ endif #=== library version =========================================================== -# check library version if meta file exists +# if meta file exists, check library version metafile := $(wildcard $(lib.name)-meta.pd) @@ -576,8 +678,7 @@ MAKEFLAGS += --no-builtin-rules .PRECIOUS: .SUFFIXES: .PHONY: all build-classes build-lib $(classes) $(makefiledirs) $(makefiles)\ - install install-classes install-lib \ - install-datafiles install-datadirs \ + install install-executables install-datafiles install-datadirs \ force clean vars allvars depend help @@ -586,8 +687,10 @@ MAKEFLAGS += --no-builtin-rules ################################################################################ -# build lib when make-lib-executable = true, otherwise build classes (default) -all: $(if $(make-lib-executable), build-lib, build-classes) +# target all builds class executables plus optional shared lib +# or alternatively a single lib executable when make-lib-executable=true +all: $(executables) + $(info ++++ info: $(if $(executables),executables in $(lib.name) completed)) # build all with -g option turned on for debug symbols alldebug: c.flags += -g @@ -595,12 +698,8 @@ alldebug: cxx.flags += -g alldebug: all -#=== one class per executable ================================================== - +#=== class executable ========================================================== -# build all class executables (default) -build-classes: $(classes.executables) - $(info ++++ info: class executables in $(lib.name) completed) # recipe for linking objects in class executable # argument $1 = compiler type (c or cxx) @@ -675,8 +774,8 @@ lib$(lib.name).$(shared.extension): $(shared.objects) #=== object files ============================================================== -# recipe to make .o from source -# argument $1 is compiler tupe (c or cxx) +# recipe to make .o file from source +# argument $1 is compiler type (c or cxx) define make-object-file $(info ++++ info: making $@ in lib $(lib.name)) $(compile-$1) \ @@ -729,9 +828,14 @@ $(foreach v, $(classes), $(eval $(declare-class-executable-target))) # Note that it is also possible to trigger a build via install targets, in # which case implicit prerequisites are not checked. -must-build-everything := $(filter all default lib, $(goals)) -must-build-class := $(filter $(classes), $(goals)) -must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources)) +# When the Pd include path contains spaces it will mess up the implicit +# prerequisites rules so we do not evaluate them in that case. + +ifndef pdincludepathwithspaces + must-build-everything := $(filter all default lib, $(goals)) + must-build-class := $(filter $(classes), $(goals)) + must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources)) +endif # declare implicit prerequisites rule like 'object.o: header1.h header2.h ...' # argument $1 is input source file(s) @@ -822,6 +926,15 @@ endef # Install targets depend on successful exit status of target all because nothing # must be installed in case of a build error. + +# -p = preserve time stamps +# -m = set permission mode (as in chmod) +# -d = create all components of specified directories +INSTALL = install +INSTALL_PROGRAM := $(INSTALL) -p -m 644 +INSTALL_DATA := $(INSTALL) -p -m 644 +INSTALL_DIR := $(INSTALL) -m 755 -d + # strip spaces from file names executables := $(strip $(executables)) datafiles := $(strip $(datafiles)) @@ -834,21 +947,21 @@ install: $(if $(datafiles), install-datafiles) install: $(if $(datadirs), install-datadirs) install-executables: all - $(INSTALL_DIR) -v $(installpath) - $(INSTALL_PROGRAM) $(executables) $(installpath) + $(INSTALL_DIR) -v "$(installpath)" + $(INSTALL_PROGRAM) $(executables) "$(installpath)" $(info ++++ info: executables of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) install-datafiles: all - $(INSTALL_DIR) -v $(installpath) - $(INSTALL_DATA) $(datafiles) $(installpath) + $(INSTALL_DIR) -v "$(installpath)" + $(INSTALL_DATA) $(datafiles) "$(installpath)" $(info ++++ info: data files of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) install-datadirs: all - @set -x; $(INSTALL_DIR) $(addprefix $(installpath)/, $(datadirs)) && \ - $(foreach v, $(datadirs), \ - $(INSTALL_DATA) $(wildcard $v/*) $(installpath)/$v;) + $(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";) + $(foreach v, $(datadirs), \ + $(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";) $(info ++++ info: data directories of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) @@ -900,7 +1013,8 @@ distclean: clean # When 'continue-make=yes' is set, sub-makes will report 'true' to the parent # process regardless of their real exit status. This prevents the parent make -# from being aborted by a sub-make error. +# from being aborted by a sub-make error. Useful when you want to quickly find +# out which sub-makes from a large set will succeed. ifeq ($(continue-make),yes) continue = || true endif @@ -940,10 +1054,8 @@ link-lib \ link-shared \ make-object-file \ make-preprocessor-file \ -make-assembly-file \ -install-class-executable \ -define-class-sources \ -declare-helptext +make-assembly-file + # show variables from makefiles vars: @@ -980,26 +1092,32 @@ depend: #=== show help text ============================================================ -# show targets and other info for user +# brief info about targets and paths + +mpdh := $(shell ls "$(pdincludepath)m_pd.h") +mpdh := $(if $(mpdh), $(mpdh), m_pd.h not found. Is Pd(-extended) installed?) + help: - @echo "$(declare-helptext)" - -define declare-helptext -\nMain targets (for complete overview of targets see Makefile.pdlibbuilder):\ -\n\nall (default target): build executables\ -\ninstall: install executables / data files\ -\nvars: print makefile variables for troubleshooting\ -\nhelp: print this help text\ -\n\nPd API m_pd.h is searched at the following paths (in order of priority):\ -$(addprefix \n, $(mpdhsearchpaths)) \ -\n\nPd API m_pd.h is found at the following pdincludepath: \ -\n$(pdincludepath)\ -\n\nAlternatively you can specify variable pdincludepath as argument.\ -\n\nBase path for installation of all components is:\ -\n$(installpath)\ -\n -endef + @echo + @echo " Main targets:" + @echo " all: build executables (default target)" + @echo " install: install all components of the library" + @echo " vars: print makefile variables for troubleshooting" + @echo " allvars: print all variables for troubleshooting" + @echo " help: print this help text" + @echo + @echo " Pd API m_pd.h:" + @echo " $(shell ls "$(pdincludepath)m_pd.h")" + @echo " You may specify your preferred include path as argument to" + @echo " the make command, like 'pdincludepath=path/to/pd/src'." + @echo + @echo " Path for installation of your libdir(s):" + @echo " $(objectsdir)" + @echo " Alternatively you may specify your path for installation as argument" + @echo " to the make command, like 'objectsdir=path/to/pd-externals'." + @echo " For detailed info read the doc sections in Makefile.pdlibbuilder." + @echo #=== dummy target ============================================================== @@ -1010,6 +1128,10 @@ coffee: ################################################################################ -### the end #################################################################### +### end of rules sections ###################################################### ################################################################################ + +# for syntax highlighting in vim and github +# vim: set filetype=make: + |