1 # Copyright 2004-2023 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # FIXME:brobecker/2004-03-31:
19 # The following functions should eventually be part of dejagnu. Even after
20 # these functions becomes available in dejagnu, we will keep for a while
21 # a copy here in order to avoid increasing the dejagnu version
24 proc gdb_find_gnatmake {} {
27 set root "$tool_root_dir/gcc"
30 if ![is_remote host] {
31 set file [lookfor_file $root gnatmake]
33 set GM "$file -I$root/ada/rts --GCC=$root/xgcc --GNATBIND=$root/gnatbind --GNATLINK=$root/gnatlink -cargs -B$root -largs --GCC=$root/xgcc -margs";
38 set GM [transform gnatmake]
44 proc gdb_find_gdc {} {
46 print "Tool Root: $tool_root_dir"
48 if {![is_remote host]} {
49 set file [lookfor_file $tool_root_dir gdc]
51 set file [lookfor_file $tool_root_dir gcc/gdc]
54 set CC "$file -B[file dirname $file]/"
56 set CC [transform gdc]
59 set CC [transform gdc]
65 proc gdb_find_gfortran {} {
68 if {![is_remote host]} {
69 set file [lookfor_file $tool_root_dir gfortran]
71 set file [lookfor_file $tool_root_dir gcc/gfortran]
74 set CC "$file -B[file dirname $file]/"
76 set CC [transform gfortran]
79 set CC [transform gfortran]
89 if {![is_remote host]} {
90 set file [lookfor_file $tool_root_dir gccgo]
92 set root [file dirname $file]
93 set GO "$file -B$root/gcc/"
98 set GO [transform gccgo]
104 proc gdb_find_go_linker {} {
108 proc gdb_find_rustc {} {
110 if {![is_remote host]} {
111 set rustc [lookfor_file $tool_root_dir rustc]
119 append rustc " --color never"
124 proc gdb_find_ldd {} {
125 global LDD_FOR_TARGET
126 if [info exists LDD_FOR_TARGET] {
127 set ldd $LDD_FOR_TARGET
134 proc gdb_find_objcopy {} {
135 global OBJCOPY_FOR_TARGET
136 if [info exists OBJCOPY_FOR_TARGET] {
137 set objcopy $OBJCOPY_FOR_TARGET
139 set objcopy [transform objcopy]
144 # find target objdump
145 proc gdb_find_objdump {} {
146 global OBJDUMP_FOR_TARGET
147 if [info exists OBJDUMP_FOR_TARGET] {
148 set objdump $OBJDUMP_FOR_TARGET
150 set objdump [transform objdump]
155 proc gdb_find_readelf {} {
156 global READELF_FOR_TARGET
157 if [info exists READELF_FOR_TARGET] {
158 set readelf $READELF_FOR_TARGET
160 set readelf [transform readelf]
165 proc gdb_find_eu-unstrip {} {
166 global EU_UNSTRIP_FOR_TARGET
167 if [info exists EU_UNSTRIP_FOR_TARGET] {
168 set eu_unstrip $EU_UNSTRIP_FOR_TARGET
170 set eu_unstrip [transform eu-unstrip]
175 # Local version of default_target_compile, to be used for languages that
176 # dejagnu's default_target_compile doesn't support.
177 proc gdb_default_target_compile_1 {source destfile type options} {
178 global target_triplet
180 global CFLAGS_FOR_TARGET
181 global compiler_flags
183 if { $destfile == "" && $type != "preprocess" && $type != "none" } {
184 error "Must supply an output filename for the compile to default_target_compile"
190 set compiler_type "c"
193 # linker_opts_order is one of "sources-then-flags", "flags-then-sources".
194 # The order matters for things like -Wl,--as-needed. The default is to
195 # preserve existing behavior.
196 set linker_opts_order "sources-then-flags"
198 set dest [target_info name]
200 if {[info exists CFLAGS_FOR_TARGET]} {
201 append add_flags " $CFLAGS_FOR_TARGET"
204 if {[info exists target_info(host,name)]} {
205 set host [host_info name]
213 set compiler_type "ada"
214 if {[board_info $dest exists adaflags]} {
215 append add_flags " [target_info adaflags]"
217 if {[board_info $dest exists gnatmake]} {
218 set compiler [target_info gnatmake]
220 set compiler [find_gnatmake]
225 set compiler_type "c++"
226 if {[board_info $dest exists cxxflags]} {
227 append add_flags " [target_info cxxflags]"
229 append add_flags " [g++_include_flags]"
230 if {[board_info $dest exists c++compiler]} {
231 set compiler [target_info c++compiler]
233 set compiler [find_g++]
238 set compiler_type "d"
239 if {[board_info $dest exists dflags]} {
240 append add_flags " [target_info dflags]"
242 if {[board_info $dest exists dcompiler]} {
243 set compiler [target_info dcompiler]
245 set compiler [find_gdc]
250 set compiler_type "f90"
251 if {[board_info $dest exists f90flags]} {
252 append add_flags " [target_info f90flags]"
254 if {[board_info $dest exists f90compiler]} {
255 set compiler [target_info f90compiler]
257 set compiler [find_gfortran]
262 set compiler_type "go"
263 if {[board_info $dest exists goflags]} {
264 append add_flags " [target_info goflags]"
266 if {[board_info $dest exists gocompiler]} {
267 set compiler [target_info gocompiler]
269 set compiler [find_go]
271 if {[board_info $dest exists golinker]} {
272 set linker [target_info golinker]
274 set linker [find_go_linker]
276 if {[board_info $dest exists golinker_opts_order]} {
277 set linker_opts_order [target_info golinker_opts_order]
281 if { $i == "rust" } {
282 set compiler_type "rust"
283 if {[board_info $dest exists rustflags]} {
284 append add_flags " [target_info rustflags]"
286 if {[board_info $dest exists rustflags]} {
287 set compiler [target_info rustflags]
289 set compiler [find_rustc]
293 if {[regexp "^dest=" $i]} {
294 regsub "^dest=" $i "" tmp
295 if {[board_info $tmp exists name]} {
296 set dest [board_info $tmp name]
301 if {[regexp "^compiler=" $i]} {
302 regsub "^compiler=" $i "" tmp
305 if {[regexp "^early_flags=" $i]} {
306 regsub "^early_flags=" $i "" tmp
307 append early_flags " $tmp"
309 if {[regexp "^additional_flags=" $i]} {
310 regsub "^additional_flags=" $i "" tmp
311 append add_flags " $tmp"
313 if {[regexp "^ldflags=" $i]} {
314 regsub "^ldflags=" $i "" tmp
315 append ldflags " $tmp"
317 if {[regexp "^libs=" $i]} {
318 regsub "^libs=" $i "" tmp
321 if {[regexp "^incdir=" $i]} {
322 regsub "^incdir=" $i "-I" tmp
323 append add_flags " $tmp"
325 if {[regexp "^libdir=" $i]} {
326 regsub "^libdir=" $i "-L" tmp
327 append add_flags " $tmp"
329 if {[regexp "^ldscript=" $i]} {
330 regsub "^ldscript=" $i "" ldscript
332 if {[regexp "^redirect=" $i]} {
333 regsub "^redirect=" $i "" redirect
335 if {[regexp "^optimize=" $i]} {
336 regsub "^optimize=" $i "" optimize
338 if {[regexp "^timeout=" $i]} {
339 regsub "^timeout=" $i "" timeout
343 if {[board_info $host exists cflags_for_target]} {
344 append add_flags " [board_info $host cflags_for_target]"
348 global CXX_FOR_TARGET
350 global F90_FOR_TARGET
351 global GNATMAKE_FOR_TARGET
353 global GO_LD_FOR_TARGET
354 global RUSTC_FOR_TARGET
356 if {[info exists GNATMAKE_FOR_TARGET]} {
357 if { $compiler_type == "ada" } {
358 set compiler $GNATMAKE_FOR_TARGET
362 if {[info exists CC_FOR_TARGET]} {
363 if { $compiler == "" } {
364 set compiler $CC_FOR_TARGET
368 if {[info exists CXX_FOR_TARGET]} {
369 if { $compiler_type == "c++" } {
370 set compiler $CXX_FOR_TARGET
374 if {[info exists D_FOR_TARGET]} {
375 if { $compiler_type == "d" } {
376 set compiler $D_FOR_TARGET
380 if {[info exists F90_FOR_TARGET]} {
381 if { $compiler_type == "f90" } {
382 set compiler $F90_FOR_TARGET
386 if { $compiler_type == "go" } {
387 if {[info exists GO_FOR_TARGET]} {
388 set compiler $GO_FOR_TARGET
390 if {[info exists GO_LD_FOR_TARGET]} {
391 set linker $GO_LD_FOR_TARGET
395 if {[info exists RUSTC_FOR_TARGET]} {
396 if {$compiler_type == "rust"} {
397 set compiler $RUSTC_FOR_TARGET
401 if { $type == "executable" && $linker != "" } {
405 if { $compiler == "" } {
406 if { [board_info $dest exists compiler] } {
407 set compiler [board_info $dest compiler]
408 } elseif { $compiler_type eq "c" } {
409 set compiler [find_gcc]
411 if { $compiler == "" } {
412 return "default_target_compile: No compiler to compile with"
416 if {![is_remote host]} {
417 if { [which $compiler] == 0 } {
418 return "default_target_compile: Can't find $compiler."
422 if {$type == "object"} {
423 if {$compiler_type == "rust"} {
424 append add_flags "--emit obj"
426 append add_flags " -c"
430 if { $type == "preprocess" } {
431 append add_flags " -E"
434 if { $type == "assembly" } {
435 append add_flags " -S"
438 if {[board_info $dest exists cflags]} {
439 append add_flags " [board_info $dest cflags]"
442 if { $type == "executable" } {
443 if {[board_info $dest exists ldflags]} {
444 append add_flags " [board_info $dest ldflags]"
446 if { $compiler_type == "c++" } {
447 append add_flags " [g++_link_flags]"
451 catch "glob -nocomplain $tool_root_dir/libstdc++/libstdc++.so* $tool_root_dir/libstdc++/libstdc++.sl" tmp
452 if { ${tmp} != "" } {
453 if {[regexp ".*solaris2.*" $target_triplet]} {
455 append add_flags " -R$tool_root_dir/libstdc++"
456 } elseif {[regexp ".*(osf|irix5|linux).*" $target_triplet]} {
458 append add_flags " -Wl,-rpath,$tool_root_dir/libstdc++"
464 if {![info exists ldscript]} {
465 set ldscript [board_info $dest ldscript]
469 if { $i == "debug" } {
470 if {[board_info $dest exists debug_flags]} {
471 append add_flags " [board_info $dest debug_flags]"
473 append add_flags " -g"
478 if {[info exists optimize]} {
479 append add_flags " $optimize"
482 if { $type == "executable" } {
483 append add_flags " $ldflags"
485 if {[file exists $x]} {
488 append add_flags " $x"
492 if {[board_info $dest exists libs]} {
493 append add_flags " [board_info $dest libs]"
496 # This probably isn't such a good idea, but it avoids nasty
497 # hackiness in the testsuites.
498 # The math library must be linked in before the C library. The C
499 # library is linked in by the linker script, so this must be before
501 if {[board_info $dest exists mathlib]} {
502 append add_flags " [board_info $dest mathlib]"
504 append add_flags " -lm"
507 # This must be added here.
508 append add_flags " $ldscript"
510 if {[board_info $dest exists remote_link]} {
512 append add_flags " -Wl,-r"
514 if {[board_info $dest exists output_format]} {
515 append add_flags " -Wl,-oformat,[board_info $dest output_format]"
519 if {[board_info $dest exists multilib_flags]} {
520 append add_flags " [board_info $dest multilib_flags]"
523 verbose "doing compile"
526 if {[is_remote host]} {
528 set file [remote_download host $x]
530 warning "Unable to download $x to host."
531 return "Unable to download $x to host."
533 append sources " $file"
540 if {[is_remote host]} {
541 append add_flags " -o " [file tail $destfile]
542 remote_file host delete [file tail $destfile]
544 if { $destfile != "" } {
545 append add_flags " -o $destfile"
549 # This is obscure: we put SOURCES at the end when building an
550 # object, because otherwise, in some situations, libtool will
551 # become confused about the name of the actual source file.
554 set opts "$early_flags $add_flags $sources"
557 switch $linker_opts_order {
558 "flags-then-sources" {
559 set opts "$early_flags $add_flags $sources"
561 "sources-then-flags" {
562 set opts "$early_flags $sources $add_flags"
565 error "Invalid value for board_info linker_opts_order"
570 set opts "$early_flags $sources $add_flags"
574 if {[is_remote host]} {
575 if {[host_info exists use_at]} {
576 set fid [open "atfile" "w"]
579 set opts "@[remote_download host atfile]"
580 remote_file build delete atfile
584 verbose "Invoking the compiler as $compiler $opts" 2
586 if {[info exists redirect]} {
587 verbose "Redirecting output to $redirect" 2
588 set status [remote_exec host "$compiler $opts" "" "" $redirect]
590 if {[info exists timeout]} {
591 verbose "Setting timeout to $timeout" 2
592 set status [remote_exec host "$compiler $opts" "" "" "" $timeout]
594 set status [remote_exec host "$compiler $opts"]
598 set compiler_flags $opts
599 if {[is_remote host]} {
600 remote_upload host [file tail $destfile] $destfile
601 remote_file host delete [file tail $destfile]
603 set comp_output [prune_warnings [lindex $status 1]]
604 regsub "^\[\r\n\]+" $comp_output "" comp_output
605 if { [lindex $status 0] != 0 } {
606 verbose -log "compiler exited with status [lindex $status 0]"
608 if { [lindex $status 1] != "" } {
609 verbose -log "output is:\n[lindex $status 1]" 2
611 if { [lindex $status 0] != 0 && "${comp_output}" == "" } {
612 set comp_output "exit status is [lindex $status 0]"
614 return ${comp_output}
617 # If dejagnu's default_target_compile supports the language specified in
618 # OPTIONS, use it. Otherwise, use gdb_default_target_compile_1.
619 proc gdb_default_target_compile {source destfile type options} {
620 global use_gdb_compile
622 set need_local_lang 0
623 set need_local_early_flags 0
626 if { $i == "ada" || $i == "d" || $i == "go" || $i == "rust" } {
627 set need_local_lang [info exists use_gdb_compile($i)]
631 set need_local_lang 0
635 set need_local_lang [info exists use_gdb_compile(fortran)]
638 if { [regexp "^early_flags=" $i] } {
639 set need_local_early_flags 1
643 if { $need_local_lang || $need_local_early_flags } {
644 return [gdb_default_target_compile_1 $source $destfile $type $options]
647 return [dejagnu_default_target_compile $source $destfile $type $options]
650 # Array of languages for which dejagnu's default_target_compile is missing
652 array set use_gdb_compile [list]
654 # Note missing support in dejagnu's default_target_compile. This
655 # needs to be fixed by porting the missing support to Dejagnu.
656 set note_prefix "Dejagnu's default_target_compile is missing support for "
657 set note_suffix ", using local override"
659 if {[info procs find_gnatmake] == ""} {
660 rename gdb_find_gnatmake find_gnatmake
661 set use_gdb_compile(ada) 1
662 gdb_note [join [list $note_prefix "Ada" $note_suffix] ""]
665 if {[info procs find_gfortran] == ""} {
666 rename gdb_find_gfortran find_gfortran
667 set use_gdb_compile(fortran) 1
668 gdb_note [join [list $note_prefix "Fortran" $note_suffix] ""]
671 if {[info procs find_go_linker] == ""} {
672 rename gdb_find_go find_go
673 rename gdb_find_go_linker find_go_linker
674 set use_gdb_compile(go) 1
675 gdb_note [join [list $note_prefix "Go" $note_suffix] ""]
678 if {[info procs find_gdc] == ""} {
679 rename gdb_find_gdc find_gdc
680 set use_gdb_compile(d) 1
681 gdb_note [join [list $note_prefix "D" $note_suffix] ""]
684 if {[info procs find_rustc] == ""} {
685 rename gdb_find_rustc find_rustc
686 set use_gdb_compile(rust) 1
687 gdb_note [join [list $note_prefix "Rust" $note_suffix] ""]
690 # If dejagnu's default_target_compile is missing support for any language,
692 if { [array size use_gdb_compile] != 0 } {
693 catch {rename default_target_compile dejagnu_default_target_compile}
694 rename gdb_default_target_compile default_target_compile
698 # Provide 'lreverse' missing in Tcl before 7.5.
700 if {[info procs lreverse] == ""} {
701 proc lreverse { arg } {
703 while { [llength $retval] < [llength $arg] } {
704 lappend retval [lindex $arg end-[llength $retval]]
710 # Various ccache versions provide incorrect debug info such as ignoring
711 # different current directory, breaking GDB testsuite.
712 set env(CCACHE_DISABLE) 1
713 unset -nocomplain env(CCACHE_NODISABLE)