javareconf 11.5 KB
Newer Older
1 2 3 4 5 6 7
if test -z "${R_HOME}"; then
    echo "This command can be executed via R CMD only!"
    exit 1
fi

tools_classpath=${R_SHARE_DIR}/java

8 9 10 11 12 13 14 15
revision='$Rev: 47538 $'
version=`set - ${revision}; echo ${2}`
version="R Java configurator: ${R_VERSION} (r${version})

Copyright (C) 2002-6 The R Core Development Team.
This is free software; see the GNU General Public License version 2
or later for copying conditions.  There is NO warranty."

16 17 18 19 20 21
usage="
Usage: R CMD javareconf [options]

Detect current Java setup and update the corresponding configuration in R.

Options:
22
  -h, --help     print this help message and exit
23
  -v, --version  print version info and exit
24 25
  -n, --dry-run  perform Java detection, but don't touch any
                 configurations files
26 27 28
  -e <prog>      same as -n but exports all detected variables
                 and runs <prog>. If -e is the last argument
                 or <prog> is '' then a shell is used instead
29 30 31 32 33 34 35 36 37 38
  xxx=yyy        evaluate the corresponding expression
                 (e.g. JAVA_HOME=/usr/lib/java)

Environment variables that can be used to influence the detection:
  JAVA           path to a Java interpreter executable
                 By default first 'java' command found on the PATH
                 is taken (unless JAVA_HOME is also specified).
  JAVA_HOME      home of the Java environment. If not specified,
                 it will be detected automatically from the Java
                 interpreter.
39 40 41 42 43 44 45 46 47 48 49
  JAVAC          path to a Java compiler
  JAVAH          path to a Java header/stub generator
  JAR            path to a Java archive tool

The following variables should be used with extreme caution. They
must all match, so use only if you have a very special setup that
javareconf cannot detect automatically:
  JAVA_LD_LIBRARY_PATH library path necessary at run-time
  JAVA_CPPFLAGS  C preprocessor flags necessary to compile JNI programs
  JAVA_LIBS      libraries (as linker flags) necessary to compile
                 JNI programs
50 51 52 53 54

Report bugs to <r-bugs@r-project.org>."


dry_run=no
55
export_vars=no
56 57 58
while test -n "${1}"; do
    case ${1} in
	-help | --help | -h) echo "${usage}"; exit 0 ;;
59
	-v | --version) echo "${version}"; exit 0 ;;
60
	-n | --dry-run) dry_run=yes ;;
61
	-e) dry_run=yes; export_vars=yes; run_prog=${2}; shift ;;
62 63 64 65 66 67 68 69 70 71 72 73
	*=*) eval ${1} ;;
    esac
    shift
done

## find java compiler binaries
if test -z "${JAVA_HOME}" ; then
    JAVA_PATH=${PATH}
else
    if test ! -e "${JAVA_HOME}"; then
	echo "*** JAVA_HOME is not a valid path, ignoring"
	JAVA_HOME=
74 75 76 77
	JAVA_PATH=${PATH}
    else
	## try jre/bin first just in case we don't have full JDK
	JAVA_PATH=${JAVA_HOME}:${JAVA_HOME}/jre/bin:${JAVA_HOME}/bin:${JAVA_HOME}/../bin:${PATH}
78 79 80 81
    fi
fi
## if 'java' is not on the PATH or JAVA_HOME, add some guesses as of
## where java could live
82
JAVA_PATH=${JAVA_PATH}:/usr/java/bin:/usr/jdk/bin:/usr/lib/java/bin:/usr/lib/jdk/bin:/usr/local/java/bin:/usr/local/jdk/bin:/usr/local/lib/java/bin:/usr/local/lib/jdk/bin
83 84 85 86 87 88 89 90 91 92 93 94 95

if test -z "$JAVA"; then
    save_IFS=$IFS; IFS=:
    for dir in ${JAVA_PATH}; do
	if test -f "$dir/java"; then
	    JAVA="$dir/java"
	    break
	fi
    done
    IFS=${save_IFS}
fi

if test -z "$JAVA"; then
96
    echo "~*** Cannot find any Java interpreter~*** Please make sure 'java' is on your PATH or set JAVA_HOME correspondingly"|${SED-sed} -e 'y/~/\n/' >&2
97 98 99 100 101 102 103
    exit 1
fi

