Bug 52122 - [4.7/4.8/4.9 Regression] incorrect ln -s replacement for mingw like targets in configure files
Summary: [4.7/4.8/4.9 Regression] incorrect ln -s replacement for mingw like targets i...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.7.0
: P2 normal
Target Milestone: 4.7.4
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-04 13:24 UTC by Daniel Starke
Modified: 2013-05-13 20:09 UTC (History)
5 users (show)

See Also:
Host: mingw
Target: mingw
Build: mingw
Known to work:
Known to fail: 4.6.3
Last reconfirmed: 2013-02-12 00:00:00


Attachments
possible patch for gcc 4.7.0 (2.28 KB, patch)
2012-04-26 18:06 UTC, Daniel Starke
Details | Diff
Patch for using recursive copy for directories. (465 bytes, patch)
2013-01-16 09:51 UTC, Kai Tietz
Details | Diff
Patch for all needed files for cp -pR (2.95 KB, patch)
2013-02-08 17:28 UTC, Karlson2k
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Starke 2012-02-04 13:24:38 UTC
Taking the current gcc 4.7 trunk revision 183875 (and even older versions like 4.6.x) as well as the libraries used the configure files are set to use "cp -p" as replacement for "ln -s" for mingw targets. This is correct for files but not for directories especially when contianing sub directories. My proposal is to replace it with "cp -pr" to handle recursion. As a result of the current problem ada fails bootstrapping on mingw while trying to copy a folder of header files.

Extract from gcc/configure:
472    as_ln_s='ln -s'
473    # ... but there are two gotchas:
474    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
475    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
476    # In both cases, we have to default to `cp -p'.
477    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
478      as_ln_s='cp -p'

