| # Copyright (C) 1992-2019, 2020 Free Software Foundation, Inc. |
| # |
| # This file is part of DejaGnu. |
| # |
| # DejaGnu is free software; you can redistribute it and/or modify it |
| # under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # DejaGnu is distributed in the hope that it will be useful, but |
| # WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| # General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with DejaGnu; if not, write to the Free Software Foundation, |
| # Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| |
| # This file was written by Rob Savoye <rob@welcomehome.org>. |
| |
| # this contains a list of gcc options and their respective directories. |
| |
| # Find the pieces of libgloss for testing the GNU development tools |
| # needed to link a set of object files into an executable. |
| # This usually means setting the -L and -B paths correctly. |
| # |
| proc libgloss_link_flags { args } { |
| global target_cpu |
| global srcdir |
| |
| # libgloss doesn't work native |
| if {[isnative]} { |
| return "" |
| } |
| |
| # if we're on a remote host, we can't search for the file, so we can only |
| # use an installed compiler, so we don't add any paths here. |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| # map the target_cpu to the proper libgloss directory. unfortunately, these |
| # directory names are hardcoded into libgloss. |
| switch -glob -- $target_cpu { |
| "sparc86x" { |
| set cpu sparc |
| } |
| "sparclite" { |
| set cpu sparc |
| } |
| "sparclet" { |
| set cpu sparc |
| } |
| "sparc64*" { |
| set cpu sparc |
| } |
| "hppa*" { |
| set cpu pa |
| } |
| "mips*" { |
| set cpu mips |
| } |
| "powerpc*" { |
| set cpu rs6000 |
| } |
| "d10v*" { |
| set cpu libnosys |
| } |
| "xscale*" { |
| set cpu arm |
| } |
| "aarch64*" { |
| set cpu aarch64 |
| } |
| default { |
| set cpu $target_cpu |
| } |
| } |
| |
| set gloss_srcdir "" |
| # look for the libgloss srcdir sp we can find the linker scripts |
| set gloss_srcdir [lookfor_file $srcdir libgloss/$cpu] |
| |
| # set the proper paths for gcc if the target subdir exists, else assume we |
| # have no libgloss support for this target. |
| if { $gloss_srcdir eq "" } { |
| return "" |
| } |
| if {[file exists [file join $gccpath libgloss $cpu]]} { |
| verbose "Libgloss path is $gccpath/libgloss/$cpu" 2 |
| return "-B$gccpath/libgloss/$cpu/ -L$gccpath/libgloss/$cpu -L$gloss_srcdir" |
| } else { |
| verbose -log "No libgloss support for this target." 2 |
| return "" |
| } |
| } |
| |
| # There aren't any, but we'll be orthogonal here. |
| # |
| proc libgloss_include_flags { args } { |
| return "" |
| } |
| |
| # Find the newlib libraries in the current source tree. |
| # |
| proc newlib_link_flags { args } { |
| global tool_root_dir |
| |
| # libgloss doesn't work native |
| if {[isnative]} { |
| return "" |
| } |
| |
| # if we're on a remote host, we can't search for the file, so we can only |
| # use an installed compiler, so we don't add any paths here. |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set ld_script_path [lookfor_file $tool_root_dir "ld/ldscripts"] |
| if { $ld_script_path ne "" } { |
| set result "-L[file dirname $ld_script_path]" |
| } else { |
| set result "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| verbose "Looking for $gccpath/newlib" |
| if {[file exists [file join $gccpath newlib]]} { |
| verbose "Newlib path is $gccpath/newlib" |
| return "$result -B$gccpath/newlib/ -L$gccpath/newlib" |
| } else { |
| verbose "No newlib support for this target" |
| return $result |
| } |
| } |
| |
| proc newlib_include_flags { args } { |
| global srcdir |
| |
| if {[isnative]} { |
| return "" |
| } |
| |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| if {[file exists [file join $gccpath newlib]]} { |
| verbose "Newlib path is $gccpath/newlib" |
| |
| set newlib_dir [lookfor_file $srcdir newlib/libc/include/assert.h] |
| if { $newlib_dir ne "" } { |
| set newlib_dir [file dirname $newlib_dir] |
| } |
| # Note - we use -isystem rather than -I because newlib contains |
| # system header files. This is especially important for the |
| # limits.h header which makes use of the #include_next directive. |
| # #include_next will generate error messages from GCC if compiling |
| # in strict ANSI mode or if another limits.h header cannot be found. |
| # When it is included via -isystem these things do not happen. |
| return " -isystem $gccpath/newlib/targ-include -isystem $newlib_dir" |
| } else { |
| verbose "No newlib support for this target" |
| } |
| } |
| |
| proc libio_include_flags { args } { |
| global srcdir |
| global tool_root_dir |
| |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| if { $gccpath eq "" } { |
| set gccpath $tool_root_dir |
| } |
| |
| set libio_bin_dir [lookfor_file $gccpath libio/_G_config.h] |
| |
| # linux doesn't build _G_config.h and the test above fails, so |
| # we search for iostream.list too. |
| if { $libio_bin_dir eq "" } { |
| set libio_bin_dir [lookfor_file $gccpath libio/iostream.list] |
| } |
| |
| set libio_src_dir [lookfor_file $srcdir libio/Makefile.in] |
| if { $libio_bin_dir ne "" && $libio_src_dir ne "" } { |
| set libio_src_dir [file dirname $libio_src_dir] |
| set libio_bin_dir [file dirname $libio_bin_dir] |
| # Note - unlike the newlib_include_flags proc above we use the -I |
| # switch to specify the include paths. This is because these headers |
| # are not system headers, and if -isystem were to be used GCC would |
| # generate an implicit extern "C" { ... } surrounding them. This |
| # will break targets which do not define NO_IMPLICIT_EXTERN_C. |
| return " -I$libio_src_dir -I$libio_bin_dir" |
| } else { |
| return "" |
| } |
| } |
| |
| proc libio_link_flags { args } { |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| set libio_dir [lookfor_file $gccpath libio/libio.a] |
| if { $libio_dir ne "" } { |
| return "-L[file dirname $libio_dir]" |
| } else { |
| return "" |
| } |
| } |
| |
| proc g++_include_flags { args } { |
| global srcdir |
| global target_alias |
| |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath [get_multilibs] |
| set libio_dir "" |
| set flags "" |
| |
| set dir [lookfor_file $srcdir libg++] |
| if { $dir ne "" } { |
| # See comment in libio_include_flags about using -I. |
| append flags " -I$dir -I$dir/src" |
| } |
| |
| set dir [lookfor_file $srcdir libstdc++-v3] |
| if { $dir ne "" } { |
| append flags " -I$dir/include -I$dir/include/std -I$dir/include/c_std -I$dir/libsupc++" |
| } |
| |
| set dir [lookfor_file $gccpath libstdc++-v3] |
| if { $dir ne "" } { |
| append flags " -I$dir/include -I$dir/include/$target_alias" |
| } |
| |
| set dir [lookfor_file $srcdir libstdc++] |
| if { $dir ne "" } { |
| append flags " -I$dir -I$dir/stl" |
| } |
| |
| return $flags |
| } |
| |
| proc g++_link_flags { args } { |
| global srcdir |
| global ld_library_path |
| |
| set gccpath [get_multilibs] |
| set libio_dir "" |
| set flags "" |
| set ld_library_path "." |
| |
| if { $gccpath ne "" } { |
| if {[file exists [file join $gccpath lib libstdc++.a]]} { |
| append ld_library_path ":$gccpath/lib" |
| } |
| if {[file exists [file join $gccpath libg++ libg++.a]]} { |
| append flags "-L$gccpath/libg++ " |
| append ld_library_path ":$gccpath/libg++" |
| } |
| if {[file exists [file join $gccpath libstdc++ libstdc++.a]]} { |
| append flags "-L$gccpath/libstdc++ " |
| append ld_library_path ":$gccpath/libstdc++" |
| } |
| if {[file exists [file join $gccpath libstdc++-v3 src .libs libstdc++.a]]} { |
| append flags "-L$gccpath/libstdc++-v3/src/.libs " |
| append ld_library_path ":$gccpath/libstdc++-v3/src/.libs" |
| } |
| if {[file exists [file join $gccpath libiberty libiberty.a]]} { |
| append flags "-L$gccpath/libiberty " |
| } |
| if {[file exists [file join $gccpath librx librx.a]]} { |
| append flags "-L$gccpath/librx " |
| } |
| } else { |
| global tool_root_dir |
| |
| set libgpp [lookfor_file $tool_root_dir libg++] |
| if { $libgpp ne "" } { |
| append flags "-L$libgpp " |
| append ld_library_path ":$libgpp" |
| } |
| set libstdcpp [lookfor_file $tool_root_dir libstdc++] |
| if { $libstdcpp ne "" } { |
| append flags "-L$libstdcpp " |
| append ld_library_path ":$libstdcpp" |
| } |
| set libiberty [lookfor_file $tool_root_dir libiberty] |
| if { $libiberty ne "" } { |
| append flags "-L$libiberty " |
| } |
| set librx [lookfor_file $tool_root_dir librx] |
| if { $librx ne "" } { |
| append flags "-L$librx " |
| } |
| } |
| return $flags |
| } |
| |
| proc libstdc++_include_flags { args } { |
| global srcdir |
| global target_alias |
| |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath [get_multilibs] |
| set libio_dir "" |
| set flags "" |
| |
| set dir [lookfor_file $srcdir libstdc++-v3] |
| if { $dir ne "" } { |
| # See comment in libio_include_flags about using -I. |
| append flags " -I$dir/include -I$dir/include/std -I$dir/include/c_std -I$dir/libsupc++" |
| } |
| |
| set gccpath [get_multilibs] |
| |
| set dir [lookfor_file $gccpath libstdc++-v3] |
| if { $dir ne "" } { |
| append flags " -I$dir/include -I$dir/include/$target_alias" |
| } |
| |
| set dir [lookfor_file $srcdir libstdc++] |
| if { $dir ne "" } { |
| append flags " -I$dir -I$dir/stl" |
| } |
| |
| return $flags |
| } |
| |
| proc libstdc++_link_flags { args } { |
| global srcdir |
| global ld_library_path |
| |
| set gccpath [get_multilibs] |
| set libio_dir "" |
| set flags "" |
| |
| if { $gccpath ne "" } { |
| if {[file exists [file join $gccpath libstdc++ libstdc++.a]]} { |
| append flags "-L$gccpath/libstdc++ " |
| append ld_library_path ":$gccpath/libstdc++" |
| } |
| if {[file exists [file join $gccpath libiberty libiberty.a]]} { |
| append flags "-L$gccpath/libiberty " |
| } |
| if {[file exists [file join $gccpath librx librx.a]]} { |
| append flags "-L$gccpath/librx " |
| } |
| } else { |
| global tool_root_dir |
| |
| set libstdcpp [lookfor_file $tool_root_dir libstdc++] |
| if { $libstdcpp ne "" } { |
| append flags "-L$libstdcpp " |
| append ld_library_path ":$libstdcpp" |
| } |
| set libiberty [lookfor_file $tool_root_dir libiberty] |
| if { $libiberty ne "" } { |
| append flags "-L$libiberty " |
| } |
| set librx [lookfor_file $tool_root_dir librx] |
| if { $librx ne "" } { |
| append flags "-L$librx " |
| } |
| } |
| return $flags |
| } |
| |
| # Get the list of directories and -m options for gcc. This is kinda bogus that |
| # generic testing software needs support for gcc hardwired in, but to make |
| # testing the GNU tools work right, there didn't seem to be any other way. |
| # |
| proc get_multilibs { args } { |
| global target_alias |
| global board |
| global board_info |
| |
| # if we're on a remote host, we can't search for the file, so we can only |
| # use an installed compiler, so we don't add any paths here. |
| if {[isremote host]} { |
| return "" |
| } |
| |
| if {[info exists board]} { |
| set target_board $board |
| } else { |
| set target_board [target_info name] |
| } |
| |
| if { [llength $args] == 0 } { |
| if {[board_info $target_board exists multitop]} { |
| return "[board_info $target_board multitop]" |
| } |
| |
| set board_info($target_board,multitop) "" |
| } |
| |
| if { [board_info $target_board exists compiler] } { |
| set compiler [board_info $target_board compiler] |
| } else { |
| set compiler [find_gcc] |
| } |
| |
| if { $compiler eq "" } { |
| return "" |
| } |
| |
| foreach x $compiler { |
| if {[regexp "^-B" $x]} { |
| regsub "^-B" $x "" comp_base_dir |
| set comp_base_dir [file dirname $comp_base_dir] |
| break |
| } |
| } |
| |
| regexp "/.* " $compiler compiler |
| set compiler [string trimright $compiler " "] |
| verbose "compiler is $compiler" |
| |
| if { [which $compiler] == 0 } { |
| return "" |
| } |
| |
| if { [llength $args] > 0 } { |
| set mopts [lindex $args 0] |
| } else { |
| if { [board_info $target_board exists multilib_flags] } { |
| set mopts [board_info $target_board multilib_flags] |
| } else { |
| set mopts "" |
| } |
| } |
| |
| set default_multilib [exec $compiler --print-multi-lib] |
| set default_multilib [lindex $default_multilib 0] |
| set extra [string trimleft $default_multilib ".;@@"] |
| |
| # extract the options and their directory names as know by gcc |
| foreach i "[exec $compiler --print-multi-lib]" { |
| if {$extra ne ""} { |
| # string trimright would do the wrong thing if we included |
| # the leading @@ in $extra |
| set i [string trimright $i $extra] |
| set i [string trimright $i "@@"] |
| } |
| set opts "" |
| set dir "" |
| regexp -- "\[a-z0-9=/\.-\]*;" $i dir |
| set dir [string trimright $dir "\;@"] |
| regexp -- "\;@*\[\@a-zA-Z0-9=/\.-\]*" $i opts |
| set opts [split [string trimleft $opts "\;@@"] "@@"] |
| lappend multilibs "$dir {$opts }" |
| |
| # If args contains arguments don't use the first one as |
| # multilib option unless it qualifies as a multilib option. |
| if { [llength $args] > 0 } { |
| set override_opt [lindex $args 0] |
| foreach j $opts { |
| if {$j == $override_opt} { |
| set mopts $override_opt |
| } |
| } |
| } |
| } |
| |
| regsub "^-" $mopts "" moptions |
| regsub -all " -" $moptions " " dirty_moptions |
| set moptions "" |
| foreach x [split $dirty_moptions " "] { |
| if { $x ne "" && [lsearch -exact $moptions $x] < 0 } { |
| lappend moptions $x |
| } |
| } |
| |
| if {![info exists comp_base_dir]} { |
| set comp_base_dir [file dirname [file dirname [file dirname [file dirname [file dirname [exec $compiler --print-prog-name=cc1]]]]]] |
| } |
| |
| # search for the top level multilib directory |
| set multitop [lookfor_file $comp_base_dir $target_alias] |
| if { $multitop eq "" } { |
| set multitop [lookfor_file $comp_base_dir "libraries"] |
| if { $multitop eq "" } { |
| set multitop "[lookfor_file $comp_base_dir gcc/xgcc]" |
| if { $multitop ne "" } { |
| set multitop [file dirname [file dirname $multitop]] |
| } else { |
| return "" |
| } |
| } |
| } |
| |
| set gccpath [eval exec $compiler --print-multi-directory $mopts] |
| set gccpath [lindex $gccpath 0] |
| if { $gccpath ne "" } { |
| verbose "GCC path is $gccpath" |
| if { [llength $args] == 0 } { |
| set board_info($target_board,multitop) $multitop/$gccpath |
| } |
| return $multitop/$gccpath |
| } |
| |
| # extract the MULTILIB_MATCHES from dumpspecs |
| set multimatches "" |
| set lines [split [exec $compiler -dumpspecs] "\n"] |
| for {set i 0} {$i <= [llength $lines] - 1} {incr i 1} { |
| if {"*multilib_matches:" eq "[lindex $lines $i]"} { |
| set multimatches [lindex $lines [expr {$i + 1}]] |
| break |
| } |
| } |
| # if we find some |
| if {$multimatches ne ""} { |
| # Split it into a list of pairs. If an moptions are the first |
| # of a pair, then replace it with the second. If an moption |
| # is not in multimatches, we assume it's not a multilib option |
| |
| set splitmatches [split $multimatches ";"] |
| set multimatches "" |
| foreach i $splitmatches { |
| lappend multimatches [split $i " "] |
| } |
| verbose "multimatches: $multimatches" 3 |
| |
| verbose "options before multimatches: $moptions" 3 |
| set toptions $moptions |
| set moptions "" |
| foreach i $toptions { |
| foreach j $multimatches { |
| verbose "comparing [lindex $j 0] == $i" 3 |
| if {[lindex $j 0] == $i} { |
| lappend moptions [lindex $j 1] |
| } |
| } |
| } |
| verbose "options after multimatches: $moptions" 3 |
| } |
| |
| # make a list of -m<foo> options from the various compiler config variables |
| set gccpath "" |
| |
| # compare the lists of gcc options with the list of support multilibs |
| verbose "Supported multilibs are: $multilibs" 3 |
| set best 0 |
| foreach i $multilibs { |
| set hits 0 |
| set opts [lindex $i 1] |
| if { [llength $opts] <= [llength $moptions] } { |
| foreach j $moptions { |
| # see if all the -m<foo> options match any of the multilibs |
| verbose "Looking in $i for $j" 3 |
| if { [lsearch -exact $opts $j] >= 0 } { |
| incr hits |
| } |
| } |
| |
| if { $hits > $best } { |
| verbose "[lindex $i 0] is better, using as gcc path" 2 |
| set gccpath "[lindex $i 0]" |
| set best $hits |
| } |
| } |
| } |
| if {![info exists multitop]} { |
| return "" |
| } |
| |
| verbose "gccpath is $gccpath" 3 |
| |
| if {[file exists [file join $multitop $gccpath]]} { |
| verbose "GCC path is $multitop/$gccpath" 3 |
| if { [llength $args] == 0 } { |
| set board_info($target_board,multitop) $multitop/$gccpath |
| } |
| return $multitop/$gccpath |
| } else { |
| verbose "GCC path is $multitop" 3 |
| if { [llength $args] == 0 } { |
| set board_info($target_board,multitop) $multitop |
| } |
| return $multitop |
| } |
| } |
| |
| proc find_binutils_prog { name } { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| |
| set file [lookfor_file $tool_root_dir $name] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir $name-new] |
| } |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir binutils/$name] |
| } |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir binutils/$name-new] |
| } |
| if { $file ne "" } { |
| set NAME $file |
| } else { |
| set NAME [transform $name] |
| } |
| } else { |
| set NAME [transform $name] |
| } |
| return $NAME |
| } |
| |
| proc find_gcc {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir xgcc] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/xgcc] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform gcc] |
| } |
| } else { |
| set CC [transform gcc] |
| } |
| return $CC |
| } |
| |
| proc find_gcj {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir gcj] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/gcj] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform gcj] |
| } |
| } else { |
| set CC [transform gcj] |
| } |
| return $CC |
| } |
| |
| proc find_g++ {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir xg++] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/xg++] |
| } |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir g++] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform g++] |
| } |
| } else { |
| set CC [transform g++] |
| } |
| return $CC |
| } |
| |
| proc find_gdc {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir gdc] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/gdc] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform gdc] |
| } |
| } else { |
| set CC [transform gdc] |
| } |
| return $CC |
| } |
| |
| proc find_g77 {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir g77] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/g77] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform g77] |
| } |
| } else { |
| set CC [transform g77] |
| } |
| return $CC |
| } |
| |
| proc find_gfortran {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir gfortran] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/gfortran] |
| } |
| if { $file ne "" } { |
| set CC "$file -B[file dirname $file]/" |
| } else { |
| set CC [transform gfortran] |
| } |
| } else { |
| set CC [transform gfortran] |
| } |
| return $CC |
| } |
| |
| proc find_gnatmake {} { |
| global tool_root_dir |
| |
| if {![isremote host]} { |
| set file [lookfor_file $tool_root_dir gnatmake] |
| if { $file eq "" } { |
| set file [lookfor_file $tool_root_dir gcc/gnatmake] |
| } |
| if { $file ne "" } { |
| set root [file dirname $file] |
| set CC "$file -I$root/ada/rts --GCC=$root/xgcc --GNATBIND=$root/gnatbind --GNATLINK=$root/gnatlink -cargs -B$root -largs --GCC=$root/xgcc -B$root -margs" |
| } else { |
| set CC [transform gnatmake] |
| } |
| } else { |
| set CC [transform gnatmake] |
| } |
| return $CC |
| } |
| |
| proc find_go {} { |
| global tool_root_dir |
| |
| set GO "" |
| |
| if {![is_remote host]} { |
| set file [lookfor_file $tool_root_dir gccgo] |
| if { $file ne "" } { |
| set root [file dirname $file] |
| set GO "$file -B$root/gcc/" |
| } |
| } |
| |
| if { $GO eq "" } { |
| set GO [transform gccgo] |
| } |
| |
| return $GO |
| } |
| |
| proc find_go_linker {} { |
| return [find_go] |
| } |
| |
| proc find_rustc {} { |
| global tool_root_dir |
| if {![is_remote host]} { |
| set rustc [lookfor_file $tool_root_dir rustc] |
| if {$rustc eq ""} { |
| set rustc rustc |
| } |
| } else { |
| set rustc "" |
| } |
| if {$rustc ne ""} { |
| append rustc " --color never" |
| } |
| return $rustc |
| } |
| |
| proc find_nm {} { |
| global tool_root_dir |
| |
| set NM "" |
| if {![isremote host]} { |
| set NM [lookfor_file $tool_root_dir nm-new] |
| if {$NM eq ""} { |
| set NM [lookfor_file $tool_root_dir binutils/nm-new] |
| } |
| } |
| if { $NM eq ""} { |
| set NM [transform nm] |
| } |
| return $NM |
| } |
| |
| proc process_multilib_options { args } { |
| global board |
| global board_variant_list |
| global is_gdb_remote |
| |
| set is_gdb_remote 0 |
| |
| if {[board_info $board exists multilib_flags]} { |
| return |
| } |
| eval add_multilib_option $args |
| |
| set multilib_flags "" |
| |
| foreach x $board_variant_list { |
| regsub -all "^\[ \t\]*" $x "" x |
| regsub -all "\[ \t\]*$" $x "" x |
| |
| if { $x eq "" } { |
| continue |
| } |
| switch -glob -- $x { |
| "aout" { |
| set_board_info obj_format "a.out" |
| } |
| "elf" { |
| set_board_info obj_format "elf" |
| } |
| "pe" { |
| set_board_info obj_format "pe" |
| } |
| "ecoff" { |
| set_board_info obj_format "ecoff" |
| } |
| "stabs" { |
| set_board_info debug_flags "-gstabs" |
| } |
| "dwarf2" { |
| set_board_info debug_flags "-gdwarf2" |
| } |
| "gdb:*=*" { |
| regsub "^gdb:\[^=\]*=(.*)$" $x "\\1" value |
| regsub "^gdb:(\[^=\]*)=.*$" $x "\\1" variable |
| set_board_info $variable $value |
| } |
| "gdb*remote" { |
| set is_gdb_remote 1 |
| } |
| "little*endian" - |
| "el" - |
| "EL" { |
| append multilib_flags " -EL" |
| } |
| "big*endian" - |
| "eb" - |
| "EB" { |
| append multilib_flags " -EB" |
| } |
| "soft*float" { |
| append multilib_flags " -msoft-float" |
| } |
| "-*" { |
| append multilib_flags " $x" |
| } |
| default { |
| append multilib_flags " -m$x" |
| } |
| } |
| } |
| set_board_info multilib_flags $multilib_flags |
| } |
| |
| proc add_multilib_option { args } { |
| global board_variant_list |
| |
| if {![info exists board_variant_list]} { |
| set board_variant_list "" |
| } |
| set board_variant_list [concat $args $board_variant_list] |
| } |
| |
| proc find_gas { } { |
| global tool_root_dir |
| |
| set AS "" |
| |
| if {![isremote host]} { |
| set AS [lookfor_file $tool_root_dir as-new] |
| if { $AS eq "" } { |
| set AS [lookfor_file $tool_root_dir gas/as-new] |
| } |
| } |
| if { $AS eq "" } { |
| set AS [transform as] |
| } |
| return $AS |
| } |
| |
| proc find_ld { } { |
| global tool_root_dir |
| |
| set LD "" |
| |
| if {![isremote host]} { |
| set LD [lookfor_file $tool_root_dir ld-new] |
| if { $LD eq "" } { |
| set LD [lookfor_file $tool_root_dir ld/ld-new] |
| } |
| } |
| if { $LD eq "" } { |
| set LD [transform ld] |
| } |
| return $LD |
| } |
| |
| proc build_wrapper { gluefile } { |
| global libdir |
| global tool |
| |
| if {[target_info exists wrap_m68k_aout]} { |
| set flags "additional_flags=-DWRAP_M68K_AOUT" |
| set result "" |
| } elseif {[target_info exists uses_underscores]} { |
| set flags "additional_flags=-DUNDERSCORES" |
| set result "-Wl,-wrap,_exit -Wl,-wrap,__exit -Wl,-wrap,_main -Wl,-wrap,_abort" |
| |
| } else { |
| set flags "" |
| if {[target_info exists is_vxworks]} { |
| set flags "additional_flags=-DVXWORKS" |
| set result "-Wl,-wrap,exit -Wl,-wrap,_exit -Wl,-wrap,main -Wl,-wrap,abort" |
| } else { |
| set result "-Wl,-wrap,exit -Wl,-wrap,_exit -Wl,-wrap,main -Wl,-wrap,abort" |
| } |
| } |
| if {[target_info exists wrap_compile_flags]} { |
| lappend flags "additional_flags=[target_info wrap_compile_flags]" |
| } |
| if { [target_compile $libdir/testglue.c $gluefile object $flags] eq "" } { |
| set gluefile [remote_download host $gluefile ${tool}_tg.o] |
| return [list $gluefile $result] |
| } else { |
| return "" |
| } |
| } |
| |
| |
| proc winsup_include_flags { args } { |
| global srcdir |
| |
| if {[isnative]} { |
| return "" |
| } |
| |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| if {[file exists [file join $gccpath winsup]]} { |
| verbose "Winsup path is $gccpath/winsup" |
| |
| set winsup_dir [lookfor_file $srcdir winsup/include/windows.h] |
| if { $winsup_dir ne "" } { |
| set winsup_dir [file dirname $winsup_dir] |
| # See comment in libio_include_flags about using -I. |
| return " -I$winsup_dir" |
| } |
| } |
| verbose "No winsup support for this target" |
| |
| } |
| |
| # Find the winsup libraries in the current source tree. |
| # |
| proc winsup_link_flags { args } { |
| # libgloss doesn't work native |
| if {[isnative]} { |
| return "" |
| } |
| |
| # if we're on a remote host, we can't search for the file, so we can only |
| # use an installed compiler, so we don't add any paths here. |
| if {[isremote host]} { |
| return "" |
| } |
| |
| set gccpath "[get_multilibs]" |
| |
| verbose "Looking for $gccpath/winsup" |
| if {[file exists [file join $gccpath winsup]]} { |
| verbose "Winsup path is $gccpath/newlib" |
| return "-B$gccpath/winsup/ -L$gccpath/winsup" |
| } else { |
| verbose "No winsup support for this target" |
| return "" |
| } |
| } |