1# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2# 2001, 2002, 2003 Free Software Foundation, Inc. 3# 4# This file is part of DejaGnu. 5# 6# DejaGnu is free software; you can redistribute it and/or modify it 7# under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# DejaGnu is distributed in the hope that it will be useful, but 12# WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14# General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with DejaGnu; if not, write to the Free Software Foundation, 18# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20# This file was written by Rob Savoye. (rob@welcomehome.org) 21# and extensively modified by Bob Manson. (manson@cygnus.com) 22 23# a hairy pattern to recognize text 24set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]" 25 26# 27# this is a collection of support procs for the target data 28# structures. We use a named array, since Tcl has no real data 29# structures. Here's the special index words for the array: 30# Required fields are: 31# name - the name of the target. (mostly for error messages) This 32# should also be the string used for this target's array. 33# It should also be the same as the linker script so we 34# can find them dynamically. 35# Optional fields are: 36# ldflags - the flags required to produce a fully linked executable. 37# config - the target canonical for this target. This is a regexp 38# as passed to istarget or isnative. 39# cflags - the flags required to produce an object file from a 40# source file. 41# connect - the connectmode for this target. This is for both IP and 42# serial connections. 43# hostname - the hostname of the target. This is for TCP/IP based 44# connections, and is also used for versions of tip that 45# use /etc/remote. 46# serial - the serial port. This is typically /dev/tty? or com?:. 47# baud - the baud rate for a serial port connection. 48# netport - the IP port. 49# x10 - parameters for the x10 controller (used to reboot) 50# fileid - the fileid or spawn id of of the connection. 51# prompt - a regexp for matching the prompt. 52# ioport - the port for I/O on dual port systems. 53# 54# there are three main arrays, indexed in with "target", "build", and "host". 55# all other targets are indexed with a name usually based on the linker script 56# like "idp", or "ex93x.ld". 57# 58 59# 60# Set the target connection. 61# 62proc push_target { name } { 63 global target_abbrev 64 65 pop_config target 66 push_config target $name 67} 68 69# 70# Set the host connnection. 71# 72proc push_host { name } { 73 pop_config host 74 push_config host $name 75} 76 77# 78# Set the build connnection. 79# 80proc push_build { name } { 81 pop_config build 82 push_config build $name 83} 84 85# 86# Set the config for the current host or target connection. 87# 88proc push_config { type name } { 89 global target_info 90 91 verbose "pushing config for $type, name is $name" 92 if [info exists target_info($type,name)] { 93 if { $target_info($type,name) == $name } { 94 error "pushing config for $type, '$name' twice" 95 } 96 } 97 set target_info($type,name) $name 98} 99 100# 101# Set the current connection for target or host. 102# 103proc pop_config { type } { 104 global target_info 105 106 if [info exists target_info(${type},name)] { 107 unset target_info(${type},name) 108 } 109} 110 111# 112# Unset the target connection. 113# 114proc pop_target { } { 115 pop_config target 116} 117 118# 119# Unset the host connection. 120# 121proc pop_host { } { 122 pop_config host 123} 124 125# 126# Remove extraneous warnings we don't care about 127# 128proc prune_warnings { text } { 129 global host_triplet 130 131 # remove the \r part of "\r\n" so we don't break all the patterns 132 # we want to match. 133 regsub -all -- "\r" $text "" text 134 135 # This is from sun4's. Do it for all machines for now. 136 # The "\\1" is to try to preserve a "\n" but only if necessary. 137 if [ishost "sparc-*-sunos*"] { 138 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text 139 } 140 141 # See Brendan for the raison d'etre of this one. 142 if [ishost "alpha*-*-*"] { 143 regsub -all "(^|\n)(/usr/(ucb|bin)/ld.*without exceptions was\[^\n\]+\n?)" $text "\\1" text 144 } 145 if [ishost "hppa*-*-hpux*"] { 146 # Ignore the compiler's warnings about PA incompatibility. 147 regsub -all "(^|\n)\[^\n\]*PA 2.0 object file \[^\n\]* was detected. The linked output may not run on a PA 1.x system." $text "" text 148 149 regsub -all "(^|\n)\[^\n\]*PA 2.0 object file \[^\n\]* was detected. The linked output may not run on a PA 1.x system." $text "" text 150 151 # And the linker's +vcompatwarnings verbage. 152 regsub -all "(^|\n)\[^\n\]*Linker features were used that may not be supported\[^\n\]*.\[^\n\]*." $text "" text 153 154 # Ignore these warnings, which the HP aCC compiler seems to 155 # generate on HP-UX 10.30 and 11.0. (Something is probably 156 # wrong with some system headers, but still...) 157 # 158 # This particular warning always is given with a line of warning 159 # text, followed by a source line, followed by a line with "^^^" 160 # underlining an offending symbol name. Here we slurp up the 161 # warning text and the next two lines, assuming that they are 162 # the source line and underline chars. 163 # 164 regsub -all "Warning .*The linkage directive is ignored for an object or function declared static..\[^\n\]*.\[^\n\]*." $text "" text 165 166 # Ignore these warnings, which I often see from the ANSI C 167 # compiler installed on HP-UX 11.0 machines. (Something is 168 # probably wrong with an installation, or perhaps NLS isn't 169 # quite healthy yet on 11.0. In either case, it's easier to 170 # "fix" this nit here, than it is to track down & fix the 171 # root cause.) 172 # 173 # This particular warning always is given with a line of warning 174 # text, followed by line that says "Using internal messages". 175 # 176 regsub -all "Warning: Unable to open pxdb message catalog.*" $text "" text 177 regsub -all ".* Using internal messages.*" $text "" text 178 179 # Another form of the "unable to find message catalog" warning. 180 # 181 regsub -all "cpp: warning .*Possibly incorrect message catalog." $text "" text 182 183 # Another odd warning on 11.0. 184 # 185 regsub -all "aCC .assigner.: Warning .*Could not find library for -l.*" $text "" text 186 187 # Oh heck, just keep adding 'em here... 188 # 189 regsub -all "aCC .assigner.: Warning .*Could not satisfy instantiation request for \[^\n\]* contained in\[^\n\]*\n\t/lib/pa20_64/lib\[a-zA-Z0-9\]*.sl" $text "" text 190 191 # Remove the lines that are output by the HP F77 compiler to 192 # indicate the functions that are being compiled. 193 upvar compiler_type compiler_type 194 if { [info exists compiler_type] && $compiler_type == "f77" } { 195 regsub -all "\[ \ta-zA-Z_0-9\./\]*:\[\r\n\]+" $text "" text 196 } 197 198 # Ignore the warnings about unknown options 199 regsub -all ".*warning \[0-9\]+: Unknown option.*ignored.*" $text "" text 200 201 } 202 203 # Ignore these. 204 regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text 205 regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text 206 207 # This is from sun4's. Do it for all machines for now. 208 # The "\\1" is to try to preserve a "\n" but only if necessary. 209 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text 210 211 # This happens when compiling on Alpha OSF/1 with cc -g -O. 212 regsub -all "(^|\n)(\n*uopt: Warning: file not optimized; use -g3 if both optimization and debug wanted\n?)+" $text "\\1" text 213 214 # This happens when compiling on Alpha OSF using gas. 215 regsub -all "(^|\n)(/usr/.*/ld:\nWarning: Linking some objects which contain exception information sections\n\tand some which do not. This may cause fatal runtime exception handling\n\tproblems\[^\n\]*\n?)+" $text "\\1" text 216 217 # This happens on SunOS with cc -g -O. 218 regsub -all "(^|\n)(cc: Warning: -O conflicts with -g. -O turned off.\n?)+" $text "\\1" text 219 220 # This happens when assembling code with the native HP assembler 221 regsub -all "(^|\n)(as:\[^\n\]*err#13.\n .warning.\[^\n\]*\n?)+" $text "\\1" text 222 223 # When using the HP assembler, -g isn't supported. 224 regsub -all "(^|\n)(cc1: warning: -g is only supported when using GAS on this processor\[^\n\]*\ncc1: warning:\[^\n\]*\n?)+" $text "\\1" text 225 regsub -all "(^|\n)(cc1plus: warning: -g is only supported when using GAS on this processor\[^\n\]*\ncc1plus: warning:\[^\n\]*\n?)+" $text "\\1" text 226 227 # This happens when testing across NFS. 228 regsub -all "(^|\n)((NFS|nfs) server \[^\n\]* not responding\[^\n\]*\n?)+" $text "\\1" text 229 regsub -all "(^|\n)((NFS|nfs) server \[^\n\]* (ok|is alive again)\[^\n\]*\n?)+" $text "\\1" text 230 231 # This happens when testing across NFS on osf4. 232 regsub -all "(^|\n)(NFS3 server \[^\n\]* not responding still trying\[^\n\]*\n?)+" $text "\\1" text 233 regsub -all "(^|\n)(NFS3 server \[^\n\]* ok\[^\n\]*\n?)+" $text "\\1" text 234 235 # When using the IRIX 6 o32 assembler, -g isn't supported 236 regsub -all "(^|\n)(cc1: warning: `-g' not supported by this configuration of GCC\[^\n\]*\n?)+" $text "\\1" text 237 regsub -all "(^|\n)(cc1plus: warning: `-g' not supported by this configuration of GCC\[^\n\]*\n?)+" $text "\\1" text 238 239 regsub -all "(^|\n)(cc1: warning: -mabi=32 does not support -g\[^\n\]*\n?)+" $text "\\1" text 240 regsub -all "(^|\n)(cc1plus: warning: -mabi=32 does not support -g\[^\n\]*\n?)+" $text "\\1" text 241 242 # This happens with the o32 assembler on IRIX 6. 243 regsub -all "(^|\n)(as: Warning: -O3 is not supported for assembly compiles for ucode compilers; changing to -O2.\n?)+" $text "\\1" text 244 245 # This happens when using g++ on a DWARF system. 246 regsub -all "(^|\n)(cc1plus: warning: -g option not supported for C\\+\\+ on systems using the DWARF debugging format\n?)+" $text "\\1" text 247 248 # This is from sun4's. Do it for all machines for now. 249 # The "\\1" is to try to preserve a "\n" but only if necessary. 250 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text 251 252 # See Brendan for the raison d'etre of this one. 253 if [string match "alpha*-*-*" $host_triplet] { 254 regsub -all "(^|\n)(/usr/(ucb|bin)/ld.*without exceptions was\[^\n\]+\n?)" $text "\\1" text 255 } 256 257 # Don't pay attention to the AIX4 linker warnings. 258 regsub -all "(^|\n)(ld:.*WARNING: Duplicate.*ld:.*Use the -bload\[^\n\]*\n?)" $text "\\1" text 259 260 # Or the IRIX 6 ones. 261 regsub -all "(^|\n)(ld(|32|64): WARNING \[^\n\]*\n?)+" $text "\\1" text 262 regsub -all "(^|\n)(ld(|32|64): Giving up.*Use -wall\[^\n\]*\n?)+" $text "\\1" text 263 264 # Or the NetBSD ones. 265 regsub -all "(^|\n)(\[^\n\]*: In function\[^\n\]*\n\[^\n\]\[^\n\]*warning:this program uses \[^\n\]*)" $text "\\1" text 266 regsub -all "(^|\n)(\[^\n\]*: In function\[^\n\]*\n\[^\n\]\[^\n\]*warning:reference to compatibility \[^\n\]*)" $text "\\1" text 267 regsub -all "(^|\n)(\[^\n\]*:\[0-9\]+: warning: \[^\n\]* possibly used unsafely, use \[^\n\]*\n?)" $text "\\1" text 268 regsub -all "(^|\n)(\[^\n\]*: warning: reference to compatibility glob\[^\n\]*\n?)" $text "\\1" text 269 270 # GNU ld warns about functions marked as dangerous in GNU libc. 271 regsub -all "(^|\n)\[^\n\]*: In function\[^\n\]*\n\[^\n\]\[^\n\]*function is dangerous\[^\n\]*" $text "" text 272 273 # GNU ld warns about functions marked as dangerous in GNU libc. 274 regsub -all "(^|\n)\[^\n\]*: In function\[^\n\]*\n\[^\n\]\[^\n\]*the use of \[^\n\]* is dangerous, better use \[^\n\]*" $text "" text 275 276 # Libgloss libnosys defines functions that warn when linked in 277 regsub -all "(^|\n)\[^\n\]*: In function\[^\n\]*\n\[^\n\]\[^\n\]*is not implemented and will always fail\[^\n\]*" $text "" text 278 279 # Cygwin cc1 warns about -fpic and -fPIC 280 regsub -all ".*: warning: -f(pic|PIC) ignored for target .*" $text "" text 281 282 # It might be tempting to get carried away and delete blank lines, etc. 283 # Just delete *exactly* what we're ask to, and that's it. 284 return $text 285} 286 287# 288# Invoke the compiler. This gets interesting cause the compiler may 289# not be on the same machine we're running DejaGnu on. 290# 291 292proc target_compile {source destfile type options} { 293 set target [target_info name] 294 if { [info proc ${target}_compile] != "" } { 295 return [${target}_compile $source $destfile $type $options] 296 } else { 297 return [default_target_compile $source $destfile $type $options] 298 } 299} 300 301proc default_target_compile {source destfile type options} { 302 global target_triplet 303 global tool_root_dir 304 global CFLAGS_FOR_TARGET 305 global compiler_flags 306 307 if { $destfile == "" && $type != "preprocess" && $type != "none" } { 308 error "Must supply an output filename for the compile to default_target_compile" 309 } 310 311 set add_flags "" 312 set libs "" 313 set compiler_type "c" 314 set compiler "" 315 set ldflags "" 316 set dest [target_info name] 317 318 if [info exists CFLAGS_FOR_TARGET] { 319 append add_flags " $CFLAGS_FOR_TARGET" 320 } 321 322 if [info exists target_info(host,name)] { 323 set host [host_info name] 324 } else { 325 set host "unix" 326 } 327 328 foreach i $options { 329 if { $i == "c++" } { 330 set compiler_type "c++" 331 if [board_info $dest exists cxxflags] { 332 append add_flags " [target_info cxxflags]" 333 } 334 append add_flags " [g++_include_flags]" 335 if [board_info $dest exists c++compiler] { 336 set compiler [target_info c++compiler] 337 } else { 338 set compiler [find_g++] 339 } 340 } 341 342 if { $i == "f77" } { 343 set compiler_type "f77" 344 if [board_info $dest exists f77flags] { 345 append add_flags " [target_info f77flags]" 346 } 347# append add_flags " [f77_include_flags]" 348 if [board_info $dest exists f77compiler] { 349 set compiler [target_info f77compiler] 350 } else { 351 set compiler [find_g77] 352 } 353 } 354 355 if [regexp "^dest=" $i] { 356 regsub "^dest=" $i "" tmp 357 if [board_info $tmp exists name] { 358 set dest [board_info $tmp name] 359 } else { 360 set dest $tmp 361 } 362 } 363 if [regexp "^compiler=" $i] { 364 regsub "^compiler=" $i "" tmp 365 set compiler $tmp 366 } 367 if [regexp "^additional_flags=" $i] { 368 regsub "^additional_flags=" $i "" tmp 369 append add_flags " $tmp" 370 } 371 if [regexp "^ldflags=" $i] { 372 regsub "^ldflags=" $i "" tmp 373 append ldflags " $tmp" 374 } 375 if [regexp "^libs=" $i] { 376 regsub "^libs=" $i "" tmp 377 append libs " $tmp" 378 } 379 if [regexp "^incdir=" $i] { 380 regsub "^incdir=" $i "-I" tmp 381 append add_flags " $tmp" 382 } 383 if [regexp "^libdir=" $i] { 384 regsub "^libdir=" $i "-L" tmp 385 append add_flags " $tmp" 386 } 387 if [regexp "^ldscript=" $i] { 388 regsub "^ldscript=" $i "" ldscript 389 } 390 if [regexp "^redirect=" $i] { 391 regsub "^redirect=" $i "" redirect 392 } 393 if [regexp "^optimize=" $i] { 394 regsub "^optimize=" $i "" optimize 395 } 396 if [regexp "^timeout=" $i] { 397 regsub "^timeout=" $i "" timeout 398 } 399 } 400 401 if [board_info $host exists cflags_for_target] { 402 append add_flags " [board_info $host cflags_for_target]" 403 } 404 405 global CC_FOR_TARGET 406 global CXX_FOR_TARGET 407 global F77_FOR_TARGET 408 409 if [info exists CC_FOR_TARGET] { 410 if { $compiler == "" } { 411 set compiler $CC_FOR_TARGET 412 } 413 } 414 415 if [info exists CXX_FOR_TARGET] { 416 if { $compiler_type == "c++" } { 417 set compiler $CXX_FOR_TARGET 418 } 419 } 420 421 if [info exists F77_FOR_TARGET] { 422 if { $compiler_type == "f77" } { 423 set compiler $F77_FOR_TARGET 424 } 425 } 426 427 if { $compiler == "" } { 428 set compiler [board_info $dest compiler] 429 if { $compiler == "" } { 430 return "default_target_compile: No compiler to compile with" 431 } 432 } 433 434 if ![is_remote host] { 435 if { [which $compiler] == 0 } { 436 return "default_target_compile: Can't find $compiler." 437 } 438 } 439 440 if {$type == "object"} { 441 append add_flags " -c" 442 } 443 444 if { $type == "preprocess" } { 445 append add_flags " -E" 446 } 447 448 if { $type == "assembly" } { 449 append add_flags " -S" 450 } 451 452 if [board_info $dest exists cflags] { 453 append add_flags " [board_info $dest cflags]" 454 } 455 456 if { $type == "executable" } { 457 # This must be added here. 458 # if [board_info $dest exists ldscript] { 459 # append add_flags " [board_info $dest ldscript]" 460 # } 461 462 if [board_info $dest exists ldflags] { 463 append add_flags " [board_info $dest ldflags]" 464 } 465 if { $compiler_type == "c++" } { 466 append add_flags " [g++_link_flags]" 467 } 468 if [isnative] { 469 # This is a lose. 470 catch "glob -nocomplain $tool_root_dir/libstdc++/libstdc++.so* $tool_root_dir/libstdc++/libstdc++.sl" tmp 471 if { ${tmp} != "" } { 472 if [regexp ".*solaris2.*" $target_triplet] { 473 # Solaris 2 474 append add_flags " -R$tool_root_dir/libstdc++" 475 } elseif [regexp ".*(osf|irix5|linux).*" $target_triplet] { 476 # OSF/1 or Irix5 477 append add_flags " -Wl,-rpath,$tool_root_dir/libstdc++" 478 } elseif [regexp ".*hppa.*" $target_triplet] { 479 # HP/UX 480 append add_flags " -Wl,-a,shared_archive" 481 } 482 } 483 } 484 } 485 486 if ![info exists ldscript] { 487 set ldscript [board_info $dest ldscript] 488 } 489 490 foreach i $options { 491 if { $i == "debug" } { 492 if [board_info $dest exists debug_flags] { 493 append add_flags " [board_info $dest debug_flags]" 494 } else { 495 append add_flags " -g" 496 } 497 } 498 } 499 500 if [info exists optimize] { 501 append add_flags " $optimize" 502 } 503 504 if { $type == "executable" } { 505 append add_flags " $ldflags" 506 foreach x $libs { 507 if [file exists $x] { 508 append source " $x" 509 } else { 510 append add_flags " $x" 511 } 512 } 513 514 if [board_info $dest exists libs] { 515 append add_flags " [board_info $dest libs]" 516 } 517 518 # This probably isn't such a good idea, but it avoids nasty 519 # hackiness in the testsuites. 520 # The math library must be linked in before the C library. The C 521 # library is linked in by the linker script, so this must be before 522 # the linker script. 523 if [board_info $dest exists mathlib] { 524 append add_flags " [board_info $dest mathlib]" 525 } else { 526 append add_flags " -lm" 527 } 528 529 # This must be added here. 530 append add_flags " $ldscript" 531 532 if [board_info $dest exists remote_link] { 533 # Relink option. 534 append add_flags " -Wl,-r" 535 } 536 if [board_info $dest exists output_format] { 537 append add_flags " -Wl,-oformat,[board_info $dest output_format]" 538 } 539 } 540 541 if [board_info $dest exists multilib_flags] { 542 append add_flags " [board_info $dest multilib_flags]" 543 } 544 545 verbose "doing compile" 546 547 set sources "" 548 if [is_remote host] { 549 foreach x $source { 550 set file [remote_download host $x] 551 if { $file == "" } { 552 warning "Unable to download $x to host." 553 return "Unable to download $x to host." 554 } else { 555 append sources " $file" 556 } 557 } 558 } else { 559 set sources $source 560 } 561 562 if [is_remote host] { 563 append add_flags " -o a.out" 564 remote_file host delete a.out 565 } else { 566 if { $destfile != "" } { 567 append add_flags " -o $destfile" 568 } 569 } 570 571 # This is obscure: we put SOURCES at the end when building an 572 # object, because otherwise, in some situations, libtool will 573 # become confused about the name of the actual source file. 574 if {$type == "object"} { 575 set opts "$add_flags $sources" 576 } else { 577 set opts "$sources $add_flags" 578 } 579 580 if [is_remote host] { 581 if [host_info exists use_at] { 582 set fid [open "atfile" "w"] 583 puts $fid "$opts" 584 close $fid 585 set opts "@[remote_download host atfile]" 586 remote_file build delete atfile 587 } 588 } 589 590 verbose "Invoking the compiler as $compiler $opts" 2 591 592 if [info exists redirect] { 593 verbose "Redirecting output to $redirect" 2 594 set status [remote_exec host "$compiler $opts" "" "" $redirect] 595 } else { 596 if [info exists timeout] { 597 verbose "Setting timeout to $timeout" 2 598 set status [remote_exec host "$compiler $opts" "" "" "" $timeout] 599 } else { 600 set status [remote_exec host "$compiler $opts"] 601 } 602 } 603 604 set compiler_flags $opts 605 if [is_remote host] { 606 remote_upload host a.out $destfile 607 remote_file host delete a.out 608 } 609 set comp_output [prune_warnings [lindex $status 1]] 610 regsub "^\[\r\n\]+" $comp_output "" comp_output 611 if { [lindex $status 0] != 0 } { 612 verbose -log "compiler exited with status [lindex $status 0]" 613 } 614 if { [lindex $status 1] != "" } { 615 verbose -log "output is:\n[lindex $status 1]" 2 616 } 617 if { [lindex $status 0] != 0 && "${comp_output}" == "" } { 618 set comp_output "exit status is [lindex $status 0]" 619 } 620 return ${comp_output} 621} 622 623proc reboot_target { } { 624 set result [remote_reboot target] 625 puts "REBOOT_TARGET: \"$result\"" 626 return ${result} 627} 628 629# 630# Invoke this if you really want as to be called directly, rather than 631# calling the compiler. FLAGS are any additional flags to pass to the 632# assembler. 633# 634proc target_assemble { source destfile flags } { 635 return [default_target_assemble $source $destfile $flags] 636} 637 638proc default_target_assemble { source destfile flags } { 639 global AS_FOR_TARGET 640 global ASFLAGS_FOR_TARGET 641 642 if [info exists AS_FOR_TARGET] { 643 set AS "$AS_FOR_TARGET" 644 } else { 645 if ![board_info target exists assembler] { 646 set AS [find_gas] 647 } else { 648 set AS [board_info target assembler] 649 } 650 } 651 652 if [info exists ASFLAGS_FOR_TARGET] { 653 append flags " $ASFLAGS_FOR_TARGET" 654 } 655 656 if [is_remote host] { 657 set source [remote_download host $source] 658 set dest "a.out" 659 } else { 660 set dest $destfile 661 } 662 set status [remote_exec host "$AS $source $flags -o $dest"] 663 if [is_remote host] { 664 remote_upload host $dest $destfile 665 } 666 667 set comp_output [prune_warnings [lindex $status 1]] 668 if { [lindex $status 0] != 0 } { 669 verbose -log "assembler exited with status [lindex $status 0]" 670 } 671 if { [lindex $status 1] != "" } { 672 verbose -log "assembler output is:\n[lindex $status 1]" 2 673 } 674 return ${comp_output} 675} 676 677# 678# Invoke this if you really want ld to be called directly, rather than 679# calling the compiler. FLAGS are any additional flags to pass to the 680# linker. 681# 682proc target_link { objects destfile flags } { 683 return [default_link target "$objects" "$destfile" $flags] 684} 685 686proc default_link { board objects destfile flags } { 687 global LD_FOR_TARGET 688 global LDFLAGS_FOR_TARGET 689 690 # return -L's in ldflags 691 proc only--Ls { ldflags } { 692 set result "" 693 set ldflags [split $ldflags] 694 set len [llength $ldflags] 695 for { set i 0 } { $i < $len } { incr i } { 696 # ??? We ignore the situation where a -L is actually the argument 697 # to an option. 698 set arg [lindex $ldflags $i] 699 regsub "^-Wl," $arg "" arg 700 if [regexp "^-L" $arg] { 701 # Is the directory in the next arg, or part of this one? 702 if { "$arg" == "-L" } { 703 if { $i + 1 < $len } { 704 append result " -L [lindex $ldflags $i+1]" 705 incr i 706 } 707 } else { 708 append result " $arg" 709 } 710 } 711 } 712 return $result 713 } 714 715 if [info exists LD_FOR_TARGET] { 716 set LD "$LD_FOR_TARGET" 717 } else { 718 if ![board_info target exists linker] { 719 set LD [find_ld] 720 } else { 721 set LD [board_info target linker] 722 } 723 } 724 725 if [info exists LDFLAGS_FOR_TARGET] { 726 append flags " $LDFLAGS_FOR_TARGET" 727 } 728 729 # `ldflags' consists of arguments to gcc (that are then 730 # passed to ld), not arguments to ld directly. 731 # We need the -L's. 732 if [board_info $board exists ldflags] { 733 set ldflags [board_info $board ldflags] 734 set ldflags [only--Ls $ldflags] 735 append flags " $ldflags" 736 } 737 738 if [board_info $board exists ldscript] { 739 # strip leading -Wl, if present 740 set ldscript [board_info $board ldscript] 741 regsub "^-Wl," $ldscript "" ldscript 742 append flags " $ldscript" 743 } 744 745 if [is_remote host] { 746 foreach x $objects { 747 set nobjects "$nobjects [remote_download host $x]" 748 } 749 set objects "$nobjects" 750 set dest "a.out" 751 } else { 752 set dest $destfile 753 } 754 set status [remote_exec host "$LD $objects $flags -o $dest"] 755 if [is_remote host] { 756 remote_upload host $dest $destfile 757 } 758 759 set comp_output [prune_warnings [lindex $status 1]] 760 if { [lindex $status 0] != 0 } { 761 verbose -log "linker exited with status [lindex $status 0]" 762 } 763 if { [lindex $status 1] != "" } { 764 verbose -log "linker output is:\n[lindex $status 1]" 2 765 } 766 return ${comp_output} 767} 768