Rev 9218 | Blame | Last modification | View Log | Download | RSS feed
#!/bin/sh## ${R_HOME}/bin/buildrevision='$Revision: 1.20 $'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 theterms of the GNU General Public License.For more information about these matters, see the files named COPYING."usage="Usage: R CMD build [options] pkgdirsBuild R packages from package sources in the directories specified bypkgdirs. A variety of diagnostic checks and cleanups are performedprior 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) filesEmail bug reports to <r-bugs@lists.r-project.org>."R_opts="--vanilla"debug=falseforce=falsepkgs=## Parse argument command linewhile test -n "${1}"; docase ${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}" ;;esacshiftdonestart_dir=`pwd`stars="*"## Determine whether echo can suppress newlines.if echo "testing\c" | grep c >/dev/null; thenif echo -n "testing" | sed s/-n/xn/ | grep xn >/dev/null; thenECHO_N= ECHO_C= ECHO_T=' 'elseECHO_N=-n ECHO_C= ECHO_T=fielseECHO_N= ECHO_C='\c' ECHO_T=fi## A few useful output functionschecking () {if ${debug}; thenecho "${stars} checking $@ ..."elseecho ${ECHO_N} "${stars} checking $@ ...${ECHO_C}"fi}creating () { echo ${ECHO_N} "${stars} creating $@ ...${ECHO_C}"; }message () { echo "${stars} $@"; }result () { echo "${ECHO_T} $@"; }## Get one field including all continuation lines from a DCF fileget_dcf_field () {ws="[ ]" # space and tabsed -n "/^${1}:/,/^[^ ]/{p;}" ${2} | \sed -n "/^${1}:/{s/^${1}:${ws}*//;p;}/^${ws}/{s/^${ws}*//;p;}"}## 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; thenresult "OK"elseresult "NO"if ${force}; thenecho "overwriting \`${oldindex}' as \`--force' was given"cp ${newindex} ${oldindex}elseecho "use \`--force' to overwrite the existing \`${oldindex}'"fifirm -f ${newindex}}## For updating `TITLE'updateTitle () {oldtitle=TITLEnewtitle=${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}"; thenif ${force}; thenresult "NO"echo "overwriting \`${oldtitle} as \`--force' was given"cp ${newtitle} ${oldtitle}elseresult "ERROR: package names do not match"echo "use \`--force' to overwrite the existing \`${oldtitle}'"exit 1fielif diff -b ${newtitle} ${oldtitle} > /dev/null; thenresult "OK"elseresult "NO"if ${force}; thenecho "overwriting \`${oldtitle} as \`--force' was given"cp ${newtitle} ${oldtitle}elseecho "use \`--force' to overwrite the existing \`${oldtitle}'"fifirm -f ${newtitle}}## Initial checkscheckdir () {cd ${start_dir}checking "package dir"if test -d ${1}; thendir=`cd ${1}; pwd`elseresult "ERROR: package dir \`${1}' does not exist"exit 1firesult "OK"## Check whether `DESCRIPTION' exists and contains required fieldschecking "for \`DESCRIPTION'"if test -r ${dir}/DESCRIPTION; then:elseresult "ERROR: file \`DESCRIPTION' not found"exit 1firesult "OK"checking "\`DESCRIPTION' license entry"license=`get_dcf_field License ${dir}/DESCRIPTION`if test -z "${license}"; thenresult "ERROR: no license entry in \`DESCRIPTION'"exit 1firesult "OK"checking "\`DESCRIPTION' version entry"foo=`grep "^Version" ${dir}/DESCRIPTION`version=`set - ${foo}; echo ${2}`if test -z "${version}"; thenresult "ERROR: no version entry in \`DESCRIPTION'"exit 1firesult "OK"}## The work horsecheckpkg () {cd ${start_dir}if ${is_bundle}; then## If this package is part of a bundle, we need to make sure the## directory exists and contains a `DESCRIPTION.in' file.## Note that this code repeats the first two tests in checkdir().checking "package dir"if test -d ${1}; thendir=`cd ${1}; pwd`elseresult "ERROR: package dir \`${1}' does not exist"exit 1firesult "OK"description=DESCRIPTION.inchecking "for \`${description}'"if test -r ${dir}/${description}; then:elseresult "ERROR: file \`${description}' not found"exit 1firesult "OK"elsedir=`cd ${1}; pwd`description=DESCRIPTIONficd ${dir}checking "\`${description}' package entry"package=`get_dcf_field Package ${description}`if test -z "${package}"; thenresult "ERROR: no package entry in \`${description}'"exit 1fiif test "${package}" != `basename ${dir}`; thenresult "ERROR: package field in \`${description}' differs from dir name"exit 1firesult "OK"## Check for title entry and/or `TITLE'checking "\`${description}' title entry"title=`get_dcf_field Title ${description}`if test -z "${title}"; thenresult "WARNING: no title entry in \`${description}'"elseresult "OK"fichecking "for \`TITLE'"if test -r TITLE; thenresult "OK"if test -n "${title}"; thenchecking "whether \`TITLE' is up-to-date"updateTitle "${package}"fielseresult "NO"if test -n "${title}"; thencreating "\`TITLE' from \`${description}' title entry"${R_HOME}/bin/maketitle > TITLEif test ${?} -ne 0; thenresult "ERROR"exit 1elseresult "OK"fielseresult "ERROR: no \`TITLE' and no \`${description}' title entry"exit 1fifi## Check R documentation filesif test -d man; thenchecking "Rd files"all_file=${TMPDIR:-/tmp}/Rall${$}tag_file=${TMPDIR:-/tmp}/Rtag${$}rm -f ${all_file} 2>/dev/nullfind man -name "*.[Rr]d" -print | sort > ${all_file}Rdfiles=`cat ${all_file}`if test -n "${Rdfiles}"; thenbadfiles=`grep "<" ${all_file}`if test -n "${badfiles}"; thenresult "ERROR"echo "Cannot handle Rd file names containing \`<'."echo "These are not legal file names on all R platforms."echo "Please rename the following files and try again."echo "${badfiles}"exit 1fiany=for tag in name alias title description keyword; dorm -f ${tag_file} 2>/dev/nullgrep -l "^\\\\${tag}" ${Rdfiles} > ${tag_file} 2>/dev/nullbadfiles=`comm -2 -3 ${all_file} ${tag_file}`if test -n "${badfiles}"; thenif test -z "${any}"; thenresult "WARNING:"fiany="${any} ${tag}"echo "Rd files without \`${tag}':"echo "${badfiles}"fidonefor tag in name title description usage arguments format details \value references source seealso examples note author \synopsis; dorm -f ${tag_file} 2>/dev/nullpattern="^\\\\${tag}"for f in ${Rdfiles}; docount=`grep ${pattern} ${f} | wc -l`if test ${count} -gt 1; thenecho ${f} >> ${tag_file}fidoneif test -f ${tag_file}; thenif test -z "${any}"; thenresult "WARNING:"fiany="${any} ${tag}"echo "Rd files with duplicate \`${tag}':"cat ${tag_file}fidoneif test -z "${any}"; thenresult "OK"fielseresult "WARNING: no Rd files found"firm -f ${all_file} ${tag_file} 2>/dev/nullfi## Check for `INDEX'checking "for \`INDEX'"if test -r INDEX; thenresult "OK"if test -n "${Rdfiles}"; thenchecking "whether \`INDEX' is up-to-date"updateIndex "INDEX"fielseresult "NO"if test -n "${Rdfiles}"; thencreating "\`INDEX' from Rd files"${R_HOME}/bin/Rdindex ${Rdfiles} > INDEXif test ${?} -ne 0; thenresult "ERROR"exit 1elseresult "OK"fielseresult "ERROR: no \`INDEX' and no Rd files found."exit 1fifi## Update `data/00Index'if test -d data; thenif test -n "${Rdfiles}"; thenRdfiles=`grep -l "\\\\keyword{datasets}" ${Rdfiles}`fichecking "for \`data/00Index'"if test -r data/00Index; thenresult "OK"if test -n "${Rdfiles}"; thenchecking "whether \`data/00Index' is up-to-date"updateIndex "data/00Index"fielseresult "NO"if test -n "${Rdfiles}"; thencreating "\`data/00Index' from Rd files"${R_HOME}/bin/Rdindex ${Rdfiles} > data/00Indexif test ${?} -ne 0; thenresult "ERROR"exit 1elseresult "OK"fielseresult "ERROR: no \`data/00Index' and no Rd files found."exit 1fififi## Check for undocumented objectsif test -d R -a -d man; thenchecking "for undocumented objects"out=`echo "undoc(dir = \"${dir}\")" \| ${R_HOME}/bin/R.bin ${R_opts}`err=`echo "${out}" | grep "^Error"`out=`echo "${out}" | grep "^ *\\["`if test -z "${err}"; thenif test -n "${out}"; thenresult "WARNING:"echo "${out}"elseresult "OK"fielseerr=`echo "${err}" | sed -e 's/^Error *//'`result "ERROR:"echo "${err}"exit 1fifi## Clean up `src'if test -d src; thenmessage "cleaning \`src'"if test -r src/Makefile; then(cd src && make clean)elserm -f src/*.o src/*.s[lo]fifi## Other cleanupsif test -x cleanup; thenmessage "running \`cleanup'"./cleanupfi}buildpkg () {cd ${start_dir}/${1}## Final cleanupsfor f in .Rdata .Rhistory; dojunk=`find . -name ${f}`if test -n "${junk}"; thenmessage "removing left-over \`${f}' files"rm -f ${junk}fidone## And finally build the package (bundle)cd ..package=`basename ${1}`exclude_file=${TMPDIR:-/tmp}/Rbuild${$}rm -f ${exclude_file} 2>/dev/null \|| (echo "cannot create file with exclude patterns" && exit 2)find ${package} -type d -name check >> ${exclude_file}find ${package} -type d -name '*[Oo]ld' >> ${exclude_file}find ${package} -name GNUMakefile >> ${exclude_file}find ${package} -name CVS >> ${exclude_file}find ${package} -name \*~ >> ${exclude_file}message "building \`${start_dir}/${package}_${version}.tar.gz'"tar chfX - ${exclude_file} ${package} | \gzip -c9 > ${start_dir}/${package}_${version}.tar.gzrm -f ${exclude_file}}## The main loopif ${debug}; then set -x; fifor p in ${pkgs}; doecho "Building package \`${p}'"checkdir ${p}if grep "^Contains" ${p}/DESCRIPTION >/dev/null; thenecho "Looks like \`${p}' is a package bundle"is_bundle=truebundlepkgs=`get_dcf_field Contains ${p}/DESCRIPTION`for pp in ${bundlepkgs}; domessage "checking package \`${pp}' in bundle \`${p}'"stars="**"checkpkg ${p}/${pp}stars="*"doneelseis_bundle=falsecheckpkg ${p}fibuildpkg ${p}echodone### Local Variables: ***### mode: sh ***### sh-indentation: 2 ***### End: ***