--- ./etc/Makefile.in.genlibs-patch Sat Dec 2 11:25:28 2000 +++ ./etc/Makefile.in Wed Jan 3 15:20:53 2001 @@ -53,6 +53,9 @@ @for f in $(OBJECTS) $(EXPORTFILE); do \ $(INSTALL_DATA) $${f} $(rhome)/etc; \ done + @for f in *.package-template; do \ + $(INSTALL_DATA) $${f} $(rhome)/etc; \ + done installdirs: @$(MKINSTALLDIRS) $(rhome)/etc install-gnome: --- ./etc/Makevars.in.package-template.genlibs-patch Wed Jan 3 15:20:53 2001 +++ ./etc/Makevars.in.package-template Wed Jan 3 15:23:54 2001 @@ -0,0 +1,4 @@ +# src/Makevars.in + +PKG_LIBS_ADD=@PKG_LIBPATH@ @PKG_R_LIBS@ + --- ./etc/install-sh.package-template.genlibs-patch Wed Jan 3 15:20:53 2001 +++ ./etc/install-sh.package-template Wed Jan 3 15:20:53 2001 @@ -0,0 +1,3 @@ +#/bin/sh +echo "dummy install script, edit me if necessary" + --- ./etc/acinclude.m4.package-template.genlibs-patch Wed Jan 3 15:20:53 2001 +++ ./etc/acinclude.m4.package-template Wed Jan 3 15:20:53 2001 @@ -0,0 +1,96 @@ +dnl acinclude.m4 +dnl +dnl autoconf macro to search for an installed contributed R package +dnl +AC_DEFUN(R_FIND_LIB,[ + AC_CACHE_CHECK([for R library $1], + r_library_$1,[ +if test -z "${R_HOME}" ; then + R_HOME=`R RHOME` +fi + +if test -z "${R_HOME}" ; then + echo "Cannot find the R distribution!" + exit 1 +fi + +dnl identify PATH where the library is installed (multiple paths possible!) +dnl (one gets eaten by autoconf, thats why the triple brackets below!) +cat >conftest.R <2){ + for (j in pc[[1:(length(pc)-2)]]) + if(nchar(j)>0) p<-paste(p,j,sep="/") + numfound<-numfound+1 + if(nchar(outp)>0) + outp<-paste(outp,p,sep=":") + else + outp<-p + } + } + } + out<-paste(out,outp,sep="") + cat(paste(out,"\n","export PKG_LIBPATH_$1\nPKG_NUM=", + as.character(numfound),"\n","export PKG_NUM\n",sep=""), file="./$1Libs") +} +paste.libs() +EOT + +echo "source(\"conftest.R\")" | ${R_HOME}/bin/R --vanilla >/dev/null +rm -f conftest.R + +eval "`cat ./$1Libs`" +rm -f ./$1Libs + +if test -z "${PKG_LIBPATH_$1}" ; then + echo "Cannot find the $1 library for R." + echo "Please install it, or set the environment R_LIBS so that it can be" + echo "found in an R session." + exit 1; +else + echo "package found" +fi + +if test "${PKG_NUM}" -gt 1; then + echo "WARNING: Package $1 found more then once!" +fi + +dnl choose the first component from the list PKG_LIBPATH_$1 which contains +dnl a dynamic or static package library in its ./lib subdirectory +PKG_R_LIB_$1_found=false +for i in `echo ${PKG_LIBPATH_$1}| sed -e 's/:/ /g'`; do +dnl should use something like SHLIBEXT instead of .so: + if test -f ${i}/lib/lib$1.so; then + echo "found lib$1.so at: ${i}/lib" + PKG_LIBPATH="${PKG_LIBPATH} -L${i}/lib" + PKG_R_LIBS="${PKG_R_LIBS} -l$1" + PKG_R_LIB_$1_found=true + break + else + if test -f ${i}/lib/lib$1.a; then + echo "found lib$1.a at: ${i}/lib" + PKG_LIBPATH="${PKG_LIBPATH} -L${i}/lib" + PKG_R_LIBS="${PKG_R_LIBS} -l$1" + PKG_R_LIB_$1_found=true + break + fi + fi +done +if test ! $PKG_R_LIB_$1_found; then + echo "Neither dynamic nor static library for $1 found." + echo "You may need to reinstall $1 with --create-lib-so or --create-lib-a" + echo "as options to R INSTALL" + exit 1 +fi +AC_SUBST(PKG_LIBPATH) +AC_SUBST(PKG_R_LIBS) + ] + ) +]) --- ./etc/configure.in.package-template.genlibs-patch Wed Jan 3 15:20:53 2001 +++ ./etc/configure.in.package-template Wed Jan 3 15:20:53 2001 @@ -0,0 +1,16 @@ +# package/configure.in + +AC_INIT(%FIRST_SRC_FILE%) # replace with appropriate source file in src + +AM_INIT_AUTOMAKE("%PACKAGE%",%VERSION%) + +# find installation path for dependency package "somepack" and test for +# availability of shared or static library libsomepack.{so,a} +# +# uncomment and repeat the following line for each package from +# which you want to use compiled functions: +# +#R_FIND_LIB(somepack) + +AC_OUTPUT(src/Makevars) + --- ./etc/Makeconf.in.genlibs-patch Fri Dec 1 12:51:50 2000 +++ ./etc/Makeconf.in Wed Jan 3 15:23:16 2001 @@ -41,7 +41,7 @@ ALL_CPPFLAGS = $(R_XTRA_CPPFLAGS) $(PKG_CPPFLAGS) $(CPPFLAGS) ALL_CXXFLAGS = $(R_XTRA_CXXFLAGS) $(PKG_CXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(CXXFLAGS) ALL_FFLAGS = $(R_XTRA_FFLAGS) $(PKG_FFLAGS) $(FPICFLAGS) $(SHLIB_FFLAGS) $(FFLAGS) -ALL_LIBS = $(LIBPATHS) $(PKG_LIBS) $(SHLIB_LIBADD) +ALL_LIBS = $(LIBPATHS) $(PKG_LIBS) $(SHLIB_LIBADD) $(PKG_LIBS_ADD) .SUFFIXES: .SUFFIXES: .c .cc .cpp .C .f .o .lo @@ -59,3 +59,6 @@ $(SHLIB): $(OBJS) $(SHLIB_LINK) -o $@ $(OBJS) $(ALL_LIBS) + +$(LIB): $(OBJS) + $(AR) ru $@ $(OBJS) --- ./configure.in.genlibs-patch Fri Dec 8 21:22:35 2000 +++ ./configure.in Wed Jan 3 15:20:53 2001 @@ -1031,6 +1031,7 @@ src/scripts/Rdindex src/scripts/Rprof src/scripts/SHLIB + src/scripts/LIB src/scripts/Sd2Rd src/scripts/build src/scripts/build-help --- ./src/library/base/R/library.R.genlibs-patch Sat Dec 2 14:03:41 2000 +++ ./src/library/base/R/library.R Wed Jan 3 15:20:53 2001 @@ -12,6 +12,8 @@ if (!character.only) package <- as.character(substitute(package)) pkgname <- paste("package", package, sep = ":") + if (pkgname == "package:lib") + stop("package name \"lib\" is reserved for internal use") if (is.na(match(pkgname, search()))) { packagedir <- system.file("", pkg = package, lib = lib.loc) if (packagedir == "") { --- ./src/scripts/Makefile.in.genlibs-patch Sun Nov 26 18:55:06 2000 +++ ./src/scripts/Makefile.in Wed Jan 3 15:20:53 2001 @@ -12,7 +12,7 @@ SCRIPTS_S = BATCH LINK Rcmd Rdiff Rd2dvi Rd2txt filename help \ help.links maketitle massage-Examples pager -SCRIPTS_B_IN = COMPILE.in INSTALL.in REMOVE.in Rd2contents.in \ +SCRIPTS_B_IN = COMPILE.in INSTALL.in LIB.in REMOVE.in Rd2contents.in \ Rdconv.in Rdindex.in Rprof.in SHLIB.in Sd2Rd.in \ build-help.in build.in check.in extract-usage.in SCRIPTS_B = $(SCRIPTS_B_IN:.in=) --- ./src/scripts/LIB.in.genlibs-patch Wed Jan 3 15:20:53 2001 +++ ./src/scripts/LIB.in Wed Jan 3 15:20:53 2001 @@ -0,0 +1,59 @@ +#!/bin/sh +# +# ${R_HOME}/bin/LIB + +# @configure_input@ + +revision='$Revision: 1.12 $' +version=`set - ${revision}; echo ${2}` +version="R shared library builder ${version}" + +usage="Usage: R LIB [options] files + +Build a static library for linking into other packages from the +specified source or object files (which are automagically made from +their sources). If not given via \`--output', the name for the library +is determined from the first file. + +Options: + -h, --help print short help message and exit + -o, --output=LIB use LIB as (full) name for the built library + -v, --version print version info and exit + +Report bugs to ." + +lib= +objs= +MAKE=${MAKE-@MAKE@} +makefiles="-f ${R_HOME}/etc/Makeconf" + +while test -n "${1}"; do + case ${1} in + -h|--help) + echo "${usage}"; exit 0 ;; + -v|--version) + echo "${version}"; exit 0 ;; + -o) + lib=${2}; shift ;; + --output=*) + lib=`echo "${1}" | sed -e 's/[^=]*=//'` ;; + *.cc|*.[cfo]) + if test -z "${lib}"; then + lib="`echo ${1} | sed 's/\.[^\.][^\.]*$/.a/'`" + fi + objs="${objs} `echo ${1} | sed 's/\.[^\.][^\.]*$/.o/'`" + ;; + esac + shift +done + +if test -r Makevars; then + makefiles="-f Makevars ${makefiles}" +fi + +${MAKE} ${makefiles} LIB="${lib}" OBJS="${objs}" + +### Local Variables: *** +### mode: sh *** +### sh-indentation: 2 *** +### End: *** --- ./src/scripts/build.in.genlibs-patch Wed Dec 6 17:26:05 2000 +++ ./src/scripts/build.in Wed Jan 3 15:20:53 2001 @@ -24,6 +24,7 @@ use File::Compare; use File::Find; use File::Path; +use File::Copy; use Getopt::Long; use R::Dcf; use R::Utils; @@ -43,6 +44,7 @@ $make = '@MAKE@'; my @knownoptions = ("help|h", "version|v", "binary", "no-docs", + "makevars", "use-zip", "use-zip-help", "use-zip-data", "force"); my $WINDOWS = R_getenv("R_UNDER_WINDOWS", 0); @@ -54,6 +56,7 @@ $R_exe = "Rterm.exe"; $MAKE = "make"; @knownoptions = ("help|h", "version|v", "binary", "docs:s", + "makevars", "use-zip", "use-zip-help", "use-zip-data"); } @@ -215,11 +218,139 @@ #********************************************************** +# Add src/Makevars.in, acinclude.m4 and configure.in +# +# needed for including other libraries shared object code +# +sub addAutoconf { + + my ($pkg, $description, $log) = @_; + + my $backup = 0; + + # check for user supplied Makefile: + if (-r "src/Makefile"){ + $log->message("src/Makefile exists, not adding src/Makevars.in, ". + "acinclude.m4 and\n configure.in. Remove " . + "src/Makefile and try to move the statements\n" . + "from src/Makefile to src/Makevars.in afterwards."); + } + else{ + # find first source file for AC_INIT macro + my @src_files = (); + + sub findSourceFiles { + push(@src_files, $File::Find::name) if (/^.*\.f$/); + push(@src_files, $File::Find::name) if (/^.*\.c$/); + } + + find(\&findSourceFiles,'src'); + + my $first_src_file = pop(@src_files); + + # create configure.in, replace placeholders with package name, version + # and first source file + if (-r "configure.in"){ + copy("configure.in", "configure.in.bak"); + $log->message("BACKUP: configure.in --> configure.in.bak"); + $backup=1; + } + $rval = open (FHIN, + "< ${R_HOME}/etc/configure.in.package-template"); + die "could not open configure.in.package-template\n" + unless defined $rval; + $rval = open (FHOUT, + "> configure.in"); + die "could not open configure.in\n" + unless defined $rval; + my $old_nl = $\; + $\ = "\n"; # automatically add newline on print + LINE: + while(){ + chop; + s/\%PACKAGE\%/$pkg/g; + s/\%VERSION\%/$description->{'Version'}/g; + s/\%FIRST_SRC_FILE\%/$first_src_file/g; + print FHOUT; + } + close(FHIN); + close(FHOUT); + $\ = $old_nl; + $log->message("configure.in written."); + + # create acinclude.m4 + if (-r "acinclude.m4"){ + copy("acinclude.m4", "acinclude.m4.bak"); + $log->message("BACKUP: acinclude.m4 --> acinclude.m4.bak"); + $backup=1; + } + copy("${R_HOME}/etc/acinclude.m4.package-template", "acinclude.m4"); + $log->message("acinclude.m4 written."); + + # create src/Makevars.in + if (-r "src/Makevars.in"){ + copy("src/Makevars.in", "src/Makevars.in.bak"); + $log->message("BACKUP: src/Makevars.in --> src/Makevars.in.bak"); + $backup=1; + } + copy("${R_HOME}/etc/Makevars.in.package-template", "src/Makevars.in"); + $log->message("src/Makevars.in written."); + + # create install-sh + if (-r "install-sh"){ + copy("install-sh", "install-sh.bak"); + $log->message("BACKUP: install-sh --> install-sh.bak"); + $backup=1; + } + copy("${R_HOME}/etc/install-sh.package-template", "install-sh"); + chmod("install-sh",755); + $log->message("install-sh written, to make ./configure happy."); + + # backup old configure, aclocal.m4 and src/Makevars files + if (-r "configure"){ + copy("configure", "configure.bak"); + $log->message("BACKUP: configure --> configure.bak"); + $backup=1; + } + if (-r "aclocal.m4"){ + copy("aclocal.m4", "aclocal.m4.bak"); + $log->message("BACKUP: aclocal.m4 --> aclocal.m4.bak"); + $backup=1; + } + if (-r "src/Makevars"){ + copy("src/Makevars", "src/Makevars.bak"); + $log->message("BACKUP: src/Makevars --> src/Makevars.bak"); + $backup=1; + } + + # run aclocal and autoconf + $log->message("running aclocal"); + system("aclocal"); + $log->message("running autoconf"); + system("autoconf"); + + # finished. + $log->message("You should now edit configure.in and maybe " . + "src/Makevars.in and then\n rerun autoconf and " . + "./configure (and aclocal if acinclude.m4 has been\n" . + "changed)."); + if($backup==1){ + $log->warning("WARNING: Please check the backup files, " . + "they will be lost at the next run!"); + } + } +} + +#********************************************************** sub prepare_pkg { my ($pkg, $in_bundle, $description, $log) = @_; + if($pkg eq "lib"){ + die "ERROR: package name \"lib\" reserved for internal use" + } + chdir($pkg); my $pkgdir = getcwd(); my $pkgname = basename($pkg); @@ -247,6 +378,15 @@ if(!$WINDOWS && -x "./cleanup"){ $log->message("running cleanup"); system("./cleanup"); + } + + if($opt_makevars){ + $log->message("adding configure scripts"); + if(-d "src"){ + addAutoconf($pkg, $description, $log); + } else{ + $log->message("WARNING: not adding configure scripts, no src dir!"); + } } updateIndex("INDEX", "man", 0, $log); --- ./src/scripts/INSTALL.in.genlibs-patch Fri Dec 1 12:48:33 2000 +++ ./src/scripts/INSTALL.in Wed Jan 3 15:20:53 2001 @@ -32,6 +32,8 @@ --use-zip-data collect data files in zip archive --use-zip-help collect help and examples into zip archives --use-zip combine \`--use-zip-data' and \`--use-zip-help' + --create-lib-so create a reusable lib.so shared library + --create-lib-a create a reusable lib.a static library Report bugs to ." @@ -89,6 +91,8 @@ use_configure=true use_zip_data= use_zip_help= +build_lib_so=false +build_lib_a=false while test -n "${1}"; do case ${1} in @@ -122,6 +126,10 @@ use_zip_data=true ;; --use-zip-help) use_zip_help=true ;; + --create-lib-so) + build_lib_so=true ;; + --create-lib-a) + build_lib_a=true ;; -l|--library) lib=${2}; shift ;; --library=*) @@ -182,6 +190,10 @@ fi do_install () { + if [ "${1}" = "lib" ]; then + echo "ERROR: package name \"lib\" resrved for internal use" + exit 1 + fi cd "${1}" pkg=`basename "${1}"` @@ -233,9 +245,41 @@ if test -r Makevars; then makefiles="-f Makevars ${makefiles}" fi + if ${build_lib_so}; then \ + ${MAKE} ${makefiles} \ + PKG_LIBPATH="`echo $R_LIBS| \ + awk '{np=split(\$1,pc,\":\"); \ + for (i=1;i<=np;i++) \ + if (pc[i]!=\"\") printf \"-L%s/lib \",pc[i];}'`" \ + && cp *.@SHLIB_EXT@ ${lib}/${pkg}/libs \ + || error=true; \ + mkdir -p ${lib}/lib; \ + ln -sf ../${pkg}/libs/${pkg}.@SHLIB_EXT@ \ + ${lib}/lib/lib${pkg}.@SHLIB_EXT@; \ + ln -sf ../${pkg}/libs/${pkg}.@SHLIB_EXT@ \ + ${lib}/lib/${pkg}.@SHLIB_EXT@; \ + else \ + if ${build_lib_a}; then \ ${MAKE} ${makefiles} \ + PKG_LIBPATH="`echo $R_LIBS| \ + awk '{np=split(\$1,pc,\":\"); \ + for (i=1;i<=np;i++) \ + if (pc[i]!=\"\") printf \"-L%s/lib \",pc[i];}'`" && \ + ${MAKE} ${makefiles} lib${pkg}.a LIBS=lib${pkg}.a \ && cp *.@SHLIB_EXT@ ${lib}/${pkg}/libs \ || error=true; \ + mkdir -p ${lib}/lib; \ + cp lib${pkg}.a ${lib}/lib/lib${pkg}.a; \ + else \ + ${MAKE} ${makefiles} \ + && cp *.@SHLIB_EXT@ ${lib}/${pkg}/libs \ + || error=true; \ + fi; \ + fi; \ + if ${build_lib_a}; then \ + mkdir -p ${lib}/lib; \ + cp lib${pkg}.a ${lib}/lib/; \ + fi; \ if ${clean}; then ${MAKE} clean fi @@ -245,7 +289,38 @@ srcs=`ls *.[cfC] *.cc *.cpp 2>/dev/null` sh ${R_HOME}/bin/SHLIB -o ${pkg}.@SHLIB_EXT@ ${srcs} \ && cp *.@SHLIB_EXT@ ${lib}/${pkg}/libs \ - || error=true; \ + || error=true; \ + if ${build_lib_so}; then + PKG_LIBPATH="`echo $R_LIBS| \ + awk '{np=split(\$1,pc,\":\"); \ + for (i=1;i<=np;i++) \ + if (pc[i]!=\"\") printf \"-L%s/lib \",pc[i];}'`" \ + sh ${R_HOME}/bin/SHLIB \ + -o ${lib}/${pkg}/libs/${pkg}.@SHLIB_EXT@ ${srcs} \ + || error=true; \ + mkdir -p ${lib}/lib; \ + ln -sf ../${pkg}/libs/${pkg}.@SHLIB_EXT@ \ + ${lib}/lib/lib${pkg}.@SHLIB_EXT@; \ + ln -sf ../${pkg}/libs/${pkg}.@SHLIB_EXT@ \ + ${lib}/lib/${pkg}.@SHLIB_EXT@; \ + else \ + if ${build_lib_a}; then \ + mkdir -p ${lib}/lib; \ + PKG_LIBPATH="`echo $R_LIBS| \ + awk '{np=split(\$1,pc,\":\"); \ + for (i=1;i<=np;i++) \ + if (pc[i]!=\"\") printf \"-L%s/lib \",pc[i];}'`" \ + sh ${R_HOME}/bin/SHLIB \ + -o ${lib}/${pkg}/libs/${pkg}.@SHLIB_EXT@ ${srcs} && \ + sh ${R_HOME}/bin/LIB \ + -o ${lib}/lib/lib${pkg}.a ${srcs} \ + || error=true; \ + else \ + sh ${R_HOME}/bin/SHLIB \ + -o ${lib}/${pkg}/libs/${pkg}.@SHLIB_EXT@ ${srcs} \ + || error=true; \ + fi; \ + fi if ${clean}; then rm -f .libs _libs *.o *.@SHLIB_EXT@ fi --- ./src/scripts/R.sh.in.genlibs-patch Sun Nov 26 23:11:15 2000 +++ ./src/scripts/R.sh.in Wed Jan 3 15:20:53 2001 @@ -6,11 +6,17 @@ ## NOTE: ## We must set this here rather than in the main binary. -: ${R_LD_LIBRARY_PATH=${R_HOME}/bin:@R_LD_LIBRARY_PATH@} +: ${R_LD_LIBRARY_PATH=${R_HOME}/bin:@R_LD_LIBRARY_PATH@:${R_HOME}/library/lib} if test -z "${@shlibpath_var@}"; then @shlibpath_var@="${R_LD_LIBRARY_PATH}" else @shlibpath_var@="${R_LD_LIBRARY_PATH}:${@shlibpath_var@}" +fi +if test -n "${R_LIBS}"; then + R_LIBS_PARTS=`echo $R_LIBS| sed -e 's/:/ /g'` + for i in $R_LIBS_PARTS; do + @shlibpath_var@="${@shlibpath_var@}:$i/lib" + done fi export @shlibpath_var@