locks.h: Use atomic builtins For Linux EABI.
[gcc.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 LIBJAVA
255 if [info exists LIBJAVA] {
256 set libjava $LIBJAVA;
257 } else {
258 set libjava [libjava_find_lib libjava gcj]
259 }
260 set cxxflags "$libjava -ljvm"
261
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 lappend cxxflags -shared-libgcc -lgcj -liconv
271 }
272
273 if { [istarget "*-*-solaris*"] } {
274 lappend cxxflags "-lsocket"
275 }
276
277 return $cxxflags
278 }
279
280 # Do all the work for a single invocation API test. Return 0 on
281 # failure.
282 proc gcj_jni_invocation_test_one {file} {
283 global env
284 global runtests
285 global host_triplet
286 global INTERPRETER
287
288 # The base name. We use it for several purposes.
289 set main [file rootname [file tail $file]]
290 if {! [runtest_file_p $runtests $main]} {
291 # Simply skip it.
292 return 1
293 }
294
295 # if {! [bytecompile_file $file [pwd]]} {
296 # fail "bytecompile $file"
297 # # FIXME - should use `untested' on all remaining tests.
298 # # But that is hard.
299 # return 0
300 # }
301 # pass "bytecompile $file"
302
303 set cfile [file rootname $file].c
304
305 set cxxflags [gcj_jni_get_cxxflags_invocation]
306 if {! [gcj_jni_invocation_compile_c_to_binary $cfile $cxxflags]} {
307 # FIXME
308 return 0
309 }
310
311 set resultfile [file rootname $file].out
312
313 set env(CLASSPATH) $file
314 verbose "CLASSPATH = $env(CLASSPATH)"
315 if {! [gcj_invoke $main $resultfile ""]} {
316 unset env(CLASSPATH)
317 # FIXME
318 return 0
319 }
320 unset env(CLASSPATH)
321
322 # We purposely ignore errors here; we still want to run the other
323 # appropriate tests.
324 set errname [file rootname [file tail $file]]
325
326 # When we succeed we remove all our clutter.
327 eval gcj_cleanup [glob -nocomplain -- ${main}.*] \
328 [list $main]
329
330 return 1
331 }
332
333 proc gcj_jni_pr29812 {} {
334 global srcdir subdir
335 global INTERPRETER runtests
336
337 # Set up a global we need.
338 libjava_arguments
339
340 set b ${srcdir}/${subdir}
341
342 if {! [runtest_file_p $runtests pr29812]} {
343 # Simply skip it.
344 return 1
345 }
346
347 if {! [gcj_jni_compile_c_to_so $b/pr29812.c ""]} {
348 return 0
349 }
350 if {! [gcj_jni_compile_c_to_so $b/pr29812_injar.c ""]} {
351 return 0
352 }
353
354 set gij [libjava_find_gij]
355 if {$INTERPRETER == "yes" && $gij != ""} {
356 if {! [libjava_invoke pr29812 "gij test" opts $gij \
357 "" $b/pr29812.out "" \
358 -classpath $b/pr29812.jar pr29812 $b/pr29812_injar.jar]} {
359 return 0
360 }
361 }
362
363 # When we succeed we remove all our clutter.
364 eval gcj_cleanup [glob -nocomplain -- *pr29812*]
365 }
366
367 # Run the JNI tests.
368 proc gcj_jni_run {} {
369 global srcdir subdir
370 global build_triplet host_triplet
371
372 # For now we only test JNI on native builds.
373 if {$build_triplet == $host_triplet} {
374 catch { lsort [glob -nocomplain ${srcdir}/${subdir}/*.jar] } srcfiles
375
376 foreach x $srcfiles {
377 gcj_jni_test_one $x
378 }
379
380 # Run JNI invocation API tests
381 catch { lsort [glob -nocomplain ${srcdir}/${subdir}/invocation/*.jar] } srcfiles
382
383 foreach x $srcfiles {
384 gcj_jni_invocation_test_one $x
385 }
386
387 gcj_jni_pr29812
388 } else {
389 verbose "JNI tests not run in cross-compilation environment"
390 }
391 }
392
393 gcj_jni_run