echo "Java interpreter : $JAVA"
jires=`$JAVA -classpath ${tools_classpath} getsp -test`
if test "$jires" != "Test1234OK"; then
    echo "$jires"
104
    echo "~*** Java interpreter doesn't work properly.~"|${SED-sed} -e 'y/~/\n/' >&2
105 106 107 108 109 110 111 112
    exit 1
fi

if test -z "${JAVA_HOME}"; then
    JAVA_HOME=`$JAVA -classpath ${tools_classpath} getsp java.home`
fi

if test -z "${JAVA_HOME}"; then
113
    echo "~*** Cannot find Java environemnt.~*** Please set JAVA_HOME correspondingly.~"|${SED-sed} -e 'y/~/\n/' >&2
114 115 116 117 118 119
    exit 1
fi

echo "Java version     : `$JAVA -classpath ${tools_classpath} getsp java.version 2>/dev/null`"
echo "Java home path   : ${JAVA_HOME}"

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
# optional parts - compiler, javah and jar
if test -z "$JAVAC"; then
    save_IFS=$IFS; IFS=:
    for dir in ${JAVA_PATH}; do
	if test -f "$dir/javac"; then
	    JAVAC="$dir/javac"
	    break
	fi
    done
    IFS=${save_IFS}
fi

# test functionality of the compiler
javac_works='not present'
if test -n "$JAVAC"; then
    javac_works='not functional'
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#    tempdir=`mktemp -d`

    : ${TMPDIR=/tmp}
    { tempdir=`(mktemp -d -q "${TMPDIR}/RJRECONF.XXXXXX") 2>/dev/null` \
	&& test -n "${tempdir}" && test -d "${tempdir}" ; } ||
    { test -n "${RANDOM}" && tempdir=${TMPDIR}/RJRECONF$$-${RANDOM} \
	&& (mkdir "${tempdir}") ; } ||
    { tempdir=${TMPDIR}/RJRECONF.$$-`date +%m%d%H%M%S` \
	&& (mkdir "${tempdir}"); } ||
    { tempdir=${TMPDIR}/RJRECONF.$$ && (mkdir "${tempdir}") ; } ||
    (error "cannot create temporary directory" && exit 1)

    echo "public class A { }" > ${tempdir}/A.java
    if test -e ${tempdir}/A.java; then
	if "${JAVAC}" ${tempdir}/A.java >/dev/null; then
           if test -e ${tempdir}/A.class; then
152 153 154 155
		javac_works=yes
	    fi
	fi
    fi
156 157
    rm -rf ${tempdir}

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
fi
if test "${javac_works}" = yes; then
    echo "Java compiler    : ${JAVAC}"
else
    echo "Java compiler    : ${javac_works}"
fi

if test -z "$JAVAH"; then
    save_IFS=$IFS; IFS=:
    for dir in ${JAVA_PATH}; do
	if test -f "$dir/javah"; then
	    JAVAH="$dir/javah"
	    break
	fi
    done
    IFS=${save_IFS}
fi
echo "Java headers gen.: ${JAVAH}"

if test -z "$JAR"; then
    save_IFS=$IFS; IFS=:
    for dir in ${JAVA_PATH}; do
	if test -f "$dir/jar"; then
	    JAR="$dir/jar"
	    break
	fi
    done
    IFS=${save_IFS}
fi
echo "Java archive tool: ${JAR}"

: ${JAVA_LIBS=~autodetect~}
: ${JAVA_CPPFLAGS=~autodetect~}
: ${JAVA_LD_LIBRARY_PATH=~autodetect~}
custom_JAVA_LIBS="${JAVA_LIBS}"
custom_JAVA_CPPFLAGS="${JAVA_CPPFLAGS}"
custom_JAVA_LD_LIBRARY_PATH="${JAVA_LD_LIBRARY_PATH}"


# sys-dependent tweaks to JNI flags
198 199 200 201 202
hostos=`uname 2>/dev/null`
case "$hostos" in
    Darwin*)
	JAVA_LD_LIBRARY_PATH=
	JAVA_LIBS="-framework JavaVM"
203
	JAVA_CPPFLAGS='-I$(JAVA_HOME)/include'
