Skip to content

Commit

Permalink
Merge commit '77525265694bac50ed94c5ef62ebbae680c72ab0'
Browse files Browse the repository at this point in the history
  • Loading branch information
umlaeute committed Mar 14, 2024
2 parents 6ecaf9c + 7752526 commit 9e32956
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 47 deletions.
8 changes: 8 additions & 0 deletions pd-lib-builder/CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
73 changes: 49 additions & 24 deletions pd-lib-builder/Makefile.pdlibbuilder
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -102,6 +102,8 @@ version = 0.6.0
# Optional user variables for make command line or environment:
#
# - PLATFORM
# - extension
# - floatsize
#
# Deprecated path variables:
#
Expand Down Expand Up @@ -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 (<system>-<cpu>-<floatsize>.<ext>)
#
# CPPFLAGS:
# Preprocessor flags which are not strictly required for building.
#
Expand Down Expand Up @@ -442,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 ====================================================

Expand All @@ -451,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.
Expand Down Expand Up @@ -584,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

Expand Down Expand Up @@ -639,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)
Expand Down Expand Up @@ -683,6 +706,7 @@ endif
### variables: files ###########################################################
################################################################################

object.extension = $(extension).o

#=== sources ===================================================================

Expand All @@ -709,10 +733,10 @@ all.sources := $(classes.sources) $(lib.setup.sources) \


# 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)))
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)

Expand All @@ -723,12 +747,13 @@ all.objects = $(classes.objects) $(common.objects) $(shared.objects) \
# construct class executable names from class names
classes.executables := $(addsuffix .$(extension), $(classes))

# Construct shared lib executable name if shared sources are defined. If
# extension and shared extension are not identical, use both to facilitate co-
# installation for different platforms, like .m_i386.dll and .m_amd64.dll.
# 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
ifeq ($(extension), $(shared.extension))
shared.lib = lib$(lib.name).$(shared.extension)
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
Expand Down Expand Up @@ -790,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
Expand Down Expand Up @@ -874,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

Expand Down Expand Up @@ -949,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)


Expand All @@ -974,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
Expand Down Expand Up @@ -1005,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
Expand Down
3 changes: 2 additions & 1 deletion pd-lib-builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 48 additions & 22 deletions pd-lib-builder/tips-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ pd-lib-builder cheatsheet

# Creating special builds

## building for non-native platform
## Building for non-native platform

Using pd-lib-builder >=0.6.0 we can define variable `PLATFORM` to specify a
target triplet for cross-compilation. Assuming a W32 package for Pd is unzipped
into path `${PDWIN32}`, to build for Windows 32 bit:

make PLATFORM=i686-w64-mingw32 PDDIR="${PDWIN32}"

#### older pd-lib-builder versions
#### Older pd-lib-builder versions

Using pd-lib-builder < 0.6.0, in the absence of variable `PLATFORM`, you would
instead override variables `system`, `target.arch`, `CC` and / or `CXX`,
`STRIP`. Example:

make system=Windows target.arch=i686 CC=i686-w64-mingw32-gcc STRIP=i686-w64-mingw32-strip PDDIR="${PDWIN32}"

#### toolchains
#### Toolchains

To build for non-native OS and/or architecture you need a cross toolchain. On
Linux such toolchains are relatively easy to get. For example Debian Buster
Expand All @@ -34,31 +34,51 @@ for a given platform to get the whole toolchain):
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
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"
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.

## building externals for W64 (64-bit Windows)
For example, to build a "fat" external for both 64-bit Intel and Arm (Apple
Silicon):

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 arch="x86_64 arm64"

make CPPFLAGS="-DPD_LONGINTTYPE=__int64" CC=x86_64-w64-mingw32-gcc
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
~~~

To build a double-precision external for W64, use something like:
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).

make CPPFLAGS="-DPD_LONGINTTYPE=__int64 -DPD_FLOATSIZE=64" CC=x86_64-w64-mingw32-gcc
## Building double-precision externals

At the time of writing (2023-07-06) there is no official Pd that supports
double-precision numbers yet.
However, if you do get hold of an experimental double-precision Pd, you can
easily build your externals for 64-bit numbers, by passing `floatsize=64`
as an argument to `make`.
Starting with Pd>=0.54, double precision externals use different extensions
from traditional (single-precision) externals.
The extension consists of the OS ("linux", "darwin", "windows"), the CPU
architecture ("amd64" (x86_64), "i386" (x86), "arm64",...) and the floatsize
in bits ("64" for double-precision), followed by the system's native extension
for dynamic libraries (".dll" on Windows, ".so" on macOS/Linux/un*xes).
As of pd-lib-builder==0.7.0, you have to manually pass this extension:

## 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
Expand Down Expand Up @@ -98,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`

Expand All @@ -109,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:

Expand All @@ -117,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:
Expand All @@ -126,24 +149,25 @@ 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:

~~~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:

Expand All @@ -170,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:
Expand All @@ -184,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:

Expand Down Expand Up @@ -213,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.
Expand All @@ -228,4 +255,3 @@ git submodule update

In general, I would suggest to **avoid** `git submodule`, and instead use the
better `git subtree` (above).

0 comments on commit 9e32956

Please sign in to comment.