OSDN Git Service

5fa6edefb71631ec1c9931ffd0fe2d2332b558ce
[pf3gnuchains/gcc-fork.git] / libjava / testsuite / libjava.jni / jni.exp
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 subdir
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.
16 # HP-UX uses sl, so we check this too, otherwise we take so.
17
18   if { [istarget "*-*-darwin*"] } {
19       set so_extension "dylib"
20       set so_flag "-dynamiclib"
21   } elseif { [istarget "hppa*-hp-hpux*"] } {
22       set so_extension "sl"
23       set so_flag "-shared"
24   } else {
25       set so_extension "so"
26       set so_flag "-shared"
27   }
28   set filename [file tail $file]
29   set name [file rootname $filename]
30   set soname lib${name}.${so_extension}
31
32   lappend options "additional_flags=${so_flag} -fPIC"
33   # Find the generated header.
34   lappend options "additional_flags=-I. -I.. -I$srcdir/$subdir"
35
36   # Ensure that the generated header has correct prototypes.
37   set cfile [file rootname $file].c
38   if { [file exists $cfile]} {
39     # This option is only valid for C sources.
40     lappend options "additional_flags=-Wmissing-prototypes"
41   }
42
43   # Find jni.h and jni_md.h.
44   lappend options "additional_flags=-I$srcdir/../include -I$srcdir/../classpath/include"
45
46   # Append C++ options
47   lappend options "additional_flags=$options_cxx"
48
49   set x [libjava_prune_warnings \
50            [target_compile $file $soname executable $options]]
51   if {$x != ""} {
52     verbose "target_compile failed: $x" 2
53     fail "$filename compilation"
54     return 0
55   }
56
57   pass "$filename compilation"
58   return 1
59 }
60
61 # Build a header file from a .class file.  Return 0 on failure.
62 proc gcj_jni_build_header {file} {
63   global libgcj_jar
64
65   set gcjh [find_gcjh]
66   set file [file rootname $file]
67
68   set cmd "$gcjh -jni -force -classpath .:$libgcj_jar $file"
69   verbose $cmd
70
71   set x [string trim [libjava_prune_warnings \
72                         [lindex [local_exec $cmd "" "" 300] 1]]]
73   if {$x != ""} {
74     verbose "local_exec failed: $x" 2
75     fail "$file header generation"
76     return 0
77   }
78
79   pass "$file header generation"
80   return 1
81 }
82
83 # Do all the work for a single JNI test.  Return 0 on failure.
84 proc gcj_jni_test_one {file} {
85   global runtests
86   global host_triplet
87   global INTERPRETER
88
89 # Apple uses a different extension for shared/dynamic libraries
90 # so we check against powerpc-apple-darwin and set them to
91 # dylib.
92 # HP-UX uses sl, so we check this too, otherwise we take so.
93
94   if { [istarget "*-*-darwin*"] } {
95       set so_extension "dylib"
96   } elseif { [istarget "hppa*-hp-hpux*"] } {
97       set so_extension "sl"
98   } else {
99       set so_extension "so"
100   }
101
102   # The base name.  We use it for several purposes.
103   set main [file rootname [file tail $file]]
104   if {! [runtest_file_p $runtests $main]} {
105     # Simply skip it.
106     return 1
107   }
108
109 #   if {! [bytecompile_file $file [pwd]]} {
110 #     fail "bytecompile $file"
111 #     # FIXME - should use `untested' on all remaining tests.
112 #     # But that is hard.
113 #     return 0
114 #   }
115 #   pass "bytecompile $file"
116
117 #   set bytefile [file rootname [file tail $file]].class
118 #   if {! [gcj_jni_build_header $bytefile]} {
119 #     # FIXME
120 #     return 0
121 #   }
122
123   set cfile [file rootname $file].c
124   set cxxflags ""
125   set cxxldlibflags {}
126   # If there is no `.c' file, assume there is a `.cc' file.
127   if {! [file exists $cfile]} {
128     set cfile [file rootname $file].cc
129
130     set cxxflaglist {}
131     foreach arg [split [libjava_find_lib libstdc++-v3/src stdc++] " "] {
132       switch -glob -- $arg {
133         "-L*" {
134           set arg [string range $arg 2 end]
135           lappend cxxldlibflags $arg
136           # Strip the `.libs' directory; we link with libtool which
137           # doesn't need it.
138           set arg "-L[file dirname $arg]"
139         }
140       }
141       lappend cxxflaglist $arg
142       # In case the libstdc++ is not installed yet, we pass the build
143       # directory of it to the cxxflaglist.
144       lappend cxxflaglist "-L$cxxldlibflags"
145     }
146
147     # If you're building the compiler with --prefix set to a place
148     # where it's not yet installed, then the linker won't be able to
149     # find the libgcc used by libffi.dylib.  We could pass the
150     # -dylib_file option, but that's complicated, and it's much easier
151     # to just make the linker find libgcc using -L options.
152     if { [istarget "*-*-darwin*"] } {
153         lappend cxxflaglist "-shared-libgcc -lstdc++"
154     } else {
155         lappend cxxflaglist "-lstdc++"
156     }
157
158     set cxxflags [join $cxxflaglist]
159   }
160
161   if {! [gcj_jni_compile_c_to_so $cfile $cxxflags]} {
162     # FIXME
163     return 0
164   }
165
166   set args [list "additional_flags=-fjni"]
167   if {! [gcj_link $main $main $file $args]} {
168     # FIXME
169     return 0
170   }
171
172   set resultfile [file rootname $file].out
173
174   if {! [gcj_invoke $main $resultfile $cxxldlibflags]} {
175     # FIXME
176     return 0
177   }
178
179   # We purposely ignore errors here; we still want to run the other
180   # appropriate tests.
181   set errname [file rootname [file tail $file]]
182   set gij [libjava_find_gij]
183   # libjava_find_gij will return "" if it couldn't find the
184   # program; in this case we want to skip the test.
185   # If the libraries are not installed yet, we have to pass them via
186   # cxxldlibflags to libjava_invoke.
187   if {$INTERPRETER == "yes" && $gij != ""} {
188     libjava_invoke $errname "gij test" opts $gij \
189       "" $resultfile $cxxldlibflags \
190       -classpath $file $main
191   }
192
193   # When we succeed we remove all our clutter.
194   eval gcj_cleanup [glob -nocomplain -- ${main}.*] \
195     [list $main lib${main}.${so_extension}]
196
197   return 1
198 }
199
200 # Compile a single C file and produce a binary.  OPTIONS is a list of
201 # options to pass to the compiler.  Returns 0 on failure, 1 on
202 # success.
203 proc gcj_jni_invocation_compile_c_to_binary {file {options {}}} {
204   global srcdir subdir
205   global host_triplet
206   verbose "options: $options"
207   set options_cxx $options
208   set options ""
209
210   set filename [file tail $file]
211   set name [file rootname $filename]
212
213   # Set some darwin specific options
214   if { [istarget "*-*-darwin*"] } {
215       lappend options "additional_flags= -bind_at_load -multiply_defined suppress"
216   }
217   # Find the generated header.
218   lappend options "additional_flags=-I. -I.. -I$srcdir/$subdir"
219
220   # Find jni.h and jni_md.h.
221   lappend options "additional_flags=-I$srcdir/../include -I$srcdir/../classpath/include"
222
223   # Append C++ options
224   lappend options "additional_flags=$options_cxx"
225
226   set x [libjava_prune_warnings \
227            [target_compile $file $name executable $options]]
228   if {$x != ""} {
229     verbose "target_compile failed: $x" 2
230     fail "$filename compilation"
231     return 0
232   }
233
234   pass "$filename compilation"
235   return 1
236 }
237
238 # Do all the work for a single invocation API test.  Return 0 on
239 # failure.
240 proc gcj_jni_invocation_test_one {file} {
241   global env
242   global runtests
243   global host_triplet
244   global INTERPRETER
245
246   # The base name.  We use it for several purposes.
247   set main [file rootname [file tail $file]]
248   if {! [runtest_file_p $runtests $main]} {
249     # Simply skip it.
250     return 1
251   }
252
253 #   if {! [bytecompile_file $file [pwd]]} {
254 #     fail "bytecompile $file"
255 #     # FIXME - should use `untested' on all remaining tests.
256 #     # But that is hard.
257 #     return 0
258 #   }
259 #   pass "bytecompile $file"
260
261   set cfile [file rootname $file].c
262   # Darwin needs -liconv linked, otherwise we get some unresolved.
263   # If you're building the compiler with --prefix set to a place
264   # where it's not yet installed, then the linker won't be able to
265   # find the libgcc used by libffi.dylib.  We could pass the
266   # -dylib_file option, but that's complicated, and it's much easier
267   # to just make the linker find libgcc using -L options.
268   # Similar logic applies to libgcj.
269   if { [istarget "*-*-darwin*"] } {
270       set cxxflags "-L../.libs -shared-libgcc -ljvm -lgcj -liconv"
271   } else {
272       global LIBJAVA
273       if [info exists LIBJAVA] {
274           set libjava $LIBJAVA;
275       } else {
276           set libjava [libjava_find_lib libjava gcj]
277       }
278       set cxxflags "$libjava -ljvm"
279   }
280
281   if { [istarget "*-*-solaris*"] } {
282     lappend cxxflags "-lsocket"
283   }
284
285   if {! [gcj_jni_invocation_compile_c_to_binary $cfile $cxxflags]} {
286     # FIXME
287     return 0
288   }
289
290   set resultfile [file rootname $file].out
291
292   set env(CLASSPATH) $file
293   verbose "CLASSPATH = $env(CLASSPATH)"
294   if {! [gcj_invoke $main $resultfile ""]} {
295     unset env(CLASSPATH)
296     # FIXME
297     return 0
298   }
299   unset env(CLASSPATH)
300
301   # We purposely ignore errors here; we still want to run the other
302   # appropriate tests.
303   set errname [file rootname [file tail $file]]
304
305   # When we succeed we remove all our clutter.
306   eval gcj_cleanup [glob -nocomplain -- ${main}.*] \
307     [list $main]
308
309   return 1
310 }
311
312 # Run the JNI tests.
313 proc gcj_jni_run {} {
314   global srcdir subdir
315   global build_triplet host_triplet
316
317   # For now we only test JNI on native builds.
318   if {$build_triplet == $host_triplet} {
319     catch { lsort [glob -nocomplain ${srcdir}/${subdir}/*.jar] } srcfiles
320
321     foreach x $srcfiles {
322       gcj_jni_test_one $x
323     }
324
325     # Run JNI invocation API tests
326     catch { lsort [glob -nocomplain ${srcdir}/${subdir}/invocation/*.jar] } srcfiles
327
328     foreach x $srcfiles {
329       gcj_jni_invocation_test_one $x
330     }
331   } else {
332     verbose "JNI tests not run in cross-compilation environment"
333   }
334 }
335
336 gcj_jni_run