Code Monkey home page Code Monkey logo

pd-lib-builder's Introduction

# Pure Data

This is the README file for Pd, a free real-time computer music system.

## Getting Pd

You can get Pd for Linux, macOS, or Microsoft Windows from:

    http://msp.ucsd.edu/software.html

or from the Pure Data community site:

    https://puredata.info

Installation instructions are in INSTALL.txt and the Pd Manual at:

    http://msp.ucsd.edu/Pd_documentation/index.htm

If you download and unpack Pd, you will also find the Manual locally
in the file "doc/1.manual/index.htm".

Linux (or FreeBSD): In some Linux installations you can download Pd via "apt-get
install puredata" or "dnf install puredata"; otherwise you can download
the source and compile it as described in INSTALL.txt.

Apple macOS: Pd binaries are distributed as a "tar.gz" file. The web browser
will probably download this archive into your Downloads folder. Double click
to extract the archived Mac app which you can then run and/or drag into your
Applications folder.

Microsoft Windows: Pd binaries are distributed as a self-extracting executable
or as a "zip" file.

If you have questions about Pd or if you wish to be notified of releases,
you can browse and/or join the Pd mailing list:

    https://lists.puredata.info/listinfo

Many extensions to Pd are available, for instance to add video and 3D graphics.
The easiest way to get these is to use the "Find externals" command in Pd's Help
menu.

## Copyright

Except as otherwise noted, all files in the Pd distribution are

    Copyright (c) 1997-2024 Miller Puckette and others.

For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see LICENSE.txt included in the Pd distribution.
(Note that Tcl/Tk, expr, and some other files are copyrighted separately).

## Acknowledgements

Thanks to Harry Castle, Krzysztof Czaja, Mark Danks, Christian Feldbauer,
Guenter Geiger, Kerry Hagan, Trevor Johnson, Fernando Lopez-Lezcano, Adam
Lindsay, Karl MacMillan, Thomas Musil, Toshinori Ohkouchi, Winfried Ritsch,
Vibeke Sorensen, Rand Steiger, Hans-Christoph Steiner, Shahrokh Yadegari, Dan
Wilcox, David Zicarelli, IOhannes m zmoelnig, Christof Ressi, Antoine Rousseau,
Alexandre Torres Porres, Claude Heiland-Allen, Roman Haefeli, Lucarda, Seb Shader
and probably many others for contributions of code, documentation, ideas, and
expertise. This work has received support from Intel, Keith McMillen Instruments,
ZKM, IEM, and UCSD.

pd-lib-builder's People

Contributors

danomatika avatar katjav avatar umlaeute avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pd-lib-builder's Issues

pdbinpath vs PDBINDIR on w32 builds

it seems that (with 872c34b) the PDBINDIR var is not honoured. instead the pdbinpath is used. shouldn't it be the other way around if PDDIR is set?

$ export CC=gcc
$ mingw32-make PDDIR="Pd"
gcc -DPD -I "C:\projects\libdir./Pd/src" -DMSW -DNT   -DVERSION='"1.11"' -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=pentium4 -msse -msse2 -mfpmath=sse -o foo.o -c foo.c
++++ info: linking objects in foo.dll for lib foo
gcc -static-libgcc -shared -Wl,--enable-auto-import "/pd.dll"    -o foo.dll foo.o
gcc.exe: error: C:/Program Files/Git/pd.dll: No such file or directory
Makefile.pdlibbuilder:796: recipe for target 'foo.dll' failed
mingw32-make: *** [foo.dll] Error 1

datafiles with special characters ($)

while converting a project to the pd-lib-builder Makefile I ran into the following problem:

one (well, two) of datafiles contains a $ in the filename (yes, ugly; but cannot be helped now).
unfortunately this makes make install bail out with an error:

$ find abs/ -name "*.pd"
abs/$args-help.pd