204 205 206 207 208 209 210 211 212
	;;
    *)
	## we need to reset LD_LIBRARY_PATH, because Java automatically
	## adds all LD_LIBRARY_PATH to Java path
	save_LDLP=${LD_LIBRARY_PATH}
	LD_LIBRARY_PATH=
	export LD_LIBRARY_PATH
	# remove trailing : (if any) and replace occurrences of JAVA_HOME
	# with $(JAVA_HOME)
213
	JAVA_LD_LIBRARY_PATH=`$JAVA -classpath ${tools_classpath} getsp java.library.path| ${SED-sed} -e s:${JAVA_HOME}:\$\(JAVA_HOME\):g -e 's/:$//'`
214 215 216
	LD_LIBRARY_PATH=${save_LDLP}
	export LD_LIBRARY_PATH
	# build JAVA_LIBS from the detected path
217
	JAVA_LIBS=`echo ${JAVA_LD_LIBRARY_PATH}|${SED-sed} -e 's|:| -L|g'`
218 219 220
	if test -n "${JAVA_LIBS}"; then JAVA_LIBS="-L${JAVA_LIBS}"; fi
	JAVA_LIBS="${JAVA_LIBS} -ljvm"
	# create shell-version to be used in scripts
221
	JAVA_LD_LIBRARY_PATH_SH=`echo ${JAVA_LD_LIBRARY_PATH}|${SED-sed} -e 's:$(JAVA_HOME):\$\{JAVA_HOME\}:g'`
222 223 224

        ## includes consist of two parts - jni.h and machine-dependent jni_md.h
        jinc=''
225
	JAVA_CPPFLAGS=''
226 227 228 229 230 231
        for pinc in include ../include jre/include; do
          if test -e "${JAVA_HOME}/${pinc}/jni.h"; then jinc="${JAVA_HOME}/${pinc}"; break; fi
        done
        ## only if we get jni.h we can try to find jni_md.h
        if test -n "${jinc}"; then
           JAVA_CPPFLAGS="-I${jinc}"
232
           jmdinc=''
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
           jmdirs=''
	   ## we are not in configure, so we need to find the OS from R
	   host_os=`echo 'cat(R.version$os)'|${R_HOME}/bin/R --vanilla --slave 2>/dev/null`
           ## put the most probable locations for each system in the first place
           case "${host_os}" in
             linux*)   jmdirs=linux;;
             bsdi*)    jmdirs=bsdos;;
             osf*)     jmdirs=alpha;;
             solaris*) jmdirs=solaris;;
             freebsd*) jmdirs=freebsd; add_java_libs='-lpthread';;
           esac
	   ## in case host_os detection failed, add all candidates
	   if test -z "${jmdirs}"; then jmdirs='linux solaris freebsd alpha bsdos'; fi
           ## prepend . and append less-likely ones
           jmdirs=". ${jmdirs} genunix ppc x86 iris hp-ux aix win32 cygwin openbsd"
           for pimd in ${jmdirs}; do
             if test -e "${jinc}/${pimd}/jni_md.h"; then jmdinc="${jinc}/${pimd}"; break; fi
           done
           if test -z "${jmdinc}"; then
             # ultima-ratio: use find and pray that it works
253
             jmdinc=`find "${jinc}/" -name jni_md.h 2> /dev/null |head -n 1 2>/dev/null`
254 255 256 257 258 259 260
             if test -n "${jmdinc}"; then jmdinc=`dirname "${jmdinc}"`; fi
           fi
           if test -n "${jmdinc}"; then
             if test "${jmdinc}" != "${jinc}/."; then
               JAVA_CPPFLAGS="${JAVA_CPPFLAGS} -I${jmdinc}"
             fi
           fi
261
	   JAVA_CPPFLAGS=`echo ${JAVA_CPPFLAGS} | ${SED-sed} -e s:${JAVA_HOME}:\$\(JAVA_HOME\):g`
262
        fi
263 264 265
	;;
esac

266 267 268 269 270 271
if test -n "${add_java_libs}"; then JAVA_LIBS="${JAVA_LIBS} ${add_java_libs}"; fi

## honor user overrides
acx_custom_java_libs=no
if test "${custom_JAVA_LIBS}" != '~autodetect~'; then
  JAVA_LIBS="${custom_JAVA_LIBS}"
272
  JAVA_LIBS0=`echo ${JAVA_LIBS} | ${SED-sed} -e s:${JAVA_HOME}:\$\(JAVA_HOME\):g`
