OSDN Git Service

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