I hope this is the right place for this issue as I am not certain how the configure system is handled.
Comment 1 Richard Biener 2012-04-05 10:55:03 UTC
Please update this bug with respect to the mailing list discussion that took place.
Comment 2 Daniel Starke 2012-04-05 16:14:19 UTC
(In reply to comment #1)
> Please update this bug with respect to the mailing list discussion that took
> place.

Can you please add a link to the mailing list discussion you are referring to?
Comment 3 Richard Biener 2012-04-26 14:06:14 UTC
PR50942 is a duplicate?  Mailinglist discussion: http://gcc.gnu.org/ml/gcc-patches/2012-02/msg00442.html
Comment 4 Daniel Starke 2012-04-26 18:06:54 UTC
Created attachment 27249 [details]
possible patch for gcc 4.7.0
Comment 5 Daniel Starke 2012-04-26 18:07:37 UTC
The mailinglist discussion covers only a part of the problem. I have attached a possible patch for gcc 4.7.0 to highlight to problem.
Comment 6 Tim Van Holder 2012-08-08 21:10:24 UTC
Daniel, your patch modifies the configure scripts, which are generated files - so the effect would be temporary at best.

I don't have a gcc checkout handy (nor high-speed internet), so I can't check this myself right now, but:
- If the configure.ac scripts use autoconf's own AC_LN_S macro, then a bug
  report should be submitted to the autoconf maintainers, and a GCC_LN_S macro
  would probably have to be created with the fix in place (to avoid depending
  on an upstream fix). Of course if autoconf uses all this internally, an
  upstream fix may be the only avenue.
- If a gcc-specific macro is already being used (grep for "ln" or "cp -p" in
  the top-level "config" subdir (*.m4) to get an idea), then just put the
  fix(es) there

Based on the variables seen in your patch it's probably going to be both (as_ln_s is an autoshell (part of autoconf) variable, gcc_cv_prog_LN_S sounds like a GCC-specific one).

Once the macros are added/fixed, whatever script/command regenerates all the gcc configure scripts will propagate those changes automatically (and they will stay present even if a user regenerates a configure script).

Note: I think I see an LN="cp -p" remain untouched in your patch - surely if the "ln -s" replacement needs to support directories, so does the one for plain ln?
Comment 7 Daniel Starke 2012-09-22 16:00:03 UTC
It seems to be partly a gcc autoconfig macro issue. Seeing the following in gcc/acinclude.m4

dnl See if symbolic links work and if not, try to substitute either hard links or simple copy.
AC_DEFUN([gcc_AC_PROG_LN_S],
[AC_MSG_CHECKING(whether ln -s works)
AC_CACHE_VAL(gcc_cv_prog_LN_S,
[rm -f conftestdata_t
echo >conftestdata_f
if ln -s conftestdata_f conftestdata_t 2>/dev/null
then
  gcc_cv_prog_LN_S="ln -s"
else
  if ln conftestdata_f conftestdata_t 2>/dev/null
  then
    gcc_cv_prog_LN_S=ln
  else
    if cp -p conftestdata_f conftestdata_t 2>/dev/null
    then
      gcc_cv_prog_LN_S="cp -p"
    else
      gcc_cv_prog_LN_S=cp
    fi
  fi
fi
rm -f conftestdata_f conftestdata_t
])dnl
LN_S="$gcc_cv_prog_LN_S"
if test "$gcc_cv_prog_LN_S" = "ln -s"; then
  AC_MSG_RESULT(yes)
else
  if test "$gcc_cv_prog_LN_S" = "ln"; then
    AC_MSG_RESULT([no, using ln])
  else
    AC_MSG_RESULT([no, and neither does ln, so using $gcc_cv_prog_LN_S])
  fi
fi
AC_SUBST(LN_S)dnl
])

it is obvious that gcc_cv_prog_LN_S="cp -p" needs to be changed to gcc_cv_prog_LN_S="cp -pr".

On the other hand running autoconfig on this configure.ac:
AC_PREREQ(2.64)
AC_INIT
AC_PROG_LN_S

returns the wrong output as also seen in the patch with:
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -p'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -p'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -p'
  fi
else
  as_ln_s='cp -p'
fi

The part mentioned by Tim Vanholder that was not in the attached patch was certainly just overseen by me as it was not necessary to build gcc.
I have just filed a bug report against autoconf.
Comment 8 Andris Pavenis 2012-09-23 05:56:08 UTC
One also needs

LN_S = cp -pr 

for DJGPP (v 2.0.3 only, current development version supports symlinks)
Comment 9 Daniel Starke 2012-09-24 16:55:33 UTC
The problem in autoconf was fixed with version 2.69. I suggest to update AC_PREREQ within the configure.ac files to this version.
Comment 10 Daniel Starke 2012-09-24 16:57:53 UTC
Here is the reference to the autoconf change:
http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=17ea0df46f819a9b64c21151983a5c5b8561fefb
Comment 11 Jakub Jelinek 2013-01-16 09:08:51 UTC
I'd say it is too late for autoconf update for 4.8 now, if this is about LN_S uses in a single Makefile (are we talking about libada/Makefile.in ? ), you could temporarily use something like
ifeq (cp -p,$(LN_S))
LN_S_RECURSIVE = cp -pR
else
LN_S_RECURSIVE = $(LN_S)
endif
(or even limit it to targets known to support cp -pR well that don't have ln -s)
and use $(LN_S_RECURSIVE) in
        $(LN_S) $(ADA_RTS_DIR) adainclude
        $(LN_S) $(ADA_RTS_DIR) adalib
(2x) instead $(LN_S).  Then for 4.9 we can upgrade autoconf requirements and revert this.
Comment 12 Kai Tietz 2013-01-16 09:51:45 UTC
Created attachment 29176 [details]
Patch for using recursive copy for directories.

AFAIU we are talking about libada only here.  I agree that it is too late for an libtool update for 4.8 gcc.

As suggested the changeLog for libada/

        * Makefile.in (LN_S_RECUSIVE): New.
        (adainclude, adalib): Use LN_S_RECURSIVE for copy.

As soon as libtool got updated this patch can be removed.
Comment 13 Karlson2k 2013-02-08 17:28:03 UTC
Created attachment 29398 [details]
Patch for all needed files for cp -pR
Comment 14 Karlson2k 2013-02-09 15:03:24 UTC
Reconfirming this problem for GCC 4.7.2

Configured with:
../../source/gcc-4.7.2/configure --build=i686-pc-mingw32 --host=i686-pc-mingw32 --target=i686-w64-mingw32 --disable-nls --disable-multilib --prefix=/home/xxx/mingw-w64/mingw-w64-i686 --with-sysroot=/home/xxx/mingw-w64/mingw-w64-i686 --with-native-system-header-dir=/i686-w64-mingw32/include --with-host-libstdcxx=/mingw/lib/gcc/mingw32/4.7.2/libstdc++.a --disable-cloog-version-check --disable-ppl-version-check --with-mpc=/home/xxx/mingw-w64/packages/gcc/packages/mpc/mpc-1.0.1-i686 --with-mpfr=/home/xxx/mingw-w64/packages/gcc/packages/mpfr/mpfr-3.1.1-i686 --with-gmp=/home/xxx/mingw-w64/packages/gcc/packages/gmp/gmp-5.1.0-i686 --with-ppl=/home/xxx/mingw-w64/packages/gcc/packages/ppl/ppl-1.0-i686 --with-isl=/home/xxx/mingw-w64/packages/gcc/packages/isl/isl-0.11.1-i686 --with-cloog=/home/xxx/mingw-w64/packages/gcc/packages/cloog-ppl/cloog-ppl-0.15.11-i686 --enable-languages=ada,c,c++ --enable-threads=win32 --enable-fully-dynamic-string --disable-sjlj-exceptions --with-multilib-list=m32 --with-arch=pentium3 --enable-leading-mingw64-underscores --with-dwarf2 --enable-lto --disable-win32-registry --with-win32-nlsapi=unicode --enable-libstdcxx-debug

Failed at:
rm -rf adainclude
rm -rf adalib
cp -p ../.././gcc/ada/rts adainclude
cp: omitting directory `../.././gcc/ada/rts'
make[1]: *** [gnatlib-plain] Error 1
make[1]: Leaving directory `/home/xxx/mingw-w64/packages/gcc/build/4.7.2-i686-w64-mingw32/i686-w64-mingw32/libada'
make: *** [all-target-libada] Error 2
Comment 15 Kai Tietz 2013-02-12 15:32:15 UTC
Author: ktietz
Date: Tue Feb 12 15:32:01 2013
New Revision: 195980

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195980
Log:
        PR target/52122
        * Makefile.in (LN_S_RECUSIVE): New.
        (adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    trunk/libada/ChangeLog
    trunk/libada/Makefile.in
Comment 16 Kai Tietz 2013-02-12 15:37:09 UTC
Author: ktietz
Date: Tue Feb 12 15:36:56 2013
New Revision: 195981

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195981
Log:
        PR target/52122
        * Makefile.in (LN_S_RECUSIVE): New.
        (adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    branches/gcc-4_7-branch/libada/ChangeLog
    branches/gcc-4_7-branch/libada/Makefile.in
Comment 17 Kai Tietz 2013-02-12 15:39:07 UTC
Author: ktietz
Date: Tue Feb 12 15:38:57 2013
New Revision: 195982

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195982
Log:
        PR target/52122
        * Makefile.in (LN_S_RECUSIVE): New.
        (adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    branches/gcc-4_6-branch/libada/ChangeLog
    branches/gcc-4_6-branch/libada/Makefile.in
Comment 18 Kai Tietz 2013-02-12 15:44:07 UTC
So required patch is applied to 4.6 branch , 4.7 branch, and trunk.  Issue is fixed.  As reminder I will keep this bug in status waiting, so we don't miss to remove this patch as soon as libtool got updated.
Comment 19 Dominique d'Humieres 2013-02-12 17:51:13 UTC
This breaks bootstrap on x86_64-apple-darwin10:

...

test -f stamp-libada || \
	make -C ../.././gcc/ada "MAKEOVERRIDES=" "LDFLAGS=" "LN_S=ln -s" "SHELL=/bin/sh" "GNATLIBFLAGS=-W -Wall -gnatpg -nostdinc " "GNATLIBCFLAGS=-g -O2 " "GNATLIBCFLAGS_FOR_C=-W -Wall -g -O2 -fexceptions -DIN_RTS -DHAVE_GETIPINFO " "PICFLAG_FOR_TARGET=-fno-common" "THREAD_KIND=native" "TRACE=no" "MULTISUBDIR=" "libsubdir=/opt/gcc/gcc4.8w/lib/gcc/x86_64-apple-darwin10.8.0/4.8.0" "objext=.o" "prefix=/opt/gcc/gcc4.8w" "exeext=.exeext.should.not.be.used " 'CC=the.host.compiler.should.not.be.needed' "GCC_FOR_TARGET=/opt/gcc/build_w/./gcc/xgcc -B/opt/gcc/build_w/./gcc/ -B/opt/gcc/gcc4.8w/x86_64-apple-darwin10.8.0/bin/ -B/opt/gcc/gcc4.8w/x86_64-apple-darwin10.8.0/lib/ -isystem /opt/gcc/gcc4.8w/x86_64-apple-darwin10.8.0/include -isystem /opt/gcc/gcc4.8w/x86_64-apple-darwin10.8.0/sys-include   " "CFLAGS=-g -O2" gnatlib-shared \
	&& touch stamp-libada
rm -rf adainclude
rm -rf adalib
../.././gcc/ada/rts adainclude
make[2]: ../.././gcc/ada/rts: Permission denied
make[2]: *** [gnatlib-shared] Error 1
make[1]: *** [all-target-libada] Error 2
make: *** [all] Error 2
Comment 20 Kai Tietz 2013-02-12 18:02:56 UTC
Hmm,

why is NS_RECURSIVE for you an empty?  It should become either cp -pR, or be equal to content of LN_S.
Comment 21 Kai Tietz 2013-02-12 18:04:53 UTC
"LN_S_RECURSIVE" I mean.
Comment 22 Dominique d'Humieres 2013-02-12 18:07:16 UTC
> why is NS_RECURSIVE for you an empty?  It should become either cp -pR, or be
> equal to content of LN_S.

No idea. For a successfull bootstrap I see

..
rm -rf adainclude
rm -rf adalib
mv -f .deps/minloc0_8_i4.Tpo .deps/minloc0_8_i4.Plo
ln -s ../.././gcc/ada/rts adainclude
...
Comment 23 Karlson2k 2013-02-12 18:11:09 UTC
Try to use LN_S_RECURSIVE:= instead of LN_S_RECURSIVE=
Comment 24 Jakub Jelinek 2013-02-12 18:41:37 UTC
Can you please try the following?
echo > Makefile <<\EOF
LN_S=cp -p
ifeq (cp -p,$(LN_S))
LN_S_RECURSIVE=cp -pr
else
LN_S_RECURSIVE=$(LN_S)
endif
all:
	echo $(LN_S_RECURSIVE)
EOF
make; make LN_S='ln -s'; make LN_S='cp -p'
sed 's/LN_S=cp -p/LN_S=ln -s/' Makefile
make; make LN_S='ln -s'; make LN_S='cp -p'
Works for me just fine.  Perhaps you have buggy make?
Comment 25 Dominique d'Humieres 2013-02-12 19:14:45 UTC
> Can you please try the following?
> ...
> Works for me just fine.  Perhaps you have buggy make?

Is this working?

[macbook] f90/bug% cat Makefile
LN_S=cp -p
ifeq (cp -p,$(LN_S))
LN_S_RECURSIVE=cp -pr
else
LN_S_RECURSIVE=$(LN_S)
endif
all:
	echo $(LN_S_RECURSIVE)
[macbook] f90/bug% make
echo cp -pr
cp -pr
[macbook] f90/bug% make LN_S='ln -s'
echo ln -s
ln -s
[macbook] f90/bug% make LN_S='cp -p'
echo cp -pr
cp -pr

[macbook] f90/bug% cat Makefile
LN_S=ln -s
ifeq (cp -p,$(LN_S))
LN_S_RECURSIVE=cp -pr
else
LN_S_RECURSIVE=$(LN_S)
endif
all:
	echo $(LN_S_RECURSIVE)
[macbook] f90/bug% make
echo ln -s
ln -s
[macbook] f90/bug% make LN_S='ln -s'
echo ln -s
ln -s
[macbook] f90/bug% make LN_S='cp -p'
echo cp -pr
cp -pr
Comment 26 Jakub Jelinek 2013-02-12 19:49:34 UTC
Yes.  Then I have no idea why it doesn't work for you during bootstrap.
Stick some echo ln_s $(LN_S) ln_s_recursive $(LN_S_RECURSIVE) into the targets
that use $(LN_S_RECURSIVE), before they use it?
Comment 27 Dominique d'Humieres 2013-02-12 20:16:29 UTC
(In reply to comment #23)
> Try to use LN_S_RECURSIVE:= instead of LN_S_RECURSIVE=

As in

--- ../_clean/libada/Makefile.in	2013-02-12 16:45:25.000000000 +0100
+++ libada/Makefile.in	2013-02-12 19:16:14.000000000 +0100
@@ -44,9 +44,9 @@ LN_S=@LN_S@
 AWK=@AWK@
 
 ifeq (cp -p,$(LN_S))
-LN_S_RECURSIVE = cp -pR
+LN_S_RECURSIVE := cp -pR
 else
-LN_S_RECURSIVE = $(LN_S)
+LN_S_RECURSIVE := $(LN_S)
 endif
 
 # Variables for the user (or the top level) to override.

? If yes, it does not work.
Comment 28 Tom de Vries 2013-02-13 09:53:07 UTC
I seem to be running into the same problem as described in comment 19, while doing a x86_64-unknown-linux-gnu non-bootstrap build:
...
../.././gcc/ada/rts adainclude
checking for C compiler default output file name... /bin/bash: ../.././gcc/ada/rts: Is a directory
make[2]: *** [gnatlib-shared] Error 126
make[2]: Leaving directory `ref-13-02-13/nobootstrap/build/x86_64-unknown-linux-gnu/libada'
make[1]: *** [all-target-libada] Error 2
...
Comment 29 Kai Tietz 2013-02-13 10:03:41 UTC
I reverted patch.  But still have no idea what was actual going wrong here.
Comment 30 Tom de Vries 2013-02-13 10:06:11 UTC
This will probably fix it:
...
Index: Makefile.in
===================================================================
--- Makefile.in (revision 195997)
+++ Makefile.in (working copy)
@@ -115,8 +115,8 @@
	&& touch stamp-libada
	-rm -rf adainclude
	-rm -rf adalib
-       $(LN_S_RECUSIVE) $(ADA_RTS_DIR) adainclude
-       $(LN_S_RECUSIVE) $(ADA_RTS_DIR) adalib
+       $(LN_S_RECURSIVE) $(ADA_RTS_DIR) adainclude
+       $(LN_S_RECURSIVE) $(ADA_RTS_DIR) adalib

 osconstool:
	$(MAKE) -C $(GCC_DIR)/ada $(LIBADA_FLAGS_TO_PASS) ./bldtools/oscons/xoscons
...
Comment 31 Jakub Jelinek 2013-02-13 10:09:02 UTC
(In reply to comment #30)
> --- Makefile.in (revision 195997)
> +++ Makefile.in (working copy)
> @@ -115,8 +115,8 @@
>     && touch stamp-libada
>     -rm -rf adainclude
>     -rm -rf adalib
> -       $(LN_S_RECUSIVE) $(ADA_RTS_DIR) adainclude
> -       $(LN_S_RECUSIVE) $(ADA_RTS_DIR) adalib
> +       $(LN_S_RECURSIVE) $(ADA_RTS_DIR) adainclude
> +       $(LN_S_RECURSIVE) $(ADA_RTS_DIR) adalib
> 
>  osconstool:
>     $(MAKE) -C $(GCC_DIR)/ada $(LIBADA_FLAGS_TO_PASS) ./bldtools/oscons/xoscons
> ...

Please install as obvious.
Comment 32 Kai Tietz 2013-02-13 10:19:35 UTC
Author: ktietz
Date: Wed Feb 13 10:19:26 2013
New Revision: 196002

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196002
Log:
PR target/52122
* Makefile.in (LN_S_RECUSIVE): New.
(adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    trunk/libada/ChangeLog
    trunk/libada/Makefile.in
Comment 33 Kai Tietz 2013-02-13 10:20:49 UTC
Author: ktietz
Date: Wed Feb 13 10:20:30 2013
New Revision: 196003

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196003
Log:
PR target/52122
* Makefile.in (LN_S_RECUSIVE): New.
(adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    branches/gcc-4_7-branch/libada/ChangeLog
    branches/gcc-4_7-branch/libada/Makefile.in
Comment 34 Kai Tietz 2013-02-13 10:21:35 UTC
Author: ktietz
Date: Wed Feb 13 10:21:25 2013
New Revision: 196004

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196004
Log:
PR target/52122
* Makefile.in (LN_S_RECUSIVE): New.
(adainclude, adalib): Use LN_S_RECURSIVE for copy.

Modified:
    branches/gcc-4_6-branch/libada/ChangeLog
    branches/gcc-4_6-branch/libada/Makefile.in
Comment 35 Tom de Vries 2013-02-13 10:25:21 UTC
Kai,

> * Makefile.in (LN_S_RECUSIVE): New.

please fix up the log messages.

Thanks,
- Tom
Comment 36 Andris Pavenis 2013-02-14 04:25:17 UTC
This way does not work for DJGPP v2.03 (version v2.04pre is OK).

For DJGPP v2.03:

AC_PROG_LN_S tries 'ln -s', which do not work, after that it falls back to simple
'ln' which creates copy of file (acts as 'cp'). As the result we'll getting LN_S=ln in Makefile

Correct way should be detecting whether ln -s works for directories in configure script and adding corresponding substitution for Makefile.in for LN_S_RECURSIVE like

LN_S_RECURSIVE=@LN_S_RECURSIVE@

Tests could look like:
- create directory and file in the it
- try to create symlink to directory and look whether it succeeds
- check for presence of the file through symlink

Less pedantic way could be avoiding using file in subdirectory and relaying on success of 'ln -s' only.
Comment 37 Jakub Jelinek 2013-04-12 15:17:05 UTC
GCC 4.6.4 has been released and the branch has been closed.
Comment 38 Kai Tietz 2013-05-13 20:09:11 UTC
Due 4.6 is closed, and bug was fixed for 4.7 and upward, I close this bug.  Please report issue for DJGPP as separate bug, if problem still exists.