# javaDetect.tcl --
#
# Utility to find libjvm prior to loading tclJBlend
namespace eval java {}
# java::jvmFindInt --
#
# Internal function to traverse given directories and accumulate
# matching file names which are filtered against directory patterns.
#
# Results:
# Path names are appended to the result list variable.
proc java::jvmFindInt {result dirs name nc filters} {
upvar $result ret
set subdirs {}
foreach dir $dirs {
foreach fn [glob -nocomplain -dir $dir -types {f l} $name] {
if {$nc} {
foreach pat $filters {
if {[string match -nocase $pat $fn]} {
lappend ret $fn
break
}
}
} else {
foreach pat $filters {
if {[string match $pat $fn]} {
lappend ret $fn
break
}
}
}
}
lappend subdirs {*}[glob -nocomplain -dir $dir -types {d l} *]
}
if {[llength $subdirs]} {
tailcall java::jvmFindInt ret $subdirs $name $nc $filters
}
}
# java::jvmFindReg --
#
# Internal function to traverse the Windows registry for
# path names to the JVM runtime library.
#
# Results:
# Path names are appended to the result list variable.
proc java::jvmFindReg {result} {
upvar $result ret
set top HKEY_LOCAL_MACHINE\\Software\\JavaSoft
foreach dir {"JDK" "Java Development Kit" "Java Runtime Environment"} {
set dir [join [list $top $dir] \\]
if {[catch {registry keys $dir} subdirs]} {
continue
}
foreach sub $subdirs {
set sub [join [list $dir $sub] \\]
if {![catch {registry get $sub RuntimeLib} val]} {
if {[file exists $val]} {
lappend ret $val
}
}
}
}
}
# java::jvmFind --
#
# Try to find libjvm.so or jvm.dll depending on platform.
#
# Results:
# On success, the LOAD_JVM environment variable is set
# to the shared library or dll to be loaded.
proc java::jvmFind {} {
if {[info exists ::env(LOAD_JVM)] && $::env(LOAD_JVM) ne ""} {
# already set, do nothing
return
}
set lib {}
switch -- [info sharedlibextension] {
.dll {
# Windows
package require registry
set ret {}
java::jvmFindReg ret
set lib [lindex [lsort -decreasing -dictionary $ret] 0]
}
.dylib {
# MacOSX
set libs /Library/Java/JavaVirtualMachines
set ret {}
java::jvmFindInt ret $libs libjvm[info sharedlibextension] 0 *
set lib [lindex [lsort -decreasing -dictionary $ret] 0]
}
default {
# all else POSIX guesswork
set arch $::tcl_platform(machine)
set libs /usr/local/lib/jvm
switch -glob -- $arch {
x86_64 - amd64 {
if {$::tcl_platform(pointerSize) < 8} {
set arch [list {*i[3-6]86*} *x86/*]
lappend libs /usr/lib/jvm
} else {
set arch [list *x86_64* *amd64*]
lappend libs /usr/lib64/jvm /usr/lib/jvm
}
}
aarch64 {
if {$::tcl_platform(pointerSize) < 8} {
set arch *arm*
lappend libs /usr/lib/jvm
} else {
set arch [list *aarch64* *arm64*]
lappend libs /usr/lib64/jvm /usr/lib/jvm
}
}
i86pc {
lappend libs /usr/jdk/latest/jre /usr/jdk/instances
if {$::tcl_platform(pointerSize) < 8} {
set arch [list {*i[3-6]86*} *86/*]
} else {
set arch [list *amd64* *x86_64*]
}
}
default {
set arch *
lappend libs /usr/lib/jvm
}
}
set ret {}
java::jvmFindInt ret $libs libjvm[info sharedlibextension] 0 $arch
set i [lsearch -glob $ret */default-java/*]
if {$i >= 0} {
set lib [lindex $ret $i]
} else {
set ret [lsort -decreasing -dictionary $ret]
# prefer JDK (OpenJDK)
set i [lsearch -glob $ret *java*openjdk*]
if {$i < 0} {
# fallback to JDK (any)
set i [lsearch -glob $ret */java*]
}
if {$i < 0} {
# fallback to JRE (OpenJDK)
set i [lsearch -glob $ret *openjdk*]
}
if {$i < 0} {
# last resort: the very first hit
set i 0
}
set lib [lindex $ret $i]
}
}
}
if {$lib ne ""} {
set ::env(LOAD_JVM) $lib
}
return
}
java::jvmFind
rename java::jvmFind {}
rename java::jvmFindReg {}
rename java::jvmFindInt {}