273 274 275 276 277 278 279
  acx_custom_java_libs=yes
fi
if test "${custom_JAVA_CPPFLAGS}" != '~autodetect~'; then
  JAVA_CPPFLAGS="${custom_JAVA_CPPFLAGS}"
fi
if test "${custom_JAVA_LD_LIBRARY_PATH}" != '~autodetect~'; then
  JAVA_LD_LIBRARY_PATH="${custom_JAVA_LD_LIBRARY_PATH}"
280
  JAVA_LD_LIBRARY_PATH_SH=`echo ${JAVA_LD_LIBRARY_PATH}|${SED-sed} -e 's:$(JAVA_HOME):\$\{JAVA_HOME\}:g'`
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
  if test "${acx_custom_java_libs}" != yes; then
    echo ''
    echo ' ** Warning: you are using custom JAVA_LD_LIBRARY_PATH without' >&2
    echo '    custom JAVA_LIBS. We cannot guarantee that this will work,' >&2
    echo '    both settings must match for a proper Java operation!' >&2
  fi
else
  if test "${acx_custom_java_libs}" = yes; then
    echo ''
    echo ' ** Warning: you are using custom JAVA_LIBS setting without' >&2
    echo '    specifying JAVA_LD_LIBRARY_PATH. We cannot gearantee that' >&2
    echo '    this will work, both must match for a proper Java operation!' >&2
  fi
fi

296 297
echo "Java library path: ${JAVA_LD_LIBRARY_PATH}"
echo "JNI linker flags : ${JAVA_LIBS}"
298
echo "JNI cpp flags    : ${JAVA_CPPFLAGS}"
299 300 301

echo ""

302 303 304 305 306 307 308 309 310 311 312 313
if test "${export_vars}" = yes; then
    export JAVA_HOME JAVA JAVAC JAVAH JAR JAVA_LIBS JAVA_CPPFLAGS JAVA_LD_LIBRARY_PATH
    echo "The following Java variables have been exported:"
    echo "JAVA_HOME JAVA JAVAC JAVAH JAR JAVA_LIBS JAVA_CPPFLAGS JAVA_LD_LIBRARY_PATH"
    test -z "${run_prog}" && test -n "${SHELL}" && run_prog="${SHELL}"
    test -z "${run_prog}" && run_prog=/bin/sh
    echo "Runnig: ${run_prog}"
    ${run_prog}
    exit 0
fi

test "${dry_run}" = yes && exit 0
314 315 316 317 318

echo "Updating Java configuration in ${R_HOME}"

files="${R_HOME}/etc${R_ARCH}/Makeconf ${R_HOME}/etc${R_ARCH}/ldpaths"
for file in $files; do
319
    ${SED-sed} -e "s|JAVA =.\{0,\}|JAVA = $JAVA|" -e "s|JAVA_HOME =.\{0,\}|JAVA_HOME = ${JAVA_HOME}|" -e "s|: \${JAVA_HOME=.\{1,\}|: \${JAVA_HOME=${JAVA_HOME}}|" -e "s|: \${R_JAVA_LD_LIBRARY_PATH=.\{1,\}|: \${R_JAVA_LD_LIBRARY_PATH=${JAVA_LD_LIBRARY_PATH_SH}}|" -e "s|JAVA_LIBS =.\{0,\}|JAVA_LIBS = ${JAVA_LIBS}|g" -e "s|JAVA_LD_LIBRARY_PATH =.\{0,\}|JAVA_LD_LIBRARY_PATH = ${JAVA_LD_LIBRARY_PATH}|" -e "s|JAVAC =.\{0,\}|JAVAC = $JAVAC|" -e "s|JAVAH =.\{0,\}|JAVAH = $JAVAH|" -e "s|JAR =.\{0,\}|JAR = $JAR|" "${file}" -e "s|JAVA_CPPFLAGS =.\{0,\}|JAVA_CPPFLAGS = ${JAVA_CPPFLAGS}|g"> "${file}.new"
320 321 322 323
    if test -f "${file}.new"; then
	mv "${file}" "${file}.old"
	mv "${file}.new" "${file}"
    else
324
	echo "*** cannot create ${file}.new~*** Please run as root if required.~" | ${SED-sed} -e 'y/~/\n/' >&2
325 326 327 328 329
	exit 1
    fi
done

echo "Done."
330
echo ''