diff --git a/emacs-build.sh b/emacs-build.sh new file mode 100644 index 0000000..cae2280 --- /dev/null +++ b/emacs-build.sh @@ -0,0 +1,401 @@ +#!/bin/bash +# Copyright 2020 Juan Jose Garcia-Ripoll +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +######################################## +# +# EMACS-BUILD +# +# Standalone script to build Emacs from a running copy of Mingw64. It immitates +# the steps that Emacs developers can take to build the standard distributions. +# See write_help below for all options. +# + +function write_help () { + cat <&2 +} + + +function full_dependency_list () +{ + # Given a list of packages, print a list of all dependencies + # + # Input + # $1 = list of packages without dependencies + # + # Packages we do not want to distribute (spurious dependencies) + local skip_pkgs="glib2" + # Packages that have to be replaced by others for distribution + local munge_pgks=" + s,$mingw_prefix-libwinpthread,$mingw_prefix-libwinpthread-git,g; + s,$mingw_prefix-libtre,$mingw_prefix-libtre-git,g;" + + local packages=`for i in $packages; do echo $mingw_prefix-$i; done` + local skip_pkgs=`for p in $skip_pkgs; do echo s,$mingw_prefix-$p,,g; done` + + local oldpackages="" + local dependencies="" + while test "$oldpackages" != "$packages" ; do + oldpackages="$packages" + dependencies=`pacman -Qii $oldpackages | grep Depends | sed -e 's,>=[^ ]*,,g;s,Depends[^:]*:,,g;s,None,,g;' -e "$skip_pkgs" -e "$munge_pgks"` + packages=`echo $oldpackages $dependencies | sed -e 's, ,\n,g' | sort | uniq` + done + echo $packages +} + +function emacs_dependencies () +{ + # Print the list of all mingw/msys packages required for running emacs with + # the selected features. Cache the result value. + # + if test -z "$emacs_dependencies"; then + errcho Inspecting required packages for build features + errcho $features + local feature_selector=`echo $features | sed -e 's, ,|,g'` + local packages=`feature_list | grep -E "$feature_selector" | cut -d ' ' -f 2-` + emacs_dependencies=`full_dependency_list $packages` + errcho Total packages required: + errcho `echo $emacs_dependencies | sed -e 's, ,\n,g' -` + fi + echo $emacs_dependencies +} + +function prepare_source_dir () +{ + if test -d "$source_dir"; then + if test -f "$source_dir/configure"; then + echo Configure script exists. Nothing to do in source directory $source_dir + echo + return 0 + fi + cd "$source_dir" && ./autogen.sh && return 0 + echo Unable to prepare source directory. Autoreconf failed. + else + echo Source directory $source_dir missing + echo Run script with --clone first + echo + fi + return -1 +} + +function prepare_build_dir () +{ + if test -d "$build_dir"; then + if test -f "$build_dir/config.log"; then + rm -rf "$build_dir/*" + else + echo Cannot rebuild on existing directory $build_dir + return -1 + fi + else + mkdir -p "$build_dir" + fi +} + +function configure_build_dir () +{ + cd "$build_dir" + options="--without-compress-install --without-dbus" + for f in $all_features; do + if echo $features | grep f > /dev/null; then + options="--with-$f $options" + else + options="--without-$f $options" + fi + done + echo Configuring Emacs with options + echo $options + if "$source_dir/configure" "--prefix=$install_dir" $options >$log_file 2>&1; then + echo Emacs configured + else + echo Configuration failed + return -1 + fi +} + +function action0_clone () +{ + # Download the Emacs source files using Git. + # + if which git >/dev/null 2>&1; then + echo Found git, nothing to install. + else + echo Git is not found, installing it. + pacman -S --noconfirm git + fi + pushd . >/dev/null + local error + if test -d "$source_dir"; then + echo Updating repository + cd "$source_dir" + git pull && git reset --hard && git checkout + error=$? + if test $? != 0; then + echo Source repository update failed. + fi + else + echo Cloning Emacs repository from Savannah at $emacs_repo. + git clone --depth 1 -b $branch "$emacs_repo" "$source_dir" && \ + cd "$source_dir" && git config pull.rebase false + error=$? + if test $? != 0; then + echo Git clone failed. Deleting source directory. + rm -rf "$source_dir" + fi + fi + # + # If there was a 'configure' script, remove it, to force running autoreconf + # again before builds. + rm -f "$source_dir/configure" + popd >/dev/null + return $? +} + +function action1_ensure_packages () +{ + # Collect the list of packages required for running Emacs, and ensure they + # have been installed. + # + echo Ensuring packages are installed + if pacman -Qi `emacs_dependencies` >/dev/null; then + echo All packages are installed. + else + echo Some packages are missing. Installing them with pacman. + pacman -S --noconfirm -q `emacs_dependencies` + fi +} + +function action2_build () +{ + if prepare_source_dir && prepare_build_dir && configure_build_dir; then + echo Building Emacs in directory $build_dir + echo Log file is saved into $log_file + if make -j 4 -C $build_dir $build_dir >>$log_file 2>&1; then + echo Installing Emacs into directory $install_dir + if make -j 4 -C $build_dir install >>$log_file 2>&1; then + echo Process succeeded + return 0 + fi + fi + fi + echo Configuration and build process failed + echo Please check log file $log_file + return -1 +} + +function action3_package_deps () +{ + # Collect the list of packages required for running Emacs, gather the files + # from those packages and compress them into $emacs_depsfile + # + rm -f "$emacs_depsfile" + mkdir -p `dirname "$emacs_depsfile"` + cd $mingw_dir + pacman -Ql `emacs_dependencies` | cut -d ' ' -f 2 | sort | uniq \ + | sed "s,^$mingw_dir,,g" | dependency_filter | xargs zip -9 "$emacs_depsfile" +} + +function action4_package () +{ + # Package a prebuilt emacs with and without the required dependencies, ready + # for distribution. + # + if test ! -f $emacs_depsfile; then + echo Missing dependency file $emacs_depsfile. Run with --deps first. + fi + rm -f "$install_dir/bin/emacs-*.exe" + strip "$install_dir/bin/*.exe" "$install_dir/libexec/emacs/*/*/*.exe" + rm -f "$emacs_nodepsfile" + mkdir -p `dirname "$emacs_nodepsfile"` + cd "$install_dir" + if zip -9vr "$emacs_nodepsfile" *; then + echo Built $emacs_nodepsfile; echo + else + echo Failed to compress distribution file $emacs_nodepsfile; echo + return -1 + fi + cp $emacs_depsfile $emacs_distfile + cd "$install_dir" + if zip -9vr "$emacs_distfile" *; then + echo Built $emacs_distfile; echo + else + echo Failed to compress distribution file $emacs_distfile; echo + return -1 + fi +} + +function feature_list () { + cat <