diff --git a/.git-ci/gitlab-iem.yml b/.git-ci/gitlab-iem.yml
new file mode 100644
index 0000000..1b8ba82
--- /dev/null
+++ b/.git-ci/gitlab-iem.yml
@@ -0,0 +1,140 @@
+#######################################################################
+### .git-ci/gitlab-iem.yml for Pd externals: v1.2
+###
+### this can be used for any external with a build system like:
+### - 'make' builds the external
+### - 'make install' installs the external to be used by Pd
+### the following make variables must be honoured:
+### - extension: filename extension for externals
+### - DESTDIR: base directory for 'make install'
+### - pkglibdir: directory to put externals into (relative to DESTDIR)
+###
+### one well known build-system that can be used straight away is
+### "pd-lib-builder" -> https://github.com/pure-data/pd-lib-builder/
+#######################################################################
+
+variables:
+  PDVERSION: 0.49-0
+
+#######################################################################
+### configuration templates (to be used for snapshot and release builds)
+.build:snapshot: &snapshot
+  except:
+    - tags
+  artifacts: &snapshot_artifacts
+    name: ${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${CI_JOB_NAME%_*}
+    paths:
+      - "${CI_JOB_NAME}/${CI_PROJECT_NAME}"
+    expire_in: 1 week
+
+.build:release: &release
+  only:
+    - tags
+  artifacts: &release_artifacts
+    name: ${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${CI_JOB_NAME%_*}
+    paths:
+      - "${CI_JOB_NAME}/${CI_PROJECT_NAME}"
+
+.build:linux: &build_linux
+  image: gcc
+  stage: build
+  before_script:
+    - apt-get update && apt-get install -y --no-install-recommends make puredata-dev puredata
+    - export PD=/usr/bin/pd
+  script:
+    - make
+    - make install DESTDIR=$(pwd) pkglibdir=/${CI_JOB_NAME}
+
+.build:macos: &build_macos
+  tags:
+     - osx
+  stage: build
+  before_script:
+    - wget -q -O Pd.tgz http://msp.ucsd.edu/Software/pd-${PDVERSION}.mac.tar.gz
+    - rm -rf /Applications/Pd*.app/
+    - tar xvf Pd.tgz -C /Applications/
+    - rm -f Pd.tgz
+    - export PD=$(find /Applications/Pd*.app/Contents/Resources/bin/ type f -name pd -print -quit)
+  script:
+    - make
+    - make install DESTDIR=$(pwd) pkglibdir=/${CI_JOB_NAME}
+
+.build:w32: &build_w32
+  stage: build
+  tags:
+    - windows
+  variables:
+    IEMCI_CONFIGURATIONS: mingw32
+  before_script:
+    - wget -q -O Pd.zip http://msp.ucsd.edu/Software/pd-${PDVERSION}-i386.msw.zip
+    - rm -rf "${PROGRAMFILESX86}/pd"; mkdir -p "${PROGRAMFILESX86}/pd"
+    - unzip -q Pd.zip -d "${PROGRAMFILESX86}/pd"
+    - mv -v "${PROGRAMFILESX86}/pd"/*/* "${PROGRAMFILESX86}/pd"
+    - export PD="${PROGRAMFILESX86}/pd/bin/pd.com"
+  script:
+    - make
+    - make install DESTDIR=$(pwd) pkglibdir=/${CI_JOB_NAME}
+
+.build:w64: &build_w64
+  stage: build
+  tags:
+    - windows
+  variables:
+    IEMCI_CONFIGURATIONS: mingw64
+  before_script:
+    - wget -q -O Pd.zip http://msp.ucsd.edu/Software/pd-${PDVERSION}.msw.zip
+    - rm -rf "${PROGRAMFILES}/pd"; mkdir -p "${PROGRAMFILES}/pd"
+    - unzip -q Pd.zip -d "${PROGRAMFILES}/pd"
+    - mv -v "${PROGRAMFILES}/pd"/*/* "${PROGRAMFILES}/pd"
+    - export PD="${PROGRAMFILES}/pd/bin/pd.com"
+  script:
+    - make extension=m_amd64
+    - make install extension=m_amd64 DESTDIR=$(pwd) pkglibdir=/${CI_JOB_NAME}
+
+#######################################################################
+### the actual jobs: (linux,macos,windows)*(release,snapshot)
+
+Linux:
+  <<: *build_linux
+  <<: *release
+Darwin:
+  <<: *build_macos
+  <<: *release
+w32:
+  <<: *build_w32
+  <<: *release
+w64:
+  <<: *build_w64
+  <<: *release
+
+
+Linux_snapshot:
+  <<: *build_linux
+  <<: *snapshot
+Darwin_snapshot:
+  <<: *build_macos
+  <<: *snapshot
+w32_snapshot:
+  <<: *build_w32
+  <<: *snapshot
+w64_snapshot:
+  <<: *build_w64
+  <<: *snapshot
+
+#######################################################################
+### create deken packages and (optionally) upload them
+deken:
+  stage: deploy
+  image: debian:buster
+  only:
+    - tags
+  variables:
+    DEKEN_ROOT: "yes"
+  before_script:
+    - apt-get update && apt-get --no-install-recommends -y install deken git
+  script:
+    - chmod -R go-w .
+    - git archive --format=tar --prefix=tmp/${CI_PROJECT_NAME}/ HEAD | tar xf -
+    - deken package --version="${CI_COMMIT_TAG#v}" */"${CI_PROJECT_NAME}"
+    - ls ./*.dek
+    - test -z "${DEKEN_USERNAME}" || test -z "${DEKEN_PASSWORD}" || deken upload --no-source-error ./*.dek
diff --git a/.travis.yml b/.travis.yml
index 8eaef23..90b3cca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,10 @@
 language: c
+sudo: false
 
 env:
   global:
         - secure: "H+FS0KWYGx4JBMcPdhhJus9LgFhh5luIU4rfWl6Fsh4q0VJmT1tSO3KYlEQYkenS4xX/sUtN/Yus1b8L0MkuM3akEEPAA26Up9leFsarIQrD3dGYmoNQ4R2eG1Et8hoNwQwXQ1f30wrqfykVK+83rzqSlpoz+nhTBKZNYC7tfn0="
-        - COVERITY_SCAN_BRANCH_PATTERN="coverity_scan"
+        - COVERITY_SCAN_BRANCH_PATTERN="(master|coverity_scan)"
         - COVERITY_SCAN_NOTIFICATION_EMAIL="zmoelnig@users.sourceforge.net"
         - COVERITY_SCAN_BUILD_COMMAND="make"
 
@@ -14,9 +15,14 @@ matrix:
       env:
         - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
 
-before_install:
-- sudo apt-get update -qq
-- sudo apt-get install -qq puredata-dev
+addons:
+  apt:
+    packages:
+      - puredata-dev
+
+#before_install:
+#- sudo apt-get update -qq
+#- sudo apt-get install -qq puredata-dev
 
 before_script:
   # implement Coverity Scan with before_script instead of addons.coverity_scan
diff --git a/Makefile b/Makefile
index 971cae4..b3a89f0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,427 +1,47 @@
-## Pd library template version 1.0.11
-# For instructions on how to use this template, see:
-#  http://puredata.info/docs/developer/MakefileTemplate
-LIBRARY_NAME = iemnet
-
-# add your .c source files, one object per file, to the SOURCES
-# variable, help files will be included automatically, and for GUI
-# objects, the matching .tcl file too
-SOURCES = tcpserver.c tcpclient.c tcpsend.c tcpreceive.c udpreceive.c udpsend.c udpclient.c udpserver.c
-
-SHARED_SOURCES = iemnet.c iemnet_data.c  iemnet_receiver.c  iemnet_sender.c
-SHARED_HEADERS = iemnet_data.h  iemnet.h
-
-# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
-# be included automatically
-PDOBJECTS = udpsndrcv.pd
-
-# example patches and related files, in the 'examples' subfolder
-#EXAMPLES = bothtogether.pd
-
-# manuals and related files, in the 'manual' subfolder
-#MANUAL = manual.txt
-
-# if you want to include any other files in the source and binary tarballs,
-# list them here.  This can be anything from header files, test patches,
-# documentation, etc.  README.txt and LICENSE.txt are required and therefore
-# automatically included
-EXTRA_DIST = ChangeLog FEATURES.txt NOTES.txt
-
-LIBS_windows=-lpthread
-
-#overriding the datestring
-# run `make CPPFLAGS="-DBUILD_DATE='\"somewhen in August\"'"`
-
-
-#------------------------------------------------------------------------------#
-#
-# things you might need to edit if you are using other C libraries
-#
-#------------------------------------------------------------------------------#
-
-ALL_CFLAGS = -I"$(PD_INCLUDE)"
-ALL_LDFLAGS =  
-SHARED_LDFLAGS =
-ALL_LIBS = 
-
-
-#------------------------------------------------------------------------------#
-#
-# you shouldn't need to edit anything below here, if we did it right :)
-#
-#------------------------------------------------------------------------------#
-
-# these can be set from outside without (usually) breaking the build
-CFLAGS := -Wall -Wno-unused -W -g
-
-# get library version from meta file
-LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
-
-ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"'
-
-PD_INCLUDE = $(PD_PATH)/include/pd
-# where to install the library, overridden below depending on platform
-prefix = /usr/local
-libdir = $(prefix)/lib
-pkglibdir = $(libdir)/pd-externals
-objectsdir = $(pkglibdir)
-
-INSTALL = install
-INSTALL_PROGRAM = $(INSTALL) -p -m 644
-INSTALL_DATA = $(INSTALL) -p -m 644
-INSTALL_DIR     = $(INSTALL) -p -m 755 -d
-
-ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
-	         $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
-
-DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
-ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
-
-UNAME := $(shell uname -s)
-ifeq ($(UNAME),Darwin)
-  CPU := $(shell uname -p)
-  ifeq ($(CPU),arm) # iPhone/iPod Touch
-    SOURCES += $(SOURCES_iphoneos)
-    EXTENSION = pd_darwin
-    SHARED_EXTENSION = dylib
-    OS = iphoneos
-    PD_PATH = /Applications/Pd-extended.app/Contents/Resources
-    IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
-    CC=$(IPHONE_BASE)/gcc
-    CPP=$(IPHONE_BASE)/cpp
-    CXX=$(IPHONE_BASE)/g++
-    ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
-    IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
-    OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
-    ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS)
-    ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
-    SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT)
-    ALL_LIBS += -lc $(LIBS_iphoneos)
-    STRIP = strip -x
-    DISTBINDIR=$(DISTDIR)-$(OS)
-  else # Mac OS X
-    SOURCES += $(SOURCES_macosx)
-    EXTENSION = pd_darwin
-    SHARED_EXTENSION = dylib
-    OS = macosx
-    PD_PATH = /Applications/Pd-extended.app/Contents/Resources
-    OPT_CFLAGS = -ftree-vectorize
-# build universal 32-bit on 10.4 and 32/64 on newer
-    ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
-      FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
-    else
-      FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.4
-      SOURCES += $(SOURCES_iphoneos)
-    endif
-    ALL_CFLAGS += $(FAT_FLAGS) -fPIC
-ifneq ($(strip $(realpath /sw/include)),)
-    ALL_CFLAGS += -I/sw/include
-endif
-    # if the 'pd' binary exists, check the linking against it to aid with stripping
-    BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
-    ALL_LDFLAGS += $(FAT_FLAGS) -bundle $(BUNDLE_LOADER) -undefined dynamic_lookup
-ifneq ($(strip $(realpath /sw/lib)),)
-    ALL_LDFLAGS += -L/sw/lib
-endif
-    SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \
-	-install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0
-    ALL_LIBS += -lc $(LIBS_macosx)
-    STRIP = strip -x
-    DISTBINDIR=$(DISTDIR)-$(OS)
-# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
-    pkglibdir=$(HOME)/Library/Pd
-  endif
-endif
-# Tho Android uses Linux, we use this fake uname to provide an easy way to
-# setup all this things needed to cross-compile for Android using the NDK
-ifeq ($(UNAME),ANDROID)
-  CPU := arm
-  SOURCES += $(SOURCES_android)
-  EXTENSION = pd_linux
-  SHARED_EXTENSION = so
-  OS = android
-  PD_PATH = /usr
-  NDK_BASE := /usr/local/android-ndk
-  NDK_PLATFORM_VERSION := 5
-  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm
-  NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
-  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86
-  CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT)
-  OPT_CFLAGS = -O2 -funroll-loops -fomit-frame-pointer
-  CFLAGS += 
-  LDFLAGS += -rdynamic -shared
-  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
-  LIBS += -lc $(LIBS_android)
-  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \
-	--strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
-endif
-ifeq ($(UNAME),Linux)
-  CPU := $(shell uname -m)
-  SOURCES += $(SOURCES_linux)
-  EXTENSION = pd_linux
-  SHARED_EXTENSION = so
-  OS = linux
-  PD_PATH = /usr
-  OPT_CFLAGS = -O2 -funroll-loops -fomit-frame-pointer
-  ALL_CFLAGS += -fPIC
-  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
-  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
-  ALL_LIBS += -lc $(LIBS_linux)
-  STRIP = strip --strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
-endif
-ifeq ($(UNAME),GNU)
-  # GNU/Hurd, should work like GNU/Linux for basically all externals
-  CPU := $(shell uname -m)
-  SOURCES += $(SOURCES_linux)
-  EXTENSION = pd_linux
-  SHARED_EXTENSION = so
-  OS = linux
-  PD_PATH = /usr
-  OPT_CFLAGS = -O2 -funroll-loops -fomit-frame-pointer
-  ALL_CFLAGS += -fPIC
-  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
-  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
-  ALL_LIBS += -lc $(LIBS_linux)
-  STRIP = strip --strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
-endif
-ifeq ($(UNAME),GNU/kFreeBSD)
-  # Debian GNU/kFreeBSD, should work like GNU/Linux for basically all externals
-  CPU := $(shell uname -m)
-  SOURCES += $(SOURCES_linux)
-  EXTENSION = pd_linux
-  SHARED_EXTENSION = so
-  OS = linux
-  PD_PATH = /usr
-  OPT_CFLAGS = -O2 -funroll-loops -fomit-frame-pointer
-  ALL_CFLAGS += -fPIC
-  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
-  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
-  ALL_LIBS += -lc $(LIBS_linux)
-  STRIP = strip --strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
-endif
-ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
-  CPU := $(shell uname -m)
-  SOURCES += $(SOURCES_cygwin)
-  EXTENSION = dll
-  SHARED_EXTENSION = dll
-  OS = cygwin
-  PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd
-  OPT_CFLAGS = -O2 -funroll-loops -fomit-frame-pointer
-  ALL_CFLAGS += 
-  ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
-  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB) -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
-  ALL_LIBS += -lc -lpd $(LIBS_cygwin)
-  STRIP = strip --strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)
-endif
-ifeq (MINGW,$(findstring MINGW,$(UNAME)))
-  CPU := $(shell uname -m)
-  SOURCES += $(SOURCES_windows)
-  EXTENSION = dll
-  SHARED_EXTENSION = dll
-  OS = windows
-  PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd)
-  # MinGW doesn't seem to include cc so force gcc
-  CC=gcc
-  OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
-  ALL_CFLAGS += -mms-bitfields
-  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj"
-  SHARED_LDFLAGS += -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj"
-  ALL_LIBS += -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 $(LIBS_windows)
-  STRIP = strip --strip-unneeded -R .note -R .comment
-  DISTBINDIR=$(DISTDIR)-$(OS)
-endif
-
--include Makefile.local
-
-# in case somebody manually set the HELPPATCHES above
-HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
-
-ALL_CFLAGS := $(CPPFLAGS) $(ALL_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
-ALL_LDFLAGS := $(ALL_LDFLAGS) $(LDFLAGS)
-ALL_LIBS := $(ALL_LIBS) $(LIBS)
-
-SHARED_SOURCES ?= $(shell test ! -e lib$(LIBRARY_NAME).c || \
-	echo lib$(LIBRARY_NAME).c )
-SHARED_HEADERS ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h)
-SHARED_LIB ?= lib$(LIBRARY_NAME:=.$(SHARED_EXTENSION))
-
-.PHONY = all clean distclean install dist \
-        etags dpkg-source showsetup \
-        libdir_install install-objects \
-        single_install install-libobject \
-        install-doc install-examples install-manual \
-        libdir $(LIBRARY_NAME)
-
-all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
-
-%.o: %.c $(SHARED_HEADERS)
-	$(CC) $(ALL_CFLAGS) -o $@ -c $<
-
-%.$(EXTENSION): %.o $(SHARED_LIB)
-	$(CC) $(ALL_LDFLAGS) -o $@ $^  $(ALL_LIBS)
-	chmod a-x $@
-
-# this links everything into a single binary file
-$(LIBRARY_NAME): $(LIBRARY_NAME).$(EXTENSION)
-
-$(LIBRARY_NAME).$(EXTENSION): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
-	$(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS)
-	chmod a-x $@
-
-$(SHARED_LIB): $(SHARED_SOURCES:.c=.o)
-	$(CC) $(SHARED_LDFLAGS) $(LDFLAGS) -o $@ $^ $(ALL_LIBS)
-
-install: libdir_install
-
-# The meta and help files are explicitly installed to make sure they are
-# actually there.  Those files are not optional, then need to be there.
-install-objects: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) $(PDOBJECTS) $(SHARED_TCL_LIB)
-	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
-		$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_DATA) $^ \
-		$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \
-		$(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \
-			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-libdir_install: install-objects install-doc install-examples install-manual
-
-# install library linked as single binary
-install-libobject: $(LIBRARY_NAME).$(EXTENSION)
-	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_PROGRAM) $^ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	-$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
-
-single_install: install-libobject install-doc install-examples install-manual
-
-install-doc:
-	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
-		$(INSTALL_DATA) $(HELPPATCHES) \
-			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
-	$(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
-	$(INSTALL_DATA) ChangeLog $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/CHANGES.txt
-
-install-examples:
-	test -z "$(strip $(EXAMPLES))" || \
-		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \
-		for file in $(EXAMPLES); do \
-			$(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \
-		done
-
-install-manual:
-	test -z "$(strip $(MANUAL))" || \
-		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
-		for file in $(MANUAL); do \
-			$(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
-		done
-
-
-clean:
-	-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCES:.c=.o)
-	-rm -f -- $(SOURCES:.c=.$(EXTENSION))
-	-rm -f -- $(LIBRARY_NAME).o
-	-rm -f -- $(LIBRARY_NAME).$(EXTENSION)
-	-rm -f -- $(SHARED_LIB)
-
-distclean: clean
-	-rm -f -- $(DISTBINDIR).tar.gz
-	-rm -rf -- $(DISTBINDIR)
-	-rm -f -- $(DISTDIR).tar.gz
-	-rm -rf -- $(DISTDIR)
-	-rm -f -- $(ORIGDIR).tar.gz
-	-rm -rf -- $(ORIGDIR)
-
-
-$(DISTBINDIR):
-	$(INSTALL_DIR) $(DISTBINDIR)
-
-libdir: all $(DISTBINDIR)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTBINDIR)
-	$(INSTALL_DATA) $(SOURCES) $(SHARED_SOURCES) $(SHARED_HEADERS) $(DISTBINDIR)
-	$(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
-	test -z "$(strip $(EXTRA_DIST))" || \
-		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTBINDIR)
-#	tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR)
-
-$(DISTDIR):
-	$(INSTALL_DIR) $(DISTDIR)
-
-$(ORIGDIR):
-	$(INSTALL_DIR) $(ORIGDIR)
-
-dist: $(DISTDIR)
-	$(INSTALL_DATA) Makefile  $(DISTDIR)
-	$(INSTALL_DATA) README.txt $(DISTDIR)
-	$(INSTALL_DATA) LICENSE.txt $(DISTDIR)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTDIR)
-	test -z "$(strip $(ALLSOURCES))" || \
-		$(INSTALL_DATA) $(ALLSOURCES)  $(DISTDIR)
-	test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \
-		$(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl))  $(DISTDIR)
-	test -z "$(strip $(SHARED_HEADERS))" || \
-		$(INSTALL_DATA) $(SHARED_HEADERS)  $(DISTDIR)
-	test -z "$(strip $(SHARED_SOURCES))" || \
-		$(INSTALL_DATA) $(SHARED_SOURCES)  $(DISTDIR)
-	test -z "$(strip $(PDOBJECTS))" || \
-		$(INSTALL_DATA) $(PDOBJECTS)  $(DISTDIR)
-	test -z "$(strip $(HELPPATCHES))" || \
-		$(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR)
-	test -z "$(strip $(EXTRA_DIST))" || \
-		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTDIR)
-	test -z "$(strip $(EXAMPLES))" || \
-		$(INSTALL_DIR) $(DISTDIR)/examples && \
-		for file in $(EXAMPLES); do \
-			$(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
-		done
-	test -z "$(strip $(MANUAL))" || \
-		$(INSTALL_DIR) $(DISTDIR)/manual && \
-		for file in $(MANUAL); do \
-			$(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
-		done
-	tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
-
-# make a Debian source package
-dpkg-source:
-	debclean
-	make distclean dist
-	mv $(DISTDIR) $(ORIGDIR)
-	tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR)
-	rm -f -- $(DISTDIR).tar.gz
-	rm -rf -- $(DISTDIR) $(ORIGDIR)
-	cd .. && dpkg-source -b $(LIBRARY_NAME)
-
-etags:
-	etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
-
-showsetup:
-	@echo "CC: $(CC)"
-	@echo "CFLAGS: $(CFLAGS)"
-	@echo "LDFLAGS: $(LDFLAGS)"
-	@echo "LIBS: $(LIBS)"
-	@echo "ALL_CFLAGS: $(ALL_CFLAGS)"
-	@echo "ALL_LDFLAGS: $(ALL_LDFLAGS)"
-	@echo "ALL_LIBS: $(ALL_LIBS)"
-	@echo "PD_INCLUDE: $(PD_INCLUDE)"
-	@echo "PD_PATH: $(PD_PATH)"
-	@echo "objectsdir: $(objectsdir)"
-	@echo "LIBRARY_NAME: $(LIBRARY_NAME)"
-	@echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
-	@echo "SOURCES: $(SOURCES)"
-	@echo "SHARED_HEADERS: $(SHARED_HEADERS)"
-	@echo "SHARED_SOURCES: $(SHARED_SOURCES)"
-	@echo "SHARED_LIB: $(SHARED_LIB)"
-	@echo "PDOBJECTS: $(PDOBJECTS)"
-	@echo "ALLSOURCES: $(ALLSOURCES)"
-	@echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))"
-	@echo "UNAME: $(UNAME)"
-	@echo "CPU: $(CPU)"
-	@echo "pkglibdir: $(pkglibdir)"
-	@echo "DISTDIR: $(DISTDIR)"
-	@echo "ORIGDIR: $(ORIGDIR)"
+# Makefile for iemnet
+
+lib.name = iemnet
+
+class.sources = \
+        tcpserver.c \
+        tcpclient.c \
+        tcpsend.c \
+        tcpreceive.c \
+        udpreceive.c \
+        udpsend.c \
+        udpclient.c \
+        udpserver.c
+
+shared.sources = \
+	iemnet.c \
+	iemnet_data.c \
+	iemnet_receiver.c \
+	iemnet_sender.c
+
+datafiles = \
+	iemnet-meta.pd \
+	tcpclient-help.pd \
+	tcpreceive-help.pd \
+	tcpsend-help.pd \
+	tcpserver-help.pd \
+	udpclient-help.pd \
+	udpreceive-help.pd \
+	udpsend-help.pd \
+	udpserver-help.pd \
+	udpsndrcv-help.pd \
+	udpsndrcv.pd \
+	LICENSE.txt \
+	README.txt
+
+cflags = -DVERSION='"$(lib.version)"'
+
+define forWindows
+  ldlibs = -lwsock32 -lpthread
+endef
+
+# 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))
diff --git a/debian/changelog b/debian/changelog
index f3d9b6d..1f3b102 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+pd-iemnet (0.2.2+git20191112.895d985-1) UNRELEASED; urgency=medium
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 13 Nov 2019 00:04:30 +0000
+
 pd-iemnet (0.2.1-2) unstable; urgency=medium
 
   * Simplified & unified d/rules
diff --git a/iemnet-meta.pd b/iemnet-meta.pd
index dd8c519..857e818 100644
--- a/iemnet-meta.pd
+++ b/iemnet-meta.pd
@@ -1,11 +1,12 @@
 #N canvas 169 49 432 242 10;
-#X text 47 84 iemnet: high performance networking with Pd;
-#X text 41 134 (c) 2010 IOhannes m zm�lnig \, Institute of Electronic
+#X text 41 134 (c) 2010 IOhannes m zmölnig \, Institute of Electronic
 Music and Acoustics (IEM) \, University of Music and Performing Arts
 \, Graz \, Austria;
 #N canvas 25 49 420 300 META 0;
-#X text 10 10 VERSION 0.2.1;
+#X text 10 10 VERSION 0.2.2;
 #X text 10 30 AUTHOR IOhannes m zmoelnig <zmoelnig@iem.at>;
 #X text 10 50 NAME iemnet;
 #X text 10 70 LICENSE GPL-2;
+#X text 9 91 DESCRIPTION high performance networking with Pd;
 #X restore 20 20 pd META;
+#X text 47 84 iemnet: high performance networking with Pd;
diff --git a/pd-lib-builder/CHANGELOG.txt b/pd-lib-builder/CHANGELOG.txt
new file mode 100644
index 0000000..971cf80
--- /dev/null
+++ b/pd-lib-builder/CHANGELOG.txt
@@ -0,0 +1,97 @@
+Changelog for Makefile.pdlibbuilder.
+
+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)
diff --git a/pd-lib-builder/Makefile.pdlibbuilder b/pd-lib-builder/Makefile.pdlibbuilder
new file mode 100644
index 0000000..a0194b2
--- /dev/null
+++ b/pd-lib-builder/Makefile.pdlibbuilder
@@ -0,0 +1,1297 @@
+# Makefile.pdlibbuilder dated 2018-03-15
+version = 0.5.1
+
+# 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
+# - <classname>.class.sources
+# - <classname>.class.ldflags
+# - <classname>.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
+#
+# 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.
+#
+# <classname>.class.sources:
+# Source file(s) (C or C++) specific to class <classname>. Use this for
+# multiple-source classes or when class name != source file basename.
+#
+# 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.
+#
+# <classname>.class.ldflags and <classname>.class.ldlibs:
+# Define ldflags resp. ldlibs specific to class <classname>. These flags are
+# added to platform-specific flags defined by Makefile.pdlibbuilder, and flags
+# defined in your Makefile for the whole library. Note: cflags can not be
+# defined per class in the current implementation.
+#
+# datafiles and datadirs:
+# All extra files you want to include in binary distributions of the
+# library: abstractions and help patches, example patches, meta patch, readme
+# and license texts, manuals, sound files, etcetera. Use 'datafiles' for all
+# files that should go into your lib rootdir and 'datadirs' for complete
+# directories you want to copy from source to distribution.
+#
+# 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.
+#
+# 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
+# <classname>: force clean build of an individual class
+# <sourcefile>.pre: make preprocessor output file in current working directory
+# <sourcefile>.lst: make asm/source output file in current working directory
+#
+# install: install executables and data files
+# clean: remove build products from source tree
+#
+# help: print help text
+# vars: print makefile variables
+# allvars: print all variables
+# depend: print generated prerequisites
+# 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 <lib.name>-meta.pd are part of the libdir
+# convention. Help patches for each class and abstraction are supposed to be
+# available. Makefile.pdlibbuilder does not force the presence of these files
+# however. It does not automatically include such files in libdir installations.
+# Data files you want to include in distributions must be defined explicitly in
+# your Makefile.
+#
+#
+#=== Makefile.pdlibbuilder syntax conventions ==================================
+#
+#
+# Makefile.pdlibbuilder variable names are lower case. Default make variables,
+# environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR)
+# are upper case. Use target 'allvars' to print all variables and their values.
+#
+# 'Fields' in data variables are separated by dots, like in 'foo.class.sources'.
+# Words in variables expressing a function or command are separated by dashes,
+# like in 'make-lib-executable'.
+#
+#
+#=== useful make options =======================================================
+#
+#
+# Use 'make -d <target>' to print debug details of the make process.
+# Use 'make -p <target>' to print make's database.
+#
+#
+#=== 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
+
+
+################################################################################
+### 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 ###########################################################
+################################################################################
+
+
+#=== sources ===================================================================
+
+
+# (re)define <classname>.class.sources using file names in class.sources
+
+define add-class-source
+$(notdir $(basename $v)).class.sources += $v
+endef
+
+$(foreach v, $(class.sources), $(eval $(add-class-source)))
+
+# derive class names from <classname>.class.sources variables
+sourcevariables := $(filter %.class.sources, $(.VARIABLES))
+classes := $(basename $(basename $(sourcevariables)))
+
+# accumulate all source files specified in makefile
+classes.sources := $(sort $(foreach v, $(sourcevariables), $($v)))
+all.sources := $(classes.sources) $(lib.setup.sources) \
+  $(shared.sources) $(common.sources)
+
+
+#=== object files ==============================================================
+
+
+# construct object filenames from all C and C++ source file names
+classes.objects := $(addsuffix .o, $(basename $(classes.sources)))
+common.objects := $(addsuffix .o, $(basename $(common.sources)))
+shared.objects := $(addsuffix .o, $(basename $(shared.sources)))
+lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources)))
+all.objects = $(classes.objects) $(common.objects) $(shared.objects) \
+  $(lib.setup.objects)
+
+
+#=== executables ===============================================================
+
+
+# use recursive variables here because executable extension is not yet known
+
+# construct class executable names from class names
+classes.executables = $(addsuffix .$(extension), $(classes))
+
+# construct shared lib executable name if shared sources are defined
+ifdef shared.sources
+  shared.lib = lib$(lib.name).$(shared.extension)
+else
+  shared.lib =
+endif
+
+
+################################################################################
+### platform detection #########################################################
+################################################################################
+
+
+#=== operating system ==========================================================
+
+
+# The following systems are defined: Linux, Darwin, Windows. GNU and
+# GNU/kFreeBSD are treated as Linux to get the same options.
+
+uname := $(shell uname)
+
+ifeq ($(findstring $(uname), Linux GNU GNU/kFreeBSD), $(uname))
+  system = Linux
+endif
+
+ifeq ($(uname), Darwin)
+  system = Darwin
+endif
+
+ifeq ($(filter MINGW% MSYS%, $(uname)), $(uname))
+  system = Windows
+endif
+
+# Unfortunately not all Mingw versions provide a link cc > gcc, therefore
+# gcc is hardcoded here (but not if CC is redefined).
+ifeq ($(system), Windows)
+  ifeq ($(origin CC), default)
+    CC = gcc
+  endif
+endif
+
+# evaluate possible system-specific multiline defines from library makefile
+$(eval $(for$(system)))
+
+
+# TODO: Cygwin, Android
+
+
+#=== architecture ==============================================================
+
+
+# native architecture of the build machine
+build.arch := $(shell uname -m)
+
+# Target architecture as reported by compiler. Give precedence to eventual
+# user-defined compiler. The first field of <cpu>-<vendor>-<os> is extracted.
+ifneq ($(origin CXX), default)
+  dumpmachine.cpu = $(firstword $(subst -, ,$(shell $(CXX) -dumpmachine)))
+else
+  dumpmachine.cpu = $(firstword $(subst -, ,$(shell $(CC) -dumpmachine)))
+endif
+
+# Target architecture as reported by compiler is only used for Windows at the
+# moment. For other systems this still has to be tested.
+ifeq ($(system), Windows)
+  target.arch = $(dumpmachine.cpu)
+else
+  target.arch = $(build.arch)
+endif
+
+
+################################################################################
+### variables per platform #####################################################
+################################################################################
+
+
+#=== flags per architecture ====================================================
+
+
+# Set architecture-dependent cflags, mainly for Linux. For Mac and Windows,
+# arch.c.flags are overriden below.
+
+# Raspberry Pi 1st generation
+ifeq ($(target.arch), armv6l)
+  arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard
+
+# Beagle, Udoo, RPi2 etc.
+else ifeq ($(target.arch), armv7l)
+  arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard
+
+# Intel 32 bit, build with SSE and SSE2 instructions
+else ifeq ($(findstring $(target.arch), i386 i686), $(target.arch))
+  arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2
+
+# Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions
+else ifeq ($(findstring $(target.arch), x86_64), $(target.arch))
+  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 ================================================
+
+
+# On OSX we try to build fat binaries by default. It is assumed that OSX i386
+# can build for ppc and OSX x86_64 can't. TODO: try to refine this condition.
+# LLVM-clang doesn't support -fcheck-new, therefore this flag is omitted for
+# OSX x86_64.
+
+
+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
+  version.flag := $(filter $(cflags), -mmacosx-version-min=%)
+  ifeq ($(target.arch), i386)
+    cxx.flags := -fcheck-new
+    arch := ppc i386 x86_64
+    version.flag = -mmacosx-version-min=10.4
+  endif
+  ifeq ($(target.arch), x86_64)
+    arch := i386 x86_64
+    version.flag = -mmacosx-version-min=10.6
+  endif
+  ifneq ($(filter -mmacosx-version-min=%, $(cflags)),)
+    version.flag := $(filter -mmacosx-version-min=%, $(cflags))
+  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 ($(MINGW_CHOST), i686-w64-mingw32)
+    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 ($(filter i%86 mingw32, $(target.arch)), $(target.arch))
+     arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse
+  else ifeq (x86_64, $(target.arch))
+    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.dll"
+  c.ldlibs :=
+  cxx.flags := -fcheck-new
+  cxx.ldflags := -static-libgcc -static-libstdc++ -shared \
+    -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll"
+  cxx.ldlibs :=
+  shared.extension = dll
+  shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd.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)" $(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 := $(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: 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.
+
+# '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.dll")
+endif
+
+# print Makefile.pdlibbuilder version
+$(info ++++ info: using Makefile.pdlibbuilder version $(version))
+
+# 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 .o, $(basename $($2.class.sources))) \
+  $(addsuffix .o, $(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 lib$(lib.name).$(shared.extension) $(shared.objects) \
+  $($1.ldlibs) $(shared.ldlibs)
+endef
+
+# rule for linking objects in shared executable
+# build recipe is in macro 'link-shared'
+lib$(lib.name).$(shared.extension): $(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.
+
+%.o:: %.c
+	$(call make-object-file,c)
+
+%.o:: %.cc
+	$(call make-object-file,cxx)
+
+%.o:: %.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 .o, $(basename $($v.class.sources))) \
+  $(addsuffix .o, $(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)$(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
+
+
+#=== 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:
+
diff --git a/pd-lib-builder/README.md b/pd-lib-builder/README.md
new file mode 100644
index 0000000..75e070e
--- /dev/null
+++ b/pd-lib-builder/README.md
@@ -0,0 +1,113 @@
+
+
+### Makefile.pdlibbuilder ###
+
+Helper makefile for Pure Data external libraries.
+Written by Katja Vetter March-June 2015 for the public domain. No warranties.
+Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's
+ShakeNMake.
+
+GNU make version >= 3.81 required.
+
+
+### 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 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.
+
+
+### 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. A tips&tricks page is in the works. 
+
+
+### 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 ###
+
+
+Here are a few projects using the Makefile.pdlibbuilder approach:
+
+https://github.com/pure-data/helloworld
+
+https://github.com/electrickery/pd-cyclone (stable)
+
+https://github.com/porres/pd-cyclone (experimental)
+
+https://git.iem.at/pd/iemguts
+
+https://git.iem.at/pd/iemnet
+
+https://git.iem.at/pd/iem_ambi
+
+https://git.iem.at/pd/mediasettings
+
+https://git.iem.at/pd-gui/punish
+
+https://github.com/residuum/PuRestJson
+
+More examples will be referenced here when they are available. 
diff --git a/pd-lib-builder/tips-tricks.md b/pd-lib-builder/tips-tricks.md
new file mode 100644
index 0000000..084f9ef
--- /dev/null
+++ b/pd-lib-builder/tips-tricks.md
@@ -0,0 +1,211 @@
+pd-lib-builder cheatsheet
+=========================
+
+# Creating special builds
+
+## cross-compiling W32 binaries from linux
+
+I'm using the following to cross-compile W32 binaries on my Debian/64bit system,
+using `mingw-w64`.
+
+Assuming you have unzipped a W32 package for Pd into `${WINPDPATH}`, run:
+
+    make system=Windows pdbinpath="${WINPDPATH}/bin/" pdincludepath="${WINPDPATH}/src/" CC=i686-w64-mingw32-gcc
+
+(if the project uses C++, you might also need to set `CXX=i686-w64-mingw32-g++`)
+
+## building double-precision externals
+
+At the time of writing (2018-02) 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:
+
+   make CPPFLAGS="-DPD_FLOATSIZE=64"
+
+## building externals for W64 (64-bit Windows)
+
+At the time of writing (2018-02) there is no official Pd that supports
+W64 yet.
+However, if you do get hold of an experimental W64 Pd, you can
+easily build your externals for this environment with
+
+   make CPPFLAGS="-DPD_LONGINTTYPE=__int64" CC=x86_64-w64-mingw32-gcc
+
+
+To build a double-precision external for W64, use something like:
+
+   make CPPFLAGS="-DPD_LONGINTTYPE=__int64 -DPD_FLOATSIZE=64" CC=x86_64-w64-mingw32-gcc
+
+
+## TODO universal binaries on OSX
+
+
+# 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 <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." 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).
+
diff --git a/tcpclient.c b/tcpclient.c
index cf0bc18..4caaeaf 100644
--- a/tcpclient.c
+++ b/tcpclient.c
@@ -46,7 +46,7 @@ typedef struct _tcpclient {
   int              x_serialize;
 
   int             x_fd; // the socket
-  char           *x_hostname; // address we want to connect to as text
+  const char     *x_hostname; // address we want to connect to as text
   int             x_connectstate; // 0 = not connected, 1 = connected
   int             x_port; // port we're connected to
   long            x_addr; // address we're connected to as 32bit int
diff --git a/udpclient.c b/udpclient.c
index ca6d0c5..728ac69 100644
--- a/udpclient.c
+++ b/udpclient.c
@@ -43,7 +43,7 @@ typedef struct _udpclient {
   t_iemnet_receiver*x_receiver;
 
   int             x_fd; // the socket
-  char           *x_hostname; // address we want to connect to as text
+  const char     *x_hostname; // address we want to connect to as text
   int             x_connectstate; // 0 = not connected, 1 = connected
   u_short         x_port; // port we're sending to
   u_short         x_sendport; // port we're sending from