This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Danny Smith wrote: > > Pedro Alves > Tuesday, 19 December 2006 12:47 a.m. >> >>Danny Smith wrote: >> >> >>>Could you add a test for symlinks (on cygwin), eg where >> >> >> >>I've added tests for symlinks. Should I guard them for MinGW? How? >>The symlink functionality comes from the host not from the target. >>Using msys or 'gcc -mno-cygwin' should work, no? >> > > > Mingw-hosted ld.exe (whether in msys env or built with -mno-cygwin, > depends on MS msvcrt.dll, > which has not a clue about cygwin symlinks. Cygwin-hosted ld.exe depends > on cygwin1.dll so does recognize symlinks. > >
I understand that. What I was missing, was the fact that you probably are using cygwin to drive dejagnu, but building with --host=i686-pc-mingw32. Well, I tried doing the same and this is what I came up with.
First, I tried puting c:/MinGW first on the PATH, and then building with configure --host=i686-pc-mingw32 --target=i686-pc-mingw32. That has the problem that absolute paths won't match between cygwin and MinGW, so I came up with the scripts in the attached cygming_wrappers.tar.gz. They are wrappers around gcc, g++, gas and ld, which will do the path translation using cygpath. Works pretty well, but to run the testsuite, we would need the mingw.exp --host_board file attached. It was only after doing this, that I realized that MinGW understands the /mingw path, so if I do a /mingw mount on cygwin, the paths will match in both environments. Next, I put the binutils sources under /mingw/src, and I don't need the scripts anymore. :) Talk about overengineering. :) Well, the scripts are still useful, me thinks, because they allow me to build MinGW stuff even when the sources are not under /mingw. It is just for the testsuite that they become a nuisance. So, I attached them anyway since someone may find them useful. (Of course, they are a proof of concept, so don't expect them to be complete, or even fully correct. But, they did build binutils. )
I now see the problem you where seing. Cygwin's ln -s puts a symlink under tmpdir/ld, but the mingw/msvcrt ld doesn't understand it. To me this sounds clearly as a "if I do this, then it breaks. Then don't" do it!" case. I solved it in two ways. One without any changes to binutils whatsoever, and another one with a testsuite patch.
- The first solution was to devise an "ln" wrapper script, that filters out "-s | --symlink" and converts a symlink request into a hardlink, which resolves to a copy on Windows. This makes cygwin's ln look like msys ln. This works pretty well, and doesn't need any change in binutils, but it is awkward to have to remember to put that script on the PATH.
- The second solution is to change a bit the testsuite to detect when we are building a mingw target under cygwin. That is implemented in the diff attached. I only implemented it in ld, but if this is wanted I can provide patches for the rest of the testsuites.
What do you guys think? Both versions of the "ln -s" fix look ugly, but I would rather go the with the testsuite fix.
Cheers, Pedro Alves
Attachment:
cygming_wrappers.tar.gz
Description: application/gzip
#!/bin/bash # # A wrapper for calling stripping the -s and --symlink options from ln invocations. # Author: Pedro Alves <pedro_alves@portugalmail.pt> # Version: 0.01 # ME="`basename $0`" EXEC_CMD="/usr/bin/ln" #exec -a "$ME" "$EXEC_CMD" "$@" echo "------------------------------------------------------------------------------" TARGET="" LINK_NAME="" ARGS="" while [ -n "$1" ]; do arg="$1" shift case "$arg" in -s | --sy*) continue ;; --*s*) ;; -*s*) arg=`echo ${arg} | sed s/s//g` ;; -*) ;; *) if [ "x$TARGET" = "x" ]; then TARGET=$arg elif [ "x$LINK_NAME" = "x" ]; then LINK_NAME=$arg fi continue ;; esac ARGS="$ARGS '$arg'" done if [ "x$TARGET" != "x" ] && [ "x$LINK_NAME" != "x" ]; then DIR=`dirname $LINK_NAME` TARGET=$DIR/$TARGET fi eval "set -- $ARGS $TARGET $LINK_NAME" echo "$EXEC_CMD" "$@" exec -a "$ME" "$EXEC_CMD" "$@"
Index: ld/testsuite/config/default.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/config/default.exp,v retrieving revision 1.11 diff -u -p -r1.11 default.exp --- ld/testsuite/config/default.exp 27 May 2005 17:27:03 -0000 1.11 +++ ld/testsuite/config/default.exp 21 Dec 2006 12:43:33 -0000 @@ -51,12 +51,37 @@ if {![file isdirectory tmpdir]} then { catch "exec mkdir tmpdir" status } +# +# ld_symlink +# ln -s wrapper +# +proc ld_symlink { target link_name up_result } { + upvar 1 $up_result result + set uname "unknown" + catch "exec uname -o " uname + + if { [string match $uname "Cygwin"] && [istarget *-pc-mingw*] } { + # If a relative path was passed, we must adjust + # target, since in symlinks they are relative to link_name, + # while in cp, they are relative to $pwd + if { [string first "/" $target] != 0 } { + set dirname [file dirname $link_name] + if { [string compare $dirname ""] != 0 } { + set target "$dirname/$target" + } + } + catch "exec cp $target $link_name" result + } else { + catch "exec ln -s $target $link_name " result + } +} + # Make a symlink from tmpdir/as to the assembler in the build tree, so # that we can use a -B option to gcc to force it to use the newly # built assembler. if {![file isdirectory tmpdir/gas]} then { catch "exec mkdir tmpdir/gas" status - catch "exec ln -s ../../../gas/as-new tmpdir/gas/as" status + ld_symlink "../../../gas/as-new" "tmpdir/gas/as" status } set gcc_gas_flag "-B[pwd]/tmpdir/gas/" @@ -65,7 +90,9 @@ set gcc_gas_flag "-B[pwd]/tmpdir/gas/" # built linker. if {![file isdirectory tmpdir/ld]} then { catch "exec mkdir tmpdir/ld" status - catch "exec ln -s ../../ld-new tmpdir/ld/ld" status + verbose "calling ld_symlink "../../ld-new" "tmpdir/ld/ld"" + ld_symlink "../../ld-new" "tmpdir/ld/ld" status + verbose "status=$status" } set gcc_ld_flag "-B[pwd]/tmpdir/ld/" @@ -209,7 +236,7 @@ proc ld_nm { nm nmflags object } { # # ld_exec -# execute ithe target +# execute the target # proc ld_exec { target output } { default_ld_exec $target $output Index: ld/testsuite/ld-pe/direct.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-pe/direct.exp,v retrieving revision 1.1 diff -u -p -r1.1 direct.exp --- ld/testsuite/ld-pe/direct.exp 19 Dec 2006 01:51:02 -0000 1.1 +++ ld/testsuite/ld-pe/direct.exp 21 Dec 2006 11:58:19 -0000 @@ -97,7 +97,8 @@ proc test_direct_link_dll {} { # Check dll direct linking through symlink to .dll. # Create symbolic link. - catch "exec ln -fs direct_dll.dll $tmpdir/libdirect_dll.dll.a" ln_catch + catch "exec rm -f $tmpdir/libdirect_dll.dll.a" ln_catch + ld_symlink direct_dll.dll $tmpdir/libdirect_dll.dll.a ln_catch set msg "linking client (symlink -> .dll)" if [ld_simple_link $CC $tmpdir/direct_client_symlink_dll.exe "$tmpdir/direct_client.o $tmpdir/libdirect_dll.dll.a" ] { pass $msg @@ -107,7 +108,8 @@ proc test_direct_link_dll {} { # Check dll direct linking through symlink to .sl. # Create symbolic link. - catch "exec ln -fs direct_dll.sl $tmpdir/libdirect_sl.dll.a" ln_catch + catch "exec rm -f $tmpdir/libdirect_sl.dll.a" ln_catch + ld_symlink direct_dll.sl $tmpdir/libdirect_sl.dll.a ln_catch set msg "linking client (symlink -> .sl)" if [ld_simple_link $CC $tmpdir/direct_client_symlink_sl.exe "$tmpdir/direct_client.o $tmpdir/libdirect_sl.dll.a" ] { pass $msg
# The canonical unix board description. load_generic_config "unix"; process_multilib_options ""; set_board_info compiler "[find_gcc]"; set_board_info bmk,use_alarm 1; set_board_info gdb,noinferiorio 1; set_board_info use_cygpath 1; #Need a way to auto-detect which testsuite is running #so the set AS* below always work... #These are needed for the gas testsuite set AS_NEW [findfile $base_dir/../as-new "../as-new" [transform as]] set AS "as-new $AS_NEW"; #These are needed for the ld testsuite #set as_new [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]] set as_new $base_dir/../gas/as-new set as "as-new $as_new"; set AS "as-new $as_new"; set ld_new [findfile $base_dir/ld-new $base_dir/ld-new [transform ld]] set ld "ld-new $ld_new"; set LD "ld-new $ld_new"; set_board_info ldflags "-Wl,--enable-auto-import" send_user "configuring for mingw testing\n";
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |