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