#!/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. # . scripts/tools.sh . scripts/pdf-tools.sh . scripts/aspell.sh . scripts/hunspell.sh . scripts/gzip.sh . scripts/msys2_extra.sh . scripts/gnutls.sh function write_help () { echo "Emacs-build tool version $emacs_build_version, (c) 2020 Juan Jose Garcia-Ripoll" cat "$emacs_build_root/scripts/help.txt" echo write_features } function write_features () { local inactive="" for f in $all_features; do if [[ ! " $features " =~ .*$f ]]; then inactive="$f $inactive" fi done echo "Compressed installation: $emacs_compress_files" echo "Strip executables: $emacs_strip_executables" echo "Emacs features:" for f in $features; do echo " --with-$f"; done for f in $inactive; do echo " --without $f"; done } function write_version_number () { echo $emacs_build_version exit 0 } function check_mingw_architecture () { case "$MSYSTEM" in MINGW32) architecture=i686 mingw_prefix="mingw-w64-i686" mingw_dir="$MINGW_PREFIX/" build_type="i686-w64-mingw32" ;; MINGW64) architecture=x86_64 mingw_prefix="mingw-w64-x86_64" mingw_dir="$MINGW_PREFIX/" build_type="x86_64-w64-mingw32" ;; MSYSTEM) echo This tool cannot be ran from an MSYS shell. echo Please open a Mingw64 or Mingw32 terminal. echo exit -1 ;; *) echo This tool must be run from a Mingw64/32 system echo exit -1 esac } function ensure_mingw_build_software () { local build_packages="zip unzip base-devel ${mingw_prefix}-toolchain" pacman -S --noconfirm --needed $build_packages >/dev/null 2>&1 if test "$?" != 0; then echo Unable to install $build_packages echo Giving up exit -1 fi if [ -z `which git 2>&1` ]; then echo Installing Git for MSYS2 pacman -S --noconfirm --needed git if test "$?" != 0; then echo Unable to install Git echo Giving up exit -1 fi fi } function emacs_root_packages () { local feature_selector=`echo $features | sed -e 's, ,|,g'` feature_list | grep -E "$feature_selector" | cut -d ' ' -f 2- | sed -e "s,mingw-,${mingw_prefix}-,g" } 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 packages=`emacs_root_packages` # emacs_dependencies=`full_dependency_list "$packages" "${mingw_prefix}-glib2" "Emacs"` emacs_dependencies=`full_dependency_list "$packages" "" "Emacs"` errcho Total packages required: for p in $emacs_dependencies; do errcho " $p" done fi echo $emacs_dependencies } function emacs_configure_build_dir () { cd "$emacs_build_dir" options="--disable-build-details --disable-silent-rules --without-dbus" if test "$emacs_compress_files" = "no"; then options="$options --without-compress-install" fi 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 "$emacs_source_dir/configure" "--prefix=$emacs_install_dir" $options; then echo Emacs configured else echo Configuration failed return -1 fi } function action0_clean () { rm -rf "$emacs_build_build_dir" "$emacs_build_install_dir" } function action0_clean_rest () { rm -rf "$emacs_build_git_dir" "$emacs_build_zip_dir" exit 0 } function action0_clone () { clone_repo "$emacs_branch" "$emacs_repo" "$emacs_source_dir" "$emacs_branch_name" if test "$emacs_apply_patches" = "yes"; then apply_patches "$emacs_source_dir" || true fi echo "::set-output name=EMACS_PKG_VERSION::`git_version $emacs_source_dir`" } function action1_ensure_packages () { # Collect the list of packages required for running Emacs, and ensure they # have been installed. # ensure_packages `emacs_root_packages` } function action2_build () { rm -f "$emacs_install_dir/bin/emacs.exe" if prepare_source_dir $emacs_source_dir \ && prepare_build_dir $emacs_build_dir && emacs_configure_build_dir; then echo Building Emacs in directory $emacs_build_dir make -j $emacs_build_threads -C $emacs_build_dir && return 0 fi echo Configuration and build process failed return -1 } function action2_install () { if test -f "$emacs_install_dir/bin/emacs.exe"; then echo $emacs_install_dir/bin/emacs.exe exists echo refusing to reinstall else rm -rf "$emacs_install_dir" mkdir -p "$emacs_install_dir" if test "$emacs_compress_files" = "yes"; then # If we compress files we need to install gzip no matter what # (even in pack-emacs) (action3_gzip && cd "$emacs_install_dir" && unzip "$gzip_zip_file") || return -1 fi echo Installing Emacs into directory $emacs_install_dir # HACK!!! Somehow libgmp is not installed as part of the # standalone Emacs build process. This is weird, but means # we have to copy it by hand. make -j $emacs_build_threads -C $emacs_build_dir install \ && cp "${mingw_dir}bin/libgmp"*.dll "$emacs_install_dir/bin/" \ && rm -f "$emacs_install_dir/bin/emacs-"*.exe \ && emacs_build_strip_exes "$emacs_install_dir" \ && cp "$emacs_build_root/scripts/site-start.el" "$emacs_install_dir/share/emacs/site-lisp" \ && mkdir -p "$emacs_install_dir/usr/share/emacs/site-lisp/" \ && cp "$emacs_install_dir/share/emacs/site-lisp/subdirs.el" \ "$emacs_install_dir/usr/share/emacs/site-lisp/subdirs.el" fi } function emacs_build_strip_exes () { local dir="$1" if [ "$emacs_strip_executables" = "yes" ]; then find "$dir" -name '*.exe' -exec strip -g --strip-unneeded '{}' '+' fi } 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 # package_dependencies "$emacs_depsfile" "`emacs_dependencies`" } function action4_package_emacs () { # 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. return -1 fi rm -f "$emacs_nodepsfile" "$emacs_srcfile" mkdir -p `dirname "$emacs_nodepsfile"` cd "$emacs_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 cd "$emacs_source_dir" if zip -x '.git/*' -9vr "$emacs_srcfile" *; then echo Built source package $emacs_srcfile else echo Failed to compress sources $emacs_srcfile; echo return -1 fi } function action5_package_all () { for zipfile in "$emacs_depsfile" $emacs_extensions; do if test ! -f "$zipfile"; then echo Missing zip file `basename $zipfile.` Cannot build full distribution. echo Please use --deps, --build and all extension options before --pack-all. echo return -1 fi done rm -rf "$emacs_full_install_dir" if cp -rf "$emacs_install_dir" "$emacs_full_install_dir"; then rm -f "$emacs_distfile" cd "$emacs_full_install_dir" for zipfile in "$emacs_depsfile" $emacs_extensions; do echo Unzipping $zipfile if unzip -ox $zipfile; then echo Done!; else echo Failed to unzip $zipfile return -1 fi done emacs_build_strip_exes "$emacs_full_install_dir" # find . -type f | sort | dependency_filter | xargs zip -9v "$emacs_distfile" # this is easier and not encounter IO problems zip -9vr "$emacs_distfile" ./* fi } function feature_list () { cat <&1 ; then echo Action $action succeeded. else echo Action $action failed. echo Aborting builds for branch $emacs_branch and architecture $architecture exit -1 fi done