$ cat Makefile
# ...
datafiles = $(wildcard abs/*.pd)
#...

$ make install DESTDIR=/tmp/bla
...
install: cannot stat 'abs/-help.pd': No such file or directory
Makefile.pdlibbuilder:1017: recipe for target 'install-datafiles' failed
make: *** [install-datafiles] Error 1

$ 

is there any way to support such awkward filenames?

Target architecture detection for MinGW 32 and 64

Pdlibbuilder has a crude form of automatic platform detection (OS and architecture, this issue is about the latter). Native architecture is found from uname -m, and architecture-dependent build settings are made in the assumption that the target architecture is the same.

Now that @Lucarda is paving the way towards 64 bit Windows for Pd and externals, it turns out that native architecture detection makes no sense for Mingw-w64. We need to query the compiler for architecture as @umlaeute has clarified, since Mingw-w64 can build for 32 and 64 bit Windows on 'any' architecture. It is inherently a form of cross compiling. See issue #37 that sparked the discussion. This new issue is opened because the subject went far beyond the original issue.

In short, we need two methods for architecture detection (native and target). Native architecture was always detected by pdlibbuilder with:

machine := $(shell uname -m)

where -m is short for --machine

For target architecture, the compiler can be queried with argument -dumpmachine (suggested by @umlaeute). The report comes in the form:

<cpu>-<vendor>-<os>

See https://www.gnu.org/software/autoconf/manual/autoconf-2.65/html_node/Specifying-Target-Triplets.html for info about target triplets. The first field (cpu) must be extracted. It may happen that one compiler (C or C++) is user-specified for cross-compilation and the other not, so both must be queried and a user-defined compiler must have precedence over a default compiler to find the intended target architecture.

For the moment at least, target architecture detection would be used for MinGW / MSYS only, where the choice is between compilers for 32 and 64 bit Intel / AMD. It would be nice to apply it for all platforms, but they are too diverse for a uniform solution so this must go step by step if possible at all. Anyway for MinGW it is now most important.

I'll summarize some implementation suggestions from the discussion in issue #37 later, if still relevant.

Makefile.pdlibbuilder ignores PDBINDIR

When having PD installed in none of the Windows "obvious" places (e.g. Program Files or %AppData%...etc), the Makefile's script seems to ignore the user-specified PDBINDIR when it creates the linker line that pulls in pd.dll. From the Makefile (Makefile.pdlibbuilder):

"shared.ldflags = -static-libgcc -shared "$(pdbinpath)/pd.dll"

...where it uses the 'pdbinpath' var instead...which is earlier detected with this:
"

ifeq ($(system), Windows)
pkglibdir := $(APPDATA)/Pd
ifndef pdbinpath
pdbinpath := $(shell ls -d "$(PROGRAMFILES)/pd/bin")
endif
ifndef pdincludepath
pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/src")
endif
endif
"

...which apparently takes no regard to what PDBINDIR has specified.

RESULT: the linker tries to use "/pd.dll" (since it obviously didn't find my pd's "bin" dir in any of the obvious places) and fails

WORKAROUND/HACK:
towards the top of the Makefile.pdlibbuilder, hardcode like so:
pdbinpath = $(PDBINDIR)

(This is obviously bad but it shows that this is in fact the problem, as the linking will succeed with this modification)
(For reference, my Pure Data is installed in "c:\standalone_apps\pd-0.49-0")

why no variable 'pdpath'?

The Makefile Template of pd-extended defines variable 'PD_PATH', from where 'PD_INCLUDE' (for pd API files) is derived per platform, plus paths for binaries (for Windows only).

Makefile.pdlibbuilder only has 'pdincludepath' for the directory where pd API files should sit, and 'pdbinpath' for the directory where pd.dll should be found on Windows. It doesn't define a root path for pd components, which is particularly inconvenient when you have to type two Windows paths on command line. Why not introduce 'pdpath'?

The thing is, a root path could only work if a standardized directory tree is defined for all pd flavors and build situations. And that is not at all the case. A portable install as used in a centralized build differs from a regular install. Standard pd install locations vary not only per platform (which we can detect), but there's also layout variations per pd flavor. All together it seems impossible to define just one variable and derive appropriate paths from it for all cases. Yet I'd like to make things a bit more convenient. I don't know how yet, this is just brainstorming. Let's start with an overview of standard paths per pd flavor and per platform:

vanilla pd regular installation:

Linux: /usr/include/pd
OSX: /Applications/Pd*.app/Contents/Resources/src
Windows: %PROGRAMFILES%/pd/src
Windows: %PROGRAMFILES%/pd/bin

pd-extended regular installation:

Linux: /usr/include/pdextended
OSX: /Applications/Pd-extended*.app/Contents/Resources/include/pdextended
Windows: %PROGRAMFILES%/pd/include/pdextended
Windows: %PROGRAMFILES%/pd/bin

centralized build:

Linux: $(PD_PATH)/include/pd
OSX: $(PD_PATH)/include/pd
Windows: $(PD_PATH)/include/pd, $(PD_PATH)/bin

Linux:

vanilla pd regular installation: /usr/include/pd
pd-extended regular installation: /usr/include/pdextended
centralized build: $(PD_PATH)/include/pd

OSX:

vanilla pd regular installation: /Applications/Pd*.app/Contents/Resources/src
pd-extended regular installation: /Applications/Pd-extended*.app/Contents/Resources/include/pdextended
centralized build: $(PD_PATH)/include/pd

Windows:

vanilla pd regular installation: %PROGRAMFILES%/pd/src
vanilla pd regular installation: %PROGRAMFILES%/pd/bin
pd-extended regular installation: %PROGRAMFILES%/pd/include/pdextended
pd-extended regular installation: %PROGRAMFILES%/pd/bin
centralized build: $(PD_PATH)/include/pd
centralized build: $(PD_PATH)/bin

Pd-l2ork is another flavor to reckon with. It is the active fork of pd-extended and has inherited the build system. Many makefiles in the pd-l2ork repositories still speak of 'Pd-extended' but it installs under its own application name nowadays. There's no pd-lib-builder in pd-l2ork yet but some day they may want to update actively maintained libs that use it.

Well I don't know what to make of this now. To be continued.

C++ externals fail on Windows

just taking @katjav's comment in #39 to a new issue:

All went fine, except one thing: Pd wouldn't load the C++ object in my test set (it works fine on Linux).
I haven't got the opportunity to figure out why but intuition says 'name mangling troubles'.
I don't know how Pd (from Miller's distribution) was built.

(priority of) standard search path for pd includes

Variable 'pdincludepath' stores a path to pd API headers (m_pd.h etc.) needed for compilation. If not specified as make command argument, the first path found from the following standard list is used:

  1. $(externalsdir)../pd/src
  2. pd include path of an installed Pd-extended package
  3. pd include path of an installed Pd package

This order of priority was determined at the conception of Makefile.pdlibbuilder more than a year ago, facilitating the transition between centralized and decentralized model of lib development.

The search list needs to be reconsidered now. I guess Pd-extended's unmaintained API should removed from the defaults list so no one can build or develop unintentionally against it.

Add a subdir with tests / examples to the project

In my local pdlibbuilder repo I have untracked source files for the purpose of testing. They are organized in 4 small libs to test various kinds of builds:

  • single-class executables
  • multi-class executable
  • multiple-source-file single-class executable (C++)
  • single-class executables + shared lib

Although this set covers much of pdlibbuilder's functionality, it is not a systematical test approach since it isn't part of the distribution. The classes are copied from my personal pd projects so it makes no sense to include them with pdlibbuilder.

Ideally pdlibbuilder should have specially designed test libs or objects which could not only serve for regression testing but also as examples that illustrate pdlibbuilder features. Also a part of it could integrate with the externals tutorial (http://pdstatic.iem.at/externals-HOWTO/). Then we could get rid of the puredata/helloworld repository with its discouraging submodule.

honor pkg-config for pd

Pd provides a pkg-config script, which could be utilized to guess the correct flags

$ pkg-config --cflags pd
-DPD -I/usr/include/pd
$ pkg-config --libs pd
$

for{Linux,Windows,Darwin} should not use uname

to use OS-specific sets, pd-lib-builder provides the for* mechanism

ifdef forWindows
   ldflags += -lws2_32
endef

unfortunately, this doesn't work when cross-compiling (manually adding system=Windows), because the for* defines are evaluated based on the output of uname.

instead i think the for* variants should be expanded based on the value of system.

-std=c99 / gnu99

I ran into a snag when using pd-lib-builder to compile an external:

grambidec.c:367:5: error: ‘for’ loop initial declarations are only allowed
in C99 mode
    for(int i = 0; i < 7; i++) {
    ^
grambidec.c:367:5: note: use option -std=c99 or -std=gnu99 to compile your
code

Do we need to include c99 / gnu99 CFLAG in the Makefile?

class.sources that are added in a `forLinux` clause are not built

i just stumbled upon this while modernizing hcs.

if i have an objectclass that should only build for a given platform, the documentation says to wrap it into a define forXXX clause:

# forLinux, forDarwin, forWindows:
# Shorthand for 'variable definitions for Linux only' etc. Use like:
# define forLinux
# cflags += -DLINUX
# class.sources += linuxthing.c
# endef

However, doing so does not actually work: the specified classes are not build at all.
However, the define does work, as can be seen from other variables used in the clause.

consider the following replacement of the helloworld Makefile:

# Makefile to build class 'helloworld' for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules.

# library name
lib.name = helloworld

# input source file (class name == source file basename)
class.sources =
datafiles = helloworld-meta.pd README.md

define forLinux
  class.sources += test.c
  datafiles += helloworld-help.pd
endef

# include Makefile.pdlibbuilder from submodule directory 'pd-lib-builder'
PDLIBBUILDER_DIR=pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder

Running make does not do anything.
Running make install will install the following files:

$ ls -1 .../helloworld/
helloworld-help.pd
helloworld-meta.pd
README.md

so the "helloworld.pd_linux" is missing, but the "helloworld-help.pd" gets installed.

Target 'install-strip' breaks unilinear chain of rules

Target install-strip was introduced as a response to extremely bloated executables from Mingw-w64, as an outcome of discussion in issue #42. Size reduction after stripping doesn't normally outweigh the reduction of options for troubleshooting, but that is different with Mingw-w64 where non-stripped sizes are up to 10 times larger, no matter if built with static standard lib or not.

With target install-strip as an alternative to regular install which doesn't strip, stripping appears to be optional, a choice up to anyone who builds. But that is no longer the case when for example:

  1. a library makefile defines install as prerequisite of a custom target, or
  2. a library makefile calls make install as a submake process in a custom target, or
  3. a central makefile in a multi-lib project calls make install

Think of test targets or special packaging targets in a lib makefile. Considering such use cases, 'parallel' installation targets aren't a good solution to provide optional stripping. In general a chain of make rules should be unilinear, but install-strip formally and effectively introduces a diverging build route rather than an extra option on a given route. This is not justified since stripped and non-stripped executables are supposed to be identical regarding their functionality.

A variable instead of alternative target could keep the chain of rules in pdlibbuilder unilinear from source files to installed executables, so lib makefiles and project makefiles can rely on that. Stripping could be done like:

make install strip=yes

with a strip 'function' (multiline define) which does nothing by default and only strips when strip=yes, in target install-executables.

confusing documentation about cross-compilation

The tips-and-tricks starts with a chapter "cross-compiling on linux x86_64 for other platforms":

## cross-compiling on linux x86_64 for other platforms

why does it say "linux x86_64"? the cross-build toolchains are independent of the host. e.g. (in Debian) there are "i686-linux-gnu" packages available for the arm64 architecture, and afaics you can install mingw on your raspberry.

i suggest to just drop the architecture specifier and call it "cross-compiling on linux for other platforms and architectures"

Suggestion to add “-static” for windows (64-bit Pd is coming and all externals needs recompilation: they are all 32-bit)

As the windows 64-bit Pd is coming I suggest to include “-static” in the following lines:

line 581 c.ldflags = -static -static-libgcc -shared \

line 589 shared.ldflags = -static -static-libgcc -shared "$(pdbinpath)/pd.dll"

I have tested compilation for w32 with these lines added and externals worked without the need to ship dependencies.

As an example here is https://github.com/porres/pd-cyclone [coll]. Download pkg below:

static-flag-tests.zip

The above pkg has different compilations. To test functionality close and reopen Pd on each test. (you can open ”coll-help.pd“ ::: make sure you don’t have another ”Cyclone“ somewhere in your path.)

[coll] is one case (as many others) that uses pthread and adding the “-static” flag nulls the need to ship pthread implementation.

Any thought against the “-static” flag?

no uniform naming scheme for important variables ('PD_PATH', 'objectsdir')

Variable names in makefiles should be consistent and intuitive, in particular those which are meant to be used as make command arguments. Unfortunately, a few important Makefile.pdlibbuilder variables are inconsistent in various ways. Consider 'PD_PATH' and 'objectsdir', variables to hold a path to a directory. They are passed as arguments from pd-extended's central makefile to lib makefiles, and 'inherited' by Makefile.pdlibbuilder for compatibility. But the variable names are hard to memorize because:

  1. - one is upper case, the other lower case
  2. - one has an underscore, the other not
  3. - one speaks about path, the other about directory

Regarding upper / lower case, these are the general guidelines I try to follow:

  • upper case for standard flag categories (like CFLAGS) and utilities (like CC), plus DESTDIR
  • lower case for variables defined by the makefile(s)

See https://www.gnu.org/software/make/manual/html_node/Makefile-Conventions.html. A makefile must honour CFLAGS, CC, DESTDIR etcetera, but not define them or at least allow them to be overridden from the environment because people expect that. Variables for paths (like 'prefix' and 'libdir'), should be in lower case and defined by the makefile. DESTDIR is an exception, a path component used for staged install.

Our variable 'objectsdir' defines a path to the root directory of installed pd libs and is an alias for 'pkglibdir', which in turn is a conventional name. Although 'objectsdir' is unfortunately not an apt name for a directory with libraries, at least it follows the lower case convention.

Variable PD_PATH in pd-extended's central makefile defines the path to the pd root dir inside the centralized build system. The Makefile Template has platform dependent PD_PATH definitions. Why uppercase? The Makefile Template has upper case for most (but not all) makefile-defined variables, I can't see a rule behind it.

What about the path / dir distinction? A path is a trajectory in the file system, leading to a directory or file. The meaning of 'directory' is ambiguous. It is often used to denote 'folder', more highlighting the content aspect than the trajectory aspect. Therefore I liked 'path' better initially, and implemented variables 'pdincludepath' and 'pdbinpath' analogous to 'PD_PATH' but leaving away the upper case and underscore. In retrospect I regret my choice for 'path'. Canonical names like 'includedir' and 'libdir' all specify directories with the meaning of paths, not folders. I should better have followed makefile conventions than etymological considerations. Then we could have had a coherent variable set like this:

  • pddir: path to pd root dir
  • pdincludedir: path to pd includes dir (where the pd API files are)
  • pdbindir: path to pd binary dir (where the pd executable is)
  • pdlibdir: path to pd libraries root dir

Much easier to memorize. 'PD_PATH' and 'objectsdir' could have been implemented as aliases. But... aliases are still possible of course.

OSX fat binaries, default or not?

Currently Makefile.pdlibbuilder builds fat binaries by default. This is not good practice but it follows from the fact that many people still use 32 bit Pd while being on 64 bit OSX. Some Pd libs, notably GEM, aren't ready for OSX 64 bit yet.

In the context of deken packages the fat binary default is helpful for the moment. But in the context of a centralized build system like pdl2ork and purr-data, it is not. There should at least be an easy method to override the default, from command line but also from a central makefile.

But I would like to change default build to native architecture. With commit e8a3a48 on branch optional fat, the variable to define target architecture is called 'arch' and 'fat' is equivalent for 'i386 x86_64'. The arch variable is in fact a cross compilation convenience variable and I'm planning to expand its use for other cross compilation purposes too.

Enable cross compilation

There needs to be a way to override the architecture detection to enable cross compilation, e.g. for compilation with MXE or armhf from amd64.

pd.dll: file format not recognized

Hi,

I am trying to compile pd-psycho (https://github.com/porres/pd-psycho) on Windows10 with pd-vanilla (0.49.0) using pd-lib-builder but I keep encountering error messages that I don't really understand.

I am using MinGW to be able to use the "make" command under Windows.
However, as soon as I use "make" in the pd-psycho folder, it returns this error :
69371075_399392444022904_2478048670679826432_n

Since I explicitely refered to C:/Pd/bin, I can't understand why the command returns "C:/Pd/bin/pd.dll: file not recognized: file format not recognized".

Do someone have an idea on how to fix this please ? What am I doing wrong ?

Thanks by advance

specifying a given m_pd.h file

howdy, seems pd-lib-builder will automatically search and find for a pd-extended in your system to build classes, but I'm using new stuff from new vanilla. The way I'm doing it is that i'm replacing files in extended by the new vanilla ones, but there's gotta be a better way that either exists and I dont know about or that we'd have to create.

I was thinking of a way to specify in the makefile which files to use in a subfolder or something, then I could have it in some of my projects subfolder.

cheers

target 'post' forces rebuild of executables

Commit c428456 (following up on pull request #4) introduced targets 'pre' and 'post' to be run before and after target 'all'. Turns out that target 'post' forces rebuild of executables (linking the .o files) even when .o files haven't changed. It was declared as phony target, but even without that it still acts as such, probably because 'post' is not a file so make can't compare timestamps.

While it is not a show stopper, this behavior can be very annoying when developing or bug fixing files in a large collection. Currently I don't see a solution.

Xcode 10 can't build C++ for OSX < 10.9

Reportedly, option -mmacosx-version-min can't be defined lower than 10.9 when building C++ code with Xcode 10. I don't want to set -mmacosx-version-min=10.9 for all Pd libs and regardless of Xcode version. On the other hand I don't know right away how to define it conditionally, which would require two extra checks:

  • is there any C++ code involved in the build?
  • what Xcode version is being used?

Even if these conditions can be checked, the total set of conditional checks for minimum OSX version will become rather kludgy. So I'm hoping that someone comes up with a better idea. In the meantime you may need to override the minimum OSX version as defined in the makefile. This can be done on command line like so:

$ make version.flag="-mmacosx-version-min=10.9"

(edit: version.flag is not considered an 'API' variable, use only as temporary workaround)

If your library needs a specific minimum version anyway, it can be defined in the lib Makefile:

define forDarwin
cflags = -mmacosx-version-min=10.9
endef

[Question] How to compile an external in windows.

Not familiar at all with Windows development tools.
On Linux, I know I can just follow the instructions in the Readme of pd-lib-builder and then do make in a terminal and viola!
What is the equivalent in Windows of make? I have installed Visual Studio 2017 and the C++ tools and those are working fine. Do I need Mingw or Cygwin to compile an external?
Also, I' m using Purrr Data, if that makes a difference.
Thanks in advance!

how to provide extra dynamic libraries via cmdline?

if i have an external that needs to (dynamically) link against libfoo, i can specify this dependency by adding a line:

ldlibs=-lfoo

However, it seems to be impossible to add libraries during the build process.
I would have expected the build-system to honour the LDLIBS variable, but it seems to be ignored (unlike CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS)

$ make LDLIBS=-lfoo
[...]
cc -rdynamic -shared -fPIC -Wl,-rpath,"\$ORIGIN",--enable-new-dtags -o xxx.pd_linux xxx.o  -lc -lm   

(Right now, my main motivation for this is to be able to fix broken 3rd party buildsystems, but there might be more mainstream use-cases as well).

using $(lib.version) in cflags

i would like to pass the automatic variable $(lib.version) as a preprocessor define to the compiler.
So i added the following to my Makefile:

 cflags = -DMY_VERSION=$(lib.version)

and test it with:

 $ make vars | grep cflags
 variable cflags = -DMY_VERSION=0.1.2

so far so good (0.1.2 being the version as defined in my meta-patch)
unfortunately, during the actual build the $(lib.version) is not expanded:

 $ make
 [...]
 cc -DUNIX -DPD -I "/usr/include/pd/" -fpic -DMY_VERSION= -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=core2 -mfpmath=sse -msse -msse2 -msse3  -o foo.o -c foo.c
 [...]

since i'm notoriously bad with make's variable expansion, I'm stuck...

develop source packaging target 'dist', prerequisite for debian / deken packaging

I want to develop target 'dist' as a generalized source packager for distribution targets 'dpkg-source', 'deken-source' / 'deken'. Targets would relate to each other like so:

# make source package
dist: distclean | $(all.sources) $(datafiles) $(datadirs) $(extradist)
    <commands>

# make Debian source package
dpkg-source: dist
    <commands>

# make deken source package
deken-source: dist
    <commands>

# make deken binary package with embedded source package
deken: deken-install
    make deken-source && <other commands>

# make deken binary-only package
deken-no-source: deken-install
    <commands>

# install binaries and data files at custom location for deken packaging
deken-install: installpath := $(tmpdir)/$(lib.name)
deken-install: install

Fred Jan has embedded source tarballs in deken packages 'by hand' and we found it a satisfactory approach. The source tarball doesn't clutter Pd's help browser, and a user can extract it at a location of choice.

With rules chained as indicated above you could still build targets individually, like 'deken-source' for source-only package, or 'deken-install' if you want to test the build before packaging.

Big question though........ how to implement target 'dist'? Conventionally you would replicate the source tree directory layout somewhere and populate it with all the files required for a complete build. For projects with standardized source tree this isn't too difficult because most file names are known to the makefile system anyway. But Makefile.pdlibbuilder doesn't dictate a standard layout. Moreover it doesn't forbid recursive make. Developing a method that can reliably reproduce any source tree may take a long long time.

As a simplistic (temporary?) alternative I've considered packaging the cleaned source tree straight away while exluding specified files and directories. Top level source dir in the package should be renamed $(lib.name)-$(lib.version), which I understand is possible with commands tar and zip.

Is there a good reason to not use the simplistic approach?

[WIP]--Windows paths “pd/bin” and “pd/src”

This data comes from various make allvars:

Showing what "$(PROGRAMFILES)/pd/bin") and "$(PROGRAMFILES)/pd/src") get:

Msys1 (win8.1)

Lucarda@T410 /c/KatjaV/rawCfiles
$ make allvars
ls: C:\Program Files (x86)/pd/bin: No such file or directory
ls: C:\Program Files (x86)/pd/src: No such file or directory

...

variable (environment) PROGRAMDATA = C:\ProgramData
variable (environment) PROGRAMFILES = C:\Program Files (x86)
variable (environment) PROGRAMFILES(X86) = C:\Program Files (x86)
variable (environment) PROGRAMW6432 = C:\Program Files

Msys2 (win8.1)

Lucarda@T410 MINGW32 /c/KatjaV/rawCfiles
$ make allvars
ls: cannot access 'C:\Program Files/pd/bin': No such file or directory
ls: cannot access 'C:\Program Files/pd/src': No such file or directory

.....

variable (environment) PROGRAMFILES = C:\Program Files
variable (environment) ProgramData = C:\ProgramData
variable (environment) ProgramFiles(x86) = C:\Program Files (x86)
variable (environment) ProgramW6432 = C:\Program Files

Msys2 (win10)

Lucarda@win10exthd MINGW32 /g/win10onexthd/KatjaV/rawCfiles
$ make allvars
ls: cannot access 'C:\Program Files/pd/bin': No such file or directory
ls: cannot access 'C:\Program Files/pd/src': No such file or directory

....

variable (environment) PROGRAMFILES = C:\Program Files
variable (environment) ProgramData = C:\ProgramData
variable (environment) ProgramFiles(x86) = C:\Program Files (x86)
variable (environment) ProgramW6432 = C:\Program Files

Msys2 (win10)

Lucarda@win10exthd MINGW64 /g/win10onexthd/KatjaV/rawCfiles
$ make allvars
ls: cannot access 'C:\Program Files/pd/bin': No such file or directory
ls: cannot access 'C:\Program Files/pd/src': No such file or directory

...

variable (environment) PROGRAMFILES = C:\Program Files
variable (environment) ProgramData = C:\ProgramData
variable (environment) ProgramFiles(x86) = C:\Program Files (x86)
variable (environment) ProgramW6432 = C:\Program Files

Here some usefull information. The nsi-installer script:

https://github.com/pure-data/pure-data/blob/master/msw/build-nsi.sh

[WIP] --How to handle Windows 32 and 64 bit externals

Extracted from @umlaeute @ #38 :

that problem only exists if somebody wants to use both 32bit and 64bit Pds on the same machine.

in theory Pd already has a mechanism to care for this: use a different filename extension for each platform/architecture. e.g. on linux we use .pd_linux instead of the (more standard) .so.

on w32 we could already use .m_i386 instead of the (more standard) .dll. so far nobody has adopted to this. also there currently isn't a .m_amd64 searched for on w64.

so, i think:

  • W32 32bit externals should use the .m_i386 extension instead of .dll
  • Pd ought to support the .m_amd64 extension for w64
    • for now "W32 64bit" (W64) externals should use .dll as the extension

that's probably a much better scheme than using different paths for different architectures, as it allows a single deken-external to contain multiple architectures.

Enable setting flags for OS

For my library that I am migrating from the Pd extended library template to the pd-lib-builder Makefile, I need to set OS dependent flags.

Would it be OK to include variables like windows.cflags, linux.ldflags and mac.ldlibs?

Are there any other variables that would make sense to make OS or even architecture dependent? I would implement that and file a pull request for it.

doc not clear

could u give me basic example for creating a Makefile file for compiling the code for Windows.
For example, this is what i wrote for compiling on my Linux system:

lib.name = mylib
class.sources = counter.c
include ../Makefile.pdlibbuilder

what should i write for creating a .dll and not a .pd_linux?

allow 'cflags' on all levels (class, classes, common, shared)

It would be nice if 'cflags' can be defined on every level in addition to the global 'cflags':

  • <classname>.class.cflags (applies to all sources for the given Pd class)
  • common.cflags (applies to the static library)
  • shared.cflags (applies to the shared library)

For an easy way to set the cflags for a single object file, see #65 (comment))

Use cases:

  • control compile time configurations (debug levels, default values, enable/disable features)
  • DLL export/import macros
  • pass different language specific compiler options (C vs. C++)
  • ...

LDFLAGS?

how can I add additional linker flags?

e.g. in Debian packages are routinely build with hardening enabled, which involves adding/overriding CPPFLAGS, C(XX)FLAGS and LDFLAGS.

interrelated questions around static linking of 'standard libs' with Mingw

Externals built with Mingw need linking with GNU standard libs. If these aren't provided as dlls by Pd (which is the case with vanilla Pd), an external lib must provide its own solution. Pdlibbuilder implements static linking of standard libs by default, with the effect that externals are in this respect equally 'self-supporting' for all platforms. This arrangement leaves a couple of issues though:

  1. libpthread is not included in Mingw standard libs
  2. static linking of standard libs makes externals super bloated
  3. this bloat is not optional

Issue 1 means that externals using pthread are not out of the box equally self-supporting on Windows. This could be solved by treating libpthread as a standard lib in pdlibbuilder.

The importance of issue 2 scales with the number of externals loaded in memory and number of externals distributed in a package. It seems that externals for Windows are roughly 10 times 'too large'. This may be reduced a bit by stripping.

Issue 3 is particularly annoying for monolithic Pd distributions; even when standard libs are provided as dlls, pdlibbuilder will still build those bloated externals. Therefore pdlibbuilder should support an opt-out.

I'm thinking how to solve issue 1 and 3 together, by introducing variables defining statically linked 'standard' libs including libpthread. Something like:


c.standard.static := -static-libgcc -static -lpthread
cxx.standard.static := -static-libgcc -staticlibc++ -static -lpthread

These variables should be evaluated last in the command line for the linker, such that -static will not affect other libs eventually specified. Not sure if this order of options will work. If it works, a central makefile could easily opt out of static standard libs by defining the variables empty in the call to make.

i386 architecture deprecated for macOS

Mentioned as an aside under #49, the compiler in OSX 10.14 gives this warning when trying to build a fat binary (i386 x86_64). This deserves its own issue because a deprecation warning today may be an error anytime soon.

@megrimm, can you check if the i386 architecture is included in the binary file despite the warning, or is it a native-only build now? You can run command 'file' on the binary to find out.

can we build for macOS 10.6? ("symbol not found ___exp10")

I sent this email to the Pd list and now I wonder if the issue is related to the fact we cannot build for 10.6 with pd-lib-builder, what you say?

here's the screenshot with the error of loading an external built with -pd-lib-builder in macOS 10.6.8
unnamed

detect target platform consistently, and simplify cross compilation

Experimental branch target-detection has a series of commits (starting with 1dc4219b) to implement consistent target platform detection (hardware architecture and OS). It is based on target triplet as reported by compiler with option -dumpmachine. This option was first suggested by @umlaute in the context of issue #37, to detect architectures in the case of Windows.

The jungle of GNU triplets scared me initially (some are even quadruplets), but of course pdlibbuilder supports only a small subset of them. For our purposes, the only distinction that triplets can't make is between armv6 and armv7 (both arm-linux-gnueabihf). For armv6 (first gen RPi, RPi Zero) I stayed with autodetection in native compilation only, and it must be explicited otherwise.

Commit 262143b introduces an optional user variable PLATFORM to hold a target triplet which is parsed as the base name for tools required for the build (preprocessor, compilers and strip). If the tool chain is available in the path, no other variables need to be overriden for cross compilation. It is the equivalent of autotools' --host parameter.

Using variable PLATFORM I could cross-compile for Linux (Intel and ARM), OSX and Windows, on a single Linux 64 bit machine with cross tool chains installed for all those platforms. Native compilation must be tested as well to make sure no regressions are introduced. I have no access to the following platforms: OSX > 10.8, Windows 64 and 32 bit. @Lucarda, @danomatika, could you give branch target-detection a try?

Oh I almost forgot to mention: fat-binary-default for OSX was sacrified in the process. It felt so stupid to poll the compiler for its target architecture and still add another architecture. See commit 65e9fc7 for a user-friendly alternative to get fat builds.

arch.cflags on causes FTBFS on armel

just to let you know: the automatic optimization flags for armv7l (namely: -mfloat-abi=hard) are causing build-failures on Debian's armel architecture.

 $ uname -a
 Linux abel 3.16.0-4-armmp-lpae #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) armv7l GNU/Linux

Here is a build-log for pd-cyclone (0.2~beta1), as maintained by @electrickery (which does not yet use the newest Makefile.pdlibbuilder)

removing any arch-flags as in the following invokation fixes the problem, so it is not a big problem.

 make arch.fags=""

multiple arch builds incompatible with dependency checking

Currently Makefile.pdlibbuilder makes fat binaries by default on OSX. A non clean build attempt on OSX (10.5 at least) triggers gcc error because some preprocessor flags are not allowed for multiple architecture builds, amongst them flag -MM which is used for dependency checking.

I don't want to remove dependency checking or disable it by default. Developers expect a build system to do dependency checking and it would be confusing if you need to enable it explicitly.

Alternatively we could build single architecture by default and introduce a make option to build fat binaries.

out of tree builds?

is it possible to build out-of-sourcetree builds (that is: running the build from a directory different from where the Makefile is)?

this can be very handy when building for multiple configurations (architectures, optimization,...)

allow multiple architectures of support-library

This is related to #40, but targeted at the "support library" that is built from shared.sources.

problem

Consider a library "foobar", that builds the object classes for [foo] and [bar], that both share some functionality which is collected into a shared library libfoobar.

The makefile looks like:

lib.name = foobar
class.sources = \
   foo.c \
   bar.c \
   $(empty)
shared.sources = \
   foobar.c \
   barfoo.c \
   $(empty)

PDLIBBUILDER_DIR=pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder

When compiling for Win32 (make) and Win64 (make extension=m_amd64) i get the following files:

# Win32
foobar/foo.dll
foobar/bar.dll
foobar/libfoobar.dll
# Win64
foobar/foo.m_amd64
foobar/bar.m_amd64
foobar/libfoobar.dll

I can almost merge the two directories into a single one that provides binaries for both Win32 and Win64, if it wasn't for the foobar/libfoobar.dll fiile which exists in both directories but is different (as both files have a different architecture).

variable for alternative extensions

Pd externals for Linux have extension 'pd_linux' by default but Pd also knows a couple of architecture specific Linux extensions: 'l_i386', 'l_ia64' and 'l_arm'. This is useful for 'fat library' distributions (because you can't easily make fat binaries for Linux). For convenience Makefile.pdlibbuilder could build with an appropriate alternative extension if a user specifies a certain variable, like use-alternative-extension=yes.

arch.flags vs CFLAGS

i just noticed that arch.flags will prevail even when i pass CFLAGS to the build:

 $ make CFLAGS="-g -O2"

will still contain -march=core2 -mfpmath=sse -msse -msse2, which is contrary to what i would expect, as these architecture specific flags are not strictly needed to produce a valid build (and i would argue that they are rather optimization flags).

I understand that it is easy to add another arch.flags="" to make call to make, but i think the current behaviour does not follow POLA.

-fpic vs -fPIC

I recently stumbled across a build-failure due to the use of -fpic in the pd-lib-builder.

This was on a not-so-common architecture (s390x).
The full failing build-log can be found here.

Replacing -fpic with -fPIC (upper-case) fixed the problem (replacing the compiler-flags was enough, btw)

So i wonder: why is pd-lib-builder using -fpic instead of -fPIC in the first place? (it seems that the latter is far more widespread).

shared.ldflags broken when building with helper-library

now that we have a simple test-suite it starts to catch errors :-)

using the shared.ldflags variable fails to expand the shared.lib variable.

Building the tests/multishared/ project I get:

$ make -C tests/multishared
make: Entering directory '<<pd-lib-builder>>/tests/multishared'
++++ info: using Makefile.pdlibbuilder version 0.6.0
++++ info: using Pd API /usr/include/pd/m_pd.h
++++ info: making target all in lib multishared
++++ info: making shared.o in lib multishared
cc -DPD -I "/usr/include/pd" -DUNIX  -fPIC  -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=core2 -mfpmath=sse -msse -msse2 -msse3 -o shared.o -c shared.c
++++ info: linking objects in shared lib libmultishared.pd_linux.so
cc -rdynamic -fPIC -shared -Wl,-soname,  -o libmultishared.pd_linux.so shared.o -lc -lm
/usr/bin/ld: SONAME must not be empty string; ignored
++++ info: making multisharedB.o in lib multishared
cc -DPD -I "/usr/include/pd" -DUNIX  -fPIC  -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=core2 -mfpmath=sse -msse -msse2 -msse3 -o multisharedB.o -c multisharedB.c
++++ info: linking objects in multisharedB.pd_linux for lib multishared
cc -rdynamic -shared -fPIC -Wl,-rpath,"\$ORIGIN",--enable-new-dtags    -o multisharedB.pd_linux multisharedB.o  -lc -lm   libmultishared.pd_linux.so
++++ info: making multisharedA.o in lib multishared
cc -DPD -I "/usr/include/pd" -DUNIX  -fPIC  -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops -fomit-frame-pointer -march=core2 -mfpmath=sse -msse -msse2 -msse3 -o multisharedA.o -c multisharedA.c
++++ info: linking objects in multisharedA.pd_linux for lib multishared
cc -rdynamic -shared -fPIC -Wl,-rpath,"\$ORIGIN",--enable-new-dtags    -o multisharedA.pd_linux multisharedA.o  -lc -lm   libmultishared.pd_linux.so
++++info: target all in lib multishared completed
make: Leaving directory '<<pd-lib-builder>>/tests/multishared'
$

note the lines:

cc -rdynamic -fPIC -shared -Wl,-soname,  -o libmultishared.pd_linux.so shared.o -lc -lm
/usr/bin/ld: SONAME must not be empty string; ignored

my compiler (gcc-9.2.1) is quite forgiving, so the test actually succeeds.
however, on other systems (notably an android test-build), the -Wl,-soname, flag (without an actual SONAME) raises an error (that's how i discovered it).

Running git bisect I see that this was introduced with a6975e9 (reordering makefile sections)

please tag releases

having tagged releases makes it much easier to refer to a given version than a commitish.

ld: library not found for -lgcc_s.10.5 (macOS 10.14.3)

getting this error with pd-lib-builder 5.1

ld: library not found for -lgcc_s.10.5
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I do NOT get this error with pd-lib-builder 5.0 meaning everything compiles just fine.
I tried running a diff on the two but fail to see what has changed to cause error. Maybe im missing a new flag I need to add in my Makefile?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.