pax_global_header 0000666 0000000 0000000 00000000064 14717202036 0014514 g ustar 00root root 0000000 0000000 52 comment=3db847d6027e37cec60363a857297b4f103accab
slip-0.1/ 0000775 0000000 0000000 00000000000 14717202036 0012323 5 ustar 00root root 0000000 0000000 slip-0.1/.gitignore 0000664 0000000 0000000 00000000035 14717202036 0014311 0 ustar 00root root 0000000 0000000 *.o
*.pd_linux
*.so
*~
.svn/
slip-0.1/LICENSE.txt 0000664 0000000 0000000 00000001325 14717202036 0014147 0 ustar 00root root 0000000 0000000 mrpeach - a bag of tricks
Copyright (C) 2006-2015 Martin Peach
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
slip-0.1/Makefile 0000664 0000000 0000000 00000000777 14717202036 0013776 0 ustar 00root root 0000000 0000000 # Makefile for slip
lib.name = slip
class.sources = \
slipdec.c \
slipenc.c
datafiles = \
LICENSE.txt \
README.md \
slip-meta.pd \
slipdec-help.pd \
slipenc-help.pd
# This Makefile is based on the Makefile from pd-lib-builder written by
# Katja Vetter. You can get it from:
# https://github.com/pure-data/pd-lib-builder
PDLIBBUILDER_DIR=pd-lib-builder/
include $(firstword $(wildcard $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder Makefile.pdlibbuilder))
slip-0.1/README.md 0000664 0000000 0000000 00000000510 14717202036 0013576 0 ustar 00root root 0000000 0000000 slip - Serial Line Internet Protocol for Pd
===========================================
SLIP is used to transmit packet oriented protocols through stream based
protocols (for instance: OSC over TCP).
Author: Martin Peach
## Object classes
- **[slipenc]**
encodes SLIP packets.
- **[slipdec]**
decodes SLIP packets.
slip-0.1/pd-lib-builder/ 0000775 0000000 0000000 00000000000 14717202036 0015116 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/CHANGELOG.txt 0000664 0000000 0000000 00000007401 14717202036 0017150 0 ustar 00root root 0000000 0000000 Changelog for Makefile.pdlibbuilder.
v0.7.0, dated 2023-07-06
- build double-precision externals with the 'floatsize' variable
- allow building multiple flavours of an external side-by-side (#78)
- facilitate multiple platform co-installation of shared lib (#58)
- fix use of shared.ldflags with helper-library (#64)
- fix broken armv6l platform detection (#71)
- improve documentation
v0.6.0, dated 2019-12-21
- detect target platform (OS and architecture) rather than build platform (#55)
- introduce optional user variable 'PLATFORM' for cross compilation
- no longer build OSX/MacOS fat binaries by default (#21, #50)
- do build fat binaries when 'extension=d_fat' is specified for OSX/MacOS
- fix bug where minimum OSX/MacOS version wasn't defined, and set it to 10.6
v0.5.1, dated 2018-03-15
Fixes and improvements for Windows builds:
- properly evaluate variables 'PDDIR' and 'PDBINDIR' to find pd.dll
- define default path of 32 bit Pd on 64 bit Windows
- link C++ externals with standard C libs on Windows, they don't load otherwise
- strip installed Windows binaries by default
(issues #34, #39, #41, #42 respectively)
Warning for all platforms: variable 'PD_PATH' is no longer supported, use the
equivalent 'PDDIR'.
v0.5.0, dated 2018-01-23
Implement target architecture detection for Windows builds,
and set appropriate options for 32 and 64 bit (used to be for 32 bit only).
(feature, issue #37 #38, merge commit 215bf3e)
v0.4.4, dated 2016-11-22
Use variable 'system' when evaluating 'for{Linux,Darwin,Windows}'
(bugfix, issue #31, commit 2c14110)
v0.4.3, dated 2016-11-02
Replace flags '-fpic' by 'fPIC'.
(bugfix, issue #29, commit 426b38b)
v0.4.2, dated 2016-10-30
Fix issue where incorrect message about m_pd.h is given.
(bugfix, commit 2e13d8f)
v0.4.1, dated 2016-10-27
Respect cflag for minimum OSX version when defined by lib makefile.
(bugfix, pull request #22, commit 48c4127)
v0.4.0, dated 2016-10-14
Introduced path variables PDDIR, PDINCLUDEDIR, PDBINDIR, PDLIBDIR which can
also be defined in environment.
(feature, issue #27, commit b0dab72)
v0.3.1, dated 2016-10-13
Fix bug where pd.dll wouldn't be found.
(bugfix, commit a0c87be)
v0.3.0, dated 2016-10-09
Variable 'PD_PATH' introduced for pd-extended / pd-l2ork compatibility.
(feature, issue #26, commit 41e9743)
v0.2.8, dated 2016-10-09
Allow installed files to contain weird characters (notably '$').
(bugfix, pull request #20, commit 5b920b1)
v0.2.7, dated 2016-10-04
Remove all default pd search paths except vanilla's.
(discussion, issue #25, commit a6a89dc)
v0.2.6, dated 2016-09-20
Redefined dependency checking so it won't stall rebuilds on OSX.
(bugfix, issue #16, commit 9fd1795)
v0.2.5, dated 2016-06-26
Fixed dependency checking for object files in other directories.
(bugfix, commit f06e550)
v0.2.4, dated 2016-06-25
Fixed regression bug that disabled all dependency checking.
(bugfix, commit 1d7bb5e)
v0.2.3, dated 2016-03-29
Disabled dependency checking for OSX <= 10.5 because it stalled rebuilds.
(bugfix, issue #16, commit eb614fd)
v0.2.2, dated 2016-03-28
Removed target 'pre' because it forced rebuild of everything in 'all'.
(bugfix, issue #17, commit c989c8e)
v0.2.1, dated 2015-12-27
Implement / respect 'CPPFLAGS','CFLAGS'and 'LDFLAGS'.
(bugfix, issue #5, commit 98f3582)
v0.2.0, dated 2015-12-19
Added per-platform multiline defines 'forLinux', 'forDarwin', 'forWindows'.
(feature, pull request #9, commit 3946ea5)
v0.1.0, dated 2015-12-08
Added targets 'pre' and 'post' to automatically run before and after 'all'.
(feature, pull request #4, commit a5678ac)
v0.0.2, dated 2015-12-06
Improved methods for searching pd paths.
(bugfix, commit ed37e6b)
v0.0.1, dated 2015-10-31
Fixed expansion of variable 'lib.version'.
(bugfix, issue #1, commit 974b617)
v0.0.0, dated 2015-06-24
Initial version.
(commit 16517a2)
slip-0.1/pd-lib-builder/Makefile.pdlibbuilder 0000664 0000000 0000000 00000131452 14717202036 0021224 0 ustar 00root root 0000000 0000000 # Makefile.pdlibbuilder dated 2019-12-21
version = 0.7.0
# 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.
#
# Grab the newest version of Makefile.pdlibbuilder from
# https://github.com/pure-data/pd-lib-builder/
#
# GNU make version >= 3.81 required.
#
#
#=== characteristics ===========================================================
#
#
# - 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 files, and include
# Makefile.pdlibbuilder at the end of the Makefile. Like so:
#
# ________________________________________________________________________
#
# # Makefile for mylib
#
# lib.name = mylib
#
# class.sources = myclass1.c myclass2.c
#
# 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. 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 ===============================
#
#
# Variables available for definition in your library Makefile:
#
# - lib.name
# - lib.setup.sources
# - class.sources
# - common.sources
# - shared.sources
# - .class.sources
# - .class.ldflags
# - .class.ldlibs
# - cflags
# - ldflags
# - ldlibs
# - datafiles
# - datadirs
# - makefiles
# - makefiledirs
# - externalsdir
#
# Optional multiline defines evaluated per operating system:
#
# - forLinux
# - forDarwin
# - forWindows
#
# Variables available for your makefile or make command line:
#
# - make-lib-executable
# - suppress-wunused
#
# Path variables for make command line or environment:
#
# - PDDIR
# - PDINCLUDEDIR
# - PDBINDIR
# - PDLIBDIR
#
# Standard make variables for make command line or environment:
#
# - CPPFLAGS
# - CFLAGS
# - LDFLAGS
# - CC
# - CXX
# - INSTALL
# - STRIP
# - DESTDIR
#
# Optional user variables for make command line or environment:
#
# - PLATFORM
# - extension
# - floatsize
#
# Deprecated path variables:
#
# - pdincludepath
# - pdbinpath
# - objectsdir
#
#
#=== descriptions of Makefile.pdlibbuilder API variables =======================
#
#
# 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.
#
# lib.setup.sources:
# Source file(s) (C or C++) which must be compiled only when linking all classes
# into a single lib binary.
#
# class.sources:
# All sources files (C or C++) for which the condition holds that
# class name == source file basename.
#
# .class.sources:
# Source file(s) (C or C++) specific to class . Use this for
# multiple-source classes or when class name != source file basename.
#
# common.sources:
# Source file(s) which must be statically linked to each class in the library.
#
# 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.
#
# .class.ldflags and .class.ldlibs:
# Define ldflags resp. ldlibs specific to class . 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.
#
# forLinux, forDarwin, forWindows:
# Shorthand for 'variable definitions for Linux only' etc. Use like:
# define forLinux
# cflags += -DLINUX
# class.sources += linuxthing.c
# endef
#
# makefiles and makefiledirs:
# Extra makefiles or directories with makefiles that should be made in sub-make
# processes.
#
# 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 overridden with 'make-lib-executable=no' as command argument
# to build individual class executables (the Makefile.pdlibbuilder default.)
#
# 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.
#
# PDDIR:
# Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and
# PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin.
#
# PDINCLUDEDIR:
# Directory where Pd API m_pd.h should be found, and other Pd header files.
# Overrides the default search path.
#
# PDBINDIR:
# Directory where pd.dll should be found for linking (Windows only). Overrides
# the default search path.
#
# PDLIBDIR:
# Root directory for installation of Pd library directories. Overrides the
# default install location.
#
# DESTDIR:
# Prepended path component for staged install.
#
# PLATFORM:
# Target platform for cross compilation in the form of GNU triplet:
# cpu-vendor-os. Example: x86_64-w64-mingw32. This specifies the tool chain that
# pdlibbuilder will use, if installed and locatable. System and architecture
# will then be autodefined accordingly. In most cases no other variables need to
# be overridden.
#
# extension:
# Extension for the external to use. Example: m_amd64
# A sane default is picked, but it is useful if you want to provide
# co-installable externals for multiple platforms (for the same operating
# systems)
#
# floatsize:
# the size of the t_float in bits. Example: 32
# t_float are usually single precision (32bit), which is the default.
# For double precision use floatsize=64
# When building double precision externals, you will want to set the extension
# as well, e.g. extension=windows-amd64-64.dll (--.)
#
# CPPFLAGS:
# Preprocessor flags which are not strictly required for building.
#
# CFLAGS:
# Compiler flags which are not strictly required for building. Compiler flags
# defined by Makefile.pdlibbuilder for warning, optimization and architecture
# specification are overriden by CFLAGS.
#
# LDFLAGS:
# Linker flags which are not strictly required for building. Linker flags
# defined by Makefile.pdlibbuilder for architecture specification are overriden
# by LDFLAGS.
#
# CC and CXX:
# C and C++ compiler programs as defined in your build environment.
#
# INSTALL
# Definition of install program.
#
# STRIP
# Name of strip program. Default 'strip' can be overridden in cross compilation
# environments.
#
# objectsdir:
# Root directory for installation of Pd library directories, like PDLIBDIR but
# not overridable by environment. Supported for compatibility with pd-extended
# central makefile, but deprecated otherwise.
#
# pdincludepath, pdbinpath:
# As PDINCLUDEDIR and PDBINDIR but not overridable by environment. Deprecated
# as user variables.
#
#
#=== paths =====================================================================
#
#
# 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.
#
# Default search path for m_pd.h and other API header files is platform
# dependent, and overridable by PDINCLUDEDIR:
#
# Linux: /usr/include/pd
#
# OSX: /Applications/Pd*.app/Contents/Resources/src
#
# Windows: %PROGRAMFILES%/Pd/src
# %PROGRAMFILES(X86)%/Pd/src (32 bit builds on 64 bit Windows)
#
# Default search path for binary pd.dll (Windows), overridable by PDBINDIR
#
# %PROGRAMFILES%/Pd/bin
# %PROGRAMFILES(X86)%/Pd/bin (32 bit builds on 64 bit Windows)
#
# Default location to install pd libraries is platform dependent, and
# overridable by PDLIBDIR:
#
# Linux: /usr/local/lib/pd-externals
# OSX: ~/Library/Pd
# Windows: %APPDATA%/Pd
#
# https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files
# 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 ===================================================================
#
#
# all: build $(executables) plus optional post target
# post: target to build after $(executables)
# alldebug: build all with -g option turned on for debug symbols
# : force clean build of an individual class
# .pre: make preprocessor output file in current working directory
# .lst: make asm/source output file in current working directory
#
# install: install executables and data files
# clean: remove build products from source tree
#
# help: print help text
# vars: print makefile variables
# allvars: print all variables
# depend: print generated prerequisites
# dumpmachine: print compiler output of option '-dumpmachine'
# coffee: dummy target
#
# Variable $(executables) expands to class executables plus optional shared lib,
# or alternatively to single lib executable when make-lib-executable=true.
# Targets pre and post can be defined by library makefile. Make sure to include
# Makefile.pdlibbuilder first so default target all will not be redefined.
#
#
#=== 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 -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.
#
# '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 ' to print debug details of the make process.
# Use 'make -p ' to print make's database.
#
#
#=== TODO ======================================================================
#
#
# - decide whether to use -static-libgcc or shared dll in MinGW
# - cygwin support
# - android support
# - figure out how to handle '$' in filenames
# - add makefile template targets dpkg-source dist libdir distclean tags?
#
#
#=== end of documentation sections =============================================
#
#
################################################################################
################################################################################
################################################################################
# GNU make version 3.81 (2006) or higher is required because of the following:
# - function 'info'
# - variable '.DEFAULT_GOAL'
# force exit when make version is < 3.81
ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81)
$(error GNU make version 3.81 or higher is required)
endif
# 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.
externalsdir ?= ..
# variable you can use to check if Makefile.pdlibbuilder is already included
Makefile.pdlibbuilder = true
################################################################################
### target platform detection ##################################################
################################################################################
#=== target platform ===========================================================
# PLATFORM: optional user variable to define target platform for cross
# compilation. Redefine build tools accordingly. PLATFORM should match
# the exact target prefix of tools present in $PATH, like x86_64-w64-mingw32,
# x86_64-apple-darwin12 etc. Tool definitions are exported to ensure submakes
# will get the same.
ifneq ($(PLATFORM),)
ifneq ($(findstring darwin, $(PLATFORM)),)
export CC = $(PLATFORM)-cc
export CXX = $(PLATFORM)-c++
export CPP = $(PLATFORM)-cc
else
export CC = $(PLATFORM)-gcc
export CXX = $(PLATFORM)-g++
export CPP = $(PLATFORM)-cpp
endif
STRIP = $(PLATFORM)-strip
endif
# Let (native or cross-) compiler report target triplet and isolate individual
# words therein to facilitate later processing.
target.triplet := $(subst -, ,$(shell $(CC) -dumpmachine))
#=== operating system ==========================================================
# The following systems are defined: Linux, Darwin, Windows. GNU and
# GNU/kFreeBSD are treated as Linux to get the same options.
ifneq ($(filter linux gnu% kfreebsd, $(target.triplet)),)
system = Linux
endif
ifneq ($(filter darwin%, $(target.triplet)),)
system = Darwin
endif
ifneq ($(filter mingw% cygwin%, $(target.triplet)),)
system = Windows
endif
# evaluate possible system-specific multiline defines from library makefile
$(eval $(for$(system)))
# TODO: Cygwin, Android
#=== architecture ==============================================================
# The following CPU names can be processed by pdlibbuilder:
# i*86 Intel 32 bit
# x86_64 Intel 64 bit
# arm ARM 32 bit
# aarch64 ARM 64 bit
target.arch := $(firstword $(target.triplet))
################################################################################
### variables per platform #####################################################
################################################################################
#=== flags per floatsize == ====================================================
floatsize = 32
ifneq ($(filter-out 32,$(floatsize)),)
floatsize.flags = -DPD_FLOATSIZE=$(floatsize)
else
floatsize.flags =
endif
#=== flags per architecture ====================================================
# Set architecture-dependent cflags, mainly for Linux. For Mac and Windows,
# arch.c.flags are overriden below. To see gcc's default architecture flags:
# $ gcc -Q --help=target
# ARMv6: Raspberry Pi 1st gen, not detectable from target.arch
ifeq ($(shell uname -m), armv6l)
arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard
# ARMv7: Beagle, Udoo, RPi2 etc.
else ifeq ($(target.arch), arm)
arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard
# ARMv8 64 bit, not tested yet
else ifeq ($(target.arch), aarch64)
arch.c.flags = -mcpu=cortex-a53
# Intel 32 bit, build with SSE and SSE2 instructions
else ifneq ($(filter i%86, $(target.arch)),)
arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2
# Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions
else ifeq ($(target.arch), x86_64)
arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3
# if none of the above architectures detected
else
arch.c.flags =
endif
#=== flags and paths for Linux =================================================
ifeq ($(system), Linux)
prefix = /usr/local
libdir := $(prefix)/lib
pkglibdir = $(libdir)/pd-externals
pdincludepath := $(wildcard /usr/include/pd)
extension = pd_linux
cpp.flags := -DUNIX
c.flags := -fPIC
c.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
c.ldlibs := -lc -lm
cxx.flags := -fPIC -fcheck-new
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)
endif
#=== flags and paths for Darwin ================================================
# LLVM-clang doesn't support -fcheck-new, therefore this flag is only used when
# compiling with g++.
ifeq ($(system), Darwin)
pkglibdir = $(HOME)/Library/Pd
pdincludepath := $(firstword $(wildcard \
/Applications/Pd*.app/Contents/Resources/src))
extension = pd_darwin
cpp.flags := -DUNIX -DMACOSX -I /sw/include
c.flags :=
c.ldflags := -undefined suppress -flat_namespace -bundle
c.ldlibs := -lc
cxx.ldflags := -undefined suppress -flat_namespace -bundle
cxx.ldlibs := -lc
shared.extension = dylib
shared.ldflags = -dynamiclib -undefined dynamic_lookup \
-install_name @loader_path/$(shared.lib) \
-compatibility_version 1 -current_version 1.0
ifneq ($(filter %g++, $(CXX)),)
cxx.flags := -fcheck-new
endif
ifeq ($(extension), d_fat)
arch := i386 x86_64
else
arch := $(target.arch)
endif
ifneq ($(filter -mmacosx-version-min=%, $(cflags)),)
version.flag := $(filter -mmacosx-version-min=%, $(cflags))
else
version.flag = -mmacosx-version-min=10.6
endif
arch.c.flags := $(addprefix -arch , $(arch)) $(version.flag)
arch.ld.flags := $(arch.c.flags)
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 when probing for a path, and use double quotes
# when specifying a path in a command argument.
# Default paths in Mingw / Mingw-w64 environments. 'PROGRAMFILES' is standard
# location for builds with native architecture, 'ProgramFiles(x86)' for i686
# builds on x86_64 Windows (detection method by Lucas Cordiviola). Curly braces
# required because of parentheses in variable name.
ifeq ($(system), Windows)
pkglibdir := $(APPDATA)/Pd
ifeq ($(target.arch), i686)
programfiles := ${ProgramFiles(x86)}
else
programfiles := $(PROGRAMFILES)
endif
pdbinpath := $(programfiles)/Pd/bin
pdincludepath := $(programfiles)/Pd/src
endif
# Store default path to pd.dll in PDBINDIR if the latter is not user-defined.
# For include path this is done in the platform-independent paths section below,
# but for PDBINDIR it is done here so ld flags can be evaluated as immediate
# variables.
ifeq ($(system), Windows)
ifdef PDDIR
PDBINDIR := $(PDDIR)/bin
endif
PDBINDIR ?= $(pdbinpath)
endif
# TODO: decide whether -mms-bitfields should be specified.
ifeq ($(system), Windows)
cpp.flags := -DMSW -DNT
ifeq ($(target.arch), i686)
arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse
else ifeq ($(target.arch), x86_64)
cpp.flags := -DMSW -DNT -DPD_LONGINTTYPE=__int64
arch.c.flags := -march=core2 -msse -msse2 -msse3 -mfpmath=sse
else
arch.c.flags =
endif
extension = dll
c.flags :=
c.ldflags := -static-libgcc -shared \
-Wl,--enable-auto-import "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
c.ldlibs :=
cxx.flags := -fcheck-new
cxx.ldflags := -static-libgcc -static-libstdc++ -shared \
-Wl,--enable-auto-import "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
cxx.ldlibs :=
shared.extension = dll
shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
stripflags = --strip-all
endif
#=== paths =====================================================================
# Platform-dependent default paths are specified above, but overridable.
# Path variables in upper case can be defined as make command argument or in the
# environment. Variable 'objectsdir' is supported for compatibility with
# the build system that pd-l2ork has inherited from pd-extended.
PDINCLUDEDIR ?= $(pdincludepath)
PDLIBDIR ?= $(firstword $(objectsdir) $(pkglibdir))
ifdef PDDIR
PDINCLUDEDIR := $(wildcard $(PDDIR)/src)
endif
# base path where all components of the lib will be installed by default
installpath := $(DESTDIR)$(PDLIBDIR)/$(lib.name)
# check if include path 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, $(PDINCLUDEDIR)), $(PDINCLUDEDIR))
#=== accumulated build flags ===================================================
# From GNU make docs: 'Users expect to be able to specify CFLAGS freely
# themselves.' So we use CFLAGS to define options which are not strictly
# required for compilation: optimizations, architecture specifications, and
# warnings. CFLAGS can be safely overriden using a make command argument.
# Variables cflags, ldflags and ldlibs may be defined in including makefile.
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
CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags)
# preprocessor flags
cpp.flags := -DPD -I "$(PDINCLUDEDIR)" $(floatsize.flags) $(cpp.flags) $(CPPFLAGS)
# flags for dependency checking (cflags from makefile may define -I options)
depcheck.flags := $(cpp.flags) $(cflags)
# architecture specifications for linker are overridable by LDFLAGS
LDFLAGS := $(arch.ld.flags)
# now add the same ld flags to shared dynamic lib
shared.ldflags += $(LDFLAGS)
# accumulated flags for C compiler / linker
c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS)
c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS)
c.ldlibs := $(c.ldlibs) $(ldlibs)
# accumulated flags for C++ compiler / linker
cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS)
cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS)
cxx.ldlibs := $(cxx.ldlibs) $(ldlibs)
################################################################################
### variables: library name and version ########################################
################################################################################
# strip possibles spaces from lib.name, they mess up calculated file names
lib.name := $(strip $(lib.name))
# if meta file exists, check library version
metafile := $(wildcard $(lib.name)-meta.pd)
ifdef metafile
lib.version := $(shell sed -n \
's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \
$(metafile))
endif
################################################################################
### variables: files ###########################################################
################################################################################
object.extension = $(extension).o
#=== sources ===================================================================
# (re)define .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 .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 .$(object.extension), $(basename $(classes.sources)))
common.objects := $(addsuffix .$(object.extension), $(basename $(common.sources)))
shared.objects := $(addsuffix .$(object.extension), $(basename $(shared.sources)))
lib.setup.objects := $(addsuffix .$(object.extension), $(basename $(lib.setup.sources)))
all.objects = $(classes.objects) $(common.objects) $(shared.objects) \
$(lib.setup.objects)
#=== executables ===============================================================
# construct class executable names from class names
classes.executables := $(addsuffix .$(extension), $(classes))
# Construct shared lib executable name if shared sources are defined.
# If extension does not end with shared extension, use both to facilitate co-
# installation for different platforms, like .m_i386.dll and .linux-amd64-32.so
ifdef shared.sources
ifneq ($(filter %.$(shared.extension), .$(extension)), )
# $(extension) already ends with $(shared.extension), no need to duplicate it
shared.lib = lib$(lib.name).$(extension)
else
shared.lib = lib$(lib.name).$(extension).$(shared.extension)
endif
else
shared.lib :=
endif
################################################################################
### variables: tools ###########################################################
################################################################################
# aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument
compile-c := $(CC)
compile-cxx := $(CXX)
################################################################################
### checks #####################################################################
################################################################################
# At this point most variables are defined. Now do some checks and info's
# before rules begin.
# print Makefile.pdlibbuilder version before possible termination
$(info ++++ info: using Makefile.pdlibbuilder version $(version))
# Terminate if target triplet remained empty, to avoid all sorts of confusing
# scenarios and spurious bugs.
ifeq ($(target.triplet),)
$(error Command "$(CC) -dumpmachine" did not return a target triplet, \
needed for a build. \
Is compiler "$(CC)" installed in your PATH? ($(PATH)). \
Does compiler "$(CC)" support option "-dumpmachine"?)
endif
# 'forward declaration' of default target, needed to do checks
all:
# To avoid unpredictable results, make sure the default target is not redefined
# by including makefile.
ifneq ($(.DEFAULT_GOAL), all)
$(error Default target must be 'all'.)
endif
# find out which target(s) will be made
ifdef MAKECMDGOALS
goals := $(MAKECMDGOALS)
else
goals := all
endif
# store path to Pd API m_pd.h if it is found
ifdef PDINCLUDEDIR
mpdh := $(shell ls "$(PDINCLUDEDIR)/m_pd.h")
endif
# store path to pd.dll; if not found, ls will give a useful error
ifeq ($(system), Windows)
pddll := $(shell ls "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll")
endif
# when making target all, check if m_pd.h is found and print info about it
ifeq ($(goals), all)
$(if $(mpdh), \
$(info ++++ info: using Pd API $(mpdh)), \
$(warning Where is Pd API m_pd.h? Do 'make help' for info.))
endif
# print target info
$(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: \
installpath is '$(installpath)'))
#=== define executables ========================================================
# By default we build class executables, and optionally a shared dynamic link
# lib. When make-lib-executable=yes we build all classes into a single lib
# executable, on the condition that variable lib.setup.sources is defined.
ifeq ($(make-lib-executable),yes)
$(if $(lib.setup.sources), ,\
$(error Can not build library blob because lib.setup.sources is undefined))
executables := $(lib.name).$(extension)
else
executables := $(classes.executables) $(shared.lib)
endif
################################################################################
### rules: special targets #####################################################
################################################################################
# Disable built-in rules. If some target can't be built with the specified
# rules, it should not be built at all.
MAKEFLAGS += --no-builtin-rules
.PRECIOUS:
.SUFFIXES:
.PHONY: all post build-lib \
$(classes) $(makefiledirs) $(makefiles) \
install install-executables install-datafiles install-datadirs \
force clean vars allvars depend help
################################################################################
### rules: build targets #######################################################
################################################################################
# Target all forces the build of targets [$(executables) post] in
# deterministic order. Target $(executables) builds class executables plus
# optional shared lib or alternatively a single lib executable when
# make-lib-executable=true. Target post is optionally defined by
# library makefile.
all: post
post: $(executables)
all:
$(info ++++info: target all in lib $(lib.name) completed)
# build all with -g option turned on for debug symbols
alldebug: c.flags += -g
alldebug: cxx.flags += -g
alldebug: all
#=== class executable ==========================================================
# recipe for linking objects in class executable
# argument $1 = compiler type (c or cxx)
# argument $2 = class basename
define link-class
$(compile-$1) \
$($1.ldflags) $($2.class.ldflags) \
-o $2.$(extension) \
$(addsuffix .$(object.extension), $(basename $($2.class.sources))) \
$(addsuffix .$(object.extension), $(basename $(common.sources))) \
$($1.ldlibs) $($2.class.ldlibs) $(shared.lib)
endef
# general rule for linking object files in class executable
%.$(extension): $(shared.lib)
$(info ++++ info: linking objects in $@ for lib $(lib.name))
$(if $(filter %.cc %.cpp, $($*.class.sources)), \
$(call link-class,cxx,$*), \
$(call link-class,c,$*))
#=== library blob ==============================================================
# build all classes into single executable
build-lib: $(lib.name).$(extension)
$(info ++++ info: library blob $(lib.name).$(extension) completed)
# recipe for linking objects in lib executable
# argument $1 = compiler type (c or cxx)
define link-lib
$(compile-$1) \
$($1.ldflags) $(lib.ldflags) \
-o $(lib.name).$(extension) $(all.objects) \
$($1.ldlibs) $(lib.ldlibs)
endef
# rule for linking objects in lib executable
# declared conditionally to avoid name clashes
ifeq ($(make-lib-executable),yes)
$(lib.name).$(extension): $(all.objects)
$(if $(filter %.cc %.cpp, $(all.sources)), \
$(call link-lib,cxx), \
$(call link-lib,c))
endif
#=== shared dynamic lib ========================================================
# recipe for linking objects in shared executable
# argument $1 = compiler type (c or cxx)
define link-shared
$(compile-$1) \
$(shared.ldflags) \
-o $(shared.lib) $(shared.objects) \
$($1.ldlibs) $(shared.ldlibs)
endef
# rule for linking objects in shared executable
# build recipe is in macro 'link-shared'
$(shared.lib): $(shared.objects)
$(info ++++ info: linking objects in shared lib $@)
$(if $(filter %.cc %.cpp, $(shared.sources)), \
$(call link-shared,cxx), \
$(call link-shared,c))
#=== object files ==============================================================
# 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) \
$($1.flags) \
-o $@ -c $<
endef
# Three rules to create .o files. These are double colon 'terminal' rules,
# meaning they are the last in a rules chain.
%.$(object.extension):: %.c
$(call make-object-file,c)
%.$(object.extension):: %.cc
$(call make-object-file,cxx)
%.$(object.extension):: %.cpp
$(call make-object-file,cxx)
#=== explicit prerequisites for class executables ==============================
# For class executables, prerequisite rules are declared in run time. Target
# 'depend' prints these rules for debugging purposes.
# declare explicit prerequisites rule like 'class: class.extension'
# argument $v is class basename
define declare-class-target
$v: $v.$(extension)
endef
# declare explicit prerequisites rule like 'class.extension: object1.o object2.o'
# argument $v is class basename
define declare-class-executable-target
$v.$(extension): $(addsuffix .$(object.extension), $(basename $($v.class.sources))) \
$(addsuffix .$(object.extension), $(basename $(common.sources)))
endef
# evaluate explicit prerequisite rules for all classes
$(foreach v, $(classes), $(eval $(declare-class-target)))
$(foreach v, $(classes), $(eval $(declare-class-executable-target)))
#=== implicit prerequisites for class executables ==============================
# Evaluating implicit prerequisites (header files) with help from the
# preprocessor is 'expensive' so this is done conditionally and selectively.
# Note that it is also possible to trigger a build via install targets, in
# which case implicit prerequisites are not checked.
# When the Pd include path contains spaces it will mess up the implicit
# prerequisites rules.
disable-dependency-tracking := $(strip $(pdincludepathwithspaces))
ifndef disable-dependency-tracking
must-build-everything := $(filter all, $(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)
# dir is explicitly added because option -MM strips it by default
define declare-object-target
$(dir $1)$(patsubst %.o:,%.$(object.extension):,$(filter %.o: %.h, $(shell $(CPP) $(depcheck.flags) -MM $1))) $(MAKEFILE_LIST)
endef
# evaluate implicit prerequisite rules when rebuilding everything
ifdef must-build-everything
$(if $(wildcard $(all.objects)), \
$(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \
$(foreach v, $(all.sources), $(eval $(call declare-object-target, $v))))
endif
# evaluate implicit prerequisite rules when selectively building classes
ifdef must-build-class
$(foreach v, $(must-build-sources), \
$(eval $(call declare-object-target, $v)))
$(foreach v, $(shared.sources), \
$(eval $(call declare-object-target, $v)))
endif
################################################################################
### rules: preprocessor and assembly files #####################################
################################################################################
# Preprocessor and assembly output files for bug tracing etc. They are not part
# of the build processes for executables. By default these files are created in
# the current working directory. Dependency tracking is not performed, the build
# is forced instead to make sure it's up to date.
force:
#=== preprocessor file =========================================================
# make preprocessor output file with extension .pre
# argument $1 = compiler type (c or cxx)
define make-preprocessor-file
$(info ++++ info: making preprocessor output file $(notdir $*.pre) \
in current working directory)
$(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre)
endef
%.pre:: %.c force
$(call make-preprocessor-file,c)
%.pre:: %.cc force
$(call make-preprocessor-file,cxx)
%.pre:: %.cpp force
$(call make-preprocessor-file,cxx)
#=== assembly file =============================================================
# make C / assembly interleaved output file with extension .lst
# argument $1 = compiler type (c or cxx)
define make-assembly-file
$(info ++++ info: making assembly output file $(notdir $*.lst) \
in current working directory)
$(compile-$1) \
-c -Wa,-a,-ad -fverbose-asm \
$($1.flags) \
$< > $(notdir $*.lst)
endef
%.lst:: %.c force
$(call make-assembly-file,c)
%.lst:: %.cc force
$(call make-assembly-file,cxx)
%.lst:: %.cpp force
$(call make-assembly-file,cxx)
################################################################################
### rules: installation targets ################################################
################################################################################
#=== strip =====================================================================
# Stripping of installed binaries will only be done when variable 'stripflags'
# is defined non-empty. No default definition is provided except for Windows
# where the unstripped binaries are large, especially in the case of Mingw-w64.
# Note: while stripping all symbols ('-s' or '--strip-all') is possible for
# Linux and Windows, in the case of OSX only non-global symbols can be stripped
# (option '-x' or '--discard-all').
# Make definition of strip command overridable so it can be defined in an
# environment for cross-compilation.
STRIP ?= strip
# Commands in 'strip-executables' will be executed conditionally in the rule for
# target 'install-executables'.
strip-executables = cd "$(installpath)" && \
$(foreach v, $(executables), $(STRIP) $(stripflags) '$v';)
#=== install ===================================================================
# 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))
datadirs := $(strip $(datadirs))
# Do not make any install sub-target with empty variable definition because the
# install program would exit with an error.
install: $(if $(executables), install-executables)
install: $(if $(datafiles), install-datafiles)
install: $(if $(datadirs), install-datadirs)
install-executables: all
$(INSTALL_DIR) -v "$(installpath)"
$(foreach v, $(executables), \
$(INSTALL_PROGRAM) '$v' "$(installpath)";)
$(info ++++ info: executables of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
$(if $(stripflags), $(strip-executables),)
install-datafiles: all
$(INSTALL_DIR) -v "$(installpath)"
$(foreach v, $(datafiles), \
$(INSTALL_DATA) '$(v)' "$(installpath)";)
$(info ++++ info: data files of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
install-datadirs: all
$(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))
################################################################################
### rules: distribution targets ################################################
################################################################################
# TODO
# These targets are implemented in Makefile Template, but I have to figure out
# how to do it under the not-so-strict conditions of Makefile.pdlibbuilder.
# make source package
dist:
@echo "target dist not yet implemented"
# make Debian source package
dpkg-source:
@echo "target dpkg-source not yet implemented"
$(ORIGDIR):
$(DISTDIR):
################################################################################
### rules: clean targets #######################################################
################################################################################
# delete build products from build tree
clean:
rm -f $(all.objects)
rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib)
rm -f *.pre *.lst
# remove distribution directories and tarballs from build tree
distclean: clean
@echo "target distclean not yet implemented"
################################################################################
### rules: submake targets #####################################################
################################################################################
# Iterate over sub-makefiles or makefiles in other directories.
# 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. Useful when you want to quickly find
# out which sub-makes from a large set will succeed.
ifeq ($(continue-make),yes)
continue = || true
endif
# These targets will trigger sub-make processes for entries in 'makefiledirs'
# and 'makefiles'.
all alldebug install clean distclean dist dkpg-source: \
$(makefiledirs) $(makefiles)
# this expands to identical rules for each entry in 'makefiledirs'
$(makefiledirs):
$(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue)
# this expands to identical rules for each entry in 'makefiles'
$(makefiles):
$(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue)
################################################################################
### rules: convenience targets #################################################
################################################################################
#=== show variables ============================================================
# Several 'function' macro's cause errors when expanded within a rule or without
# proper arguments. Variables which are set with the define directive are only
# shown by name for that reason.
functions = \
add-class-source \
declare-class-target \
declare-class-executable-target \
declare-object-target \
link-class \
link-lib \
link-shared \
make-object-file \
make-preprocessor-file \
make-assembly-file
# show variables from makefiles
vars:
$(info ++++ info: showing makefile variables:)
$(foreach v,\
$(sort $(filter-out $(functions) functions, $(.VARIABLES))),\
$(if $(filter file, $(origin $v)),\
$(info variable $v = $($v))))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
# show all variables
allvars:
$(info ++++ info: showing default, automatic and makefile variables:)
$(foreach v, \
$(sort $(filter-out $(functions) functions, $(.VARIABLES))), \
$(info variable ($(origin $v)) $v = $($v)))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
#=== show dependencies =========================================================
# show generated prerequisites rules
depend:
$(info ++++ info: generated prerequisite rules)
$(foreach v, $(classes), $(info $(declare-class-target)))
$(foreach v, $(classes), $(info $(declare-class-executable-target)))
$(foreach v, $(all.sources), $(info $(call declare-object-target, $v)))
@echo
#=== show help text ============================================================
# brief info about targets and paths
ifdef mpdh
mpdhinfo := $(mpdh)
else
mpdhinfo := m_pd.h was not found. Is Pd installed?
endif
help:
@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 " $(mpdhinfo)"
@echo " You may specify your preferred Pd include directory as argument"
@echo " to the make command, like 'PDINCLUDEDIR=path/to/pd/src'."
@echo
@echo " Path for installation of your libdir(s):"
@echo " $(PDLIBDIR)"
@echo " Alternatively you may specify your path for installation as argument"
@echo " to the make command, like 'PDLIBDIR=path/to/pd-externals'."
@echo
@echo " Default paths are listed in the doc sections in Makefile.pdlibbuilder."
@echo
#=== platform test =============================================================
# This target can be used to test if the compiler for specified PLATFORM is
# correctly defined and available.
dumpmachine:
@$(CC) -dumpmachine
#=== dummy target ==============================================================
coffee:
@echo "Makefile.pdlibbuilder: Can not make coffee. Sorry."
################################################################################
### end of rules sections ######################################################
################################################################################
# for syntax highlighting in vim and github
# vim: set filetype=make:
slip-0.1/pd-lib-builder/README.md 0000664 0000000 0000000 00000013146 14717202036 0016402 0 ustar 00root root 0000000 0000000
### Makefile.pdlibbuilder ###
Helper makefile for Pure Data external libraries. Written by Katja Vetter
March-June 2015 for the public domain and since then developed as a Pd
community project. No warranties. Inspired by Hans Christoph Steiner's Makefile
Template and Stephan Beal's ShakeNMake.
GNU make version >= 3.81 required.
### characteristics ###
* defines build settings based on autodetected target platform
* 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 files, and include
Makefile.pdlibbuilder at the end of the Makefile. Like so:
# Makefile for mylib
lib.name = mylib
class.sources = myclass1.c myclass2.c
datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt
PDLIBBUILDER_DIR=.
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
For files in class.sources it is assumed that class name == 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, read the documentation sections in Makefile.pdlibbuilder.
### paths ###
Makefile.pdlibbuilder >= v0.4.0 supports pd path variables which can be
defined not only as make command argument but also in the environment, to
override platform-dependent defaults:
PDDIR:
Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and
PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin.
PDINCLUDEDIR:
Directory where Pd API m_pd.h should be found, and other Pd header files.
Overrides the default search path.
PDBINDIR:
Directory where pd.dll should be found for linking (Windows only). Overrides
the default search path.
PDLIBDIR:
Root directory for installation of Pd library directories. Overrides the
default install location.
### platform detection and predefined variables ###
Makefile.pdlibbuilder tries to detect architecture and operating system in
order to define platform-specific variables. Since v0.6.0 we let the compiler
report target platform, rather than taking the build machine as reference. This
simplifies cross compilation. The kind of build options that are predefined:
- optimizations useful for realtime DSP processing
- options strictly required for the platform
- options to make the build work accross a range of CPU's and OS versions
The exact choice and definition predefined variables changes over time, as new
platforms arrive and older platforms become obsolete. The easiest way to get an
overview for your platform is by checking the flags categories in the output of
target `vars`. Variables written in capitals (like `CFLAGS`) are intentionally
exposed as user variables, although technically all makefile variables can be
overridden by make command arguments.
### specific language versions ###
Makefile.pdlibbuilder handles C and C++, but can not detect if your code uses
features of a specific version (like C99, C++11, C++14 etc.). In such cases
your makefile should specify that version as compiler option:
cflags = -std=c++11
Also you may need to be explicit about minimum OSX version. For example, C++11
needs OSX 10.9 or higher:
define forDarwin
cflags = -mmacosx-version-min=10.9
endef
### documentation ###
This README.md provides only basic information. A large comment section inside
Makefile.pdlibbuilder lists and explains the available user variables, default
paths, and targets. The internal documentation reflects the exact functionality
of the particular version. For suggestions about project maintenance and
advanced compilation see tips-tricks.md.
### versioning ###
The project is versioned in MAJOR.MINOR.BUGFIX format (see http://semver.org),
and maintained at https://github.com/pure-data/pd-lib-builder. Pd lib developers
are invited to regulary check for updates, and to contribute and discuss
improvements here. If you really need to distribute a personalized version with
your library, rename Makefile.pdlibbuilder to avoid confusion.
### examples ###
The list of projects using pd-lib-builder can be helpful if you are looking for
examples, from the simplest use case to more complex implementations.
- helloworld: traditional illustration of simplest use case
- pd-windowing: straightforward real world use case of a small library
- pd-nilwind / pd-cyclone: more elaborate source tree
- zexy: migrated from autotools to pd-lib-builder
### projects using pd-lib-builder ###
non-exhaustive list
https://github.com/pure-data/helloworld
https://github.com/electrickery/pd-nilwind
https://github.com/electrickery/pd-maxlib
https://github.com/electrickery/pd-sigpack
https://github.com/electrickery/pd-tof
https://github.com/electrickery/pd-windowing
https://github.com/electrickery/pd-smlib
https://github.com/porres/pd-cyclone
https://github.com/porres/pd-else
https://github.com/porres/pd-psycho
https://git.iem.at/pd/comport
https://git.iem.at/pd/hexloader
https://git.iem.at/pd/iemgui
https://git.iem.at/pd/iemguts
https://git.iem.at/pd/iemlib
https://git.iem.at/pd/iemnet
https://git.iem.at/pd/iem_ambi
https://git.iem.at/pd/iem_tab
https://git.iem.at/pd/iem_adaptfilt
https://git.iem.at/pd/iem_roomsim
https://git.iem.at/pd/iem_spec2
https://git.iem.at/pd/mediasettings
https://git.iem.at/pd/zexy
https://git.iem.at/pd-gui/punish
https://github.com/residuum/PuRestJson
https://github.com/libpd/abl_link
https://github.com/wbrent/timbreID
https://github.com/MetaluNet/moonlib
slip-0.1/pd-lib-builder/tests/ 0000775 0000000 0000000 00000000000 14717202036 0016260 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/Makefile 0000664 0000000 0000000 00000000542 14717202036 0017721 0 ustar 00root root 0000000 0000000 # recursively build all example projects in the subdirectories
makefiledirs := $(filter-out _%, $(dir $(wildcard */Makefile)))
PDLIBBUILDER_DIR = ../
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
buildcheck installcheck: $(makefiledirs)
runcheck:
PDBINDIR=$(PDBINDIR) ./test-patches.sh $(makefiledirs:%=%*.pd)
projects:
@echo $(makefiledirs)
slip-0.1/pd-lib-builder/tests/_template_/ 0000775 0000000 0000000 00000000000 14717202036 0020371 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/_template_/Makefile 0000664 0000000 0000000 00000001423 14717202036 0022031 0 ustar 00root root 0000000 0000000 # Makefile to build class '_template_' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = _template_
# input source file (class name == source file basename)
class.sources = _template_.c
# all extra files to be included in binary distribution of the library
datafiles = _template_-help.pd _template_-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e _template_.$(extension)
installcheck: install
test -e $(installpath)/_template_.$(extension)
slip-0.1/pd-lib-builder/tests/_template_/_template_-help.pd 0000664 0000000 0000000 00000000136 14717202036 0023755 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X obj 143 125 _template_;
#X msg 143 93 7;
#X connect 1 0 0 0;
slip-0.1/pd-lib-builder/tests/_template_/_template_-meta.pd 0000664 0000000 0000000 00000000521 14717202036 0023751 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "_template_" external.;
#X text 10 30 NAME _template_;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/_template_/_template_.c 0000664 0000000 0000000 00000000663 14717202036 0022653 0 ustar 00root root 0000000 0000000 #include
t_class*_template__class;
static void _template__float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*_template__new(void) {
return pd_new(_template__class);
}
void _template__setup(void) {
post("%s", __FUNCTION__);
_template__class = class_new(gensym("_template_"), _template__new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(_template__class, _template__float);
}
slip-0.1/pd-lib-builder/tests/make-from-template.sh 0000775 0000000 0000000 00000001574 14717202036 0022315 0 ustar 00root root 0000000 0000000 #!/bin/sh
template=_template_
template_dir=${0%/*}/${template}
outdir=$1
outdir=${outdir%/}
outname=${outdir##*/}
usage() {
cat 1>&2 <
creates a new test-directory from _template_;
must not exist yet.
EOL
if [ "x$@" != "x" ]; then
echo
echo " $@" 1>&2
fi
exit 1
}
if [ "x${outdir}" = "x" ]; then
usage
fi
if [ -d "${outdir}" ]; then
usage "output directory '${outdir}' already exists!"
fi
if [ ! -d "${template_dir}" ]; then
echo "unable to find '${template_dir}'" 1>&2
exit 1
fi
mkdir -p "${outdir}" || usage "unable to create '${outdir}'!"
rmdir "${outdir}"
cp -r "${template_dir}" "${outdir}"
find "${outdir}" -type f -exec sed -e "s|${template}|${outname}|g" -i {} +
for f in "${outdir}"/*; do
g=$(echo $f | sed -e "s|${template}|${outname}|g")
if [ "x${f}" != "x${g}" ]; then
mv "${f}" "${g}"
fi
done
slip-0.1/pd-lib-builder/tests/multifor/ 0000775 0000000 0000000 00000000000 14717202036 0020121 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/multifor/Makefile 0000664 0000000 0000000 00000002141 14717202036 0021557 0 ustar 00root root 0000000 0000000 # Makefile to build class 'multifor' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = multifor
# input source file (class name == source file basename)
class.sources = multiforA.c
# additional classes
define forLinux
class.sources += multiforB.c
endef
define forDarwin
class.sources += multiforB.c
endef
define forWindows
class.sources += multiforB.c
endef
# all extra files to be included in binary distribution of the library
datafiles = multifor-help.pd multifor-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e multiforA.$(extension)
test -e multiforB.$(extension)
installcheck: install
test -e $(installpath)/multiforA.$(extension)
test -e $(installpath)/multiforB.$(extension)
test -e $(installpath)/multifor-help.pd
test -e $(installpath)/multifor-meta.pd
slip-0.1/pd-lib-builder/tests/multifor/README.md 0000664 0000000 0000000 00000000525 14717202036 0021402 0 ustar 00root root 0000000 0000000 multifor
========
minimal pd-lib-builder project that shows how to compile
a library that contains multiple C-files that are compiled into
multiple binaries each containing a different Pd-objectclass.
some of the objectclasses are only compiled on specific platforms.
this is a special case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/multifor/multifor-help.pd 0000664 0000000 0000000 00000000235 14717202036 0023235 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X msg 143 93 7;
#X obj 143 125 multiforA;
#X obj 223 125 multiforB;
#X msg 223 93 12;
#X connect 0 0 1 0;
#X connect 3 0 2 0;
slip-0.1/pd-lib-builder/tests/multifor/multifor-meta.pd 0000664 0000000 0000000 00000000515 14717202036 0023234 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "multifor" external.;
#X text 10 30 NAME multifor;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/multifor/multiforA.c 0000664 0000000 0000000 00000000651 14717202036 0022231 0 ustar 00root root 0000000 0000000 #include
t_class*multiforA_class;
static void multiforA_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multiforA_new(void) {
return pd_new(multiforA_class);
}
void multiforA_setup(void) {
post("%s", __FUNCTION__);
multiforA_class = class_new(gensym("multiforA"), multiforA_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multiforA_class, multiforA_float);
}
slip-0.1/pd-lib-builder/tests/multifor/multiforB.c 0000664 0000000 0000000 00000000651 14717202036 0022232 0 ustar 00root root 0000000 0000000 #include
t_class*multiforB_class;
static void multiforB_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multiforB_new(void) {
return pd_new(multiforB_class);
}
void multiforB_setup(void) {
post("%s", __FUNCTION__);
multiforB_class = class_new(gensym("multiforB"), multiforB_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multiforB_class, multiforB_float);
}
slip-0.1/pd-lib-builder/tests/multilib/ 0000775 0000000 0000000 00000000000 14717202036 0020101 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/multilib/Makefile 0000664 0000000 0000000 00000001714 14717202036 0021544 0 ustar 00root root 0000000 0000000 # Makefile to build class 'multilib' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = multilib
make-lib-executable=yes
# input source file (class name == source file basename)
class.sources = multilibA.c multilibB.c
# glue for building a multi-object library
lib.setup.sources = $(lib.name).c
# all extra files to be included in binary distribution of the library
datafiles = multilib-help.pd multilib-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e multilib.$(extension)
installcheck: install
test -e $(installpath)/multilib.$(extension)
test -e $(installpath)/multilib-help.pd
test -e $(installpath)/multilib-meta.pd
slip-0.1/pd-lib-builder/tests/multilib/README.md 0000664 0000000 0000000 00000000406 14717202036 0021360 0 ustar 00root root 0000000 0000000 multilib
========
minimal pd-lib-builder project that shows how to compile
a library that contains multiple C-files that are compiled into
a single binary containing different Pd-objectclasses.
this is the general case of the single-binary library structure.
slip-0.1/pd-lib-builder/tests/multilib/multilib-help.pd 0000664 0000000 0000000 00000000334 14717202036 0023175 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X declare -lib multilib;
#X msg 143 93 7;
#X obj 143 125 multilibA;
#X obj 223 125 multilibB;
#X msg 223 93 12;
#X obj 136 47 declare -lib multilib;
#X connect 0 0 1 0;
#X connect 3 0 2 0;
slip-0.1/pd-lib-builder/tests/multilib/multilib-meta.pd 0000664 0000000 0000000 00000000515 14717202036 0023174 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "multiple" external.;
#X text 10 30 NAME multiple;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/multilib/multilib.c 0000664 0000000 0000000 00000000202 14717202036 0022060 0 ustar 00root root 0000000 0000000
void multilibA_setup(void);
void multilibB_setup(void);
void multilib_setup(void) {
multilibA_setup();
multilibB_setup();
}
slip-0.1/pd-lib-builder/tests/multilib/multilibA.c 0000664 0000000 0000000 00000000651 14717202036 0022171 0 ustar 00root root 0000000 0000000 #include
t_class*multilibA_class;
static void multilibA_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multilibA_new(void) {
return pd_new(multilibA_class);
}
void multilibA_setup(void) {
post("%s", __FUNCTION__);
multilibA_class = class_new(gensym("multilibA"), multilibA_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multilibA_class, multilibA_float);
}
slip-0.1/pd-lib-builder/tests/multilib/multilibB.c 0000664 0000000 0000000 00000000651 14717202036 0022172 0 ustar 00root root 0000000 0000000 #include
t_class*multilibB_class;
static void multilibB_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multilibB_new(void) {
return pd_new(multilibB_class);
}
void multilibB_setup(void) {
post("%s", __FUNCTION__);
multilibB_class = class_new(gensym("multilibB"), multilibB_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multilibB_class, multilibB_float);
}
slip-0.1/pd-lib-builder/tests/multiple/ 0000775 0000000 0000000 00000000000 14717202036 0020113 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/multiple/Makefile 0000664 0000000 0000000 00000001665 14717202036 0021563 0 ustar 00root root 0000000 0000000 # Makefile to build class 'multiple' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = multiple
# input source file (class name == source file basename)
class.sources = multipleA.c multipleB.c
# all extra files to be included in binary distribution of the library
datafiles = multiple-help.pd multiple-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e multipleA.$(extension)
test -e multipleB.$(extension)
installcheck: install
test -e $(installpath)/multipleA.$(extension)
test -e $(installpath)/multipleB.$(extension)
test -e $(installpath)/multiple-help.pd
test -e $(installpath)/multiple-meta.pd
slip-0.1/pd-lib-builder/tests/multiple/README.md 0000664 0000000 0000000 00000000424 14717202036 0021372 0 ustar 00root root 0000000 0000000 multiple
========
minimal pd-lib-builder project that shows how to compile
a library that contains multiple C-files that are compiled into
multiple binaries each containing a different Pd-objectclass.
this is the general case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/multiple/multiple-help.pd 0000664 0000000 0000000 00000000235 14717202036 0023221 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X msg 143 93 7;
#X obj 143 125 multipleA;
#X obj 223 125 multipleB;
#X msg 223 93 12;
#X connect 0 0 1 0;
#X connect 3 0 2 0;
slip-0.1/pd-lib-builder/tests/multiple/multiple-meta.pd 0000664 0000000 0000000 00000000515 14717202036 0023220 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "multiple" external.;
#X text 10 30 NAME multiple;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/multiple/multipleA.c 0000664 0000000 0000000 00000000651 14717202036 0022215 0 ustar 00root root 0000000 0000000 #include
t_class*multipleA_class;
static void multipleA_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multipleA_new(void) {
return pd_new(multipleA_class);
}
void multipleA_setup(void) {
post("%s", __FUNCTION__);
multipleA_class = class_new(gensym("multipleA"), multipleA_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multipleA_class, multipleA_float);
}
slip-0.1/pd-lib-builder/tests/multiple/multipleB.c 0000664 0000000 0000000 00000000651 14717202036 0022216 0 ustar 00root root 0000000 0000000 #include
t_class*multipleB_class;
static void multipleB_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multipleB_new(void) {
return pd_new(multipleB_class);
}
void multipleB_setup(void) {
post("%s", __FUNCTION__);
multipleB_class = class_new(gensym("multipleB"), multipleB_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multipleB_class, multipleB_float);
}
slip-0.1/pd-lib-builder/tests/multiplexx/ 0000775 0000000 0000000 00000000000 14717202036 0020473 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/multiplexx/Makefile 0000664 0000000 0000000 00000001717 14717202036 0022141 0 ustar 00root root 0000000 0000000 # Makefile to build class 'multiplexx' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = multiplexx
# input source file (class name == source file basename)
class.sources = multiplexxA.cpp multiplexxB.c
# all extra files to be included in binary distribution of the library
datafiles = multiplexx-help.pd multiplexx-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e multiplexxA.$(extension)
test -e multiplexxB.$(extension)
installcheck: install
test -e $(installpath)/multiplexxA.$(extension)
test -e $(installpath)/multiplexxB.$(extension)
test -e $(installpath)/multiplexx-help.pd
test -e $(installpath)/multiplexx-meta.pd
slip-0.1/pd-lib-builder/tests/multiplexx/README.md 0000664 0000000 0000000 00000000432 14717202036 0021751 0 ustar 00root root 0000000 0000000 multiplexx
========
minimal pd-lib-builder project that shows how to compile
a library that contains multiplexx C-files that are compiled into
multiplexx binaries each containing a different Pd-objectclass.
this is the general case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/multiplexx/multiplexx-help.pd 0000664 0000000 0000000 00000000241 14717202036 0024156 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X msg 143 93 7;
#X obj 143 125 multiplexxA;
#X obj 223 125 multiplexxB;
#X msg 223 93 12;
#X connect 0 0 1 0;
#X connect 3 0 2 0;
slip-0.1/pd-lib-builder/tests/multiplexx/multiplexx-meta.pd 0000664 0000000 0000000 00000000521 14717202036 0024155 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "multiplexx" external.;
#X text 10 30 NAME multiplexx;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/multiplexx/multiplexxA.cpp 0000664 0000000 0000000 00000001120 14717202036 0023505 0 ustar 00root root 0000000 0000000 #include
#include
t_class*multiplexxA_class;
static void multiplexxA_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multiplexxA_new(void) {
return pd_new(multiplexxA_class);
}
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
extern "C" {
void multiplexxA_setup(void);
}
#endif
void multiplexxA_setup(void) {
std::cerr << __FUNCTION__ << std::endl;
multiplexxA_class = class_new(gensym("multiplexxA"), multiplexxA_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multiplexxA_class, multiplexxA_float);
}
slip-0.1/pd-lib-builder/tests/multiplexx/multiplexxB.c 0000664 0000000 0000000 00000000675 14717202036 0023164 0 ustar 00root root 0000000 0000000 #include
t_class*multiplexxB_class;
static void multiplexxB_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*multiplexxB_new(void) {
return pd_new(multiplexxB_class);
}
void multiplexxB_setup(void) {
post("%s", __FUNCTION__);
multiplexxB_class = class_new(gensym("multiplexxB"), multiplexxB_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multiplexxB_class, multiplexxB_float);
}
slip-0.1/pd-lib-builder/tests/multishared/ 0000775 0000000 0000000 00000000000 14717202036 0020601 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/multishared/Makefile 0000664 0000000 0000000 00000002527 14717202036 0022247 0 ustar 00root root 0000000 0000000 # Makefile to build class 'multishared' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = multishared
# common functions
shared.sources = shared.c
# input source file (class name == source file basename)
class.sources = multisharedA.c multisharedB.c
# all extra files to be included in binary distribution of the library
datafiles = multishared-help.pd multishared-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
ifeq ($(shared.extension), $(extension))
test -e lib$(lib.name).$(shared.extension)
else
test -e lib$(lib.name).$(extension).$(shared.extension)
endif
test -e multisharedA.$(extension)
test -e multisharedB.$(extension)
installcheck: install
ifeq ($(shared.extension), $(extension))
test -e $(installpath)/lib$(lib.name).$(shared.extension)
else
test -e $(installpath)/lib$(lib.name).$(extension).$(shared.extension)
endif
test -e $(installpath)/multisharedA.$(extension)
test -e $(installpath)/multisharedB.$(extension)
test -e $(installpath)/multishared-help.pd
test -e $(installpath)/multishared-meta.pd
slip-0.1/pd-lib-builder/tests/multishared/README.md 0000664 0000000 0000000 00000000520 14717202036 0022055 0 ustar 00root root 0000000 0000000 multishared
===========
minimal pd-lib-builder project that shows how to compile
a library that contains multiple C-files that are compiled into
multiple binaries each containing a different Pd-objectclass.
a local shared library is used for common components.
this is an extended case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/multishared/multishared-help.pd 0000664 0000000 0000000 00000000243 14717202036 0024374 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X msg 143 93 7;
#X obj 143 125 multisharedA;
#X obj 223 125 multisharedB;
#X msg 223 93 12;
#X connect 0 0 1 0;
#X connect 3 0 2 0;
slip-0.1/pd-lib-builder/tests/multishared/multishared-meta.pd 0000664 0000000 0000000 00000000523 14717202036 0024373 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "multishared" external.;
#X text 10 30 NAME multishared;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/multishared/multishared.h 0000664 0000000 0000000 00000000064 14717202036 0023273 0 ustar 00root root 0000000 0000000 #include
void multishared_foo(t_float f);
slip-0.1/pd-lib-builder/tests/multishared/multisharedA.c 0000664 0000000 0000000 00000000745 14717202036 0023375 0 ustar 00root root 0000000 0000000 #include "multishared.h"
t_class*multisharedA_class;
static void multisharedA_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
multishared_foo(f1);
}
static void*multisharedA_new(void) {
return pd_new(multisharedA_class);
}
void multisharedA_setup(void) {
post("%s", __FUNCTION__);
multisharedA_class = class_new(gensym("multisharedA"), multisharedA_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multisharedA_class, multisharedA_float);
}
slip-0.1/pd-lib-builder/tests/multishared/multisharedB.c 0000664 0000000 0000000 00000000745 14717202036 0023376 0 ustar 00root root 0000000 0000000 #include "multishared.h"
t_class*multisharedB_class;
static void multisharedB_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
multishared_foo(f1);
}
static void*multisharedB_new(void) {
return pd_new(multisharedB_class);
}
void multisharedB_setup(void) {
post("%s", __FUNCTION__);
multisharedB_class = class_new(gensym("multisharedB"), multisharedB_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(multisharedB_class, multisharedB_float);
}
slip-0.1/pd-lib-builder/tests/multishared/shared.c 0000664 0000000 0000000 00000000141 14717202036 0022207 0 ustar 00root root 0000000 0000000 #include "multishared.h"
void multishared_foo(t_float f) {
post("%s(%f)", __FUNCTION__, f);
}
slip-0.1/pd-lib-builder/tests/single/ 0000775 0000000 0000000 00000000000 14717202036 0017541 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/single/Makefile 0000664 0000000 0000000 00000001367 14717202036 0021210 0 ustar 00root root 0000000 0000000 # Makefile to build class 'single' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = single
# input source file (class name == source file basename)
class.sources = single.c
# all extra files to be included in binary distribution of the library
datafiles = single-help.pd single-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e single.$(extension)
installcheck: install
test -e $(installpath)/single.$(extension)
slip-0.1/pd-lib-builder/tests/single/README.md 0000664 0000000 0000000 00000000405 14717202036 0021017 0 ustar 00root root 0000000 0000000 single
======
minimal pd-lib-builder project that shows how to compile
a library that contains a single C-file that is compiled into
a single binary containing a single Pd-objectclass.
this is a degenerate case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/single/single-help.pd 0000664 0000000 0000000 00000000132 14717202036 0022271 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X obj 143 125 single;
#X msg 143 93 7;
#X connect 1 0 0 0;
slip-0.1/pd-lib-builder/tests/single/single-meta.pd 0000664 0000000 0000000 00000000511 14717202036 0022270 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "single" external.;
#X text 10 30 NAME single;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/single/single.c 0000664 0000000 0000000 00000000613 14717202036 0021166 0 ustar 00root root 0000000 0000000 #include
t_class*single_class;
static void single_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*single_new(void) {
return pd_new(single_class);
}
void single_setup(void) {
post("%s", __FUNCTION__);
single_class = class_new(gensym("single"), single_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(single_class, single_float);
}
slip-0.1/pd-lib-builder/tests/subdir/ 0000775 0000000 0000000 00000000000 14717202036 0017550 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/subdir/Makefile 0000664 0000000 0000000 00000001525 14717202036 0021213 0 ustar 00root root 0000000 0000000 # Makefile to build class 'subdir' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.
# library name
lib.name = subdir
# input source file (class name == source file basename)
class.sources = src/subdir.c src/subdir~.c
# all extra files to be included in binary distribution of the library
datafiles = subdir-help.pd subdir-meta.pd
# include Makefile.pdlibbuilder
# (for real-world projects see the "Project Management" section
# in tips-tricks.md)
PDLIBBUILDER_DIR=../..
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
# simplistic tests whether all expected files have been produced/installed
buildcheck: all
test -e subdir.$(extension)
test -e subdir~.$(extension)
installcheck: install
test -e $(installpath)/subdir.$(extension)
test -e $(installpath)/subdir~.$(extension)
slip-0.1/pd-lib-builder/tests/subdir/README.md 0000664 0000000 0000000 00000000430 14717202036 0021024 0 ustar 00root root 0000000 0000000 subdir
======
pd-lib-builder project that shows how to compile
a library that contains a single C-file in a separate src/ directory,
that is compiled into a single binary containing a subdir Pd-objectclass.
this is a special case of the one-object-per-binary library structure.
slip-0.1/pd-lib-builder/tests/subdir/src/ 0000775 0000000 0000000 00000000000 14717202036 0020337 5 ustar 00root root 0000000 0000000 slip-0.1/pd-lib-builder/tests/subdir/src/subdir.c 0000664 0000000 0000000 00000000613 14717202036 0021773 0 ustar 00root root 0000000 0000000 #include
t_class*subdir_class;
static void subdir_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*subdir_new(void) {
return pd_new(subdir_class);
}
void subdir_setup(void) {
post("%s", __FUNCTION__);
subdir_class = class_new(gensym("subdir"), subdir_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(subdir_class, subdir_float);
}
slip-0.1/pd-lib-builder/tests/subdir/src/subdir~.c 0000664 0000000 0000000 00000000702 14717202036 0022170 0 ustar 00root root 0000000 0000000 #include
t_class*subdir_tilde_class;
static void subdir_tilde_float(t_object*x, t_float f1) {
pd_error(x, "%s got %f", __FUNCTION__, f1);
}
static void*subdir_tilde_new(void) {
return pd_new(subdir_tilde_class);
}
void subdir_tilde_setup(void) {
post("%s", __FUNCTION__);
subdir_tilde_class = class_new(gensym("subdir~"), subdir_tilde_new, 0, sizeof(t_object), 0, A_NULL);
class_addfloat(subdir_tilde_class, subdir_tilde_float);
}
slip-0.1/pd-lib-builder/tests/subdir/subdir-help.pd 0000664 0000000 0000000 00000000132 14717202036 0022307 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X obj 143 125 subdir;
#X msg 143 93 7;
#X connect 1 0 0 0;
slip-0.1/pd-lib-builder/tests/subdir/subdir-meta.pd 0000664 0000000 0000000 00000000511 14717202036 0022306 0 ustar 00root root 0000000 0000000 #N canvas 966 322 200 200 10;
#N canvas 19 51 420 300 META 0;
#X text 10 10 META this is a prototype of a libdir meta file;
#X text 10 51 AUTHOR IOhannes m zmolnig;
#X text 10 110 VERSION 1.0.0;
#X text 10 90 LICENSE CC0;
#X text 10 70 DESCRIPTION Example "subdir" external.;
#X text 10 30 NAME subdir;
#X restore 10 10 pd META;
slip-0.1/pd-lib-builder/tests/subdir/subdir~-help.pd 0000664 0000000 0000000 00000000133 14717202036 0022506 0 ustar 00root root 0000000 0000000 #N canvas 335 160 450 300 12;
#X obj 143 125 subdir~;
#X msg 143 93 7;
#X connect 1 0 0 0;
slip-0.1/pd-lib-builder/tests/test-patches.sh 0000775 0000000 0000000 00000003114 14717202036 0021222 0 ustar 00root root 0000000 0000000 #!/bin/sh
## simple script to open patches via Pd, and check for errors
## - each patch is opened separately
## - if an error is encountered, the Pd-printout is displayed
## (else it is suppressed)
## - if any of the patches encountered an error, the script will
## exit with a non-0 code
if [ "x${PD}" = "x" ]; then
if [ "x${PDBINDIR}" != "x" ]; then
for exe in pd.com pd pd.exe; do
if [ -x "${PDBINDIR}/${exe}" ]; then
PD="${PDBINDIR}/${exe}"
break
fi
done
if [ "x${PD}" = "x" ]; then
echo "WARNING: couldn't find a usable Pd in '${PDBINDIR}'" 1>&2
fi
fi
fi
if [ "x${PD}" = "x" ]; then
PD=pd
fi
echo "using Pd: ${PD}"
failed=0
failed_tests=""
succeeded=0
open1patch() {
logfile=$(mktemp)
local patch=$1
local patchdir=${patch%%/*}
local patchfile=${patch#*/}
patchfile=${patchfile#/}
#echo "INFO: running ${patchfile} in ${patchdir}"
cd "${patchdir}" && \
${PD} -batch -nrt -noprefs -nostdpath -open "${patchfile}" -send "pd quit" \
>"${logfile}" 2>&1
ret=$?
if grep "error: ... couldn't create" "${logfile}" >/dev/null; then
ret=1
fi
if [ "x${ret}" != "x0" ]; then
echo ""
cat "${logfile}"
echo "FAILED[$ret]: ${patch}"
else
echo "SUCCEEDED: ${patch}"
fi
rm "${logfile}"
return $ret
}
for p in "${@}"; do
if (open1patch "${p}"); then
succeeded=$((succeeded+1))
else
failed=$((failed+1))
failed_tests="${failed_tests} ${p}"
fi
done
echo ""
echo "SUCCESS: ${succeeded}"
echo "FAILURE: ${failed}"
test ${failed} -eq 0 || echo "FAILS :${failed_tests}"
test ${failed} -eq 0
slip-0.1/pd-lib-builder/tips-tricks.md 0000664 0000000 0000000 00000021012 14717202036 0017710 0 ustar 00root root 0000000 0000000 pd-lib-builder cheatsheet
=========================
# Creating special builds
## Building for non-native platform
Using pd-lib-builder >=0.6.0 we can define variable `PLATFORM` to specify a
target triplet for cross-compilation. Assuming a W32 package for Pd is unzipped
into path `${PDWIN32}`, to build for Windows 32 bit:
make PLATFORM=i686-w64-mingw32 PDDIR="${PDWIN32}"
#### Older pd-lib-builder versions
Using pd-lib-builder < 0.6.0, in the absence of variable `PLATFORM`, you would
instead override variables `system`, `target.arch`, `CC` and / or `CXX`,
`STRIP`. Example:
make system=Windows target.arch=i686 CC=i686-w64-mingw32-gcc STRIP=i686-w64-mingw32-strip PDDIR="${PDWIN32}"
#### Toolchains
To build for non-native OS and/or architecture you need a cross toolchain. On
Linux such toolchains are relatively easy to get. For example Debian Buster
amd64 provides them for the following platforms (install g++ with dependencies
for a given platform to get the whole toolchain):
- `arm-linux-gnueabihf`
- `aarch64-linux-gnu`
- `i686-linux-gnu`
- `i686-w64-mingw32` and `x86_64-w64-mingw32` (install `mingw-w64`)
Cross toolchains for OSX/MacOS are not generally distributed. Project
`osxcross` from Thomas Poechtraeger can create them for Linux.
## Universal binaries on macOS
The compiler, by default, builds for the native architecture of the build
machine. To make a "universal" multi-arch build, specify the desired
archtectures on the command line using the "arch" pd-lib-builder Makefile
variable.
For example, to build a "fat" external for both 64-bit Intel and Arm (Apple
Silicon):
make arch="x86_64 arm64"
If the build is successful, the compiled architectures in the built external can
be confirmed via the `file` command:
~~~sh
% file vbap.pd_darwin
vbap.pd_darwin: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64:Mach-O 64-bit bundle arm64]
vbap.pd_darwin (for architecture x86_64): Mach-O 64-bit bundle x86_64
vbap.pd_darwin (for architecture arm64): Mach-O 64-bit bundle arm64
~~~
Note: The available architectures depend on which macOS version & command line
tools/Xcode combination the build system has. For example, any newer macOS
10.15+ will support both x86_64 (Intel 64-bit) and arm64 (Apple Silicon) while
OSX 10.6 - macOS 10.14 can build for x86_64 and i386 (Intel 32-bit).
## Building double-precision externals
At the time of writing (2023-07-06) there is no official Pd that supports
double-precision numbers yet.
However, if you do get hold of an experimental double-precision Pd, you can
easily build your externals for 64-bit numbers, by passing `floatsize=64`
as an argument to `make`.
Starting with Pd>=0.54, double precision externals use different extensions
from traditional (single-precision) externals.
The extension consists of the OS ("linux", "darwin", "windows"), the CPU
architecture ("amd64" (x86_64), "i386" (x86), "arm64",...) and the floatsize
in bits ("64" for double-precision), followed by the system's native extension
for dynamic libraries (".dll" on Windows, ".so" on macOS/Linux/un*xes).
As of pd-lib-builder==0.7.0, you have to manually pass this extension:
make floatsize=64 extension=windows-amd64-64.dll
make floatsize=64 extension=linux-arm64-64.so
make floatsize=64 extension=darwin-fat-64.so arch="x86_64 arm64"
# Project management
In general it is advised to put the `Makefile.pdlibbuilder` into a separate
subdirectory (e.g. `pd-lib-builder/`).
This makes it much easier to update the `Makefile.pdlibbuilder` later
You *should* also use a variable to the actual path of the Makefile.pdlibbuilder
(even if you keep it in the root-directory), as this allows easy experimenting
with newer (or older) (or site-specific) versions of the pd-lib-builder
Makefile.
~~~make
PDLIBBUILDER_DIR=pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
~~~
## Keeping pd-lib-builder up-to-date
### `git subtree`
With git-subtrees, you make the pd-lib-builder repository (or any other
repository for that matter) part of your own repository - with full history and
everything - put nicely into a distinct subdirectory.
Support for *manipulating* subtrees has been added with Git-v1.7.11 (May 2012).
The nice thing however is, that from "outside" the subtree is part of your
repository like any other directory. E.g. older versions of Git can clone your
repository with the full subtree (and all it's history) just fine.
You can also use git-archive to make a complete snapshot of your repository
(including the subtree) - nice, if you e.g. want self-contained downloads of
your project from git hosting platforms (like Github, Gitlab, Bitbucket,...)
In short, `git subtree` is the better `git submodule`.
So here's how to do it:
#### Initial setup/check-out
This will create a `pd-lib-builder/` directory containing the full history of
the pd-lib-builder repository up to its release `v0.5.0`
~~~sh
git subtree add --prefix=pd-lib-builder/ https://github.com/pure-data/pd-lib-builder v0.5.0
~~~
This will automatically merge the `pd-lib-builder/` history into your current
branch, so everything is ready to go.
#### Cloning your repository with the subtree
Nothing special, really.
Just clone your repository as always:
~~~sh
git clone https://git.example.org/pd/superbonk~.git
~~~
#### Updating the subtree
Time passes and sooner or later you will find, that there is a shiny new
pd-lib-builder with plenty of bugfixes and new features.
To update your local copy to pd-lib-builder's current `master`, simply run:
~~~sh
git subtree pull --prefix pd-lib-builder/ https://github.com/pure-data/pd-lib-builder master
~~~
#### Pulling the updated subtree into existing clones
Again, nothing special.
Just pull as always:
~~~sh
git pull
~~~
#### Further reading
More on the power of `git subtree` can be found online
- https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844
- https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree
- ...
### ~~`git submodule`~~ [DISCOURAGED]
#### Initial setup/check-out
To add a new submodule to your repository, just run `git submodule add` and
commit the changes:
~~~sh
git submodule add https://github.com/pure-data/pd-lib-builder
git commit .gitmodules pd-lib-builder/ -m "Added pd-lib-builder as git-submodule"
~~~
#### Cloning your repository with the submodule
When doing a fresh clone of your repository, pass the `--recursive` option to
automatically fetch all submodules:
~~~sh
git clone --recursive https://git.example.org/pd/superbonk~.git
~~~
If you've cloned non-recursively, you can initialize and update the submodules
manually:
~~~sh
git submodule init
git submodule update
~~~
#### Updating the submodule
Submodules are usually fixed to a given commit in their repository.
To update the `pd-lib-builder` submodule to the current `master` do something
like:
~~~sh
cd pd-lib-builder
git checkout master
git pull
cd ..
git status pd-lib-builder
git commit pd-lib-builder -m "Updated pd-lib-builder to current master"
~~~
#### Pulling the updated submodule into existing clones
After you have pushed the submodule updates in your repository, other clones of
the repository can be updated as follows:
~~~sh
git pull
~~~
The above will make your repository aware, that the submodule is out-of-sync.
~~~sh
$ LANG=C git status pd-lib-builder
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: pd-lib-builder (new commits)
$
~~~
In order to sync the submodule to the correct commit, run the following:
~~~sh
git submodule update
~~~
#### Drawbacks
`git submodule` has a number of drawbacks:
- it requires special commands to synchronize the submodules, in addition to
synching your repository.
- you must make sure to use an URL for the submodule that is accessible to your
potential users. e.g. using `git@github.com:pure-data/pd-lib-builder` is bad,
because it requires everybody who wants to checkout your sources to have a
github-account - even if they could checkout *your* repository anonymously.
- submodules will be excluded from `git archive`. This means, that if you use a
mainstream git provider (like Github, GitLab, Bitbucket,...) and make releases
by creating a `git tag`, the automatically generated zipfiles with the sources
will lack the submodule - and your users will not be able to compile your
source code.
In general, I would suggest to **avoid** `git submodule`, and instead use the
better `git subtree` (above).
slip-0.1/slip-meta.pd 0000664 0000000 0000000 00000000416 14717202036 0014544 0 ustar 00root root 0000000 0000000 #N canvas 14 194 200 200 10;
#N canvas 604 86 420 300 META 0;
#X text 7 60 VERSION 0.1;
#X text 6 86 AUTHOR Martin Peach;
#X text 7 112 LICENSE GNU GPL v2+;
#X text 8 14 NAME slip;
#X text 6 37 DESCRIPTION delimit packets for serial transport;
#X restore 10 10 pd META;
slip-0.1/slipdec-help.pd 0000664 0000000 0000000 00000005323 14717202036 0015224 0 ustar 00root root 0000000 0000000 #N canvas 1 53 901 442 10;
#X obj 388 325 print decoded;
#X msg 319 159 192 192 192 192 192;
#X floatatom 339 182 5 0 0 0 - - -;
#X obj 382 238 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577
0;
#X text -57 298 The motivation behind SLIP is the need to determine
the boundaries of a packet when it is received one byte at a time \,
as with a serial channel. Bytes are integers between 0 and 255;
#X msg 185 25 verbosity \$1;
#X obj 185 6 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
;
#X text -57 355 SLIP (RFC 1055) is a simple encoding that prefixes
each packet with 192 \, and replaces 192s inside the packet with 219
followed by 220 Any 219 will be replaced with 219 and 221 The packet
ends with 192;
#X text 443 160 Null packets are invisible;
#X obj 427 274 print valid;
#X text -57 193 Note that the SLIP specification limits the maximum
packet size to 1006...;
#X obj 388 245 slipdec;
#X text -57 221 ...but a float argument to slipdec or slipenc will
set another maximum packet size;
#X msg 229 69 192 \, 1.33 \, 192;
#X text 335 45 This should give 1 192;
#X text 321 69 Only bytes are permitted;
#X msg 275 115 192 219 5 6 7 192;
#X msg 253 93 1 43 5 6 7 192;
#X text 348 92 Missing 192 at start is OK;
#X text -58 139 [slipdec];
#X text 548 404 Author: Martin Peach \, 2010/10/01;
#X msg 205 45 192 1 \, 219 \, 220 \, 192;
#X msg 297 137 1 25 5 6 7;
#X text -57 257 Input can be any combination of float and list of floats
as long as they are integers on [0...255];
#X text 385 115 Bad escapes are invalid;
#X text 368 136 Unterminated input will be accumulated until end is
received;
#X text 636 368 See also:;
#X obj 695 370 slipenc;
#X text -58 153 Decodes bytes from SLIP to raw. Useful for receiving
OSC via [comport].;
#X text 427 290 Right outlet is one whenever a valid packet is output
\, zero if packet could not be decoded (bad packets are not output).
;
#X text 389 341 Left outlet gives lists of decoded bytes whenever valid
= 1;
#X text 267 24 Verbosity might be useful if things don't seem to be
working;
#N canvas 500 267 494 344 META 0;
#X text 12 155 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan
Wilkes for Pd version 0.42.;
#X text 12 25 LICENSE GPL v2 or later;
#X text 12 135 AUTHOR Martin Peach;
#X text 12 5 KEYWORDS control conversion;
#X text 12 46 DESCRIPTION decode bytes from SLIP to raw. Useful for
receiving OSC via [comport];
#X text 12 75 INLET_0 float list verbosity;
#X text 12 95 OUTLET_0 anything;
#X text 12 115 OUTLET_1 float;
#X restore 775 403 pd META;
#X connect 1 0 11 0;
#X connect 2 0 11 0;
#X connect 5 0 11 0;
#X connect 6 0 5 0;
#X connect 11 0 0 0;
#X connect 11 1 9 0;
#X connect 13 0 11 0;
#X connect 16 0 11 0;
#X connect 17 0 11 0;
#X connect 21 0 11 0;
#X connect 22 0 11 0;
slip-0.1/slipdec.c 0000664 0000000 0000000 00000017114 14717202036 0014116 0 ustar 00root root 0000000 0000000 /* slipdec.c 20100513 Martin Peach */
/* decode a list of SLIP-encoded bytes */
#include "m_pd.h"
/* -------------------------- slipdec -------------------------- */
#ifndef _SLIPCODES
/* SLIP special character codes */
#define SLIP_END 0300 /* decimal 192 indicates end of packet */
#define SLIP_ESC 0333 /* decimal 219 indicates byte stuffing */
#define SLIP_ESC_END 0334 /* decimal 220 SLIP_ESC_END means SLIP_END as data byte */
#define SLIP_ESC_ESC 0335 /* decimal 221 SLIP_ESC_ESC means SLIP_ESC as data byte */
#define MAX_SLIP 1006 /* maximum SLIP packet size */
#define _SLIPCODES
#endif /* _SLIPCODES */
static t_class *slipdec_class;
typedef struct _slipdec
{
t_object x_obj;
t_outlet *x_slipdec_out;
t_outlet *x_status_out;
t_atom *x_slip_buf;
int x_slip_length;
int x_slip_max_length;
int x_valid_SLIP;
int x_esced;
int x_verbose;
} t_slipdec;
static void *slipdec_new(t_symbol *s, int argc, t_atom *argv);
static void slipdec_dump(t_slipdec *x, int dosend);
static void slipdec_list(t_slipdec *x, t_symbol *s, int ac, t_atom *av);
static void slipdec_float(t_slipdec *x, t_float f);
static void slipdec_verbosity(t_slipdec *x, t_float f);
static void slipdec_free(t_slipdec *x);
void slipdec_setup(void);
static void *slipdec_new(t_symbol *s, int argc, t_atom *argv)
{
int i;
t_slipdec *x = (t_slipdec *)pd_new(slipdec_class);
if (x == NULL) return x;
x->x_slip_max_length = MAX_SLIP;// default unless a float argument is given
for (i = 0; i < argc; ++i)
{
if (argv[i].a_type == A_FLOAT)
{
x->x_slip_max_length = atom_getfloat(&argv[i]);
post("slipdec: maximum packet length is %d", x->x_slip_max_length);
break;
}
}
x->x_slip_buf = (t_atom *)getbytes(sizeof(t_atom)*x->x_slip_max_length);
if(x->x_slip_buf == NULL)
{
pd_error(x, "slipdec: unable to allocate %lu bytes for x_slip_buf", (long)sizeof(t_atom)*x->x_slip_max_length);
return NULL;
}
/* init the slip buf atoms to float type */
for (i = 0; i < x->x_slip_max_length; ++i) x->x_slip_buf[i].a_type = A_FLOAT;
x->x_slipdec_out = outlet_new(&x->x_obj, &s_list);
x->x_status_out = outlet_new(&x->x_obj, &s_anything);
x->x_valid_SLIP = 1;
return (x);
}
static void slipdec_dump(t_slipdec *x, int dosend)
{
outlet_float(x->x_status_out, x->x_valid_SLIP);
if(dosend)
{
if ((0 != x->x_valid_SLIP) && (x->x_slip_length > 0))
outlet_list(x->x_slipdec_out, &s_list, x->x_slip_length, x->x_slip_buf);
}
x->x_slip_length = x->x_esced = 0;
x->x_valid_SLIP = 1;
}
static void slipdec_list(t_slipdec *x, t_symbol *s, int ac, t_atom *av)
{
/* SLIP decode a list of bytes */
float f;
int i, c;
if (x->x_verbose) post ("slipdec_list: buffer length %d, esc = %d", x->x_slip_length, x->x_esced);
/* x_slip_length will be non-zero if an incomplete packet is in the buffer */
if ((ac + x->x_slip_length) > x->x_slip_max_length)
{
pd_error (x, "slipdec_list: input packet longer than %d", x->x_slip_max_length);
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);// reset
return;
}
/* for each byte in the packet, send the appropriate character sequence */
for(i = 0; ((i < ac) && (x->x_slip_length < x->x_slip_max_length)); ++i)
{
/* check each atom for byteness */
f = atom_getfloat(&av[i]);
c = (((int)f) & 0x0FF);
if (c != f)
{
/* abort, input list needs to be fixed before this is gonna wuk */
pd_error (x, "slipdec: input %f out of range [0..255]", f);
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);// reset
return;
}
if(SLIP_END == c)
{
if (x->x_verbose) post ("slipdec_list: SLIP_END at %d", x->x_slip_length);
/* If it's the beginning of a packet, ignore it */
if (x->x_slip_length)
{
if (x->x_verbose) post ("slipdec_list: end of packet");
/* send the packet */
slipdec_dump(x, 1);
}
continue;
}
if (SLIP_ESC == c)
{
if (x->x_verbose) post ("slipdec_list: SLIP_ESC %f = %d", f, c);
x->x_esced = 1;
continue;
}
if (1 == x->x_esced)
{
if (SLIP_ESC_END == c) c = SLIP_END;
else if (SLIP_ESC_ESC == c) c = SLIP_ESC;
else
{
pd_error (x, "slipdec_list: SLIP_ESC not followed by 220 or 221 (%d)", c);
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);/* reset */
return;
}
x->x_esced = 0;
}
/* Add the character to the buffer */
if (x->x_verbose) post ("slipdec_list: adding character %d to buffer[%d]", c, x->x_slip_length);
x->x_slip_buf[x->x_slip_length++].a_w.w_float = c;
}
}
static void slipdec_float(t_slipdec *x, t_float f)
{
/* SLIP decode a byte */
int c;
if (x->x_verbose) post ("slipdec_float: buffer length %d, esc = %d", x->x_slip_length, x->x_esced);
/* for each byte in the packet, send the appropriate character sequence */
/* check each atom for byteness */
c = (((int)f) & 0x0FF);
if (c != f)
{
/* abort, input list needs to be fixed before this is gonna wuk */
pd_error (x, "slipdec: input %f out of range [0..255]", f);
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);/* reset */
return;
}
if(SLIP_END == c)
{
if (x->x_verbose) post ("slipdec_float: SLIP_END at %d", x->x_slip_length);
/* If it's the beginning of a packet, ignore it */
if (0 == x->x_slip_length) return;
/* send the packet */
else
{
if (x->x_verbose) post ("slipdec_float: end of packet");
slipdec_dump(x, 1);
return;
}
}
if (SLIP_ESC == c)
{
if (x->x_verbose) post ("slipdec_float: SLIP_ESC %f = %d", f, c);
x->x_esced = 1;
return;
}
if (1 == x->x_esced)
{
if (SLIP_ESC_END == c) c = SLIP_END;
else if (SLIP_ESC_ESC == c) c = SLIP_ESC;
else
{
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);/* reset */
pd_error (x, "slipdec_float: SLIP_ESC not followed by 220 or 221 (%d)", c);
return;
}
if (x->x_verbose) post ("slipdec_float: ESCED %f = %d", f, c);
x->x_esced = 0;
}
/* Add the character to the buffer */
if (x->x_slip_length < x->x_slip_max_length)
{
if (x->x_verbose) post ("slipdec_float: adding character %d to buffer[%d]", c, x->x_slip_length);
x->x_slip_buf[x->x_slip_length++].a_w.w_float = c;
}
else
{
pd_error (x, "slipdec: input packet longer than %d", x->x_slip_length);
x->x_valid_SLIP = 0; /* not valid SLIP */
slipdec_dump(x,0);/* reset */
}
}
static void slipdec_verbosity(t_slipdec *x, t_float f)
{
x->x_verbose = (0 != f)?1:0;
}
static void slipdec_free(t_slipdec *x)
{
if (x->x_slip_buf != NULL) freebytes((void *)x->x_slip_buf, sizeof(t_atom)*x->x_slip_max_length);
}
void slipdec_setup(void)
{
slipdec_class = class_new(gensym("slipdec"),
(t_newmethod)slipdec_new, (t_method)slipdec_free,
sizeof(t_slipdec), 0, A_GIMME, 0);
class_addlist(slipdec_class, slipdec_list);
class_addfloat(slipdec_class, slipdec_float);
class_addmethod(slipdec_class, (t_method)slipdec_verbosity, gensym("verbosity"), A_FLOAT, 0);
}
/* fin slipdec.c */
slip-0.1/slipenc-help.pd 0000664 0000000 0000000 00000006310 14717202036 0015233 0 ustar 00root root 0000000 0000000 #N canvas 1 53 855 568 10;
#X obj -98 77 packOSC;
#X msg -98 52 /test 1 2 3 192 218 219 220 221 222;
#X floatatom -72 99 5 0 0 0 - - -;
#X text -99 3 [slipenc]: Encode a list of bytes using Serial Line Internet
Protocol (SLIP);
#X obj -71 246 print encoded;
#X obj -71 163 print original;
#X obj 8 381 print decoded;
#X obj -98 141 t a a;
#X obj -98 224 t a a;
#X msg 124 60 /test/pi 3.14159;
#X msg 233 60 /test/pi \$1;
#X obj 233 40 expr 4*atan(1);
#X obj 233 22 bng 15 250 50 0 empty empty empty 17 7 0 10 -4034 -86277
-1;
#X obj -98 448 unpackOSC;
#X obj -98 364 t a a;
#X obj -98 469 routeOSC /test;
#X obj -92 492 print test;
#X obj -17 492 print other;
#X obj -98 515 routeOSC /pi;
#X floatatom -98 537 12 0 0 0 - - -;
#X text -16 190 Encodes a list of bytes for transmission through a
serial link using SLIP (RFC 1055). Useful for sending OSC through [comport].
;
#X msg -52 124 192 192 192 192 192;
#X obj -104 322 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577
0;
#X obj -103 186 cnv 15 60 30 empty empty empty 20 12 0 14 -4034 -66577
0;
#X msg 27 174 1 2 3 4;
#X text 340 77 The motivation behind SLIP is the need to determine
the boundaries of a packet when it is received one byte at a time \,
as with a serial channel. Bytes are integers between 0 and 255;
#X msg 79 124 1 2 3 4 5 6;
#X msg 160 124 1.1 2.22 3 4 5 6;
#X text -37 98 single floats will pass through as single packets;
#X msg -76 290 verbosity \$1;
#X obj -76 271 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X text 340 134 SLIP (RFC 1055) is a simple encoding that prefixes
each packet with 192 \, and replaces 192s inside the packet with 219
followed by 220 Any 219 will be replaced with 219 and 221 The packet
ends with 192;
#X obj -71 383 list split 1;
#X obj -71 404 == 47;
#X obj -98 425 spigot;
#X text -35 403 select OSC messages based on the leading '/';
#X obj -59 358 print valid;
#X text 56 234 Note that the SLIP specification limits the maximum
packet size to 1006...;
#X obj -98 191 slipenc;
#X obj -98 329 slipdec;
#X text 31 530 Author: Martin Peach \, 2010/10/01;
#X text 57 262 ...but a float argument to slipenc will set another
maximum packet size;
#N canvas 529 327 494 344 META 0;
#X text 12 135 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan
Wilkes for Pd version 0.42.;
#X text 12 25 LICENSE GPL v2 or later;
#X text 12 115 AUTHOR Martin Peach;
#X text 12 5 KEYWORDS control conversion;
#X text 12 95 OUTLET_0 anything;
#X text 12 46 DESCRIPTION encode a list of bytes using Serial Line
Internet Protocol (SLIP);
#X text 12 75 INLET_0 float list;
#X restore 693 530 pd META;
#X connect 0 0 7 0;
#X connect 1 0 0 0;
#X connect 2 0 7 0;
#X connect 7 0 38 0;
#X connect 7 1 5 0;
#X connect 8 0 39 0;
#X connect 8 1 4 0;
#X connect 9 0 0 0;
#X connect 10 0 0 0;
#X connect 11 0 10 0;
#X connect 12 0 11 0;
#X connect 13 0 15 0;
#X connect 14 0 34 0;
#X connect 14 1 6 0;
#X connect 14 1 32 0;
#X connect 15 0 16 0;
#X connect 15 0 18 0;
#X connect 15 1 17 0;
#X connect 18 0 19 0;
#X connect 21 0 7 0;
#X connect 24 0 38 0;
#X connect 26 0 7 0;
#X connect 27 0 7 0;
#X connect 29 0 39 0;
#X connect 30 0 29 0;
#X connect 32 0 33 0;
#X connect 33 0 34 1;
#X connect 34 0 13 0;
#X connect 38 0 8 0;
#X connect 39 0 14 0;
#X connect 39 1 36 0;
slip-0.1/slipenc.c 0000664 0000000 0000000 00000014730 14717202036 0014131 0 ustar 00root root 0000000 0000000 /* slipenc.c 20100513 Martin Peach */
/* encode a list of bytes as SLIP */
/*
* From RFC 1055:
* PROTOCOL
*
* The SLIP protocol defines two special characters: SLIP_END and SLIP_ESC. SLIP_END is
* octal 300 (decimal 192) and SLIP_ESC is octal 333 (decimal 219) not to be
* confused with the ASCII ESCape character; for the purposes of this
* discussion, SLIP_ESC will indicate the SLIP SLIP_ESC character. To send a
* packet, a SLIP host simply starts sending the data in the packet. If
* a data byte is the same code as SLIP_END character, a two byte sequence of
* SLIP_ESC and octal 334 (decimal 220) is sent instead. If it the same as
* an SLIP_ESC character, an two byte sequence of SLIP_ESC and octal 335 (decimal
* 221) is sent instead. When the last byte in the packet has been
* sent, an SLIP_END character is then transmitted.
*
* Phil Karn suggests a simple change to the algorithm, which is to
* begin as well as end packets with an SLIP_END character. This will flush
* any erroneous bytes which have been caused by line noise. In the
* normal case, the receiver will simply see two back-to-back SLIP_END
* characters, which will generate a bad IP packet. If the SLIP
* implementation does not throw away the zero-length IP packet, the IP
* implementation certainly will. If there was line noise, the data
* received due to it will be discarded without affecting the following
* packet.
*
* Because there is no 'standard' SLIP specification, there is no real
* defined maximum packet size for SLIP. It is probably best to accept
* the maximum packet size used by the Berkeley UNIX SLIP drivers: 1006
* bytes including the IP and transport protocol headers (not including
* the framing characters). Therefore any new SLIP implementations
* should be prepared to accept 1006 byte datagrams and should not send
* more than 1006 bytes in a datagram.
*/
#include "m_pd.h"
/* -------------------------- slipenc -------------------------- */
#ifndef _SLIPCODES
/* SLIP special character codes */
#define SLIP_END 0300 /* indicates end of packet */
#define SLIP_ESC 0333 /* indicates byte stuffing */
#define SLIP_ESC_END 0334 /* SLIP_ESC SLIP_ESC_END means SLIP_END data byte */
#define SLIP_ESC_ESC 0335 /* SLIP_ESC SLIP_ESC_ESC means SLIP_ESC data byte */
#define MAX_SLIP 1006 /* maximum SLIP packet size */
#define _SLIPCODES
#endif // _SLIPCODES
static t_class *slipenc_class;
typedef struct _slipenc
{
t_object x_obj;
t_outlet *x_slipenc_out;
t_atom *x_slip_buf;
int x_slip_length;
int x_slip_max_length;
} t_slipenc;
static void *slipenc_new(t_symbol *s, int argc, t_atom *argv);
static void slipenc_list(t_slipenc *x, t_symbol *s, int ac, t_atom *av);
static void slipenc_free(t_slipenc *x);
void slipenc_setup(void);
static void *slipenc_new(t_symbol *s, int argc, t_atom *argv)
{
int i, max_len;
t_slipenc *x = (t_slipenc *)pd_new(slipenc_class);
if (x == NULL) return x;
x->x_slip_max_length = MAX_SLIP; // default unless float argument given
for (i = 0; i < argc; ++i)
{
if (argv[i].a_type == A_FLOAT)
{
max_len = atom_getfloat(&argv[i]);
if (max_len > 3)
{
x->x_slip_max_length = max_len;
post("slipenc: maximum packet length is %d", x->x_slip_max_length);
}
else
post("slipenc: maximum packet length must be greater than 3, using %d", x->x_slip_max_length);
break;
}
}
x->x_slip_buf = (t_atom *)getbytes(sizeof(t_atom)*x->x_slip_max_length);
if(x->x_slip_buf == NULL)
{
pd_error(x, "slipenc: unable to allocate %lu bytes for x_slip_buf", (long)sizeof(t_atom)*x->x_slip_max_length);
return NULL;
}
/* Initialize all the slip buf atoms to float type */
for (i = 0; i < x->x_slip_max_length; ++i) x->x_slip_buf[i].a_type = A_FLOAT;
x->x_slipenc_out = outlet_new(&x->x_obj, &s_list);
return (x);
}
static void slipenc_list(t_slipenc *x, t_symbol *s, int ac, t_atom *av)
{
/* SLIP encode a list of bytes */
float f;
int i, c;
i = 0;
/* for each byte in the packet, send the appropriate character sequence */
while (i < ac)
{
x->x_slip_length = 0;
/* send an initial SLIP_END character to flush out any data that may */
/* have accumulated in the receiver due to line noise */
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END;
while((i < ac)&&(x->x_slip_length < (x->x_slip_max_length-2)))
{
/* check each atom for byteness */
f = atom_getfloat(&av[i++]);
c = (((int)f) & 0x0FF);
if (c != f)
{
/* abort, bad input character */
pd_error (x, "slipenc: input %f out of range [0..255]", f);
return;
}
if(SLIP_END == c)
{
/* If it's the same code as a SLIP_END character, replace it with a */
/* special two-character code so as not to make the receiver think we sent SLIP_END */
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC;
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_END;
}
else if (SLIP_ESC == c)
{
/* If it's the same code as a SLIP_ESC character, replace it with a special two-character code */
/* so as not to make the receiver think we sent SLIP_ESC */
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC;
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_ESC_ESC;
}
else
{
/* Otherwise, pass the character */
x->x_slip_buf[x->x_slip_length++].a_w.w_float = c;
}
}
/* Add the SLIP_END code to tell the receiver that the packet is complete */
x->x_slip_buf[x->x_slip_length++].a_w.w_float = SLIP_END;
outlet_list(x->x_slipenc_out, &s_list, x->x_slip_length, x->x_slip_buf);
}
}
static void slipenc_free(t_slipenc *x)
{
if (x->x_slip_buf != NULL) freebytes((void *)x->x_slip_buf, sizeof(t_atom)*x->x_slip_max_length);
}
void slipenc_setup(void)
{
slipenc_class = class_new(gensym("slipenc"),
(t_newmethod)slipenc_new, (t_method)slipenc_free,
sizeof(t_slipenc), 0, A_GIMME, 0);
class_addlist(slipenc_class, slipenc_list);
}
/* fin slipenc.c*/