#!/bin/bash
# Script to fetch and build X.org (incl. XCB and pixman), DRI, Mesa and
# xkeyboard-config from CVS and GIT, and save full git snapshots of their
# source and installation.
#
# Default action:
# - Create/update a git repository for each module, under $HOME/3d-pit.
# - Install all modules, under $HOME/3d-pit/install
# - Make $HOME/3d-pit/install a git repository to track the installed binaries
# - Make $HOME/3d-pit a git super-repository which tracks all of the above
# using the submodule mechanism of git >= 1.5.3.
#
# Each of these can be disabled via command line (see the code table below).
#
# Source: http://thinkwiki.org/wiki/How_to_compile_an_experimental_X_server
# See also:
# http://wiki.x.org/wiki/ModularDevelopersGuide
# http://wiki.x.org/wiki/GitPage
# http://gitweb.freedesktop.org
# http://dri.freedesktop.org/wiki/Building
# http://www.mesa3d.org/repository.html
# http://www.mesa3d.org/install.html
# http://web.telia.com/~u89404340/touchpad
# http://www.freedesktop.org/wiki/Software_2fXKeyboardConfig
# http://gitweb.freedesktop.org/?p=xorg/util/modular.git;a=blob;f=build.sh
#############################################
# X.org setup
# This is a list of modules that are in flux and likely to be related to
# whatever you're testing (or are required for the build), sorted by
# build order (see util/modular/build.sh for dependencies).
# Check CVS and the above URLs for other modules.
# For exhaustive list, see
# get -qO - http://gitweb.freedesktop.org/ \
# | perl -ne 'print "$1\n" if m!<a href="/\?p=([^;]+);a=summary">!' \
# | egrep '^xcb/|^xorg/|^pixman/'
XORG_MODULES=(
xorg/util/macros
xorg/proto/{bigreqs,composite,fixes,damage,gl,input,kb,pm,randr,resource,xext,xcmisc}proto
xorg/proto/{fontcache,fonts,kb}proto
xorg/proto/{render,scrnsaver,video}proto
xorg/proto/{x11,xf86bigfont,xf86dga,xf86dri,xf86misc,xf86vidmode,xinerama}proto
xcb/proto
xorg/lib/lib{xtrans,Xau,Xdmcp}
xcb/libxcb
xorg/lib/lib{X11,ICE,SM,Xt,Xmu,Xcomposite,Xrender,Xdamage,Xcursor,Xi,Xinerama}
xorg/lib/lib{Xfont,Xfontcache,Xft}
xorg/lib/lib{xkbui,Xrandr,Xv,XvMC,Xxf86dga,Xxf86misc,Xxf86vm,pciaccess}
pixman
xorg/xserver
xorg/driver/xf86-video-ati
xorg/driver/xf86-input-{mouse,keyboard,joystick,evdev}
xorg/app/{xkbutils,xkbcomp,setxkbmap,xrandr,xsetpointer,xbacklight}
)
#############################################
# Init
FETCH=true
BUILD=true
RECONFIGURE=false # Reconfigure everything even if unchanged from last run
MAKE_CLEAN=false # If true, run "make clean" before building.
GIT_CLEAN=false # Use "git clean" to delete all non-source files before building.
SUPERMODULE=true # Take meta-snapshots using Git super/submodule
for OPT in "$@"; do
case "$OPT" in
(--no-fetch) FETCH=false ;;
(--no-build) BUILD=false ;;
(--no-supermodule) SUPERMODULE=false ;;
(--reconfigure) RECONFIGURE=true ;;
(--make-clean) MAKE_CLEAN=true ;;
(--git-clean) GIT_CLEAN=true ;;
(*) echo "Unknown option" >&2; exit 1 ;;
esac
done
PIT=$HOME/3d-pit # Download and build here
DEST_SUBDIR=install # Install in this subdirectory of $PIT
USE_XCB=false # Use XCB?
FLAGS='-O2 -g -march=pentium-m'
DEST=$PIT/$DEST_SUBDIR
trap "echo Aborting.; exit 1" ERR
set -E
#############################################
# Support functions
die() {
echo "$*"
exit 1
}
run() {
echo "@`pwd`: $@"
"$@" || { echo "ERROR: Command \"$*\" failed in `pwd`"; exit 1; }
}
nothing_to_commit() {
git status > /dev/null # Force check of files for which only the timestamp changed.
git diff --quiet HEAD > /dev/null
}
fetch_from_git() {
PARENT_DIR="$1"
GIT_REP="$2"
MODULE="$3"
DIR="${4:-$MODULE}"
FULLDIR="$PARENT_DIR/$DIR"
RELDIR="${FULLDIR#$PIT/}"
if [ -d "$FULLDIR" ]; then
cd "$FULLDIR"
ORIG_HEAD=`git rev-parse HEAD`
run git pull
NEW_HEAD=`git rev-parse HEAD`
[[ "$ORIG_HEAD" == "$NEW_HEAD" ]] || run git shortlog ORIG_HEAD..HEAD | cat
else
run cd "$PARENT_DIR"
run git clone "$GIT_REP/$MODULE" "$DIR"
cd "$DIR"
git gc
fi
add_to_supermodule "$RELDIR"
}
fetch_from_cvs() {
CVS_SERVER="$1"
DIR="$2"
GITIGNORES="$3"
run cd $PIT
if [ ! -d $DIR ]; then
grep -qF $CVS_SERVER ~/.cvspass || run cvs -d $CVS_SERVER login
run cvs -z3 -d $CVS_SERVER co $DIR
cd $PIT/$DIR
run git init
fi
cd $PIT/$DIR
run cvs -z3 update -ACPd -I .gitignore -I .git
find . -name .cvsignore | while read X; do cp "$X" "${X%/.cvsignore}/.gitignore"; done
echo -e "$GITIGNORES" >> .gitignore
run git add .
nothing_to_commit || run git commit -a -m "`date +'Fetched at %Y-%m-%d %H:%M:%S'`"
# We could use git-cvsimport instead, but that's way too slow:
# mkdir -p $PIT/$DIR
# cd $PIT/$DIR
# git-cvsimport -v -d "$CVS_SERVER" -r origin
add_to_supermodule "$DIR"
}
#############################################
# Handing git super/submodules
if $SUPERMODULE; then
which git-submodule >&/dev/null || \
die "Error: git >= 1.3.5 required for submodule support. Try --no-supermodule."
run mkdir -p $PIT
cd $PIT
if [ ! -d .git ]; then
run git init
echo -e 'xorg/autoconf.cache' > .gitignore
run git add .gitignore
run git commit -m 'initial'
fi
# Add new submodule's repository to the supermodule's .gitmodules
add_to_supermodule_gitmodules() {
SUBDIR="$1"
GIT_CONFIG=$PIT/.gitmodules git config "submodule.$SUBDIR.path" "$SUBDIR"
GIT_CONFIG=$PIT/.gitmodules git config "submodule.$SUBDIR.url" "$SUBDIR"
}
add_to_supermodule() {
cd $PIT
# add_to_supermodule_alternates "$1"
add_to_supermodule_gitmodules "$1"
run git add "$1"
}
else
add_to_supermodule() { true; }
fi
#############################################
# Directory hashes for change detection
LAST_HASH=.last_dir_hash
dir_hash() {
find . \( -name $LAST_HASH -o -path ./.git -prune \) -o -type f -ls | sort | md5sum
}
dir_hash_changed() {
$RECONFIGURE || [ ! -f $LAST_HASH ] || [ "`dir_hash`" != "`cat $LAST_HASH`" ]
}
save_dir_hash() {
dir_hash > $LAST_HASH
}
#############################################
# Fetching and building libDRM and DRM kernel drivers
fetch_drm() {
echo "########### Fetch DRM ###########"
DRM_GIT=git://anongit.freedesktop.org/git/mesa
fetch_from_git "$PIT" "$DRM_GIT" drm
}
build_libdrm() {
echo "########### Build libdrm ###########"
run cd $PIT/drm
! $GIT_CLEAN || run git clean -x -d
if dir_hash_changed; then
run ./autogen.sh
CFLAGS="$FLAGS" run ./configure --prefix=$DEST --quiet
save_dir_hash
fi
! $MAKE_CLEAN || run make clean
run make
save_dir_hash
run make install
save_dir_hash
}
build_drm_modules() {
echo "########### Build DRM kernel modules ###########"
run cd $PIT/drm/linux-core
! $GIT_CLEAN || run git clean -x -d
! $MAKE_CLEAN || run make clean
run make DRM_MODULES="radeon"
run sudo sh -c \
'rm -fv /lib/modules/`uname -r`/kernel/drivers/char/drm/*.ko; \
cp -v *.ko /lib/modules/`uname -r`/extra/; \
/sbin/depmod -a'
}
#############################################
# Fetching Mesa
fetch_mesa() {
echo "########### Fetching Mesa ###########"
MESA_GIT=git://anongit.freedesktop.org/git/mesa
run mkdir -p $PIT
run cd $PIT
fetch_from_git "$PIT" "$MESA_GIT" mesa
}
#############################################
# Building Mesa (do this after installing base X.org libraries
build_mesa() { (
echo "########### Building Mesa ###########"
# This uses both old-style and new-style vars, to support older Mesa snapshots.
run cd $PIT/mesa
export DRM_SOURCE_PATH=$PIT/drm
export PKG_CONFIG_PATH="$DEST/lib/pkgconfig:$PKG_CONFIG_PATH"
export DRM_SOURCE_PATH="$PIT/drm"
export DESTDIR=$DEST INSTALL_DIR=$DEST
export DRI_DRIVER_INSTALL_DIR=$DEST/lib/dri
export DRI_DIRS='r300 r200 r128 radeon'
export OPT_FLAGS="$FLAGS"
export PATH="$DEST/bin:$PATH"
run mkdir -p $DRI_DRIVER_INSTALL_DIR
! $GIT_CLEAN || run git clean -x -d
! $MAKE_CLEAN || run make clean
if [ -e configs/current ]; then
run make -e
else
run make -e linux-dri-x86
fi
run make -e install
run cp -v lib/*_dri.so $DRI_DRIVER_INSTALL_DIR
) }
#############################################
# Fetching X.org
fetch_xorg() {
echo "########### Fetching (selected) X.org modules ###########"
XORG_GIT=git://anongit.freedesktop.org/git
run mkdir -p $PIT/xorg
for D in "${XORG_MODULES[@]}"; do
if [[ $D == xcb/* ]] && ! $USE_XCB; then continue; fi
fetch_from_git $PIT/xorg "$XORG_GIT" "$D" "${D#xorg/}"
done
}
#############################################
# Building and installing X.org
# (On repeated runs we avoid rerunning autotools if nothing changed.)
build_x_module() { (
D="${1#xorg/}"
echo "########### Building xorg/$D ###########"
export PATH="$DEST/bin:$PATH"
export PKG_CONFIG_PATH="$DEST/lib/pkgconfig:$PKG_CONFIG_PATH"
export ACLOCAL="${AC_LOCAL:-aclocal} -I $DEST/share/aclocal"
export LD_LIBRARY_PATH="$DEST/lib:$LD_LIBRARY_PATH"
if [ $D == "xserver" ]; then
CONF_OPT="--with-mesa-source=$PIT/mesa --enable-xorg --disable-dmx --disable-xvfb --disable-xnest --disable-xprint --disable-freetype --disable-xselinux"
elif [ $D == "lib/libX11" ] && ! $USE_XCB; then
CONF_OPT="--with-xcb=no"
else
CONF_OPT=
fi
run cd $PIT/xorg/$D
! $GIT_CLEAN || run git clean -x -d
if dir_hash_changed; then
CFLAGS="$FLAGS" run sh autogen.sh --prefix=$DEST --quiet $CONF_OPT
# --cache-file=$PIT/xorg/autoconf.cache
save_dir_hash
fi
! $MAKE_CLEAN || run make clean
run make
save_dir_hash
run make install
save_dir_hash
if [ $D == "pixman" ]; then # as of 2007-08-07 pixman needs this hack:
[ -e $DEST/include/pixman.h ] || run ln -fs pixman-1/pixman.h $DEST/include/pixman.h
fi
) }
build_xorg() {
run cd $PIT/xorg
run mkdir -p $DEST/share/aclocal
run mkdir -p $DEST/var/log
for D in "${XORG_MODULES[@]}"; do
if [[ $D == xcb/* ]] && ! $USE_XCB; then continue; fi
build_x_module $D || return 1
done
run sudo sh -c "chown -v root $DEST/bin/Xorg; \
chmod -v 4750 $DEST/bin/Xorg"
}
#############################################
# Fetching and building xkeyboard-config
fetch_xkeyboard_config() {
echo "########### Fetching xkeyboard-config ###########"
XKBC_CVS=":pserver:anoncvs@cvs.freedesktop.org:2401/cvs/xkeyboard-config"
XKBC_DIR=xkeyboard-config
XKBC_GITIGNORES='install-sh\nmissing\npo/stamp-it'
fetch_from_cvs "$XKBC_CVS" "$XKBC_DIR" "$XKBC_GITIGNORES"
}
build_xkeyboard_config() { (
echo "########### Building xkeyboard-config ###########"
run cd $PIT/xkeyboard-config
run ./autogen.sh
export PKG_CONFIG_PATH="$DEST/lib/pkgconfig:$PKG_CONFIG_PATH"
export PATH="$DEST/bin:$PATH"
CFLAGS="$FLAGS" run ./configure --quiet --prefix=$DEST \
--with-xkb-base=$DEST/share/X11/xkb --with-xkb-rules-symlink=xorg
run make
# "make install" replaces share/X11/xkb/compiled.tmp with a junk symlink, so override it:
mv $DEST/share/X11/xkb/compiled $DEST/share/X11/xkb/compiled.tmp
run make install
rm -f $DEST/share/X11/xkb/compiled
mv $DEST/share/X11/xkb/compiled.tmp $DEST/share/X11/xkb/compiled
) }
#############################################
# Fetching and building the synaptics driver
fetch_synaptics() {
echo "########### Fetch synaptics ###########"
SYN_GIT=http://web.telia.com/~u89404340/touchpad/synaptics/.git
fetch_from_git "$PIT" "$SYN_GIT" '' synaptics
}
build_synaptics() { (
echo "########### Build synaptics ###########"
run cd $PIT/synaptics
export PKG_CONFIG_PATH="$DEST/lib/pkgconfig:$PKG_CONFIG_PATH"
export PATH="$DEST/bin:$PATH"
export CPATH="$DEST/include:$CPATH"
! $GIT_CLEAN || run git clean -x -d
! $MAKE_CLEAN || run make clean
run make
run make install PREFIX="$DEST" MANDIR="$DEST/share/man"
#run cp -v synaptics_drv.so $DEST/lib/xorg/modules/input/
) }
#############################################
# Creating a script which sets env vars
create_xsetenv() {
echo "Creating $DEST/bin/xsetenv"
cat <<EOF > $DEST/bin/xsetenv || die "Can't create $DEST/bin/xsetenv"
export PATH="$DEST/bin:$PATH"
export LD_LIBRARY_PATH="$DEST/lib:$LD_LIBRARY_PATH"
export LIBGL_DRIVERS_PATH=$DEST/lib/dri
EOF
}
#############################################
# Actual fetching and building:
if $FETCH; then
fetch_drm
fetch_mesa
fetch_xorg
fetch_xkeyboard_config
fetch_synaptics
fi
if $BUILD; then
build_libdrm
build_drm_modules
build_xorg
build_mesa
build_xkeyboard_config
build_synaptics
create_xsetenv
fi
#############################################
# Saving install and super state to git commits:
if $BUILD; then
echo "########### Record installation dir commit ###########"
cd $DEST
if [ ! -d .git ]; then
run git init
echo '/var/log' > .gitignore
run git add .gitignore
run git commit -a -m "initial"
fi
run git add .
if ! nothing_to_commit; then
run git commit -a -m "`date +'Installed at %Y-%m-%d %H:%M:%S'`"
run git gc
fi
add_to_supermodule "$DEST_SUBDIR"
fi
if $SUPERMODULE; then
echo "########### Record supermodule commit ###########"
cd $PIT
nothing_to_commit || run git commit -m "`date +'Snapshot at %Y-%m-%d %H:%M:%S'` `$FETCH && echo fetch` `$BUILD && echo build`"
fi
#############################################
echo
echo "Done."
! $FETCH || echo "Run '. $DEST/bin/xsetenv' to point env vars to this installation."