| 1 | # Tests for JNI code.
|
|---|
| 2 |
|
|---|
| 3 | # Compile a single C file and produce a .so file. OPTIONS is a list
|
|---|
| 4 | # of options to pass to the compiler. Returns 0 on failure, 1 on
|
|---|
| 5 | # success.
|
|---|
| 6 | proc gcj_jni_compile_c_to_so {file {options {}}} {
|
|---|
| 7 | global srcdir
|
|---|
| 8 |
|
|---|
| 9 | set name [file rootname [file tail $file]]
|
|---|
| 10 | set soname lib${name}.so
|
|---|
| 11 |
|
|---|
| 12 | lappend options "additional_flags=-shared -fPIC"
|
|---|
| 13 | # Find the generated header.
|
|---|
| 14 | lappend options "additional_flags=-I. -I.."
|
|---|
| 15 | # Find jni.h.
|
|---|
| 16 | lappend options "additional_flags=-I$srcdir/../include"
|
|---|
| 17 |
|
|---|
| 18 | set x [libjava_prune_warnings \
|
|---|
| 19 | [target_compile $file $soname executable $options]]
|
|---|
| 20 | if {$x != ""} {
|
|---|
| 21 | verbose "target_compile failed: $x" 2
|
|---|
| 22 | fail "$name.c compilation"
|
|---|
| 23 | return 0
|
|---|
| 24 | }
|
|---|
| 25 |
|
|---|
| 26 | pass "$name.c compilation"
|
|---|
| 27 | return 1
|
|---|
| 28 | }
|
|---|
| 29 |
|
|---|
| 30 | # Build a header file from a .class file. Return 0 on failure.
|
|---|
| 31 | proc gcj_jni_build_header {file} {
|
|---|
| 32 | set gcjh [find_gcjh]
|
|---|
| 33 | set file [file rootname $file]
|
|---|
| 34 | set x [string trim [libjava_prune_warnings \
|
|---|
| 35 | [lindex [local_exec "$gcjh -jni $file" "" "" 300] 1]]]
|
|---|
| 36 | if {$x != ""} {
|
|---|
| 37 | verbose "local_exec failed: $x" 2
|
|---|
| 38 | fail "$file header generation"
|
|---|
| 39 | return 0
|
|---|
| 40 | }
|
|---|
| 41 |
|
|---|
| 42 | pass "$file header generation"
|
|---|
| 43 | return 1
|
|---|
| 44 | }
|
|---|
| 45 |
|
|---|
| 46 | # Invoke the program and see what happens. Return 0 on failure.
|
|---|
| 47 | proc gcj_invoke {program expectFile ld_library_additions} {
|
|---|
| 48 | global env
|
|---|
| 49 | set lib_path $env(LD_LIBRARY_PATH)
|
|---|
| 50 |
|
|---|
| 51 | set newval .
|
|---|
| 52 | if {[llength $ld_library_additions] > 0} {
|
|---|
| 53 | append newval :[join $ld_library_additions :]
|
|---|
| 54 | }
|
|---|
| 55 | append newval :$lib_path
|
|---|
| 56 |
|
|---|
| 57 | setenv LD_LIBRARY_PATH $newval
|
|---|
| 58 | setenv SHLIB_PATH $newval
|
|---|
| 59 |
|
|---|
| 60 | verbose "LD_LIBRARY_PATH=$env(LD_LIBRARY_PATH)"
|
|---|
| 61 |
|
|---|
| 62 | set result [libjava_load ./$program]
|
|---|
| 63 | set status [lindex $result 0]
|
|---|
| 64 | set output [lindex $result 1]
|
|---|
| 65 |
|
|---|
| 66 | # Restore setting
|
|---|
| 67 | setenv LD_LIBRARY_PATH $lib_path
|
|---|
| 68 | setenv SHLIB_PATH $lib_path
|
|---|
| 69 |
|
|---|
| 70 | if {$status != "pass"} {
|
|---|
| 71 | verbose "got $output"
|
|---|
| 72 | fail "$program run"
|
|---|
| 73 | untested "$program output"
|
|---|
| 74 | return 0
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | set id [open $expectFile r]
|
|---|
| 78 | set expected [read $id]
|
|---|
| 79 | close $id
|
|---|
| 80 |
|
|---|
| 81 | if {! [string compare $output $expected]} {
|
|---|
| 82 | pass "$program output"
|
|---|
| 83 | return 1
|
|---|
| 84 | } else {
|
|---|
| 85 | fail "$program output"
|
|---|
| 86 | return 0
|
|---|
| 87 | }
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | # Do all the work for a single JNI test. Return 0 on failure.
|
|---|
| 91 | proc gcj_jni_test_one {file} {
|
|---|
| 92 | global runtests
|
|---|
| 93 |
|
|---|
| 94 | # The base name. We use it for several purposes.
|
|---|
| 95 | set main [file rootname [file tail $file]]
|
|---|
| 96 | if {! [runtest_file_p $runtests $main]} {
|
|---|
| 97 | # Simply skip it.
|
|---|
| 98 | return 1
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | if {! [bytecompile_file $file [pwd]]} {
|
|---|
| 102 | fail "bytecompile $file"
|
|---|
| 103 | # FIXME - should use `untested' on all remaining tests.
|
|---|
| 104 | # But that is hard.
|
|---|
| 105 | return 0
|
|---|
| 106 | }
|
|---|
| 107 | pass "bytecompile $file"
|
|---|
| 108 |
|
|---|
| 109 | set bytefile [file rootname [file tail $file]].class
|
|---|
| 110 | if {! [gcj_jni_build_header $bytefile]} {
|
|---|
| 111 | # FIXME
|
|---|
| 112 | return 0
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| 115 | set cfile [file rootname $file].c
|
|---|
| 116 | set cxxflags ""
|
|---|
| 117 | set cxxldlibflags {}
|
|---|
| 118 | # If there is no `.c' file, assume there is a `.cc' file.
|
|---|
| 119 | if {! [file exists $cfile]} {
|
|---|
| 120 | set cfile [file rootname $file].cc
|
|---|
| 121 |
|
|---|
| 122 | set cxxflaglist {}
|
|---|
| 123 | foreach arg [split [libjava_find_lib libstdc++-v3/src stdc++] " "] {
|
|---|
| 124 | switch -glob -- $arg {
|
|---|
| 125 | "-L*" {
|
|---|
| 126 | set arg [string range $arg 2 end]
|
|---|
| 127 | lappend cxxldlibflags $arg
|
|---|
| 128 | # Strip the `.libs' directory; we link with libtool which
|
|---|
| 129 | # doesn't need it.
|
|---|
| 130 | set arg "-L[file dirname $arg]"
|
|---|
| 131 | }
|
|---|
| 132 | }
|
|---|
| 133 | lappend cxxflaglist $arg
|
|---|
| 134 | }
|
|---|
| 135 |
|
|---|
| 136 | lappend cxxflaglist "-lstdc++"
|
|---|
| 137 | set cxxflags [join $cxxflaglist]
|
|---|
| 138 | }
|
|---|
| 139 |
|
|---|
| 140 | if {! [gcj_jni_compile_c_to_so $cfile]} {
|
|---|
| 141 | # FIXME
|
|---|
| 142 | return 0
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | # We use -l$main because the .so is named the same as the main
|
|---|
| 146 | # program.
|
|---|
| 147 | set args [list "additional_flags=-fjni -L. -l$main $cxxflags"]
|
|---|
| 148 | if {! [gcj_link $main $main $file $args]} {
|
|---|
| 149 | # FIXME
|
|---|
| 150 | return 0
|
|---|
| 151 | }
|
|---|
| 152 |
|
|---|
| 153 | if {! [gcj_invoke $main [file rootname $file].out $cxxldlibflags]} {
|
|---|
| 154 | # FIXME
|
|---|
| 155 | return 0
|
|---|
| 156 | }
|
|---|
| 157 |
|
|---|
| 158 | # When we succeed we remove all our clutter.
|
|---|
| 159 | eval gcj_cleanup [glob -nocomplain -- ${main}.*] [list $main lib${main}.so]
|
|---|
| 160 |
|
|---|
| 161 | return 1
|
|---|
| 162 | }
|
|---|
| 163 |
|
|---|
| 164 | # Run the JNI tests.
|
|---|
| 165 | proc gcj_jni_run {} {
|
|---|
| 166 | global srcdir subdir
|
|---|
| 167 | global build_triplet host_triplet
|
|---|
| 168 |
|
|---|
| 169 | # For now we only test JNI on native builds.
|
|---|
| 170 | if {$build_triplet == $host_triplet} {
|
|---|
| 171 | catch { lsort [glob -nocomplain ${srcdir}/${subdir}/*.java] } srcfiles
|
|---|
| 172 |
|
|---|
| 173 | foreach x $srcfiles {
|
|---|
| 174 | gcj_jni_test_one $x
|
|---|
| 175 | }
|
|---|
| 176 | } else {
|
|---|
| 177 | verbose "JNI tests not run in cross-compilation environment"
|
|---|
| 178 | }
|
|---|
| 179 | }
|
|---|
| 180 |
|
|---|
| 181 | gcj_jni_run
|
|---|