Script "build-kernelpkg.sh"
#!/bin/sh

# ------------------------
# build-kernelpkg.sh
# version 1.3.1.2
# ------------------------

# check for parameters

_usage_str="${0} [ --menuconfig | --menuconfig-only ] [ --remove-builddir ] [ --no-network-mode ]"

if [ "${1}" = "--help" ] || [ "${1}" = "--usage" ]; then
  printf "%s\n    %s\n" "Usage:" "${_usage_str}"
  exit 0
fi

MENUCONFIG_OPT=""
MENUCONFIG_ONLY_OPT=""
REMOVE_BUILDDIR_OPT=""
NO_NETWORK_MODE_OPT=""
for arg in $@
do
  is_option=`echo "${arg}" | grep -- '\-\-'`
  if [ -z "${is_option}" ]; then
    printf "%s: skipped '%s'\n" "${0}" "${arg}"
  else
    [ $arg = "--menuconfig" ] && MENUCONFIG_OPT="yes" && continue
    [ $arg = "--menuconfig-only" ] && MENUCONFIG_ONLY_OPT="yes" && continue
    [ $arg = "--remove-builddir" ] && REMOVE_BUILDDIR_OPT="yes" && continue
    [ $arg = "--no-network-mode" ] && NO_NETWORK_MODE_OPT="yes" && continue
    echo "${0}: unknown option '${arg}'"
  fi
done

if [ ! -z "${MENUCONFIG_OPT}" ] && [ ! -z "${MENUCONFIG_ONLY_OPT}" ]; then
  echo "--menuconfig and --menuconfig-only options are mutually exclusive!"
  echo "please, specify only one of them"
  exit 1
fi

[ -z "${BUILD_FARM}" ] && BUILD_FARM="${HOME}/build-farm"
if [ -d "${BUILD_FARM}" ]; then
  echo "base directory:" "${BUILD_FARM}"
else
  echo "ERROR: base directory '${BUILD_FARM}' doesn't exist. Abort."
  exit 1
fi

[ -z "${PKGBS_DIR}" ] && PKGBS_DIR="${BUILD_FARM}"/BUILD-SCRIPTS
[ -d "${PKGBS_DIR}" ] || PKGBS_DIR=`pwd`
CONFIG_PATH="${PKGBS_DIR}"/CONFIG
PPFILES_PATH="${PKGBS_DIR}"/PPFILES

# check for required scripts

if [ ! -f "${PKGBS_DIR}"/get_source_for_pkg.sh ]; then
  echo "ERROR: build farm is broken; can't find script 'get_source_for_pkg.sh'. Abort."
  exit 1
fi
if [ ! -f "${PKGBS_DIR}"/patch_raw_srcpkg.sh ]; then
  echo "ERROR: build farm is broken; can't find script 'patch_raw_srcpkg.sh'. Abort."
  exit 1
fi
if [ ! -f "${PKGBS_DIR}"/srcpkg_to_binpkg.sh ]; then
  echo "ERROR: build farm is broken; can't find script 'srcpkg_to_binpkg.sh'. Abort."
  exit 1
fi

# check for required binaries
REQD_BINS=""
which find >/dev/null 2>&1 || type find >/dev/null 2>&1 || REQD_BINS="find,${REQD_BINS}"
which sed >/dev/null 2>&1 || type sed >/dev/null 2>&1 || REQD_BINS="sed,${REQD_BINS}"
which grep >/dev/null 2>&1 || type grep >/dev/null 2>&1 || REQD_BINS="grep,${REQD_BINS}"
which lynx >/dev/null 2>&1 || type lynx >/dev/null 2>&1 || REQD_BINS="lynx,${REQD_BINS}"
which cpio >/dev/null 2>&1 || type cpio >/dev/null 2>&1 || REQD_BINS="cpio,${REQD_BINS}"
which gzip >/dev/null 2>&1 || type gzip >/dev/null 2>&1 || REQD_BINS="gzip,${REQD_BINS}"
if [ -n "${REQD_BINS}" ]; then
  echo -e `basename ${0}`: "Required binaries (${REQD_BINS}\010) are not present."
  exit 1
