diff options
Diffstat (limited to 'lib/libgloss.exp')
-rw-r--r-- | lib/libgloss.exp | 843 |
1 files changed, 843 insertions, 0 deletions
diff --git a/lib/libgloss.exp b/lib/libgloss.exp new file mode 100644 index 0000000..8c5bf87 --- /dev/null +++ b/lib/libgloss.exp @@ -0,0 +1,843 @@ +# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-dejagnu@prep.ai.mit.edu + +# This file was written by Rob Savoye. (rob@cygnus.com) + +# 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 [is_remote 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 + } + 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 == "" } { + return "" + } + if [file exists $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 [is_remote host] { + return "" + } + + set ld_script_path [lookfor_file ${tool_root_dir} "ld/ldscripts"]; + if { $ld_script_path != "" } { + set result "-L[file dirname $ld_script_path]" + } else { + set result "" + } + + set gccpath "[get_multilibs]" + + verbose "Looking for $gccpath/newlib" + if [file exists $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 [is_remote host] { + return "" + } + + set gccpath "[get_multilibs]" + + if [file exists $gccpath/newlib] { + verbose "Newlib path is $gccpath/newlib" + + set newlib_dir [lookfor_file ${srcdir} newlib/libc/include/assert.h] + if { ${newlib_dir} != "" } { + set newlib_dir [file dirname ${newlib_dir}] + } + return " -I$gccpath/newlib/targ-include -I${newlib_dir}" + } else { + verbose "No newlib support for this target" + } +} + +proc libio_include_flags { args } { + global srcdir + global tool_root_dir + + if [is_remote host] { + return "" + } + + set gccpath "[get_multilibs]" + + if { $gccpath == "" } { + 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 == "" } { + set libio_bin_dir [lookfor_file ${gccpath} libio/iostream.list]; + } + + set libio_src_dir [lookfor_file ${srcdir} libio/Makefile.in] + if { $libio_bin_dir != "" && $libio_src_dir != "" } { + set libio_src_dir [file dirname ${libio_src_dir}] + set libio_bin_dir [file dirname ${libio_bin_dir}]; + return " -I${libio_src_dir} -I${libio_bin_dir}" + } else { + return "" + } +} + +proc libio_link_flags { args } { + if [is_remote host] { + return "" + } + + set gccpath "[get_multilibs]" + + set libio_dir [lookfor_file ${gccpath} libio/libio.a] + if { $libio_dir != "" } { + return "-L[file dirname ${libio_dir}]" + } else { + return "" + } +} + +proc g++_include_flags { args } { + global srcdir + + if [is_remote host] { + return "" + } + + set gccpath [get_multilibs] + set libio_dir "" + set flags "" + + set dir [lookfor_file ${srcdir} libg++] + if { ${dir} != "" } { + append flags "-I${dir} -I${dir}/src " + } + set dir [lookfor_file ${srcdir} libstdc++] + if { ${dir} != "" } { + 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 != "" } { + if [file exists "${gccpath}/lib/libstdc++.a"] { + append ld_library_path ":${gccpath}/lib" + } + if [file exists "${gccpath}/libg++/libg++.a"] { + append flags "-L${gccpath}/libg++ " + append ld_library_path ":${gccpath}/libg++" + } + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags "-L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags "-L${gccpath}/librx " + } + } else { + global tool_root_dir; + + set libgpp [lookfor_file ${tool_root_dir} libg++]; + if { $libgpp != "" } { + append flags "-L${libgpp} "; + append ld_library_path ":${libgpp}" + } + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++]; + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} "; + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty]; + if { $libiberty != "" } { + append flags "-L${libiberty} "; + } + set librx [lookfor_file ${tool_root_dir} librx]; + if { $librx != "" } { + append flags "-L${librx} "; + } + } + return "$flags" +} + +proc libstdc++_include_flags { args } { + global srcdir + + if [is_remote host] { + return "" + } + + set gccpath [get_multilibs] + set libio_dir "" + set flags "" + + set dir [lookfor_file ${srcdir} libstdc++] + if { ${dir} != "" } { + 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 != "" } { + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags "-L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags "-L${gccpath}/librx " + } + } else { + global tool_root_dir; + + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++]; + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} "; + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty]; + if { $libiberty != "" } { + append flags "-L${libiberty} "; + } + set librx [lookfor_file ${tool_root_dir} librx]; + if { $librx != "" } { + 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 [is_remote 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 == "" } { + return ""; + } + + foreach x "$compiler" { + if [regexp "^-B" "$x"] { + regsub "^-B" "$x" "" comp_base_dir; + set comp_base_dir [file dirname $comp_base_dir]; + break; + } + } + 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 "" + } + } + + regsub "^-" $mopts "" moptions + regsub -all " -" $moptions " " dirty_moptions + set moptions "" + foreach x [split $dirty_moptions " "] { + if { $x != "" && [lsearch -exact $moptions $x] < 0 } { + lappend moptions $x + } + } + + regexp "/.* " $compiler compiler + set compiler [string trimright $compiler " "] + verbose "compiler is $compiler" + + if { [which $compiler] == 0 } { + return ""; + } + + 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]]]]]]; + } + + # set output [exec $objdump_name --file-headers objfmtst.o ] + 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 != ""} { + set i [string trimright $i $extra"] + } + 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 }" + } + + # 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:" == "[lindex $lines $i]"} { + set multimatches [lindex $lines [expr $i + 1]] + break + } + } + # if we find some + if {$multimatches != ""} { + # 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 + } + + # search for the top level multilib directory + set multitop [lookfor_file "${comp_base_dir}" "${target_alias}"] + if { $multitop == "" } { + set multitop [lookfor_file "${comp_base_dir}" "libraries"] + if { $multitop == "" } { + set multitop "[lookfor_file ${comp_base_dir} gcc/xgcc]" + if { $multitop != "" } { + set multitop [file dirname [file dirname $multitop]]; + } else { + return "" + } + } + } + + # 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 $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 ![is_remote host] { + + set file [lookfor_file $tool_root_dir $name]; + if { $file == "" } { + set file [lookfor_file $tool_root_dir ${name}-new]; + } + if { $file == "" } { + set file [lookfor_file $tool_root_dir binutils/$name]; + } + if { $file == "" } { + set file [lookfor_file $tool_root_dir binutils/${name}-new]; + } + if { $file != "" } { + set NAME "$file"; + } else { + set NAME [transform $name]; + } + } else { + set NAME [transform $name] + } + return $NAME; +} + +proc find_gcc {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir xgcc]; + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/xgcc]; + } + if { $file != "" } { + 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 ![is_remote host] { + set file [lookfor_file $tool_root_dir gcj]; + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/gcj]; + } + if { $file != "" } { + 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 ![is_remote host] { + set file [lookfor_file $tool_root_dir g++]; + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/g++]; + } + if { $file != "" } { + set CC "$file -B[file dirname $file]/"; + } else { + set CC [transform g++]; + } + } else { + set CC [transform g++] + } + return $CC; +} + +proc find_g77 {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir g77]; + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/g77]; + } + if { $file != "" } { + set CC "$file -B[file dirname $file]/"; + } else { + set CC [transform g77]; + } + } else { + set CC [transform g77] + } + return $CC; +} + +proc find_nm {} { + global tool_root_dir + + set NM "" + if ![is_remote host] { + set NM [lookfor_file $tool_root_dir nm-new] + if {$NM == ""} { + set NM [lookfor_file $tool_root_dir binutils/nm-new] + } + } + if { $NM == ""} { + 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 == "" } { + continue; + } + case $x in { + { 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 ![is_remote host] { + set AS [lookfor_file $tool_root_dir as-new]; + if { $AS == "" } { + set AS [lookfor_file $tool_root_dir gas/as-new]; + } + } + if { $AS == "" } { + set AS [transform as]; + } + return $AS; +} + +proc find_ld { } { + global tool_root_dir + + set LD "" + + if ![is_remote host] { + set LD [lookfor_file $tool_root_dir ld-new]; + if { $LD == "" } { + set LD [lookfor_file $tool_root_dir ld/ld-new]; + } + } + if { $LD == "" } { + set LD [transform ld]; + } + return $LD; +} + +proc build_wrapper { gluefile } { + global libdir + + 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,_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,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] == "" } { + set gluefile [remote_download host ${gluefile} testglue.o]; + return [list $gluefile $result]; + } else { + return "" + } +} + + +proc winsup_include_flags { args } { + global srcdir + + if [isnative] { + return "" + } + + if [is_remote host] { + return "" + } + + set gccpath "[get_multilibs]" + + if [file exists $gccpath/winsup] { + verbose "Winsup path is $gccpath/winsup" + + set winsup_dir [lookfor_file ${srcdir} winsup/include/windows.h] + if { ${winsup_dir} != "" } { + set winsup_dir [file dirname ${winsup_dir}] + 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 [is_remote host] { + return "" + } + + set gccpath "[get_multilibs]" + + verbose "Looking for $gccpath/winsup" + if [file exists $gccpath/winsup] { + verbose "Winsup path is $gccpath/newlib" + return "-B$gccpath/winsup/ -L$gccpath/winsup" + } else { + verbose "No winsup support for this target" + return "" + } +} |