#!/bin/sh # # ${R_HOME}/bin/build revision='$Revision: 1.10 $' version=`set - ${revision}; echo ${2}` version="R package builder ${version} Copyright (C) 2000 R Development Core Team. There is NO warranty. You may redistribute this software under the terms of the GNU General Public License. For more information about these matters, see the files named COPYING." usage="Usage: R CMD build [options] pkgdirs Build R packages from package sources in the directories specified by pkgdirs. A variety of diagnostic checks and cleanups are performed prior to building the packages. If necessary for passing the checks, use the \`--vsize' and \`--nsize' options to increase R's memory (\`--vanilla' is used by default). Options: -d, --debug turn on shell debugging (set -x) -h, --help print short help message and exit -v, --version print version info and exit --vsize=N set R's vector heap size to N bytes --nsize=N set R's number of cons cells to N --force force overwriting of (index) files Email bug reports to ." R_opts="--vanilla" debug=false force=false pkgs= ## Parse argument command line while test -n "${1}"; do case ${1} in -h|--help) echo "${usage}"; exit 0 ;; -v|--version) echo "${version}"; exit 0 ;; -d|--debug) debug=true ;; --force) force=true ;; --nsize=*) R_opts="{R_opts} ${1}" ;; --vsize=*) R_opts="{R_opts} ${1}" ;; *) pkgs="${pkgs} ${1}" ;; esac shift done ## Determine whether echo can suppress newlines. if echo "testing\c" | grep c >/dev/null; then if echo -n "testing" | sed s/-n/xn/ | grep xn >/dev/null; then ECHO_N= ECHO_C= ECHO_T=' ' else ECHO_N=-n ECHO_C= ECHO_T= fi else ECHO_N= ECHO_C='\c' ECHO_T= fi ## A few useful output functions checking () { if ${debug}; then echo "* checking $@ ..." else echo ${ECHO_N} "* checking $@ ...${ECHO_C}" fi } message () { echo "* $@"; } result () { echo "${ECHO_T} $@"; } ## For updating `INDEX' and `data/00Index; updateIndex () { oldindex=${1} newindex=${TMPDIR:-/tmp}/Rbuild${$} ${R_HOME}/bin/Rdindex ${Rdfiles} > ${newindex} if diff -b ${newindex} ${oldindex} > /dev/null; then result "OK" else result "NO" if ${force}; then echo "overwriting \`${oldindex}' as \`--force' was given" cp ${newindex} ${oldindex} else echo "use \`--force' to overwrite the existing \`${oldindex}'" fi fi rm -f ${newindex} } ## For updating `TITLE' updateTitle () { oldtitle=TITLE newtitle=${TMPDIR:-/tmp}/Rbuild${$} ${R_HOME}/bin/maketitle > ${newtitle} foo=`cat TITLE` package=`set - ${foo}; echo ${1}` title=`set - ${foo}; shift; echo ${*}` if test "${package}" != "${1}"; then if ${force}; then result "NO" echo "overwriting \`${oldtitle} as \`--force' was given" cp ${newtitle} ${oldtitle} else result "ERROR: package names do not match" echo "use \`--force' to overwrite the existing \`${oldtitle}'" exit 1 fi elif diff -b ${newtitle} ${oldtitle} > /dev/null; then result "OK" else result "NO" if ${force}; then echo "overwriting \`${oldtitle} as \`--force' was given" cp ${newtitle} ${oldtitle} else echo "use \`--force' to overwrite the existing \`${oldtitle}'" fi fi rm -f ${newtitle} } start_dir=`pwd` ## The work horse buildpkg () { echo "Building package \`${1}' ..." cd ${start_dir} checking "package dir" if test -d ${1}; then dir=`cd ${1}; pwd` else result "ERROR: package dir \`${1}' does not exist" exit 1 fi result "OK" ## Check whether `DESCRIPTION' exists and contains required fields checking "for \`DESCRIPTION'" if test -r ${dir}/DESCRIPTION; then cd ${dir} else result "ERROR: file \`DESCRIPTION' not found" exit 1 fi result "OK" checking "\`DESCRIPTION' license entry" foo=`grep "^License" DESCRIPTION` foo=`set - ${foo}; echo ${2}` if test -z "${foo}"; then result "ERROR: no license entry in \`DESCRIPTION'" exit 1 fi result "OK" checking "\`DESCRIPTION' package entry" foo=`grep "^Package" DESCRIPTION` package=`set - ${foo}; echo ${2}` if test -z "${package}"; then result "ERROR: no package entry in \`DESCRIPTION'" exit 1 fi if test "${package}" != `basename ${dir}`; then result "ERROR: package field in \`DESCRIPTION' differs from dir name" exit 1 fi result "OK" checking "\`DESCRIPTION' version entry" foo=`grep "^Version" DESCRIPTION` version=`set - ${foo}; echo ${2}` if test -z "${version}"; then result "ERROR: no version entry in \`DESCRIPTION'" exit 1 fi result "OK" ## Check for title entry and/or `TITLE' checking "\`DESCRIPTION' title entry" title=`grep -s "^Title:" DESCRIPTION | sed "s/^Title:[ \t]*//"` if test -z "${title}"; then result "WARNING: no title entry in \`DESCRIPTION'" else result "OK" fi checking "for \`TITLE'" if test -r TITLE; then result "OK" if test -n "${title}"; then checking "whether \`TITLE' is up-to-date" updateTitle "${package}" fi else result "NO" if test -n "${title}"; then message "creating \`TITLE' from \`DESCRIPTION' title entry" ${R_HOME}/bin/maketitle > TITLE if test ${?} -ne 0; then result "ERROR" exit 1 else result "OK" fi else result "ERROR: no \`TITLE' and no \`DESCRIPTION' title entry" exit 1 fi fi ## Check R documentation files if test -d man; then checking "Rd files" Rdfiles=`find man -name "*.[Rr]d" -print | sort` if test -n "${Rdfiles}"; then any= for tag in name alias title description keyword; do badfiles=`grep -L "^\\\\\\\\${tag}" ${Rdfiles} 2>/dev/null` if test -n "${badfiles}"; then if test -z "${any}"; then result "WARNING:" fi any="${any} ${tag}" echo "Rd files without ${tag}:" echo "${badfiles}" fi done if test -z "${any}"; then result "OK" fi else result "WARNING: no Rd files found" fi fi ## Check for `INDEX' checking "for \`INDEX'" if test -r INDEX; then result "OK" if test -n "${Rdfiles}"; then checking "whether \`INDEX' is up-to-date" updateIndex "INDEX" fi else result "NO" if test -n "${Rdfiles}"; then message "creating \`INDEX' from Rd files" ${R_HOME}/bin/Rdindex ${Rdfiles} > INDEX if test ${?} -ne 0; then result "ERROR" exit 1 else result "OK" fi else result "ERROR: no \`INDEX' and no Rd files found." exit 1 fi fi ## Update `data/00Index' if test -d data; then if test -n "${Rdfiles}"; then Rdfiles=`grep -l "\\\\keyword{datasets}" ${Rdfiles}` fi checking "for \`data/00Index'" if test -r data/00Index; then result "OK" if test -n "${Rdfiles}"; then checking "whether \`data/00Index' is up-to-date" updateIndex "data/00Index" fi else result "NO" if test -n "${Rdfiles}"; then message "creating \`data/00Index' from Rd files" ${R_HOME}/bin/Rdindex ${Rdfiles} > data/00Index if test ${?} -ne 0; then result "ERROR" exit 1 else result "OK" fi else result "ERROR: no \`data/00Index' and no Rd files found." exit 1 fi fi fi ## Check for undocumented objects if test -d R -a -d man; then checking "for undocumented objects" out=`echo "undoc(dir = \"${dir}\")" \ | ${R_HOME}/bin/R.X11 ${R_opts} \ | grep "^Error\\|^ *\\["` err=`echo "${out}" | grep "^Error"` if test -z "${err}"; then if test -n "${out}"; then result "WARNING:" echo "${out}" else result "OK" fi else err=`echo "${err}" | sed -e 's/^Error *//'` result "ERROR:" echo "${err}" exit 1 fi fi ## Clean up `src' if test -d src; then message "cleaning \`src'" if test -r src/Makefile; then (cd src && make clean) else rm -f *.o *.s[lo] fi fi ## Other cleanups for f in .Rdata .Rhistory; do junk=`find . -name ${f}` if test -n "${junk}"; then message "removing left-over \`${f}' files" rm -f ${junk} fi done if test -x cleanup; then message "running \`cleanup'" ./cleanup fi ## And finally build the package cd .. exclude_file=${TMPDIR:-/tmp}/Rbuild${$} rm -f ${exclude_file} 2>/dev/null \ || (echo "cannot create file with exclude patterns" && exit 2) for pattern in "*~" "CVS" "GNUMakefile"; do echo "${pattern}" >> ${exclude_file} done message "building \`${start_dir}/${package}_${version}.tar.gz'" tar zch -X ${exclude_file} \ -f ${start_dir}/${package}_${version}.tar.gz ${package} rm -f ${exclude_file} } ## The main loop if ${debug}; then set -x; fi for p in ${pkgs}; do buildpkg ${p} echo done ### Local Variables: *** ### mode: sh *** ### sh-indentation: 2 *** ### End: ***