fi

# get kernel's version and tarball location

PKGTITLE="linux_libre"

_network_works="yes"
if [ -z "${NO_NETWORK_MODE_OPT}" ]; then
  lynx -dump http://ftp.osuosl.org/pub/manulix/linux-libre/ 1>./linux-libre-releases.dump 2>./.lynx_error
  if [ $? -ne 0 ]; then
    ##cat ./.lynx_error
    echo "WARNING: 'lynx -dump' error."
    rm -f ./linux-libre-releases.dump 2>/dev/null
    rm -f ./.lynx_error 2>/dev/null
    _network_works="no"
  fi
  LINUX_RELEASES=`cat ./linux-libre-releases.dump 2>/dev/null`
  rm -f ./linux-libre-releases.dump 2>/dev/null
  rm -f ./.lynx_error 2>/dev/null
else
  _network_works="no"
fi

_packages_dir=`find "${BUILD_FARM}" -type d -name "PACKAGES"`
_i_have_this_srcpkg=""

if [ "${_network_works}" = "yes" ]; then
  LINUX_RELEASE_PATH=`echo "${LINUX_RELEASES}" | grep "linux\-libre" | tail -1 | tr ' ' '\n' | tail -1`
  LINUX_VERSION=`basename "${LINUX_RELEASE_PATH}"`
else
  if [ -z "${_packages_dir}" ]; then
    echo "ERROR: network connection is not available and srcpkg directory cannot be found. Abort."
    exit 1
  else
    _i_have_this_srcpkg=`find "${_packages_dir}" -name "*.srcpkg.*" -print | grep "${PKGTITLE}" | sort | tail -1`
    if [ -z "${_i_have_this_srcpkg}" ]; then
      echo "ERROR: network connection is not available and tarball cannot be found. Abort."
      exit 1
    fi
    LINUX_RELEASE_PATH=`dirname "${_i_have_this_srcpkg}"`/
    LINUX_TARBALL_PATH="${_i_have_this_srcpkg}"
    LINUX_TARBALL=`basename "${LINUX_TARBALL_PATH}"`
    LINUX_VERSION=`echo "${_i_have_this_srcpkg}" | sed -e "s|${PKGTITLE}-|@|" -e "s/.srcpkg/@/" | cut -d'@' -f2 | sed 's/v//'`
  fi
fi

LINUX_VERSION=`echo "${LINUX_VERSION}" | sed -e 's/linux-//' -e 's/libre-//' -e 's/-libre//' -e 's/-gnu//'`-libre-gnu
export LINUX_VERSION

_version_number=`echo "${LINUX_VERSION}" | cut -d'-' -f1`
if [ "${_network_works}" = "yes" ]; then
  [ -z "${_packages_dir}" ] || _i_have_this_srcpkg=`find "${_packages_dir}" -name "*.srcpkg.*" -print | grep "${PKGTITLE}" | grep "${_version_number}"`
fi

if [ "${_network_works}" = "yes" ]; then
  lynx -dump "${LINUX_RELEASE_PATH}" 1>./linux-libre-current.dump 2>./.lynx_error
  if [ $? -ne 0 ]; then
    cat ./.lynx_error
    echo "OOPS: unexpected 'lynx -dump' error. Abort."
    rm -f ./linux-libre-current.dump 2>/dev/null
    rm -f ./.lynx_error 2>/dev/null
    exit 1
  fi

  LINUX_CURRENT_FILES=`cat ./linux-libre-current.dump`
  rm -f ./linux-libre-current.dump 2>/dev/null
  rm -f ./.lynx_error 2>/dev/null

  LINUX_TARBALL=`echo "${LINUX_CURRENT_FILES}" | grep -v 'http:' | grep "[.+?]" | tr ']' '\n' | grep -v "\[" | \
    grep "linux.*libre" | grep -v "patch" | grep -v "xdelta" | grep -v "vcdiff" | \
    grep -v "\.log" | grep -v "\.sign" | grep -v "\.xz" | grep -v "\.lz" | \
    tail -1 | tr ' ' '\n' | head -1`
  LINUX_TARBALL_PATH="${LINUX_RELEASE_PATH}${LINUX_TARBALL}"
