pure-data / pd-lib-builder Goto Github PK
View Code? Open in Web Editor NEWHelper makefile for building Pure Data externals
Helper makefile for building Pure Data externals
# 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.
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
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?
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.
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 :=
endif
ifndef pdincludepath
pdincludepath :=
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")
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.
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.
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:
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.
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:
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.
The old Makefile template from SVN had support for Android (which may have bitrotted; I haven't tried it myself..). Could be nice if this build system supported it also.
Example in the wild: https://github.com/agraef/pd-lua/blob/master/Makefile#L158-L191
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
$
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
.
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?
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:
pd-lib-builder/Makefile.pdlibbuilder
Lines 158 to 163 in f087faf
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
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:
install
as prerequisite of a custom target, ormake install
as a submake process in a custom target, ormake 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
.
The tips-and-tricks starts with a chapter "cross-compiling on linux x86_64 for other platforms":
Lines 5 to 7 in df9eb41
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"
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:
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?
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:
Regarding upper / lower case, these are the general guidelines I try to follow:
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:
Much easier to memorize. 'PD_PATH' and 'objectsdir' could have been implemented as aliases. But... aliases are still possible of course.
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.
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.
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 :
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
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
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.
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:
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
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!
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).
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...
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
Is there a good reason to not use the simplistic approach?
pd 0.48-0 is out, and apparently there was a change in the filesystem structure. So we need an update here so it automatically finds it
cheers
This data comes from various make allvars
:
Showing what "$(PROGRAMFILES)/pd/bin")
and "$(PROGRAMFILES)/pd/src")
get:
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
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
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
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
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:
.m_i386
extension instead of .dll
.dll
as the extensionthat's probably a much better scheme than using different paths for different architectures, as it allows a single deken-external to contain multiple architectures.
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.
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?
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:
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
.
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:
libpthread
is not included in Mingw standard libsIssue 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.
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.
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.
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=""
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.
I was unable to compile 64-bit Cyclone without deleting “-march=pentium4“ on line 578:
arch.c.flags := -march=pentium4
-msse -msse2 -mfpmath=sse
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,...)
This is related to #40, but targeted at the "support library" that is built from shared.sources
.
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).
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.
As reported in residuum/PuRestJson#46 calling make
after a successful build gives an error message. I have traced the error to declare-object-target
(https://github.com/pure-data/pd-lib-builder/blob/master/Makefile.pdlibbuilder#L968), but I am unsure on how to fix it, as I am unsure about the intention of this definition.
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.
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).
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)
having tagged releases makes it much easier to refer to a given version than a commitish.
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.