aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cyclone/Makefile.pdlibbuilder686
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:
+