fi

# print package information

echo "building linux the kernel"
echo "version:" "${LINUX_VERSION}"
echo "tarball:" "${LINUX_TARBALL}"
echo "location:" "${LINUX_TARBALL_PATH}"
echo "---- Linux-libre, Free as in Freedo ----"

if [ -z "${LINUX_TARBALL_PATH}" ]; then
  echo "ERROR: tarball cannot be found. Abort."
  exit 1
fi

if [ "${_network_works}" = "yes" ]; then
  echo "http" "${LINUX_TARBALL_PATH}" > "${PKGBS_DIR}"/SRCINFO/srcinfo-"${PKGTITLE}"
fi

if [ -f "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}" ]; then
  if [ ! -z "${MENUCONFIG_ONLY_OPT}" ]; then
    sed -i 's/oldconfig/menuconfig/' "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}"
  fi
  if [ ! -z "${MENUCONFIG_OPT}" ]; then
    sed -i 's/make oldconfig/make oldconfig \&\& make menuconfig/' "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}"
  fi
fi

echo "related build system files/directories:"
rfile_count=0
[ -f "${PKGBS_DIR}"/PATCHCMDS/patchcmds-"${PKGTITLE}" ] && rfile_count=`expr $rfile_count '+' 1` &&
  printf "\t%s (%s)\n" "patchcmds" "'PATCHCMDS/patchcmds-${PKGTITLE}'"
[ -f "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}" ] && rfile_count=`expr $rfile_count '+' 1` &&
  printf "\t%s (%s)\n" "buildcmds" "'BUILDCMDS/buildcmds-${PKGTITLE}'"
[ -f "${PKGBS_DIR}"/POSTCMDS/postcmds-"${PKGTITLE}" ] && rfile_count=`expr $rfile_count '+' 1` &&
  printf "\t%s (%s)\n" "postcmds" "'POSTCMDS/postcmds-${PKGTITLE}'"
[ -f "${CONFIG_PATH}"/config-kernel.in ] && rfile_count=`expr $rfile_count '+' 1` &&
  printf "\t%s (%s)\n" "config" "'CONFIG/config-kernel.in'"
[ -d "${PPFILES_PATH}"/ppfiles-kernel ] && rfile_count=`expr $rfile_count '+' 1` &&
  printf "\t%s (%s)\n" "ppfiles/" "'PPFILES/ppfiles-kernel/'"
if [ $rfile_count -eq 0 ]; then
  printf "\t<%s>\n" "none"
fi

if [ -f "${CONFIG_PATH}"/config-kernel.in ]; then
  cp "${CONFIG_PATH}"/config-kernel.in "${CONFIG_PATH}"/config-kernel
  # this option just does not have any affect on a non-altivec cpu; no need to care
  ##if [ "${ALTIVEC_ON_OPT}" = "yes" ]; then
    ##sed -i 's/# CONFIG_ALTIVEC is not set/CONFIG_ALTIVEC=y/' "${CONFIG_PATH}"/config-kernel
  ##else
    ##sed -i 's/CONFIG_ALTIVEC=y/# CONFIG_ALTIVEC is not set/' "${CONFIG_PATH}"/config-kernel
  ##fi
elif [ -f "${CONFIG_PATH}"/config-kernel ]; then
  cp "${CONFIG_PATH}"/config-kernel "${CONFIG_PATH}"/
