diff --git a/pd-lib-builder/CHANGELOG.txt b/pd-lib-builder/CHANGELOG.txt index 5bdfce6..c432148 100644 --- a/pd-lib-builder/CHANGELOG.txt +++ b/pd-lib-builder/CHANGELOG.txt @@ -1,5 +1,13 @@ 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 diff --git a/pd-lib-builder/Makefile.pdlibbuilder b/pd-lib-builder/Makefile.pdlibbuilder index 7d6c11c..38a1220 100644 --- a/pd-lib-builder/Makefile.pdlibbuilder +++ b/pd-lib-builder/Makefile.pdlibbuilder @@ -1,5 +1,5 @@ # Makefile.pdlibbuilder dated 2019-12-21 -version = 0.6.0 +version = 0.7.0 # Helper makefile for Pure Data external libraries. # Written by Katja Vetter March-June 2015 for the public domain. No warranties. @@ -102,6 +102,8 @@ version = 0.6.0 # Optional user variables for make command line or environment: # # - PLATFORM +# - extension +# - floatsize # # Deprecated path variables: # @@ -205,6 +207,19 @@ version = 0.6.0 # 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. # @@ -369,78 +384,6 @@ externalsdir ?= .. 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 .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 .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 - - ################################################################################ ### target platform detection ################################################## ################################################################################ @@ -514,6 +457,14 @@ 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 ==================================================== @@ -523,7 +474,7 @@ target.arch := $(firstword $(target.triplet)) # $ gcc -Q --help=target # ARMv6: Raspberry Pi 1st gen, not detectable from target.arch -ifeq ($(shell uname), armv6l) +ifeq ($(shell uname -m), armv6l) arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard # ARMv7: Beagle, Udoo, RPi2 etc. @@ -565,7 +516,7 @@ ifeq ($(system), Linux) cxx.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags cxx.ldlibs := -lc -lm -lstdc++ shared.extension = so - shared.ldflags := -rdynamic -fPIC -shared -Wl,-soname,$(shared.lib) + shared.ldflags = -rdynamic -fPIC -shared -Wl,-soname,$(shared.lib) endif @@ -656,14 +607,14 @@ ifeq ($(system), Windows) extension = dll c.flags := c.ldflags := -static-libgcc -shared \ - -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll" + -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.dll" + -Wl,--enable-auto-import "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll" cxx.ldlibs := shared.extension = dll - shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd.dll" + shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll" stripflags = --strip-all endif @@ -711,7 +662,7 @@ endif CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags) # preprocessor flags -cpp.flags := -DPD -I "$(PDINCLUDEDIR)" $(cpp.flags) $(CPPFLAGS) +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) @@ -720,7 +671,7 @@ depcheck.flags := $(cpp.flags) $(cflags) LDFLAGS := $(arch.ld.flags) # now add the same ld flags to shared dynamic lib -shared.ldflags := $(shared.ldflags) $(LDFLAGS) +shared.ldflags += $(LDFLAGS) # accumulated flags for C compiler / linker c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS) @@ -733,6 +684,84 @@ 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 ########################################################### ################################################################################ @@ -786,7 +815,7 @@ endif # store path to pd.dll; if not found, ls will give a useful error ifeq ($(system), Windows) - pddll := $(shell ls "$(PDBINDIR)/pd.dll") + 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 @@ -870,8 +899,8 @@ define link-class $(compile-$1) \ $($1.ldflags) $($2.class.ldflags) \ -o $2.$(extension) \ - $(addsuffix .o, $(basename $($2.class.sources))) \ - $(addsuffix .o, $(basename $(common.sources))) \ + $(addsuffix .$(object.extension), $(basename $($2.class.sources))) \ + $(addsuffix .$(object.extension), $(basename $(common.sources))) \ $($1.ldlibs) $($2.class.ldlibs) $(shared.lib) endef @@ -917,13 +946,13 @@ endif define link-shared $(compile-$1) \ $(shared.ldflags) \ - -o lib$(lib.name).$(shared.extension) $(shared.objects) \ + -o $(shared.lib) $(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) +$(shared.lib): $(shared.objects) $(info ++++ info: linking objects in shared lib $@) $(if $(filter %.cc %.cpp, $(shared.sources)), \ $(call link-shared,cxx), \ @@ -945,13 +974,13 @@ endef # Three rules to create .o files. These are double colon 'terminal' rules, # meaning they are the last in a rules chain. -%.o:: %.c +%.$(object.extension):: %.c $(call make-object-file,c) -%.o:: %.cc +%.$(object.extension):: %.cc $(call make-object-file,cxx) -%.o:: %.cpp +%.$(object.extension):: %.cpp $(call make-object-file,cxx) @@ -970,8 +999,8 @@ 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))) +$v.$(extension): $(addsuffix .$(object.extension), $(basename $($v.class.sources))) \ + $(addsuffix .$(object.extension), $(basename $(common.sources))) endef # evaluate explicit prerequisite rules for all classes @@ -1001,7 +1030,7 @@ endif # 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) +$(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 diff --git a/pd-lib-builder/README.md b/pd-lib-builder/README.md index 187b132..41b37fd 100644 --- a/pd-lib-builder/README.md +++ b/pd-lib-builder/README.md @@ -35,7 +35,8 @@ Makefile.pdlibbuilder at the end of the Makefile. Like so: datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt - include Makefile.pdlibbuilder + PDLIBBUILDER_DIR=. + include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder For files in class.sources it is assumed that class name == source file @@ -68,6 +69,43 @@ 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 ### diff --git a/pd-lib-builder/tests/Makefile b/pd-lib-builder/tests/Makefile new file mode 100644 index 0000000..53b261c --- /dev/null +++ b/pd-lib-builder/tests/Makefile @@ -0,0 +1,15 @@ +# 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) diff --git a/pd-lib-builder/tests/_template_/Makefile b/pd-lib-builder/tests/_template_/Makefile new file mode 100644 index 0000000..ea5fd4f --- /dev/null +++ b/pd-lib-builder/tests/_template_/Makefile @@ -0,0 +1,24 @@ +# 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) diff --git a/pd-lib-builder/tests/_template_/_template_-help.pd b/pd-lib-builder/tests/_template_/_template_-help.pd new file mode 100644 index 0000000..94425c6 --- /dev/null +++ b/pd-lib-builder/tests/_template_/_template_-help.pd @@ -0,0 +1,4 @@ +#N canvas 335 160 450 300 12; +#X obj 143 125 _template_; +#X msg 143 93 7; +#X connect 1 0 0 0; diff --git a/pd-lib-builder/tests/_template_/_template_-meta.pd b/pd-lib-builder/tests/_template_/_template_-meta.pd new file mode 100644 index 0000000..7f997bf --- /dev/null +++ b/pd-lib-builder/tests/_template_/_template_-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/_template_/_template_.c b/pd-lib-builder/tests/_template_/_template_.c new file mode 100644 index 0000000..ef5293e --- /dev/null +++ b/pd-lib-builder/tests/_template_/_template_.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/make-from-template.sh b/pd-lib-builder/tests/make-from-template.sh new file mode 100755 index 0000000..d4f6ade --- /dev/null +++ b/pd-lib-builder/tests/make-from-template.sh @@ -0,0 +1,46 @@ +#!/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 diff --git a/pd-lib-builder/tests/multifor/Makefile b/pd-lib-builder/tests/multifor/Makefile new file mode 100644 index 0000000..48950f2 --- /dev/null +++ b/pd-lib-builder/tests/multifor/Makefile @@ -0,0 +1,39 @@ +# 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 diff --git a/pd-lib-builder/tests/multifor/README.md b/pd-lib-builder/tests/multifor/README.md new file mode 100644 index 0000000..6b336c7 --- /dev/null +++ b/pd-lib-builder/tests/multifor/README.md @@ -0,0 +1,9 @@ +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. diff --git a/pd-lib-builder/tests/multifor/multifor-help.pd b/pd-lib-builder/tests/multifor/multifor-help.pd new file mode 100644 index 0000000..05d9e93 --- /dev/null +++ b/pd-lib-builder/tests/multifor/multifor-help.pd @@ -0,0 +1,7 @@ +#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; diff --git a/pd-lib-builder/tests/multifor/multifor-meta.pd b/pd-lib-builder/tests/multifor/multifor-meta.pd new file mode 100644 index 0000000..2c696e3 --- /dev/null +++ b/pd-lib-builder/tests/multifor/multifor-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multifor/multiforA.c b/pd-lib-builder/tests/multifor/multiforA.c new file mode 100644 index 0000000..c52f68c --- /dev/null +++ b/pd-lib-builder/tests/multifor/multiforA.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multifor/multiforB.c b/pd-lib-builder/tests/multifor/multiforB.c new file mode 100644 index 0000000..74618ea --- /dev/null +++ b/pd-lib-builder/tests/multifor/multiforB.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multilib/Makefile b/pd-lib-builder/tests/multilib/Makefile new file mode 100644 index 0000000..00f20dc --- /dev/null +++ b/pd-lib-builder/tests/multilib/Makefile @@ -0,0 +1,32 @@ +# 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 diff --git a/pd-lib-builder/tests/multilib/README.md b/pd-lib-builder/tests/multilib/README.md new file mode 100644 index 0000000..4a80535 --- /dev/null +++ b/pd-lib-builder/tests/multilib/README.md @@ -0,0 +1,8 @@ +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. diff --git a/pd-lib-builder/tests/multilib/multilib-help.pd b/pd-lib-builder/tests/multilib/multilib-help.pd new file mode 100644 index 0000000..fc3931d --- /dev/null +++ b/pd-lib-builder/tests/multilib/multilib-help.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multilib/multilib-meta.pd b/pd-lib-builder/tests/multilib/multilib-meta.pd new file mode 100644 index 0000000..ef08c03 --- /dev/null +++ b/pd-lib-builder/tests/multilib/multilib-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multilib/multilib.c b/pd-lib-builder/tests/multilib/multilib.c new file mode 100644 index 0000000..82d0eac --- /dev/null +++ b/pd-lib-builder/tests/multilib/multilib.c @@ -0,0 +1,8 @@ + +void multilibA_setup(void); +void multilibB_setup(void); + +void multilib_setup(void) { + multilibA_setup(); + multilibB_setup(); +} diff --git a/pd-lib-builder/tests/multilib/multilibA.c b/pd-lib-builder/tests/multilib/multilibA.c new file mode 100644 index 0000000..4760746 --- /dev/null +++ b/pd-lib-builder/tests/multilib/multilibA.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multilib/multilibB.c b/pd-lib-builder/tests/multilib/multilibB.c new file mode 100644 index 0000000..ce7c4d8 --- /dev/null +++ b/pd-lib-builder/tests/multilib/multilibB.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multiple/Makefile b/pd-lib-builder/tests/multiple/Makefile new file mode 100644 index 0000000..eac1412 --- /dev/null +++ b/pd-lib-builder/tests/multiple/Makefile @@ -0,0 +1,28 @@ +# 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 diff --git a/pd-lib-builder/tests/multiple/README.md b/pd-lib-builder/tests/multiple/README.md new file mode 100644 index 0000000..04c8c97 --- /dev/null +++ b/pd-lib-builder/tests/multiple/README.md @@ -0,0 +1,8 @@ +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. diff --git a/pd-lib-builder/tests/multiple/multiple-help.pd b/pd-lib-builder/tests/multiple/multiple-help.pd new file mode 100644 index 0000000..0e4a43e --- /dev/null +++ b/pd-lib-builder/tests/multiple/multiple-help.pd @@ -0,0 +1,7 @@ +#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; diff --git a/pd-lib-builder/tests/multiple/multiple-meta.pd b/pd-lib-builder/tests/multiple/multiple-meta.pd new file mode 100644 index 0000000..ef08c03 --- /dev/null +++ b/pd-lib-builder/tests/multiple/multiple-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multiple/multipleA.c b/pd-lib-builder/tests/multiple/multipleA.c new file mode 100644 index 0000000..dc7bfb0 --- /dev/null +++ b/pd-lib-builder/tests/multiple/multipleA.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multiple/multipleB.c b/pd-lib-builder/tests/multiple/multipleB.c new file mode 100644 index 0000000..aaf50ba --- /dev/null +++ b/pd-lib-builder/tests/multiple/multipleB.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multiplexx/Makefile b/pd-lib-builder/tests/multiplexx/Makefile new file mode 100644 index 0000000..7438f0a --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/Makefile @@ -0,0 +1,28 @@ +# 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 diff --git a/pd-lib-builder/tests/multiplexx/README.md b/pd-lib-builder/tests/multiplexx/README.md new file mode 100644 index 0000000..82aab9b --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/README.md @@ -0,0 +1,8 @@ +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. diff --git a/pd-lib-builder/tests/multiplexx/multiplexx-help.pd b/pd-lib-builder/tests/multiplexx/multiplexx-help.pd new file mode 100644 index 0000000..b715d1a --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/multiplexx-help.pd @@ -0,0 +1,7 @@ +#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; diff --git a/pd-lib-builder/tests/multiplexx/multiplexx-meta.pd b/pd-lib-builder/tests/multiplexx/multiplexx-meta.pd new file mode 100644 index 0000000..10132c9 --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/multiplexx-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multiplexx/multiplexxA.cpp b/pd-lib-builder/tests/multiplexx/multiplexxA.cpp new file mode 100644 index 0000000..e18b2f1 --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/multiplexxA.cpp @@ -0,0 +1,19 @@ +#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); +} diff --git a/pd-lib-builder/tests/multiplexx/multiplexxB.c b/pd-lib-builder/tests/multiplexx/multiplexxB.c new file mode 100644 index 0000000..41cd95a --- /dev/null +++ b/pd-lib-builder/tests/multiplexx/multiplexxB.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/multishared/Makefile b/pd-lib-builder/tests/multishared/Makefile new file mode 100644 index 0000000..9ccb169 --- /dev/null +++ b/pd-lib-builder/tests/multishared/Makefile @@ -0,0 +1,41 @@ +# 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 diff --git a/pd-lib-builder/tests/multishared/README.md b/pd-lib-builder/tests/multishared/README.md new file mode 100644 index 0000000..85bc79b --- /dev/null +++ b/pd-lib-builder/tests/multishared/README.md @@ -0,0 +1,9 @@ +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. diff --git a/pd-lib-builder/tests/multishared/multishared-help.pd b/pd-lib-builder/tests/multishared/multishared-help.pd new file mode 100644 index 0000000..da18aed --- /dev/null +++ b/pd-lib-builder/tests/multishared/multishared-help.pd @@ -0,0 +1,7 @@ +#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; diff --git a/pd-lib-builder/tests/multishared/multishared-meta.pd b/pd-lib-builder/tests/multishared/multishared-meta.pd new file mode 100644 index 0000000..088f750 --- /dev/null +++ b/pd-lib-builder/tests/multishared/multishared-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/multishared/multishared.h b/pd-lib-builder/tests/multishared/multishared.h new file mode 100644 index 0000000..2e7712a --- /dev/null +++ b/pd-lib-builder/tests/multishared/multishared.h @@ -0,0 +1,3 @@ +#include + +void multishared_foo(t_float f); diff --git a/pd-lib-builder/tests/multishared/multisharedA.c b/pd-lib-builder/tests/multishared/multisharedA.c new file mode 100644 index 0000000..9e8ae57 --- /dev/null +++ b/pd-lib-builder/tests/multishared/multisharedA.c @@ -0,0 +1,14 @@ +#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); +} diff --git a/pd-lib-builder/tests/multishared/multisharedB.c b/pd-lib-builder/tests/multishared/multisharedB.c new file mode 100644 index 0000000..ca7b669 --- /dev/null +++ b/pd-lib-builder/tests/multishared/multisharedB.c @@ -0,0 +1,14 @@ +#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); +} diff --git a/pd-lib-builder/tests/multishared/shared.c b/pd-lib-builder/tests/multishared/shared.c new file mode 100644 index 0000000..47284a2 --- /dev/null +++ b/pd-lib-builder/tests/multishared/shared.c @@ -0,0 +1,5 @@ +#include "multishared.h" + +void multishared_foo(t_float f) { + post("%s(%f)", __FUNCTION__, f); +} diff --git a/pd-lib-builder/tests/single/Makefile b/pd-lib-builder/tests/single/Makefile new file mode 100644 index 0000000..0d36005 --- /dev/null +++ b/pd-lib-builder/tests/single/Makefile @@ -0,0 +1,24 @@ +# 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) diff --git a/pd-lib-builder/tests/single/README.md b/pd-lib-builder/tests/single/README.md new file mode 100644 index 0000000..c752acb --- /dev/null +++ b/pd-lib-builder/tests/single/README.md @@ -0,0 +1,8 @@ +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. diff --git a/pd-lib-builder/tests/single/single-help.pd b/pd-lib-builder/tests/single/single-help.pd new file mode 100644 index 0000000..1d74e5c --- /dev/null +++ b/pd-lib-builder/tests/single/single-help.pd @@ -0,0 +1,4 @@ +#N canvas 335 160 450 300 12; +#X obj 143 125 single; +#X msg 143 93 7; +#X connect 1 0 0 0; diff --git a/pd-lib-builder/tests/single/single-meta.pd b/pd-lib-builder/tests/single/single-meta.pd new file mode 100644 index 0000000..57923af --- /dev/null +++ b/pd-lib-builder/tests/single/single-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/single/single.c b/pd-lib-builder/tests/single/single.c new file mode 100644 index 0000000..a35f10c --- /dev/null +++ b/pd-lib-builder/tests/single/single.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/subdir/Makefile b/pd-lib-builder/tests/subdir/Makefile new file mode 100644 index 0000000..ac68c2a --- /dev/null +++ b/pd-lib-builder/tests/subdir/Makefile @@ -0,0 +1,27 @@ +# 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) diff --git a/pd-lib-builder/tests/subdir/README.md b/pd-lib-builder/tests/subdir/README.md new file mode 100644 index 0000000..e5185e5 --- /dev/null +++ b/pd-lib-builder/tests/subdir/README.md @@ -0,0 +1,8 @@ +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. diff --git a/pd-lib-builder/tests/subdir/src/subdir.c b/pd-lib-builder/tests/subdir/src/subdir.c new file mode 100644 index 0000000..cdcc8ce --- /dev/null +++ b/pd-lib-builder/tests/subdir/src/subdir.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/subdir/src/subdir~.c b/pd-lib-builder/tests/subdir/src/subdir~.c new file mode 100644 index 0000000..ca3ed20 --- /dev/null +++ b/pd-lib-builder/tests/subdir/src/subdir~.c @@ -0,0 +1,13 @@ +#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); +} diff --git a/pd-lib-builder/tests/subdir/subdir-help.pd b/pd-lib-builder/tests/subdir/subdir-help.pd new file mode 100644 index 0000000..725f149 --- /dev/null +++ b/pd-lib-builder/tests/subdir/subdir-help.pd @@ -0,0 +1,4 @@ +#N canvas 335 160 450 300 12; +#X obj 143 125 subdir; +#X msg 143 93 7; +#X connect 1 0 0 0; diff --git a/pd-lib-builder/tests/subdir/subdir-meta.pd b/pd-lib-builder/tests/subdir/subdir-meta.pd new file mode 100644 index 0000000..3e0b529 --- /dev/null +++ b/pd-lib-builder/tests/subdir/subdir-meta.pd @@ -0,0 +1,9 @@ +#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; diff --git a/pd-lib-builder/tests/subdir/subdir~-help.pd b/pd-lib-builder/tests/subdir/subdir~-help.pd new file mode 100644 index 0000000..d3a782b --- /dev/null +++ b/pd-lib-builder/tests/subdir/subdir~-help.pd @@ -0,0 +1,4 @@ +#N canvas 335 160 450 300 12; +#X obj 143 125 subdir~; +#X msg 143 93 7; +#X connect 1 0 0 0; diff --git a/pd-lib-builder/tests/test-patches.sh b/pd-lib-builder/tests/test-patches.sh new file mode 100755 index 0000000..0d80177 --- /dev/null +++ b/pd-lib-builder/tests/test-patches.sh @@ -0,0 +1,70 @@ +#!/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 diff --git a/pd-lib-builder/tips-tricks.md b/pd-lib-builder/tips-tricks.md index c1795f4..1835687 100644 --- a/pd-lib-builder/tips-tricks.md +++ b/pd-lib-builder/tips-tricks.md @@ -3,16 +3,15 @@ pd-lib-builder cheatsheet # Creating special builds -## cross-compiling on linux x86_64 for other platforms +## 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. Example to build W32 binaries (assuming -package `mingw-w64` is installed and a W32 package for Pd is unzipped into a -path `${PDWIN32}`: +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=x86_64-w64-mingw32 PDDIR="${PDWIN32}" + make PLATFORM=i686-w64-mingw32 PDDIR="${PDWIN32}" -#### older pd-lib-builder versions +#### 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`, @@ -20,44 +19,66 @@ instead override variables `system`, `target.arch`, `CC` and / or `CXX`, make system=Windows target.arch=i686 CC=i686-w64-mingw32-gcc STRIP=i686-w64-mingw32-strip PDDIR="${PDWIN32}" -#### toolchains +#### Toolchains -Cross toolchains for relevant platforms in Debian Buster (install g++ -with dependencies for a given platform to get the whole tool chain): +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`) -OSX/MacOS cross tool chains are not distributed by Debian. Use project -`osxcross` from Thomas Poechtraeger to create the tools. +Cross toolchains for OSX/MacOS are not generally distributed. Project +`osxcross` from Thomas Poechtraeger can create them for Linux. -## building double-precision externals +## Universal binaries on macOS -At the time of writing (2018-02) there is no official Pd that supports +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: +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 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 + 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 @@ -97,6 +118,7 @@ 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` @@ -108,6 +130,7 @@ 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: @@ -116,6 +139,7 @@ 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: @@ -125,6 +149,7 @@ git subtree pull --prefix pd-lib-builder/ https://github.com/pure-data/pd-lib-bu ~~~ #### Pulling the updated subtree into existing clones + Again, nothing special. Just pull as always: @@ -132,8 +157,8 @@ Just pull as always: 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 @@ -141,8 +166,8 @@ More on the power of `git subtree` can be found online ### ~~`git submodule`~~ [DISCOURAGED] - #### Initial setup/check-out + To add a new submodule to your repository, just run `git submodule add` and commit the changes: @@ -169,6 +194,7 @@ 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: @@ -183,6 +209,7 @@ 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: @@ -212,6 +239,7 @@ 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. @@ -227,4 +255,3 @@ git submodule update In general, I would suggest to **avoid** `git submodule`, and instead use the better `git subtree` (above). -