aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bs/README69
-rw-r--r--bs/config.mk.default61
-rwxr-xr-xbs/cross-arch.sh82
-rw-r--r--bs/deps-audio.mk38
-rw-r--r--bs/deps-conflicts.mk14
-rw-r--r--bs/deps-input.mk45
-rw-r--r--bs/deps-misc.mk17
-rwxr-xr-xbs/mkconfig-header.sh88
-rw-r--r--bs/mkconfig.h.mk54
-rwxr-xr-xbs/mkdep.sh58
-rwxr-xr-xbs/mkdir_p.sh37
-rwxr-xr-xbs/mkdist.sh50
-rwxr-xr-xbs/pkginfo-header.sh16
-rwxr-xr-xbs/pkginfo.sh19
-rwxr-xr-xbuild.mk103
15 files changed, 751 insertions, 0 deletions
diff --git a/bs/README b/bs/README
new file mode 100644
index 000000000..c5992e34c
--- /dev/null
+++ b/bs/README
@@ -0,0 +1,69 @@
+bs - build system
+-----------------
+
+bs is an attempt at a fast and reliable build system that will let
+developers build mpd without having to deal with the complexity of
+autotools. It is still a work in progress, but it seems to be
+reasonably usable (to developers) and fast.
+
+It is designed from the ground up to work with cross-compilation, as well as
+multiple build targets/configurations from the same source tree (using the O
+variable).
+
+It is NOT intended to replace autotools for distribution maintainers
+or end users who are satisfied with autotools.
+
+SYNOPSIS
+--------
+
+# To build mpd in a directory "output"
+./build.mk O=output defconfig
+$EDITOR output/config.mk
+./build.mk O=output
+
+
+FEATURES
+--------
+
+* Designed for cross-compilation from the ground up
+* Designed to easily handle multiple build directories from the same source
+ tree. Just set the O variable when invoking make (see synopsis).
+* Automatic dependency analysis (if using GCC)
+* Highly configurable (no auto-detection of dependencies to get wrong)
+* Simple, no archaic M4 macros or unreadable auto-generated shell or makefiles
+ just human-maintained GNU Make and POSIX shell.
+
+
+config.mk
+---------
+
+This is the configuration file a user should edit if they wish to
+enable/disable features or tune settings. Once created, this
+will NOT be modified by the build system, so user settings will
+always be preserved.
+
+
+VARIABLES
+---------
+
+These are conventions, not hard and fast rules (as there's no good way to
+enforce them :)
+mixed-case or lower-case variables are used by bs internally.
+ALL_CAPS variables are designed to be changed by users.
+
+
+REQUIREMENTS
+------------
+
+GNU Make, POSIX shell + common UNIX tools (awk, sed, mv, rm, mkdir).
+git (version control system) is only required if you wish to autodownload
+external dependencies (flac, tremor, mad, etc...) for static linking.
+
+
+BUGS
+----
+
+Modifications to config.mk will over-rebuild.
+
+Changes to CFLAGS/LDFLAGS from the command-line are not yet checked in
+rebuilds.
diff --git a/bs/config.mk.default b/bs/config.mk.default
new file mode 100644
index 000000000..be46f5e78
--- /dev/null
+++ b/bs/config.mk.default
@@ -0,0 +1,61 @@
+# config.mk file for the bs build-system this is the only file a user should
+# need to edit
+# report bugs to Eric Wong <normalperson@yhbt.net>
+
+# change this if cross compiling, default: @@HOST@@
+# HOST := @@HOST@@
+
+# default compiler and linker settings
+CC = gcc
+CFLAGS = -O2 -Wall \
+ -Wmissing-prototypes -Wextra -Wno-unused-parameter \
+ -Wno-deprecated-declarations -Wmissing-prototypes \
+ -Wdeclaration-after-statement -Wshadow
+
+LDFLAGS = -Wl,-O1
+
+# TCP or UNIX domain sockets support. MPD needs at least one of these
+HAVE_TCP := 1
+HAVE_UN :=
+
+# miscellaneous dependencies and features, mpd does not
+# require any of these:
+#
+HAVE_LANGINFO_CODESET :=
+HAVE_IPV6 :=
+HAVE_ICONV :=
+HAVE_ID3TAG :=
+
+MPD_PATH_MAX := 255
+
+# audio output features, at least one of these must be defined to 1
+# (and usable)
+#
+HAVE_ALSA :=
+HAVE_AO :=
+HAVE_FIFO :=
+HAVE_JACK :=
+HAVE_MVP :=
+HAVE_NULL :=
+HAVE_OSS :=
+HAVE_OSX :=
+HAVE_PULSE :=
+HAVE_SHOUT :=
+
+# input file format support, at least one of these must be defined to 1
+# (and usable)
+#
+HAVE_AUDIOFILE :=
+HAVE_FAAD :=
+HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR :=
+HAVE_FAACDECCONFIGURATION_DOWNMATRIX :=
+HAVE_FAACDECFRAMEINFO_SAMPLERATE :=
+HAVE_FLAC :=
+HAVE_HELIXMP3 :=
+HAVE_MIKMOD :=
+HAVE_MAD :=
+HAVE_MPCDEC :=
+HAVE_OGGFLAC :=
+HAVE_OGGVORBIS :=
+HAVE_TREMOR :=
+HAVE_WAVPACK :=
diff --git a/bs/cross-arch.sh b/bs/cross-arch.sh
new file mode 100755
index 000000000..c520433a5
--- /dev/null
+++ b/bs/cross-arch.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+# many parts of this blatantly ripped from GNU Autoconf macros
+# Use this for cross-compiling, as we can't run cross-compiled binaries
+# on our host.
+if test -z "$O" || ! cd "$O"; then
+ echo '$O= not defined or not a directory' >&2
+ exit 1
+fi
+
+echo '/* architecture-specific settings (auto-detected): */'
+# check sizes of various types we care for
+# this is slightly slower but much easier to read and follow than the
+# bisecting autoconf version
+for t in short int long 'long long'; do
+ > out
+ for s in 2 4 6 8 12 1 16 24 32 0; do
+ cat > t.c <<EOF
+int main(void)
+{
+ static int x[(long int)(sizeof($t)) == $s ? 1 : -1];
+ x[0] = 0;
+ return 0;
+}
+EOF
+ echo "trying sizeof($t) == $s" >> out
+ $CC -o t.o $CFLAGS $CPPFLAGS t.c \
+ >> out 2>&1 && break
+ done
+ if test $s -eq 0; then
+ echo "Unable to calculate sizeof($t) for cross-compiling" >&2
+ cat out >&2
+ exit 1
+ fi
+ t=`echo $t | tr a-z A-Z | tr ' ' _`
+ echo "#define SIZEOF_$t $s"
+ echo "SIZEOF_$t := $s" >> config_detected.mk
+done
+
+# check endian-ness
+cat > t.c <<EOF
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii(void)
+{
+ char *s = (char *)ascii_mm;
+ s = (char *)ascii_ii;
+}
+
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic(void)
+{
+ char *s = (char *)ebcdic_mm;
+ s = (char *)ebcdic_ii;
+}
+
+int main(void)
+{
+ _ascii();
+ _ebcdic();
+
+ return 0;
+}
+EOF
+
+echo "compiling endian test" > out
+$CC -o t.o $CFLAGS $CPPFLAGS t.c >> out 2>&1
+if grep BIGenDianSyS t.o >/dev/null 2>&1; then
+ echo "#define WORDS_BIGENDIAN 1"
+ echo "WORDS_BIGENDIAN := 1" >> config_detected.mk
+elif grep LiTTleEnDian t.o >/dev/null 2>&1; then
+ echo "/* #undef WORDS_BIGENDIAN */"
+ echo "# WORDS_BIGENDIAN :=" >> config_detected.mk
+else
+ echo "Unable to determine endian-ness for cross compiling" >&2
+ cat out >&2
+ exit 1
+fi
+
+echo ''
+
+exec rm -f t.o out t.c
diff --git a/bs/deps-audio.mk b/bs/deps-audio.mk
new file mode 100644
index 000000000..6f26c124e
--- /dev/null
+++ b/bs/deps-audio.mk
@@ -0,0 +1,38 @@
+ifeq ($(HAVE_ALSA),1)
+ mpd_CFLAGS += $(ALSA_CFLAGS) -DHAVE_LIBASOUND=1
+ mpd_LDFLAGS += $(ALSA_LDFLAGS) -lasound
+endif
+
+ifeq ($(HAVE_AO),1)
+ # mpd_CFLAGS += -pthread
+ mpd_LDFLAGS += -lao -lpthread
+endif
+
+ifeq ($(HAVE_FIFO),1)
+endif
+
+ifeq ($(HAVE_JACK),1)
+ mpd_LDFLAGS += -ljack
+endif
+
+ifeq ($(HAVE_MVP),1)
+endif
+
+ifeq ($(HAVE_OSX),1)
+ mpd_LDFLAGS += -framework AudioUnit -framework CoreServices
+endif
+ifeq ($(HAVE_OSS),1)
+ # check some BSDs (-lossaudio?)
+endif
+ifeq ($(HAVE_PULSE),1)
+ mpd_LDFLAGS += -lpulse -lpulse-simple
+endif
+ifeq ($(HAVE_SHOUT),1)
+ mpd_CFLAGS += -DHAVE_SHOUT_SHOUT_H=1
+ # XXX -ltheora, -lspeex
+ mpd_LDFLAGS += -lshout -logg -lvorbis -lvorbisenc -ltheora -lspeex -lpthread
+endif
+ifeq ($(HAVE_SUN),1)
+ mpd_CFLAGS += $(SUN_CFLAGS)
+ mpd_LDFLAGS += $(SUN_LDFLAGS)
+endif
diff --git a/bs/deps-conflicts.mk b/bs/deps-conflicts.mk
new file mode 100644
index 000000000..91dfa2a06
--- /dev/null
+++ b/bs/deps-conflicts.mk
@@ -0,0 +1,14 @@
+ifeq ($(HAVE_TREMOR),1)
+ ifeq ($(HAVE_SHOUT),1)
+ $(error Tremor and Shout are incompatible, enable one or the other)
+ endif
+ ifeq ($(HAVE_OGGFLAC),1)
+ $(error Tremor and OggFLAC are incompatible, enable one or the other)
+ endif
+endif
+
+ifeq ($(HAVE_HELIXMP3),1)
+ ifeq ($(HAVE_MAD),1)
+ $(error Helix MP3 and MAD are incompatible, enable one or the other)
+ endif
+endif
diff --git a/bs/deps-input.mk b/bs/deps-input.mk
new file mode 100644
index 000000000..b9f13b471
--- /dev/null
+++ b/bs/deps-input.mk
@@ -0,0 +1,45 @@
+ifeq ($(HAVE_AUDIOFILE),1)
+ mpd_LDFLAGS += -laudiofile -lm
+endif
+
+ifeq ($(HAVE_FAAD),1)
+ # XXX needs work
+ mpd_CFLAGS += $(FAAD_CFLAGS)
+ mpd_LDFLAGS += -lfaad -lmp4ff
+endif
+
+ifeq ($(HAVE_FLAC),1)
+ mpd_LDFLAGS += -lFLAC -lm
+endif
+
+ifeq ($(HAVE_HELIXMP3),1)
+ mpd_CFLAGS += $(HELIXMP3_CFLAGS)
+ mpd_LDFLAGS += $(HELIXMP3_LDFLAGS) -lmp3codecfixpt
+endif
+
+ifeq ($(HAVE_MIKMOD),1)
+ mpd_LDFLAGS += -lmikmod -lm
+endif
+
+ifeq ($(HAVE_MAD),1)
+ mpd_LDFLAGS += -lmad -lm
+endif
+
+ifeq ($(HAVE_MPCDEC),1)
+ mpd_LDFLAGS += -lmpcdec
+endif
+
+ifeq ($(HAVE_OGGFLAC),1)
+ mpd_LDFLAGS += $(OGGFLAC_LDFLAGS) -lOggFLAC -logg -lFLAC -lm
+endif
+
+ifeq ($(HAVE_OGGVORBIS),1)
+ ifeq ($(HAVE_TREMOR),1)
+ mpd_LDFLAGS += $(TREMOR_LDFLAGS) -lvorbisidec
+ else
+ mpd_LDFLAGS += $(OGGVORBIS_LDFLAGS) -lvorbis -logg -lvorbisfile
+ endif
+endif
+
+
+
diff --git a/bs/deps-misc.mk b/bs/deps-misc.mk
new file mode 100644
index 000000000..7af441839
--- /dev/null
+++ b/bs/deps-misc.mk
@@ -0,0 +1,17 @@
+ifeq ($(HAVE_ID3TAG),1)
+ mpd_LDFLAGS += -lid3tag -lz
+endif
+
+ifeq ($(HAVE_ICONV),1)
+ ifeq ($(NEED_LIBICONV),1)
+ mpd_LDFLAGS += -liconv
+ endif
+endif
+
+ifeq ($(HAVE_IPV6),1)
+endif
+
+ifeq ($(HAVE_LANGINFO_CODESET),1)
+endif
+
+mpd_LDFLAGS += -lpthread
diff --git a/bs/mkconfig-header.sh b/bs/mkconfig-header.sh
new file mode 100755
index 000000000..ff0809ffb
--- /dev/null
+++ b/bs/mkconfig-header.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+# detect the uninteresting (unlikely to be manually changed by the user)
+# parts of config.h
+
+if test -z "$O" || ! cd "$O"; then
+ echo '$O= not defined or not a directory' >&2
+ exit 1
+fi
+
+> config_detected.mk
+
+ansi_headers='assert ctype errno limits locale math signal
+stdarg stddef stdint stdio stdlib string'
+common_headers='dlfcn inttypes memory strings sched
+sys/inttypes sys/stat sys/types unistd'
+
+all_ansi=t
+echo '/* ANSI C headers: */'
+for h in $ansi_headers; do
+ if test x$h = xlocale; then
+ H=HAVE_LOCALE
+ else
+ H="HAVE_`echo $h | tr a-z A-Z | tr / _`_H"
+ fi
+ cat > t.c <<EOF
+#include <$h.h>
+int main(void) { return 0; }
+EOF
+ if $CC -o t.o $CFLAGS $CPPFLAGS t.c >> out 2>&1; then
+ echo "#define $H 1"
+ echo "$H := 1" >> config_detected.mk
+ else
+ echo "/* #undef $H */"
+ echo "# $H := " >> config_detected.mk
+ all_ansi=
+ fi
+done
+if test x$all_ansi = xt; then
+ echo '#define STDC_HEADERS 1'
+else
+ echo '/* #undef STDC_HEADERS */'
+fi
+echo ''
+echo '/* common system headers/features on UNIX and UNIX-like system: */'
+for h in $common_headers; do
+ H="HAVE_`echo $h | tr a-z A-Z | tr / _`_H"
+ cat > t.c <<EOF
+#include <$h.h>
+int main(void) { return 0; }
+EOF
+ if $CC -o t.o $CFLAGS $CPPFLAGS t.c >> out 2>&1; then
+ echo "#define $H 1"
+ echo "$H := 1" >> config_detected.mk
+ else
+ echo "/* #undef $H */"
+ echo "# $H :=" >> config_detected.mk
+ fi
+done
+
+# test for setenv
+cat > t.c <<EOF
+#include <stdlib.h>
+int main(void) { setenv("mpd","rocks", 1); return 0; }
+EOF
+if $CC -o t.o $CFLAGS $CPPFLAGS t.c >> out 2>&1; then
+ echo '#define HAVE_SETENV 1'
+ echo "HAVE_SETENV := 1" >> config_detected.mk
+else
+ echo '/* #undef HAVE_SETENV */'
+ echo "# HAVE_SETENV :=" >> config_detected.mk
+fi
+echo ''
+
+# test for alloca
+cat > t.c <<EOF
+#include <alloca.h>
+int main(void) { char *x = (char *)alloca(2 * sizeof(int)); return 0; }
+EOF
+if $CC -o t.o $CFLAGS $CPPFLAGS t.c >> out 2>&1; then
+ echo '#define HAVE_ALLOCA_H 1'
+ echo "HAVE_ALLOCA_H := 1" >> config_detected.mk
+else
+ echo '/* #undef HAVE_ALLOCA_H */'
+ echo "# HAVE_ALLOCA_H :=" >> config_detected.mk
+fi
+echo ''
+
+exec rm -f out t.c t.o
diff --git a/bs/mkconfig.h.mk b/bs/mkconfig.h.mk
new file mode 100644
index 000000000..816eb4f2e
--- /dev/null
+++ b/bs/mkconfig.h.mk
@@ -0,0 +1,54 @@
+have += TCP
+have += UN
+
+have += AUDIOFILE
+have += FAAD
+have += FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
+have += FAACDECCONFIGURATION_DOWNMATRIX
+have += FAACDECFRAMEINFO_SAMPLERATE
+have += MP4AUDIOSPECIFICCONFIG
+have += FLAC
+have += HELIXMP3
+have += MIKMOD
+have += MAD
+have += MPCDEC
+have += OGGFLAC
+have += OGGVORBIS
+have += TREMOR
+
+have += ALSA
+have += AO
+have += FIFO
+have += JACK
+have += MVP
+have += OSX
+have += OSS
+have += PULSE
+have += SHOUT
+have += SUN
+
+have += ID3TAG
+have += ICONV
+have += IPV6
+have += LANGINFO_CODESET
+
+MPD_PATH_MAX ?= 255
+req_vars += MPD_PATH_MAX
+
+export
+
+include $(O)/config.mk
+$(O)/config.h: $(O)/config_detected.h $(O)/config.mk
+ echo '#ifndef CONFIG_H' > $@+
+ echo '#define CONFIG_H' >> $@+
+ $(SHELL) ./bs/pkginfo-header.sh >> $@+
+ cat $(O)/config_detected.h >> $@+
+ echo '/* user-enabled features: */' >> $@+
+ for d in $(have); do eval "val=`echo '$$'HAVE_$$d` var=HAVE_$$d"; \
+ if test -n "$$val"; then echo "#define $$var 1" >> $@+; \
+ else echo "/* #undef $$var */" >> $@+; fi ; done
+ for d in $(req_vars); do eval "val=`echo '$$'$$d`"; \
+ echo "#define $$d $$val" >> $@+; done
+ echo '#endif /* CONFIG_H */' >> $@+
+ mv $@+ $@
+.NOTPARALLEL:
diff --git a/bs/mkdep.sh b/bs/mkdep.sh
new file mode 100755
index 000000000..019b4bc4c
--- /dev/null
+++ b/bs/mkdep.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+# $d must have a trailing slash $(dir file) in GNU Make
+f="$1"
+d="$2"
+x="$3"
+if test -z "$O"; then
+ echo '$O= not defined or not a directory' >&2
+ exit 1
+fi
+test -d "$O/$d" || "$SHELL" ./bs/mkdir_p.sh "$O/$d"
+t="$O/t.$$.d"
+depmode=
+out=
+if test -e "$O/depmode"; then
+ . "$O/depmode"
+fi
+
+case "$depmode" in
+mm)
+ $CC -MM $CPPFLAGS $CFLAGS "$f" > "$t" 2>/dev/null
+ ;;
+m)
+ $CC -M $CPPFLAGS $CFLAGS "$f" > "$t" 2>/dev/null
+ ;;
+none)
+ echo "$O/$f: $f $HDR_DEP_HACK" | sed -e 's#c:#o:#' > "$x"+
+ ;;
+*)
+ # detect our depmode
+ # -MM is gcc-specific...
+ $CC -MM $CPPFLAGS $CFLAGS "$f" > "$t" 2>/dev/null
+ if test $? -eq 0; then
+ depmode=mm
+ else
+ # ok, maybe -M is supported...
+ $CC -M $CPPFLAGS $CFLAGS "$f" \
+ > "$t" 2>/dev/null
+ if test $? -eq 0; then
+ depmode=m
+ else
+ depmode=none
+ # don't guess, fudge the dependencies by using
+ # all headers
+ echo "$O/$f: $f $HDR_DEP_HACK" \
+ | sed -e 's#c:#o:#' > "$x"+
+ fi
+ fi
+ echo "depmode=$depmode" > "$O/depmode"
+ ;;
+esac
+
+case "$depmode" in
+m|mm)
+ sed -e 's#.c$#.o#' -e "1s#^#$O/$d&#" < "$t" > "$x"+
+ ;;
+esac
+rm -f "$t"
+exec mv "$x"+ "$x"
diff --git a/bs/mkdir_p.sh b/bs/mkdir_p.sh
new file mode 100755
index 000000000..cb9e94ca7
--- /dev/null
+++ b/bs/mkdir_p.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# based on mkinstalldirs:
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+errstatus=0
+for file
+do
+ test -d "$file" && continue
+ case $file in
+ /*) pathcomp=/ ;;
+ *) pathcomp= ;;
+ esac
+ oIFS=$IFS
+ IFS=/
+ set fnord $file
+ shift
+ IFS=$oIFS
+ for d
+ do
+ test "x$d" = x && continue
+ pathcomp=$pathcomp$d
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ mkdir "$pathcomp" || lasterr=$?
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+ pathcomp=$pathcomp/
+ done
+done
+
+exit $errstatus
diff --git a/bs/mkdist.sh b/bs/mkdist.sh
new file mode 100755
index 000000000..130871345
--- /dev/null
+++ b/bs/mkdist.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+set -e
+. bs/pkginfo.sh
+head=${1-'HEAD'}
+git_ver=
+if git rev-parse --git-dir > /dev/null 2>&1; then
+ git_ver=`git describe $head`
+ git_ver=`expr "z$git_ver" : 'z.*\(-g[0-9a-f].*\)' || true`
+ if test -n "$git_ver"; then
+ dirty=`git diff-index --name-only HEAD 2>/dev/null || true`
+ if test -n "$dirty"; then
+ git_ver=$git_ver-dirty
+ fi
+ fi
+fi
+
+v=$v$git_ver
+dir=$O/$p-$v
+rm -rf "$dir"
+git tar-tree $head $dir | tar x
+
+at_files='
+Makefile.in
+aclocal.m4
+compile
+config.guess
+config.h.in
+config.sub
+configure
+depcomp
+doc/Makefile.in
+install-sh
+ltmain.sh
+missing
+mkinstalldirs
+src/Makefile.in
+src/mp4ff/Makefile.in
+'
+
+for i in $at_files; do
+ if test -f $i; then
+ echo cp $i $dir/$i
+ cp $i $dir/$i
+ fi
+done
+
+cd $O
+tar c $p-$v | gzip -9 > $p-$v.tar.gz
+rm -rf $p-$v
+echo "Generated tarball in: $p-$v.tar.gz"
diff --git a/bs/pkginfo-header.sh b/bs/pkginfo-header.sh
new file mode 100755
index 000000000..0d5e4059d
--- /dev/null
+++ b/bs/pkginfo-header.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# basic package info:
+. bs/pkginfo.sh
+cat <<EOF
+/* Basic package info: */
+#define PACKAGE "$p"
+#define VERSION "$v"
+#define PACKAGE_BUGREPORT "$b"
+#define PACKAGE_NAME "$p"
+#define PACKAGE_STRING "$p $v"
+#define PACKAGE_TARNAME "$p"
+#define PACKAGE_VERSION "$v"
+#define PROTOCOL_VERSION "$pv"
+
+EOF
+
diff --git a/bs/pkginfo.sh b/bs/pkginfo.sh
new file mode 100755
index 000000000..f04dded8f
--- /dev/null
+++ b/bs/pkginfo.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# sourcing this defines the folling variables:
+# p: package, v: version, b: bugreport email, pv: protocol version
+
+script='
+/^AC_INIT\(/ {
+ gsub("[() ]","",$0);
+ gsub("AC_INIT","",$1);
+ print "p="$1;
+ print "v="$2;
+ print "b="$3;
+}
+/^AC_DEFINE\(PROTOCOL_VERSION, / {
+ gsub("[\" ]", "", $2);
+ print "pv="$2;
+}
+'
+
+eval $(awk -F, "$script" < configure.ac)
diff --git a/build.mk b/build.mk
new file mode 100755
index 000000000..6962d00c2
--- /dev/null
+++ b/build.mk
@@ -0,0 +1,103 @@
+#!/usr/bin/make -f
+# default target
+all:
+
+# output directory can be set with O:=dir
+ifeq ($(O),)
+ O := .
+endif
+srcdir := src
+include src/Makefile.am
+mpd_SRC := $(addprefix src/,$(filter %.c,$(mpd_SOURCES)))
+mpd_HDR := $(addprefix src/,$(filter %.h,$(mpd_SOURCES)))
+mpd_OBJ := $(subst .c,.o,$(addprefix $(O)/,$(mpd_SRC)))
+mpd_DEP := $(subst .o,.d,$(mpd_OBJ))
+
+-include $(mpd_DEP)
+
+uname_s := $(shell uname -s | tr A-Z a-z 2>/dev/null || echo unknown)
+uname_m := $(shell uname -m | tr A-Z a-z 2>/dev/null || echo unknown)
+
+# build: the machine type this builds on
+# HOST: the machine this runs on
+build := $(uname_s)-$(uname_m)
+HOST ?= $(build)
+-include $(O)/config.mk
+-include $(O)/config_detected.mk
+include bs/deps-audio.mk
+include bs/deps-input.mk
+include bs/deps-misc.mk
+include bs/deps-conflicts.mk
+
+RANLIB ?= ranlib
+ifneq ($(HOST),$(build))
+ ifeq ($(origin CC),default)
+ CC := $(HOST)-$(CC)
+ endif
+ ifeq ($(origin RANLIB),default)
+ RANLIB := $(HOST)-$(RANLIB)
+ endif
+ ifeq ($(origin AR),default)
+ AR := $(HOST)-$(AR)
+ endif
+endif
+
+mpd_CFLAGS += -I$(O)/src
+mpd_LDFLAGS += -lm
+mpd_DIRS := $(O)/src/inputPlugins $(O)/src/audioOutputs
+
+STRIP ?= strip
+export O CC CPPFLAGS CFLAGS HOST SHELL
+
+defconfig: $(O)/config.mk
+
+$(O)/config.mk:
+ @test -d "$(@D)" || $(SHELL) ./bs/mkdir_p.sh "$(@D)"
+ @if ! test -e $@; then \
+ sed -e 's/@@HOST@@/$(HOST)/g' \
+ < bs/config.mk.default > $@+ && mv $@+ $@ && \
+ echo Please edit $(O)/config.mk to your liking; fi
+ @touch $@
+
+$(O)/src/../config.h: $(O)/config.h
+$(O)/config.h: $(O)/config.mk $(O)/config_detected.h
+ $(MAKE) -f bs/mkconfig.h.mk $(O)/config.h
+
+$(O)/config_detected.h:
+ @test -d "$(@D)" || $(SHELL) ./bs/mkdir_p.sh "$(@D)"
+ > $@+ && $(SHELL) ./bs/mkconfig-header.sh >> $@+ && \
+ $(SHELL) ./bs/cross-arch.sh >> $@+ && mv $@+ $@
+
+all: $(O)/src/mpd
+ @echo OK $<
+strip: $(O)/src/mpd
+ $(STRIP) $(STRIP_OPTS) $<
+$(O)/src/mpd: $(mpd_OBJ)
+ $(CC) -o $@ $^ $(CFLAGS) $(mpd_CFLAGS) $(LDFLAGS) $(mpd_LDFLAGS)
+$(O)/src/%.o: src/%.c $(O)/config.h
+ @HDR_DEP_HACK="$(O)/config.h $(mpd_HDR)" \
+ CFLAGS="$(CFLAGS) $(mpd_CFLAGS)" \
+ $(SHELL) ./bs/mkdep.sh $< $(dir $<) $(subst .o,.d,$@)
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(mpd_CFLAGS) -c -o $@ $<
+$(mpd_SRC): $(O)/config.h
+clean:
+ $(RM) $(O)/src/mpd $(mpd_OBJ)
+reallyclean: clean
+ $(RM) $(mpd_DEP) $(O)/depmode $(O)/config.h
+
+# in case a .d file had a dep on a deleted file, we have this:
+src/%.h src/%.c::
+ @true
+# we only do static linking in bs (since our main goal is cross-compiling),
+# if you want dynamic linking, use autotools
+$(O)/%.a::
+ $(RM) $@
+ $(AR) cru $@ $^
+ $(RANLIB) $@
+dist:
+ $(SHELL) ./bs/mkdist.sh
+
+.PHONY: clean reallyclean defconfig all
+.PRECIOUS: $(O)/%.h
+.SUFFIXES:
+.SUFFIXES: .c .o .h .d