else
  printf "%s: %s ('%s')\n" "WARNING" "can't locate .config file" "${CONFIG_PATH}"/config-kernel.in
fi

# get source package

if [ -z "${_i_have_this_srcpkg}" ]; then
  raw_src_success=
  "${PKGBS_DIR}"/get_source_for_pkg.sh "${PKGTITLE}"
  [ $? -eq 0 ] && raw_src_success="yes"
  if [ -z ${raw_src_success} ]; then
    echo "('get_source_for_pkg.sh' already said its error message.)"
    exit 1
  fi

  patch_success=
  "${PKGBS_DIR}"/patch_raw_srcpkg.sh "${PKGTITLE}"
  [ $? -eq 0 ] && patch_success="yes"
  cd "${PKGBS_DIR}"
  if [ -z ${patch_success} ]; then
    echo "('patch_raw_srcpkg.sh' already said its error message.)"
    exit 1
  fi
else
  printf "found local source package for '%s' (v%s): %s\n" "${PKGTITLE}" "${LINUX_VERSION}" "${_i_have_this_srcpkg}"
  mv "${_i_have_this_srcpkg}" "${BUILD_FARM}"/
  kernel_srcpkg=`basename "${_i_have_this_srcpkg}"`
  curr_wd=`pwd`
  cd "${BUILD_FARM}"

  type_of_file=`file ./"${kernel_srcpkg}" | cut -d':' -f2`
  is_bzip2=`echo "${type_of_file}" | grep -i bzip2`
  is_xz=`echo "${type_of_file}" | grep -i xz`
  is_gzip=`echo "${type_of_file}" | grep -i gzip`

  printf "extracting '%s'" "${kernel_srcpkg}"
  if [ ! -z "${is_bzip2}" ]; then
    printf " (bzip2)..."
    tar xjf ./"${kernel_srcpkg}" 2>&1
  elif [ ! -z "${is_xz}" ]; then
    printf " (xz)..."
    unxz ./"${kernel_srcpkg}" 2>&1
    kernel_srcpkg=`echo "${kernel_srcpkg}" | sed 's/\.xz//'`
    tar xf ./"${kernel_srcpkg}" 2>&1
  elif [ ! -z "${is_gzip}" ]; then
    printf " (gzip)..."
    tar xzf ./"${kernel_srcpkg}" 2>&1
  else
    echo ' (unknown!)'
    echo "ERROR: unknown compression method. Abort."
    mv ./"${kernel_srcpkg}" "${_i_have_this_srcpkg}"
    exit 1
  fi

  if [ $? -eq 0 ]; then
    echo " ok"
  else
    echo " fail"
    echo "ERROR: scrpkg extraction error. Abort."
    mv ./"${kernel_srcpkg}" "${_i_have_this_srcpkg}"
    exit 1
  fi

  mv ./"${kernel_srcpkg}" "${_i_have_this_srcpkg}"
  cd "${curr_wd}"
fi

# build it now

binpkg_success=
if [ -z ${DEBUG_PKG_OPT} ]; then
  "${PKGBS_DIR}"/srcpkg_to_binpkg.sh --kernel-mode "${PKGTITLE}"
else
  "${PKGBS_DIR}"/srcpkg_to_binpkg.sh --debug-pkg --kernel-mode "${PKGTITLE}"
fi
[ $? -eq 0 ] && binpkg_success="yes"  

if [ -f "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}" ]; then
  if [ ! -z "${MENUCONFIG_ONLY_OPT}" ]; then
    sed    -i 's/menuconfig/oldconfig/' "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}"
  fi
  if [ ! -z "${MENUCONFIG_OPT}" ]; then
    sed -i 's/oldconfig \&\& make menuconfig/oldconfig/' "${PKGBS_DIR}"/BUILDCMDS/buildcmds-"${PKGTITLE}"
  fi
fi

