1# libstdc++ "tool init file" for DejaGNU 2 3# Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18# 02110-1301, USA. 19 20 21# Define callbacks and load other libraries. This file is loaded relatively 22# early, and before any other file we write ourselves. "load_lib" will 23# find anything in the DejaGNU installation tree, or in our lib directory. 24# "load_gcc_lib" will search the core compiler's .exp collection instead. 25# 26# The naming rule is that dg.exp looks for "tool-" and runtest.exp looks 27# for "tool_" when finding callbacks. Utility routines we define for 28# our callbacks begin with "v3-". 29# 30# libstdc++_* callbacks we don't define, but could: 31# ..._option_help prints additional --help output 32# ..._option_proc (--foo) process our own options 33# ..._init (normal.exp) called once per test file 34# ..._finish bracketing function for libstdc++_init 35# ...-dg-prune removing output text, see top of system dg.exp 36# 37# Useful hook: if ${hostname}_init exists, it will be called, almost 38# the last thing before testing begins. This can be defined in, e.g., 39# ~/.dejagnurc or $DEJAGNU. 40 41proc load_gcc_lib { filename } { 42 global srcdir 43 load_file $srcdir/../../gcc/testsuite/lib/$filename 44} 45 46# system routines 47load_lib dg.exp 48load_lib libgloss.exp 49# compiler routines, then ours 50load_gcc_lib target-supports.exp 51load_gcc_lib target-supports-dg.exp 52load_lib prune.exp 53load_lib dg-options.exp 54load_gcc_lib target-libpath.exp 55load_gcc_lib wrapper.exp 56 57# Useful for debugging. Pass the name of a variable and the verbosity 58# threshold (number of -v's on the command line). 59proc v3track { var n } { 60 upvar $var val 61 verbose "++ $var is $val" $n 62} 63 64# Called by v3-init below. "Static" to this file. 65proc v3-copy-files {srcfiles} { 66 foreach f $srcfiles { 67 if { [catch { set symlink [file readlink $f] } x] } then { 68 remote_download target $f 69 } else { 70 if { [regexp "^/" "$symlink"] } then { 71 remote_download target $symlink 72 } else { 73 set dirname [file dirname $f] 74 remote_download target $dirname/$symlink 75 } 76 } 77 } 78} 79 80# Called once, during runtest.exp setup. 81proc libstdc++_init { testfile } { 82 global env 83 global v3-sharedlib 84 global srcdir blddir objdir tool_root_dir 85 global cxx cxxflags 86 global includes 87 global gluefile wrap_flags 88 global ld_library_path 89 global target_triplet 90 91 # We set LC_ALL and LANG to C so that we get the same error 92 # messages as expected. 93 setenv LC_ALL C 94 setenv LANG C 95 96 set blddir [lookfor_file [get_multilibs] libstdc++-v3] 97 set flags_file "${blddir}/scripts/testsuite_flags" 98 v3track flags_file 2 99 100 # If a test doesn't have special options, use DEFAULT_CXXFLAGS. 101 # Use this variable if the behavior 102 # 1) only applies to libstdc++ testing 103 # 2) might need to be negated 104 # In particular, some tests have to be run without precompiled 105 # headers, or without assertions. 106 global DEFAULT_CXXFLAGS 107 if ![info exists DEFAULT_CXXFLAGS] then { 108 set DEFAULT_CXXFLAGS "" 109 # Host specific goo here. 110 if { [string match "powerpc-*-darwin*" $target_triplet] } { 111 append DEFAULT_CXXFLAGS " -multiply_defined suppress" 112 } 113 } 114 v3track DEFAULT_CXXFLAGS 2 115 116 # By default, we assume we want to run program images. 117 global dg-do-what-default 118 set dg-do-what-default run 119 120 # Copy any required data files. 121 v3-copy-files [glob -nocomplain "$srcdir/data/*.tst"] 122 v3-copy-files [glob -nocomplain "$srcdir/data/*.txt"] 123 124 # Locate libgcc.a so we don't need to account for different values of 125 # SHLIB_EXT on different platforms 126 set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] 127 if {$gccdir != ""} { 128 set gccdir [file dirname $gccdir] 129 } 130 v3track gccdir 3 131 132 # Look for shared library. (ie libstdc++.so.) 133 set v3-sharedlib 0 134 set sharedlibdir [lookfor_file $blddir src/.libs/libstdc++.so] 135 if {$sharedlibdir != ""} { 136 if { [string match "*-*-linux*" $target_triplet] && [isnative] } { 137 set v3-sharedlib 1 138 verbose -log "shared library support detected" 139 } 140 } 141 v3track v3-sharedlib 3 142 143 # Compute what needs to be added to the existing LD_LIBRARY_PATH. 144 if {$gccdir != ""} { 145 set ld_library_path "" 146 append ld_library_path ":${gccdir}" 147 set compiler ${gccdir}/g++ 148 append ld_library_path ":${blddir}/src/.libs" 149 150 if { [is_remote host] == 0 && [which $compiler] != 0 } { 151 foreach i "[exec $compiler --print-multi-lib]" { 152 set mldir "" 153 regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir 154 set mldir [string trimright $mldir "\;@"] 155 if { "$mldir" == "." } { 156 continue 157 } 158 if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { 159 append ld_library_path ":${gccdir}/${mldir}" 160 } 161 } 162 } 163 164 set_ld_library_path_env_vars 165 if [info exists env(LD_LIBRARY_PATH)] { 166 verbose -log "LD_LIBRARY_PATH = $env(LD_LIBRARY_PATH)" 167 } 168 } else { 169 set compiler [transform "g++"] 170 } 171 172 # Do a bunch of handstands and backflips for cross compiling and 173 # finding simulators... 174 if [is_remote host] { 175 set header [remote_download host ${blddir}/testsuite/testsuite_hooks.h] 176 if { $header == "" } { 177 verbose -log "Unable to download ${blddir}/testsuite/testsuite_hooks.h to host." 178 return "untested" 179 } 180 set cxx [transform "g++"] 181 set cxxflags "-ggdb3" 182 set includes "-I./" 183 } else { 184 # If we find a testsuite_flags file, we're testing in the build dir. 185 if { [file exists $flags_file] } { 186 set cxx [exec sh $flags_file --build-cxx] 187 set cxxflags [exec sh $flags_file --cxxflags] 188 set includes [exec sh $flags_file --build-includes] 189 } else { 190 set cxx [transform "g++"] 191 set cxxflags "-g -O2 -D_GLIBCXX_ASSERT -fmessage-length=0" 192 set includes "-I${srcdir}" 193 } 194 } 195 196 # Always use MO files built by this test harness. 197 set cxxflags "$cxxflags -DLOCALEDIR=\".\"" 198 199 # If a PCH file is available, use it. We must delay performing 200 # this check until $cxx and such have been initialized because we 201 # perform a test compilation. (Ideally, gcc --print-file-name would 202 # list PCH files, but it does not.) 203 global PCH_CXXFLAGS 204 if ![info exists PCH_CXXFLAGS] then { 205 set src "config[pid].cc" 206 set f [open $src "w"] 207 puts $f "int main () {}" 208 close $f 209 210 set lines [v3_target_compile $src "config[pid].o" object \ 211 "additional_flags=-include additional_flags=bits/stdc++.h"] 212 if {$lines == "" } { 213 set PCH_CXXFLAGS "-include bits/stdc++.h" 214 } else { 215 set PCH_CXXFLAGS "" 216 } 217 file delete $src 218 v3track PCH_CXXFLAGS 2 219 } 220 221 libstdc++_maybe_build_wrapper "${objdir}/testglue.o" "-fexceptions" 222} 223 224# Callback for cleanup routines. 225proc libstdc++_exit { } { 226 global gluefile; 227 228 if [info exists gluefile] { 229 file_on_build delete $gluefile; 230 unset gluefile; 231 } 232} 233 234# Callback from system dg-test. 235proc libstdc++-dg-test { prog do_what extra_tool_flags } { 236 # Set up the compiler flags, based on what we're going to do. 237 switch $do_what { 238 "preprocess" { 239 set compile_type "preprocess" 240 set output_file "[file rootname [file tail $prog]].i" 241 } 242 "compile" { 243 set compile_type "assembly" 244 set output_file "[file rootname [file tail $prog]].s" 245 } 246 "assemble" { 247 set compile_type "object" 248 set output_file "[file rootname [file tail $prog]].o" 249 } 250 "link" { 251 set compile_type "executable" 252 set output_file "./[file rootname [file tail $prog]].exe" 253 } 254 "run" { 255 set compile_type "executable" 256 # FIXME: "./" is to cope with "." not being in $PATH. 257 # Should this be handled elsewhere? 258 # YES. 259 set output_file "./[file rootname [file tail $prog]].exe" 260 # This is the only place where we care if an executable was 261 # created or not. If it was, dg.exp will try to run it. 262 remote_file build delete $output_file; 263 } 264 default { 265 perror "$do_what: not a valid dg-do keyword" 266 return "" 267 } 268 } 269 270 set options "" 271 if { $extra_tool_flags != "" } { 272 verbose -log "extra_tool_flags are:" 273 verbose -log $extra_tool_flags 274 if { [string first "-x c" $extra_tool_flags ] != -1 } { 275 # Short-circut a bunch of complicated goo here for the 276 # special case of compiling a test file as a "C" file, not 277 # as C++: just use target_compile, instead of the usual 278 # gimmicks. 279 verbose -log "compiling and executing as C, not C++" 280 set compile_type "executable" 281 set output_file "./[file rootname [file tail $prog]].exe" 282 remote_file build delete $output_file; 283 lappend options "additional_flags=$extra_tool_flags" 284 set comp_output [target_compile "$prog" "$output_file" "$compile_type" $options]; 285 set comp_output [ prune_g++_output $comp_output ]; 286 return [list $comp_output $output_file] 287 } else { 288 lappend options "additional_flags=$extra_tool_flags" 289 } 290 } 291 292 # There is a libstdc++_compile made for us by default (via the tool- 293 # and-target file), but the defaults are lacking in goodness. 294 set comp_output [v3_target_compile "$prog" "$output_file" "$compile_type" $options]; 295 set comp_output [ prune_g++_output $comp_output ]; 296 297 return [list $comp_output $output_file] 298} 299 300# True if the library supports wchar_t. 301set v3-wchar_t 0 302 303# True if the library supports threads. 304set v3-threads 0 305 306# True if the library supports symbol versioning. 307set v3-symver 0 308 309# A string naming object files to be linked into all tests. 310set v3-test_objs "" 311 312# Called from libstdc++-dg-test above. Calls back into system's 313# target_compile to actually do the work. 314proc v3_target_compile { source dest type options } { 315 global gluefile 316 global wrap_flags 317 global cxx 318 global cxxflags 319 global includes 320 global blddir 321 global v3-test_objs 322 323 if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { 324 lappend options "libs=${gluefile}" 325 lappend options "ldflags=${wrap_flags}" 326 } 327 328 set cxx_final $cxx 329 set cxxlibglossflags [libgloss_link_flags] 330 set cxx_final [concat $cxx_final $cxxlibglossflags] 331 set cxx_final [concat $cxx_final $cxxflags] 332 set cxx_final [concat $cxx_final $includes] 333 334 # Flag setting based on type argument. 335 if { $type == "executable" } { 336 # Link the support objects into executables. 337 set cxx_final [concat $cxx_final ${v3-test_objs}] 338 } else { 339 if { $type == "sharedlib" } { 340 # Don't link in anything. 341 set type "executable" 342 } 343 } 344 345 lappend options "compiler=$cxx_final" 346 347 return [target_compile $source $dest $type $options] 348} 349 350 351# Build the support objects linked in with the libstdc++ tests. In 352# addition, set v3-wchar_t, v3-threads, v3-test_objs, and v3-symver 353# appropriately. 354proc v3-build_support { } { 355 global srcdir 356 global v3-wchar_t 357 global v3-threads 358 global v3-test_objs 359 global v3-symver 360 global v3-sharedlib 361 362 # Figure out whether or not the library supports certain features. 363 set v3-wchar_t 0 364 set v3-threads 0 365 set v3-symver 0 366 set v3-test_objs "" 367 368 set config_src "config.cc" 369 set f [open $config_src "w"] 370 puts $f "#include <bits/c++config.h>" 371 puts $f "#include <bits/gthr.h>" 372 close $f 373 set preprocessed [v3_target_compile $config_src "" \ 374 preprocess "additional_flags=-dN"] 375 if { [string first "_GLIBCXX_USE_WCHAR_T" $preprocessed] != -1 } { 376 verbose -log "wchar_t support detected" 377 set v3-wchar_t 1 378 } 379 if { [string first "_GLIBCXX_SYMVER" $preprocessed] != -1 } { 380 verbose -log "symbol versioning support detected" 381 set v3-symver 1 382 } 383 if { [string first "__GTHREADS" $preprocessed] != -1 } { 384 verbose -log "thread support detected" 385 set v3-threads 1 386 } 387 388 # Try to build the MO files that are used by some of the locale 389 # tests. If we can't build them, that's OK; it just means that 390 # those tests will fail. 391 foreach lang [list "fr" "de"] { 392 catch { 393 file mkdir "$lang/LC_MESSAGES" 394 remote_exec "build" "msgfmt" "-o $lang/LC_MESSAGES/libstdc++.mo $srcdir/../po/$lang.po" 395 if [is_remote host] { 396 remote_exec "host" "mkdir" "-p $lang/LC_MESSAGES" 397 remote_download "host" "$lang/LC_MESSAGES/libstdc++.mo" "$lang/LC_MESSAGES/libstdc++.mo" 398 } 399 } 400 } 401 402 # Build the support objects. 403 set source_files \ 404 [list testsuite_abi.cc testsuite_allocator.cc testsuite_character.cc testsuite_hooks.cc ] 405 foreach f $source_files { 406 set object_file [file rootname $f].o 407 # Compile with "-w" so that warnings issued by the compiler 408 # do not prevent compilation. 409 if { [v3_target_compile $srcdir/$f $object_file "object" \ 410 [list "incdir=$srcdir" "additional_flags=-w"]] 411 != "" } { 412 error "could not compile $f" 413 } 414 append v3-test_objs "$object_file " 415 } 416 417 # Build the shared support objects. 418 if { ${v3-sharedlib} == 1 } { 419 set source_files \ 420 [list testsuite_shared.cc] 421 foreach f $source_files { 422 set object_file [file rootname $f].so 423 # Compile with "-w" so that warnings issued by the compiler 424 # do not prevent compilation. 425 if { [v3_target_compile $srcdir/$f $object_file "sharedlib" \ 426 [list "incdir=$srcdir" "additional_flags=-w -shared -fPIC -DPIC"]] 427 != "" } { 428 error "could not compile $f" 429 } 430 } 431 } 432} 433 434proc check_v3_target_sharedlib { } { 435 global v3-sharedlib 436 return ${v3-sharedlib} 437} 438 439proc check_v3_target_namedlocale { } { 440 global et_namedlocale_saved 441 global et_namedlocale_target_name 442 global tool 443 444 if { ![info exists et_namedlocale_target_name] } { 445 set et_namedlocale_target_name "" 446 } 447 448 # If the target has changed since we set the cached value, clear it. 449 set current_target [current_target_name] 450 if { $current_target != $et_namedlocale_target_name } { 451 verbose "check_v3_target_namedlocale: `$et_namedlocale_target_name'" 2 452 set et_namedlocale_target_name $current_target 453 if [info exists et_namedlocale_saved] { 454 verbose "check_v3_target_namedlocale: removing cached result" 2 455 unset et_namedlocale_saved 456 } 457 } 458 459 if [info exists et_namedlocale_saved] { 460 verbose "check_v3_target_namedlocale: using cached result" 2 461 } else { 462 set et_namedlocale_saved 0 463 464 # Set up, compile, and execute a C++ test program that tries to use 465 # all the required named locales. 466 set src nlocale[pid].cc 467 set exe nlocale[pid].x 468 469 set f [open $src "w"] 470 puts $f "#include <locale>" 471 puts $f "using namespace std;" 472 puts $f "int main ()" 473 puts $f "{" 474 puts $f " try" 475 puts $f " {" 476 puts $f " locale(\"\");" 477 puts $f " locale(\"de_DE\");" 478 puts $f " locale(\"de_DE.ISO-8859-15@euro\");" 479 puts $f " locale(\"de_DE@euro\");" 480 puts $f " locale(\"en_HK\");" 481 puts $f " locale(\"en_PH\");" 482 puts $f " locale(\"en_US\");" 483 puts $f " locale(\"en_US.ISO-8859-1\");" 484 puts $f " locale(\"en_US.ISO-8859-15\");" 485 puts $f " locale(\"en_US.UTF-8\");" 486 puts $f " locale(\"es_ES\");" 487 puts $f " locale(\"es_MX\");" 488 puts $f " locale(\"fr_FR\");" 489 puts $f " locale(\"fr_FR@euro\");" 490 puts $f " locale(\"is_IS\");" 491 puts $f " locale(\"is_IS.UTF-8\");" 492 puts $f " locale(\"it_IT\");" 493 puts $f " locale(\"ja_JP.eucjp\");" 494 puts $f " locale(\"se_NO.UTF-8\");" 495 puts $f " locale(\"ta_IN\");" 496 puts $f " locale(\"zh_TW\");" 497 puts $f " return 0;" 498 puts $f " }" 499 puts $f " catch(...)" 500 puts $f " {" 501 puts $f " return 1;" 502 puts $f " }" 503 puts $f "}" 504 close $f 505 506 set lines [v3_target_compile $src $exe executable ""] 507 file delete $src 508 509 if [string match "" $lines] { 510 # No error message, compilation succeeded. 511 set result [${tool}_load "./$exe" "" ""] 512 set status [lindex $result 0] 513 remote_file build delete $exe 514 515 verbose "check_v3_target_namedlocale: status is <$status>" 2 516 517 if { $status == "pass" } { 518 set et_namedlocale_saved 1 519 } 520 } else { 521 verbose "check_v3_target_namedlocale: compilation failed" 2 522 } 523 } 524 return $et_namedlocale_saved 525} 526 527proc check_v3_target_cxa_atexit { } { 528 global et_cxa_atexit 529 global et_cxa_atexit_target_name 530 global tool 531 532 if { ![info exists et_cxa_atexit_target_name] } { 533 set et_cxa_atexit_target_name "" 534 } 535 536 # If the target has changed since we set the cached value, clear it. 537 set current_target [current_target_name] 538 if { $current_target != $et_cxa_atexit_target_name } { 539 verbose "check_v3_target_cxa_atexit: `$et_cxa_atexit_target_name'" 2 540 set et_cxa_atexit_target_name $current_target 541 if [info exists et_cxa_atexit] { 542 verbose "check_v3_target_cxa_atexit: removing cached result" 2 543 unset et_cxa_atexit 544 } 545 } 546 547 if [info exists et_cxa_atexit] { 548 verbose "check_v3_target_cxa_atexit: using cached result" 2 549 } else { 550 set et_cxa_atexit 0 551 552 # Set up, compile, and execute a C++ test program that depends 553 # on correct ordering of static object destructors. This is 554 # indicative of the presence and use of __cxa_atexit. 555 set src cxaatexit[pid].cc 556 set exe cxaatexit[pid].x 557 558 set f [open $src "w"] 559 puts $f "#include <stdlib.h>" 560 puts $f "static unsigned int count;" 561 puts $f "struct X" 562 puts $f "{" 563 puts $f " X() { count = 1; }" 564 puts $f " ~X()" 565 puts $f " {" 566 puts $f " if (count != 3)" 567 puts $f " exit(1);" 568 puts $f " count = 4;" 569 puts $f " }" 570 puts $f "};" 571 puts $f "void f()" 572 puts $f "{" 573 puts $f " static X x;" 574 puts $f "}" 575 puts $f "struct Y" 576 puts $f "{" 577 puts $f " Y() { f(); count = 2; }" 578 puts $f " ~Y()" 579 puts $f " {" 580 puts $f " if (count != 2)" 581 puts $f " exit(1);" 582 puts $f " count = 3;" 583 puts $f " }" 584 puts $f "};" 585 puts $f "Y y;" 586 puts $f "int main()" 587 puts $f "{ return 0; }" 588 close $f 589 590 set lines [v3_target_compile $src $exe executable ""] 591 file delete $src 592 593 if [string match "" $lines] { 594 # No error message, compilation succeeded. 595 set result [${tool}_load "./$exe" "" ""] 596 set status [lindex $result 0] 597 remote_file build delete $exe 598 599 verbose "check_v3_target_cxa_atexit: status is <$status>" 2 600 601 if { $status == "pass" } { 602 set et_cxa_atexit 1 603 } 604 } else { 605 verbose "check_v3_target_cxa_atexit: compilation failed" 2 606 } 607 } 608 return $et_cxa_atexit 609} 610 611proc check_v3_target_debug_mode { } { 612 global cxxflags 613 global et_debug_mode 614 615 global tool 616 617 if { ![info exists et_debug_mode_target_name] } { 618 set et_debug_mode_target_name "" 619 } 620 621 # If the target has changed since we set the cached value, clear it. 622 set current_target [current_target_name] 623 if { $current_target != $et_debug_mode_target_name } { 624 verbose "check_v3_target_debug_mode: `$et_debug_mode_target_name'" 2 625 set et_debug_mode_target_name $current_target 626 if [info exists et_debug_mode] { 627 verbose "check_v3_target_debug_mode: removing cached result" 2 628 unset et_debug_mode 629 } 630 } 631 632 if [info exists et_debug_mode] { 633 verbose "check_v3_target_debug_mode: using cached result" 2 634 } else { 635 set et_debug_mode 0 636 637 # Set up, compile, and execute a C++ test program that depends 638 # on debug mode working. 639 set src debug_mode[pid].cc 640 set exe debug_mode[pid].exe 641 642 set f [open $src "w"] 643 puts $f "#include <string>" 644 puts $f "using namespace std;" 645 puts $f "int main()" 646 puts $f "{ return 0; }" 647 close $f 648 649 set cxxflags_saved $cxxflags 650 set cxxflags "$cxxflags -Werror -O0 -D_GLIBCXX_DEBUG" 651 set lines [v3_target_compile $src $exe executable ""] 652 set cxxflags $cxxflags_saved 653 file delete $src 654 655 if [string match "" $lines] { 656 # No error message, compilation succeeded. 657 set et_debug_mode 1 658 } 659 } 660 verbose "check_v3_target_debug_mode: $et_debug_mode" 2 661 return $et_debug_mode 662} 663