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