if [ -z ${binpkg_success} ]; then
  echo "('srcpkg_to_binpkg.sh' already said its error message.)"
  exit 1
fi

cd "${PKGBS_DIR}"

[ -z "${BUILD_DIR}" ] && BUILD_DIR=`ls -tp "${BUILD_FARM}" | grep '/' | sed 's|/||' | grep "${PKGTITLE}" | grep "builddir" | head -1`
[ -z "${BUILD_DIR}" ] && BUILD_DIR=`ls -tp "${BUILD_FARM}" | grep '/' | sed 's|/||' | grep "_${PKGTITLE}_" | head -1`
[ -z "${SOURCE_DIR}" ] && SOURCE_DIR=`ls -tp "${BUILD_FARM}" | grep '/' | sed 's|/||' | grep "${PKGTITLE}" | grep "sourcedir" | head -1`
[ -z "${BUILD_DIR}" ] && BUILD_DIR="${PKGTITLE}".builddir

# locate kernel installation directory

_install_path=""
if [ ! -z "${BUILD_DIR}" ]; then
  _install_path=`find "${BUILD_FARM}/${BUILD_DIR}" -type d -name "boot" -print | grep -v "include" | grep -v "arch" | head -1`
fi
if [ -z "${_install_path}" ] && [ ! -z "${SOURCE_DIR}" ]; then
  _install_path=`find "${BUILD_FARM}/${SOURCE_DIR}" -type d -name "boot" -print | grep -v "include" | grep -v "arch" | head -1`
fi

[ -z "${_install_path}" ] && _install_path="${BUILD_FARM}"/boot
_install_path=`dirname "${_install_path}"`
printf "kernel installation directory: '%s'\n" "${_install_path}"

# create initrd as cpio archive from a directory

initrd_dir=initrd-"${LINUX_VERSION}"-powerpc
initrd_path="${_install_path}/${initrd_dir}"
the_boot_path="${_install_path}"/boot
[ -d "${initrd_path}" ] || mkdir -p "${initrd_path}"
[ -d "${the_boot_path}" ] || mkdir -p "${the_boot_path}"
initrd_name="${initrd_dir}".cpio.gz

printf "creating initrd..."

rm -f "${the_boot_path}/${initrd_name}" 2>/dev/null
rm -rf "${initrd_path}"/bin 2>/dev/null
rm -rf "${initrd_path}"/lib 2>/dev/null
mkdir -p "${initrd_path}"/bin
mkdir -p "${initrd_path}"/lib
mkdir -p "${initrd_path}"/lib/modules

cp -l /lib/ld-*.so* "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libuClibc*.so "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libc.so* "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libpthread*.so* "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libutil*.so* "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libm*.so* "${initrd_path}"/lib/ 2>/dev/null
cp -l /lib/libz.so* "${initrd_path}"/lib/ 2>/dev/null || cp -l /usr/lib/libz.so* "${initrd_path}"/lib/ 2>/dev/null

_busybox_found="yes"
which busybox 1>/dev/null 2>&1 || type busybox 1>/dev/null 2>&1 || _busybox_found="no"
if [ ${_busybox_found} = "yes" ]; then
  _busybox_bin=`which busybox 2>/dev/null || type busybox 2>/dev/null`
  cp "${_busybox_bin}" "${initrd_path}"/bin/
  curr_wd=`pwd`
  cd "${initrd_path}"/bin/
  _bb_applets=`busybox --list`
  echo "${_bb_applets}" | while read _the_applet
  do
    ln -s busybox "${_the_applet}" 
  done
else
  printf " (WARNING: can't find 'busybox', skipping it)..."
fi

cd "${initrd_path}"
echo '#!/bin/sh' > ./init
echo "" >> ./init
echo 'PATH="/bin"' >> ./init
echo 'export PATH' >> ./init
echo "" >> ./init
echo 'echo "Hello from initrd!"' >> ./init
echo '[ -x /bin/sh ] && /bin/sh || /bin/ash' >> ./init

