OSDN Git Service

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