Skip to content

Instantly share code, notes, and snippets.

@sfan5 sfan5/common.sh
Last active Jul 23, 2019

Embed
What would you like to do?
Build system & recipes for cross-compiling various libraries/programs for Windows (32-bit & 64-bit)
#!/bin/bash -eu
strip_pkg=0
_CUSTOMOPTS_E=__this_is_empty_dont_bother__
CUSTOMOPTS=($_CUSTOMOPTS_E)
common_init () {
CURRENT_PACKAGE_NAME=$(basename "$0")
FETCHCACHE="$PWD/dl"
BUILDBASE="$PWD/build"
PACKAGEDEST="$PWD"
mkdir -p $FETCHCACHE $BUILDBASE
local use64=0
local clean=0
local jobs=$(grep -c '^processor' /proc/cpuinfo)
[ "$CUSTOMOPTS" != "$_CUSTOMOPTS_E" ] && \
for optspec in "${CUSTOMOPTS[@]}"; do
local tmp=${optspec%|*}
declare -g ${tmp#*|}=0
done
while [ $# -gt 0 ]; do
case "$1" in
-j)
shift
jobs=$1
;;
--clean)
clean=1
;;
--64)
use64=1
;;
--strip)
strip_pkg=1
;;
-h|--help)
echo "This script builds the $CURRENT_PACKAGE_NAME package for Windows."
echo "Supported flags:"
echo " -h/--help Display this text"
echo " -j Use specified amount of jobs (default: $jobs)"
echo " --clean Clean before building package"
echo " --64 Build for 64-bit"
echo " --strip Strip EXE and DLL files before packaging"
if [ "$CUSTOMOPTS" != "$_CUSTOMOPTS_E" ]; then
echo "Custom options:"
for optspec in "${CUSTOMOPTS[@]}"; do
printf " --%-9s %s\n" ${optspec%%|*} "${optspec##*|}"
done
fi
exit 0
;;
*)
custom=
[ "$CUSTOMOPTS" != "$_CUSTOMOPTS_E" ] && \
for optspec in "${CUSTOMOPTS[@]}"; do
[ ! "--${optspec%%|*}" == "$1" ] && continue
local tmp=${optspec%|*}
custom=${tmp#*|}
done
if [ -z "$custom" ]; then
echo "Unknown argument: $1" >&2
exit 1
else
declare -g $custom=1
fi
;;
esac
shift
done
if [ $use64 -eq 1 ]; then
MINGW_PREFIX=x86_64-w64-mingw32
MINGW_CC=$MINGW_PREFIX-gcc
MINGW_CXX=$MINGW_PREFIX-g++
MINGW_STRIP=$MINGW_PREFIX-strip
MINGW_TYPE=win64
else
MINGW_PREFIX=i686-w64-mingw32
MINGW_CC=$MINGW_PREFIX-gcc
MINGW_CXX=$MINGW_PREFIX-g++
MINGW_STRIP=$MINGW_PREFIX-strip
MINGW_TYPE=win32
fi
export MAKEFLAGS="-j$jobs"
local builddir="$BUILDBASE/$CURRENT_PACKAGE_NAME-$MINGW_TYPE"
SRCDIR="$builddir/src"
INSTALL_DIR="$builddir/pkg"
[ $clean -eq 1 ] && rm -rf $SRCDIR
[ -d $INSTALL_DIR ] && rm -rf $INSTALL_DIR
mkdir -p $SRCDIR $INSTALL_DIR
cd $SRCDIR
}
fetch_git () {
local gitdir=$FETCHCACHE/$CURRENT_PACKAGE_NAME.git
if [ -d $gitdir ]; then
[ -f $SRCDIR/.git ] || git init --separate-git-dir=$gitdir $SRCDIR
GIT_DIR=$gitdir git fetch
GIT_DIR=$gitdir GIT_WORK_TREE=$SRCDIR git reset HEAD --hard
else
local branch=master
[ $# -ge 2 ] && branch=$2
git clone -b $branch --separate-git-dir=$gitdir "$1" $SRCDIR
fi
}
fetch_web () {
local filename=${1##*/}
[ $# -ge 3 ] && filename=$3
[ -f $FETCHCACHE/$filename ] && return 0
local filedest=$(mktemp -p $FETCHCACHE -u)
hash=$(wget -O- "$1" | tee >(sha256sum | cut -d " " -f 1) >$filedest)
if [ "$hash" != "$2" ]; then
echo "Hash mismatch for $filename" >&2
echo " expected: $2" >&2
echo " actual: $hash" >&2
rm $filedest
return 1
else
mv $filedest $FETCHCACHE/$filename
fi
}
unpack_zip () {
unzip -nd $SRCDIR $FETCHCACHE/$1
}
unpack_tar () {
local tarfile=$FETCHCACHE/$1
shift
tar -xva -f $tarfile -C $SRCDIR "$@"
}
_strip_pkg () {
find . -name '*.exe' -o -name '*.dll' -exec $MINGW_STRIP {} \;
}
package () {
local zipfile=$PACKAGEDEST/$CURRENT_PACKAGE_NAME-$1-$MINGW_TYPE.zip
pushd $INSTALL_DIR
[ $strip_pkg -eq 1 ] && _strip_pkg
rm -f $zipfile
zip -9ry $zipfile -- *
popd
}
depend_get_path () {
local p="$BUILDBASE/$1-$MINGW_TYPE/pkg"
if [ ! -d $p ]; then
echo "The dependency $1 needs to be built first" >&2
return 1
else
echo $p
fi
}
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=7.65.3
fetch_web "https://curl.haxx.se/download/curl-$pkgver.tar.bz2" \
0a855e83be482d7bc9ea00e05bdb1551a44966076762f9650959179c89fce509
unpack_tar "curl-$pkgver.tar.bz2" --strip-components=1
CC=$MINGW_CC ./configure --host=$MINGW_PREFIX --prefix=/ \
--enable-ipv6 --with-winssl --disable-ldap \
--with-zlib=$(depend_get_path zlib)
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no manpages or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=2.9.1
fetch_web "http://download.savannah.gnu.org/releases/freetype/freetype-$pkgver.tar.bz2" \
db8d87ea720ea9d5edc5388fc7a0497bb11ba9fe972245e0f7f4c7e8b1e1e84d
unpack_tar "freetype-$pkgver.tar.bz2" --strip-components=1
CC=$MINGW_CC PKG_CONFIG=/bin/false \
./configure --host=$MINGW_PREFIX --prefix=/ --with-png=no
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no manpages or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
CUSTOMOPTS[0]="all-tools|alltools|Keep all installed gettext tools"
common_init "$@"
# this is a "dual" package which includes both libiconv and gettext
iconvver=1.15
intlver=0.19.8.1
mkdir -p iconv intl
fetch_web "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$iconvver.tar.gz" \
ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
unpack_tar "libiconv-$iconvver.tar.gz" -C iconv --strip-components=1
fetch_web "https://ftp.gnu.org/gnu/gettext/gettext-$intlver.tar.xz" \
105556dbc5c3fbbc2aa0edb46d22d055748b6f5c7cd7a8d99f8e7eb84e938be4
unpack_tar "gettext-$intlver.tar.xz" -C intl --strip-components=1
pushd iconv
./configure --host=$MINGW_PREFIX --prefix=/ \
--enable-{static,shared} \
--disable-{rpath,nls}
make
make DESTDIR=$INSTALL_DIR install
popd
pushd intl
for f in gettext-{runtime,tools}/gnulib-m4/asm-underscore.m4; do
v=true
[[ "$MINGW_PREFIX" == "x86_64-"* ]] && v=false
sed 's|.*grep -E.*gl_asmext.*|if '$v';then|' -i $f
done
# trying to get it to build was too painful so i just set the --prefix...
./configure --host=$MINGW_PREFIX --prefix=/fuckyou/ \
--enable-{static,shared} \
--disable-{java,rpath,libasprintf,curses} \
--with-libiconv-prefix=$INSTALL_DIR \
--with-included-{gettext,glib,libcroco,libunistring,libxml} \
--without-{git,cvs,xz}
make
popd
pushd intl # (iconv is already installed)
make DESTDIR=$INSTALL_DIR install
pushd $INSTALL_DIR
cp -r fuckyou/* .
rm -r fuckyou
popd
popd
rm -rf $INSTALL_DIR/lib/{*.la,gettext,charset.alias,*.dll} $INSTALL_DIR/share
if [ $alltools -eq 0 ]; then
mv $INSTALL_DIR/{bin,bin.old}; mkdir -p $INSTALL_DIR/bin
cp $INSTALL_DIR/bin.old/{*.dll,iconv.exe,msgfmt.exe} $INSTALL_DIR/bin
rm -rf $INSTALL_DIR/bin.old
fi
package $intlver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=1.8.4
# URL specifies a mirror because some SF mirrors are beyond slow (~ 10 KB/s)
fetch_web "http://downloads.sourceforge.net/irrlicht/irrlicht-$pkgver.zip?use_mirror=netcologne" \
f42b280bc608e545b820206fe2a999c55f290de5c7509a02bdbeeccc1bf9e433 irrlicht-$pkgver.zip
unpack_zip irrlicht-$pkgver.zip
cd irrlicht-$pkgver
buildid=Win32-gcc
# enable Direct3D9 support
sed -r '/-DNO_IRR_COMPILE_WITH_DIRECT3D_9_/ s/^/#/
/^sharedlib_win32: LDFLAGS/ s/-ld3dx9d/-ld3dx9_43 -ldinput8 -ldxguid/' \
-i source/Irrlicht/Makefile
sed 's/defined(IRR_COMPILE_WITH_DX9_DEV_PACK)/1/' \
-i include/IrrCompileConfig.h
# modify makefile for 64-bit gcc build
if [[ "$MINGW_PREFIX" == "x86_64-"* ]]; then
sed 's/Win32-gcc/Win64-gcc/g' -i source/Irrlicht/Makefile
buildid=Win64-gcc
mkdir -p {bin,lib}/Win64-gcc
cp bin/Win32-gcc/irrlicht.ico bin/Win64-gcc
fi
# build shared lib
make -Csource/Irrlicht clean
CC=$MINGW_CC CXX=$MINGW_CXX make sharedlib_win32 -Csource/Irrlicht
# preserve the implib (.dll.a) and clean
mv lib/$buildid/libIrrlicht.a lib/$buildid/libIrrlicht.dll.a
make -Csource/Irrlicht clean
# build static lib
CC=$MINGW_CC CXX=$MINGW_CXX make staticlib_win32 -Csource/Irrlicht
mkdir -p $INSTALL_DIR/{bin/$buildid,lib}
cp -r include $INSTALL_DIR
cp -r bin/$buildid/*.{dll,ico} $INSTALL_DIR/bin/$buildid
cp -r lib/$buildid $INSTALL_DIR/lib
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=2.2.4
fetch_web "https://github.com/libgd/libgd/releases/download/gd-$pkgver/libgd-$pkgver.tar.xz" \
137f13a7eb93ce72e32ccd7cebdab6874f8cf7ddf31d3a455a68e016ecd9e4e6
unpack_tar "libgd-$pkgver.tar.xz" --strip-components=1
sed '/HAVE_LIBPNG_TRUE/ s|webpng\S*||' -i src/Makefile.in
PKG_CONFIG=/bin/false \
./configure --host=$MINGW_PREFIX --prefix=/ --with-png=$(depend_get_path libpng) \
--without-x --disable-werror
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{lib/*.la,lib/pkgconfig} # no pkg-config on windows
rm -f $INSTALL_DIR/bin/{*.exe,bdftogd} # remove obscure utilities
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
fetch_git https://github.com/google/leveldb 1.21
# build shared lib
cmake . \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=$MINGW_CC \
-DCMAKE_CXX_COMPILER=$MINGW_CXX \
-DBUILD_SHARED_LIBS=YES -DLEVELDB_BUILD_TESTS=NO
make leveldb
# build static lib
cmake . -DBUILD_SHARED_LIBS=NO
make leveldb
mkdir -p $INSTALL_DIR/{bin,lib,include}
cp -r include/leveldb $INSTALL_DIR/include
cp libleveldb.dll $INSTALL_DIR/bin
cp libleveldb.a $INSTALL_DIR/lib
cp libleveldb.dll.a $INSTALL_DIR/lib
major=$(sed -rn 's/.*int kMajorVersion = ([0-9]+);$/\1/p' include/leveldb/db.h)
minor=$(sed -rn 's/.*int kMinorVersion = ([0-9]+);$/\1/p' include/leveldb/db.h)
package $major.$minor
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=1.3.2
fetch_web "http://downloads.xiph.org/releases/ogg/libogg-$pkgver.tar.xz" \
3f687ccdd5ac8b52d76328fbbfebc70c459a40ea891dbf3dccb74a210826e79b
unpack_tar "libogg-$pkgver.tar.xz" --strip-components=1
CC=$MINGW_CC ./configure --host=$MINGW_PREFIX --prefix=/
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no manpages or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=1.6.29
fetch_web "http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pkgver.tar.xz" \
4245b684e8fe829ebb76186327bb37ce5a639938b219882b53d64bd3cfc5f239
unpack_tar "libpng-$pkgver.tar.xz" --strip-components=1
zlibpath=$(depend_get_path zlib)
CFLAGS=-I$zlibpath/include LDFLAGS="-L$zlibpath/lib -lwinpthread" \
./configure --host=$MINGW_PREFIX --prefix=/
sed '/^#am__append_9/ s|.*|am__append_9 = $(CFLAGS)|' -i Makefile
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no manpages or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=1.3.5
fetch_web "http://downloads.xiph.org/releases/vorbis/libvorbis-$pkgver.tar.xz" \
54f94a9527ff0a88477be0a71c0bab09a4c3febe0ed878b24824906cd4b0e1d1
unpack_tar "libvorbis-$pkgver.tar.xz" --strip-components=1
oggpath=$(depend_get_path libogg)
CC=$MINGW_CC \
OGG_CFLAGS=-I$oggpath/include OGG_LIBS="-L$oggpath/lib -logg" \
./configure --host=$MINGW_PREFIX --prefix=/
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no docs or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=2.1.0-beta3
fetch_web "http://luajit.org/download/LuaJIT-$pkgver.tar.gz" \
1ad2e34b111c802f9d0cdf019e986909123237a28c746b21295b63c9e785d9c3
unpack_tar "LuaJIT-$pkgver.tar.gz" --strip-components=1
# this assumes a 64-bit host os
if [[ "$MINGW_PREFIX" == "x86_64-"* ]]; then
extra=
else
extra=-m32
fi
make \
HOST_CC="gcc $extra" BUILDMODE=static \
CROSS=$MINGW_PREFIX- TARGET_SYS=Windows \
amalg
mkdir -p $INSTALL_DIR/include
cp src/*.h $INSTALL_DIR/include
cp src/luajit.exe src/libluajit.a $INSTALL_DIR
package $pkgver
#!/bin/bash -eu
. ./common.sh
common_init "$@"
pkgver=3.27.2
pkgver_year=2019
pkgver_num=3270200
fetch_web "https://www.sqlite.org/$pkgver_year/sqlite-autoconf-$pkgver_num.tar.gz" \
50c39e85ea28b5ecfdb3f9e860afe9ba606381e21836b2849efca6a0bfe6ef6e
unpack_tar "sqlite-autoconf-$pkgver_num.tar.gz" --strip-components=1
CC=$MINGW_CC ./configure --host=$MINGW_PREFIX --prefix=/ --disable-static-shell
make
make DESTDIR=$INSTALL_DIR install
rm -rf $INSTALL_DIR/{share,lib/*.la,lib/pkgconfig} # no manpages or pkg-config on windows
package $pkgver
#!/bin/bash -eu
. ./common.sh
CUSTOMOPTS[0]="no-asm|asmdisable|Don't build with assembly optimizations"
common_init "$@"
pkgver=1.2.11
fetch_web "http://zlib.net/zlib-$pkgver.tar.gz" \
c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
unpack_tar "zlib-$pkgver.tar.gz" --strip-components=1
# enable assembly optimizations
if [ $asmdisable -eq 1 ]; then
asmdef=
asmobj=
else
if [[ "$MINGW_PREFIX" == "x86_64-"* ]]; then
printf '\e[1;31mWarning: asm on x64 is broken, you should use --no-asm\e[0m\n'
asmfile=amd64/amd64-match.S
asmdef=-DNO_UNDERLINE
else
asmfile=asm686/match.S
asmdef=
fi
cp -v contrib/$asmfile match.S
asmdef="-DASMV $asmdef"
asmobj=match.o
fi
# build using win32 makefile
make PREFIX=$MINGW_PREFIX- \
LOC="$asmdef" OBJA=$asmobj \
-fwin32/Makefile.gcc
make \
DESTDIR=$INSTALL_DIR SHARED_MODE=1 \
BINARY_PATH=/bin INCLUDE_PATH=/include LIBRARY_PATH=/lib \
install -fwin32/Makefile.gcc
rm -r $INSTALL_DIR/lib/pkgconfig # no pkgconfig on windows
package $pkgver
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.