chown -R 0 "${initrd_path}"
chgrp -R 0 "${initrd_path}"
chmod -R go-rwx "${initrd_path}"
chmod u=rwx "${initrd_path}" && chmod g=rx "${initrd_path}"
chmod -R u=rwx "${initrd_path}"/bin && chmod -R g=rx "${initrd_path}"/bin
chmod -R u=rwx "${initrd_path}"/lib && chmod -R g=rx "${initrd_path}"/lib
chmod u=rwx "${initrd_path}"/init && chmod g=rx "${initrd_path}"/init

cd "${_install_path}"
gzip_initrd_success=""
find "${initrd_dir}" -print | cpio -o -H newc | gzip -9 > "${the_boot_path}/${initrd_name}"
# un-gzip it with: gunzip < initrd.cpio.gz | cpio -i --make-directories
[ $? -eq 0 ] && gzip_initrd_success="yes"
chmod 0644 "${the_boot_path}/${initrd_name}"
[ "${gzip_initrd_success}" = "yes" ] && echo " ok"
cd "${PKGBS_DIR}"

mv "${initrd_path}" "${_install_path}"/../

# deal with build and source directories

if [ ! -z "${BUILD_DIR}" ]; then
  if [ ! -z ${binpkg_success} ]; then
    if [ ! -z ${REMOVE_BUILDDIR_OPT} ]; then
      printf "removing build directory '%s' (%s)..." "${BUILD_FARM}/${PKGPREFIX}/${BUILD_DIR}" "--remove-builddir"
      rm -rf "${BUILD_FARM}/${PKGPREFIX}/${BUILD_DIR}" && echo " ok"
    fi
  fi
fi
if [ ! -z "${SOURCE_DIR}" ]; then
  if [ -z ${binpkg_success} ]; then
    BUILD_DIR=""
    echo "source directory" \(\'"${BUILD_FARM}/${PKGPREFIX}/${SOURCE_DIR}"\'\) "left untouched (errors)"
  else
    printf "removing source directory '%s'..." "${BUILD_FARM}/${PKGPREFIX}/${SOURCE_DIR}"
    rm -rf "${BUILD_FARM}/${PKGPREFIX}/${SOURCE_DIR}" && echo " ok"
  fi
fi

pkg_arch="unknown"
target_triplet=`gcc -v 2>&1 | grep "Target:" | awk '{print $2}' | tr '-' ' '`
case `uname -m` in
  ppc)
    pkg_arch="powerpc"
    ;;
  *)
    pkg_arch=`echo "${target_triplet}" | awk '{print $1}'`
    ;;
esac

# package installation directory into kernelpkg

cd "${_install_path}"
printf "compressing kernel package..."
pkg_filename="linux_libre-v${_version_number}-${pkg_arch}.kernelpkg.tar.bz2"
tar cjf "${pkg_filename}" * && echo " ok"
[ -d "${BUILD_FARM}"/PACKAGES ] || mkdir -p "${BUILD_FARM}"/PACKAGES
_bin_packages_dir="${BUILD_FARM}"/PACKAGES/binpkg-"${pkg_arch}"
[ -d "${_bin_packages_dir}" ] || mkdir -p "${_bin_packages_dir}"
mv ./"${pkg_filename}" "${_bin_packages_dir}"/ 
cd "${PKGBS_DIR}"

rm -f "${CONFIG_PATH}"/config-kernel 2>/dev/null

echo "Reached the end of script. The rest is still in progres..."

## ./build-farm/PACKAGES/binpkg-powerpc:
## linux_libre-v2.6.38.2-powerpc.kernelpkg.tar.bz2
## ./build-farm/PACKAGES/srcpkg:
## linux_libre-v2.6.38.2.srcpkg.tar.bz2
Unless otherwise stated, the content of this page is licensed under GNU Free Documentation License.