Bug 57792 - toplevel configure should enable "--with-sysroot="`xcrun --show-sdk-path`"" for darwin13 and later
Summary: toplevel configure should enable "--with-sysroot="`xcrun --show-sdk-path`"" f...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-03 01:41 UTC by Jack Howarth
Modified: 2014-11-08 14:56 UTC (History)
9 users (show)

See Also:
Host: *-*-darwin13
Target:
Build:
Known to work: 4.8.1, 4.9.0
Known to fail: 4.8.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jack Howarth 2013-07-03 01:41:40 UTC
The removal of the SDK from / (i.e. no /usr/include or /System/Library/Frameworks/*.framework/Headers directories) breaks the fixincludes step of the bootstrap on darwin. The only current workaround appears to be using the "--with-native-system-header-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/usr/include" however this causes -isysroot in the resulting compiler to malfunction so that…

/sw/lib/gcc4.8/bin/gcc-fsf-4.8 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk himenoBMTxpa.c

searches…

ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/usr/include"

Oddly executing the non-sensical…

/sw/lib/gcc4.8/bin/gcc-fsf-4.8 -isysroot / himenoBMTxpa.c 

works because the search path becomes…

/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk/usr/include

I assume no one ever tested --with-native-system-header-dir with -ixysroot before.
Comment 1 Jack Howarth 2013-07-04 15:20:57 UTC
The removal of the SDK from / on darwin exposes a defect in fixincludes. The fixinc.in hardcodes "/usr/include" without any attempt to detect if the bootstrap has been invoked with the "--with-sysroot" configure option. On darwin13, one currently has to hack around this defect with...

perl -pi -e 's|/usr/include|`xcrun --show-sdk-path`/usr/include|g' fixincludes/fixinc.in

before executing…

--prefix=/sw --prefix=/sw/lib/gcc4.8 --mandir=/sw/share/man --infodir=/sw/lib/gcc4.8/info --enable-languages=c,c++,fortran,lto,objc,obj-c++,java --with-gmp=/sw --with-libiconv-prefix=/sw --with-isl=/sw --with-cloog=/sw --with-mpc=/sw --with-system-zlib --enable-checking=release --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib --program-suffix=-fsf-4.8 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk

This bootstraps normally and produces a compiler with a functional -isysroot compiler option (i.e. the directory passed to -isysroot is appended to /).

Some mechanism needs to be added to allow the use of --with-sysroot in the bootstrap to be detected in the fixincludes/fixinc.in shell script and, if
--with-sysroot is in use, the path to the sysroot prefixed to /usr/include at…

# # # # # # # # # # # # # # # # # # # # #
#
#  Search each input directory for broken header files.
#  This loop ends near the end of the file.
#
if test $# -eq 0
then
    INPUTLIST="/usr/include"
else
    INPUTLIST="$@"
fi
Comment 2 Bruce Korb 2013-07-04 16:24:57 UTC
Paolo did the config stuff, with Kaveh's help.
However, Jack Howarth may be in a better position to
make a patch since I do not have an Apple development
system.
Comment 3 Jack Howarth 2013-07-04 17:27:47 UTC
(In reply to Bruce Korb from comment #2)
> Paolo did the config stuff, with Kaveh's help.
> However, Jack Howarth may be in a better position to
> make a patch since I do not have an Apple development
> system.

I would think that we want some permutation of the following code from gcc/configure.ac added to fixincludes/configure.ac…

AC_ARG_WITH(sysroot,
[AS_HELP_STRING([[--with-sysroot[=DIR]]],
                [search for usr/lib, usr/include, et al, within DIR])],
[
 case ${with_sysroot} in
 yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
 *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
 esac
  
 TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
 CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'

 case ${TARGET_SYSTEM_ROOT} in
 "${test_prefix}"|"${test_prefix}/"*|\
 "${test_exec_prefix}"|"${test_exec_prefix}/"*|\
 '${prefix}'|'${prefix}/'*|\
 '${exec_prefix}'|'${exec_prefix}/'*)
   t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
   TARGET_SYSTEM_ROOT_DEFINE="$t"
   ;;
 esac
], [
 TARGET_SYSTEM_ROOT=
 TARGET_SYSTEM_ROOT_DEFINE=
 CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
])
AC_SUBST(TARGET_SYSTEM_ROOT)
AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
AC_SUBST(CROSS_SYSTEM_HEADER_DIR)

as well as associated changes to fixincludes/Makefile.in and fixincludes/fixinc.in to have TARGET_SYSTEM_ROOT passed to and used by the generated fixincludes/fixin shell script. I would be happy to test any proposed fix along those lines (but I am unclear on how complex the additions to fixincludes/configure.ac need to be to handle cross compiles, etc).
Comment 4 Jack Howarth 2013-07-04 23:35:39 UTC
Sorry for the noise. The addition of…

--with-sysroot="`xcrun --show-sdk-path`"

in fact does allow fixincludes to find the buried usr/include. I'm not sure what other option I was passing that prevented that from working before.
   I have switched this PR to an enhancement request for modifying the top level configure.ac to pass…

--with-sysroot="`xcrun --show-sdk-path`"

for darwin13 or later. I am unclear how this can be done considering that the top level configure.ac doesn't mention --with-sysroot. However I am sure we should be passing it down from there to insure that all of the other configure files get that option set.
Comment 5 Jack Howarth 2013-07-05 00:37:00 UTC
I am really surprised the following change if insufficient to replace manually  passing…

--with-sysroot="`xcrun --show-sdk-path`"

to configure on the command line for darwin13...

Index: configure.ac
===================================================================
--- configure.ac        (revision 200683)
+++ configure.ac        (working copy)
@@ -2848,6 +2848,13 @@ if test x${is_cross_compiler} = xyes ; t
   target_configargs="--with-cross-host=${host_noncanonical} ${target_configargs}"
 fi
 
+case "${target}" in
+  x86_64-*-darwin13*)
+    target_configargs="--with-sysroot=\"`xcrun --show-sdk-path`\"  ${target_configargs}"
+    ;;
+esac
+
+
 # Default to --enable-multilib.
 if test x${enable_multilib} = x ; then
   target_configargs="--enable-multilib ${target_configargs}"
Index: configure
===================================================================
--- configure   (revision 200683)
+++ configure   (working copy)
@@ -7414,6 +7414,13 @@ if test x${is_cross_compiler} = xyes ; t
   target_configargs="--with-cross-host=${host_noncanonical} ${target_configargs}"
 fi
 
+case "${target}" in
+  x86_64-*-darwin13*)
+    target_configargs="--with-sysroot=\"`xcrun --show-sdk-path`\"  ${target_configargs}"
+    ;;
+esac
+
+
 # Default to --enable-multilib.
 if test x${enable_multilib} = x ; then
   target_configargs="--enable-multilib ${target_configargs}"


This patch (without explicitly passing --with-sysroot to configure) results in the fixincludes complaining about not finding /usr/include again but the top-level config.log shows target_configargs has --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk on it. Should I be appending "--with-sysroot=\"`xcrun --show-sdk-path`\" to different variable instead?
Comment 6 Jack Howarth 2013-07-05 01:25:14 UTC
(In reply to Jack Howarth from comment #5)

The same change of adding --with-sysroot=\"`xcrun --show-sdk-path`\" to build_configargs also fails when fix_includes tries to find /usr/include. Strangely, adding --with-sysroot=\"`xcrun --show-sdk-path`\" to host_configargs allows fixincludes to find the headers but then dies in stage2 with the cryptic error…

Configuring stage 2 in ./intl
Configuring stage 2 in ./libiberty
Configuring stage 2 in ./libbacktrace
Configuring stage 2 in ./libdecnumber
make[4]: Nothing to be done for `all'.
make[3]: Nothing to be done for `all'.
configure: loading cache ../config.cache
configure: loading cache ../config.cache
configure: loading cache ../config.cache
configure: loading cache ../config.cache
configure: error: `CC' has changed since the previous run:
Comment 7 Jack Howarth 2013-07-05 02:26:55 UTC
(In reply to Jack Howarth from comment #6)
My mistake in mixing host_configargs and build_configargs. The following patch works fine…

Index: configure.ac
===================================================================
--- configure.ac        (revision 200683)
+++ configure.ac        (working copy)
@@ -2848,6 +2848,13 @@ if test x${is_cross_compiler} = xyes ; t
   target_configargs="--with-cross-host=${host_noncanonical} ${target_configargs}"
 fi
 
+# Pass --with-sysroot on darwin without SDK in /
+case "${target}" in
+  x86_64-*-darwin1[[3-9]]*)
+    host_configargs="--with-sysroot=\"`xcrun --show-sdk-path`\"  ${host_configargs}"
+    ;;
+esac
+
 # Default to --enable-multilib.
 if test x${enable_multilib} = x ; then
   target_configargs="--enable-multilib ${target_configargs}"
Comment 8 mrs@gcc.gnu.org 2013-07-10 21:32:41 UTC
Fixed.
Comment 9 Hin-Tak Leung 2014-11-03 22:58:12 UTC
Did the change make it into 4.9.2? I recently tried that
and found that I need the explicit --sysroot:
https://gcc.gnu.org/ml/gcc-testresults/2014-11/msg00268.html

Otherwise it fails during the stage1-fixincludes stage.
(luckily I saw the tips and reference to this bug report
in the older buildstat).
Comment 10 Jack Howarth 2014-11-04 19:59:56 UTC
(In reply to Hin-Tak Leung from comment #9)
> Did the change make it into 4.9.2? I recently tried that
> and found that I need the explicit --sysroot:
> https://gcc.gnu.org/ml/gcc-testresults/2014-11/msg00268.html
> 
> Otherwise it fails during the stage1-fixincludes stage.
> (luckily I saw the tips and reference to this bug report
> in the older buildstat).

This change was reverted when Apple abandoned the idea of removing the /usr/include. They didn't appreciate the number of packages (like python) which would require the changes to also find the new location of the /usr/include.
Comment 11 Jack Howarth 2014-11-04 20:01:46 UTC
(In reply to Hin-Tak Leung from comment #9)
> Did the change make it into 4.9.2? I recently tried that
> and found that I need the explicit --sysroot:
> https://gcc.gnu.org/ml/gcc-testresults/2014-11/msg00268.html
> 

Also, if you can't find /usr/include on OS X, that means you need to install the Command Line Tools with 'xcode-select --install'.
Comment 12 Hin-Tak Leung 2014-11-05 05:40:43 UTC
(In reply to howarth from comment #10)
> This change was reverted when Apple abandoned the idea of removing the
> /usr/include. They didn't appreciate the number of packages (like python)
> which would require the changes to also find the new location of the
> /usr/include.

(In reply to howarth from comment #11)
> Also, if you can't find /usr/include on OS X, that means you need to install
> the Command Line Tools with 'xcode-select --install'.

Have Apple really abandoned the idea of removing /usr/include ? xcode 6.1 ships all the headers under the SDK places; indeed as you said, running 'xcode-select --install' prompts for installing the command line developer's tools, which seems
to install /usr/include ; but the Command Line Developer's Tool installed this way is only version 5.1 (i.e. against an older version of xcode, I think).

Also I think it could be a bit more user friendly - e.g. test for the existence
of /usr/include, and set "--with-sysroot=\"`xcrun --show-sdk-path`\" if /usr/include does not exist? It isn't much more code, but would make a lot of difference in user-friendliness.
Comment 13 Jack Howarth 2014-11-05 13:21:01 UTC
Yes, I am pretty sure Apple has abandoned this for good. They only attempted the change because it was assumed to be completely transparent as the compiler looks in /usr/include by default. It wasn't appreciated that this would cause...

radr://14320107 "/usr/bin/python reports back include directories that are unpopulated"

where removal of /usr/include caused the system Python.h to point to an unpopulated header directory in INCLUDEPY. While I provided them with a patch to sysconfig.py to solve this, there is no stomach at Apple for pushing such changes upstream as other packages like perl that hardcode compiler options will need to be modified as well.
    While we could add this change to FSF gcc, I don't think we want to encourage users not to install the system headers in /usr/include via the Command Line Tools of Xcode as there are other configure scripts out there which will also need to be patched to find /usr/include with `xcrun --show-sdk-path`.
    If we made any change, I would rather it be a check in FSF gcc's configure for the presence of /usr/include on darwin which provided the appropriate error message to the user that the Command Line Tools needs to be installed.
Comment 14 Hin-Tak Leung 2014-11-06 17:52:40 UTC
(In reply to howarth from comment #13)
>
>     If we made any change, I would rather it be a check in FSF gcc's
> configure for the presence of /usr/include on darwin which provided the
> appropriate error message to the user that the Command Line Tools needs to
> be installed.

I don't think mandating Command Line Tools would be a good idea - I think in that case you can have a reverse problem when your intention is to build stuff for other people: you build x intended for others, you have /usr/include but others don't, x made assumptions about the intended users having the same stuff as yours, and it doesn't work on the intended user's machine, or have mysterious errors.
Comment 15 mrs@gcc.gnu.org 2014-11-06 18:01:57 UTC
Mandating commands line tools is fine.  Would be nice if everything worked flawlessly if no optional package had to be installed, but I'm pragmatic.
Comment 16 Iain Sandoe 2014-11-06 18:38:08 UTC
(In reply to mrs@gcc.gnu.org from comment #15)
> Mandating commands line tools is fine.  Would be nice if everything worked
> flawlessly if no optional package had to be installed, but I'm pragmatic.

I'd agree with pragmatism every time.
OTOH, 
(a) it would be nice to have a heads up on the thinking going forward (would have been possible to ask filks last week).

(b) it is apparent that there's a move towards desiring a uniform interface where the {native}host is considered "just another target" with its own SDK.

I kinda like the uniformity too.
Comment 17 Jack Howarth 2014-11-06 18:44:18 UTC
(In reply to Hin-Tak Leung from comment #14)
> (In reply to howarth from comment #13)
> >
> >     If we made any change, I would rather it be a check in FSF gcc's
> > configure for the presence of /usr/include on darwin which provided the
> > appropriate error message to the user that the Command Line Tools needs to
> > be installed.
> 
> I don't think mandating Command Line Tools would be a good idea - I think in
> that case you can have a reverse problem when your intention is to build
> stuff for other people: you build x intended for others, you have
> /usr/include but others don't, x made assumptions about the intended users
> having the same stuff as yours, and it doesn't work on the intended user's
> machine, or have mysterious errors.

You have to remember that Apple expects you to build everything from within the Xcode projects while the Command Line Tools package exists to handle building outside of that mechanism. The unfortunate fact is that far too much software explicitly expects headers in /usr/include to avoid installing the Command Line Tools. In the fink project, we get endless bug reports from users who fail to install the Command Line Tools.
Comment 18 Hin-Tak Leung 2014-11-07 00:41:30 UTC
(In reply to mrs@gcc.gnu.org from comment #15)
> Mandating commands line tools is fine.  Would be nice if everything worked
> flawlessly if no optional package had to be installed, but I'm pragmatic.

The current behavior is definitely wrong: without command line tools and without --with-sysroot (i.e. just plain ./configure), ./configure returns success, but only fail to 'make' towards the end of stage1 when the build system tries to do the 'stage1-fixincludes' target.

./configure should either auto-add the --with-sysroot (as the reverted fix did), or abort with an appropriate message, like the requirement for gmp/mpfr/mpc. successful ./configure then failing part-way through make is bad.

(In reply to howarth from comment #17)
> You have to remember that Apple expects you to build everything from within
> the Xcode projects while the Command Line Tools package exists to handle
> building outside of that mechanism. The unfortunate fact is that far too
> much software explicitly expects headers in /usr/include to avoid installing
> the Command Line Tools. In the fink project, we get endless bug reports from
> users who fail to install the Command Line Tools.

Not really. Actually xcode 6.1 seem to ships all the command line tools. doing 'xcode-select --install' install a much older(?) command line tools plus headers in /usr/include. I don't know if Apple is going to keep that in-sync, but there might be a danger of the headers in /usr/include not really describing the system.

Also, people who DIY are supposed to go through all the troubles... you still haven't addressed the issue of new gcc (+ xcode building it with) may generate stuff that have additional dependencies on /usr/include, if /usr/include is around, and therefore not suitable when one is building things for others.
Comment 19 Jack Howarth 2014-11-07 02:17:34 UTC
(In reply to Hin-Tak Leung from comment #18)
> (In reply to mrs@gcc.gnu.org from comment #15)
> > Mandating commands line tools is fine.  Would be nice if everything worked
> > flawlessly if no optional package had to be installed, but I'm pragmatic.
> 
> The current behavior is definitely wrong: without command line tools and
> without --with-sysroot (i.e. just plain ./configure), ./configure returns
> success, but only fail to 'make' towards the end of stage1 when the build
> system tries to do the 'stage1-fixincludes' target.
> 
> ./configure should either auto-add the --with-sysroot (as the reverted fix
> did), or abort with an appropriate message, like the requirement for
> gmp/mpfr/mpc. successful ./configure then failing part-way through make is
> bad.
> 

The proper test to detect the missing Command Line Tools /usr/include files should be added then.

> (In reply to howarth from comment #17)
> > You have to remember that Apple expects you to build everything from within
> > the Xcode projects while the Command Line Tools package exists to handle
> > building outside of that mechanism. The unfortunate fact is that far too
> > much software explicitly expects headers in /usr/include to avoid installing
> > the Command Line Tools. In the fink project, we get endless bug reports from
> > users who fail to install the Command Line Tools.
> 
> Not really. Actually xcode 6.1 seem to ships all the command line tools.
> doing 'xcode-select --install' install a much older(?) command line tools
> plus headers in /usr/include. I don't know if Apple is going to keep that
> in-sync, but there might be a danger of the headers in /usr/include not
> really describing the system.

You must have caught them before they synced. On my machine, I have synced Xcode.app and Command Line Tools...

% /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -v
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

% /Library/Developer/CommandLineTools/usr/bin/clang -v
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

from 'xcode-select --install'.

> 
> Also, people who DIY are supposed to go through all the troubles... you
> still haven't addressed the issue of new gcc (+ xcode building it with) may
> generate stuff that have additional dependencies on /usr/include, if
> /usr/include is around, and therefore not suitable when one is building
> things for others.

Are you assuming that folks are installing third-party stuff in /usr/include? Since users should be installing only in /usr/local for that, that seems a bit out of bounds here.
Comment 20 Iain Sandoe 2014-11-08 14:52:57 UTC
Unofficially (but after chatting with a couple of folks who know):

"It should be assumed that depending on /usr/{include,lib} is unreliable".

"The RightWay(™) for the system is deemed to be finding a suitable SDK root from "wherever".  Yes, it's recognised that this is somewhat of a pain."

===

IMO we need to have a design that recognises that we (darwin support in GCC) have different objectives from Xcode.

difference: #1 we support N-K (where N == host OS version, and K might be +/- some number > 1).  This means that we want to be able to find SDKs for system versions that might not be included in the "current" Xcode.  I don't like the idea of shoe-horning those (extra SDKs) into Xcode just so that it can find them - although I know folks already do that.

- note that -mmacosx-version-min= and MACOSX_DEPLOYMENT_TARGET can go some way towards achieving part of those objectives - but it won't (for example) let you build for powerpc-darwin9 from x86-86-darwin13 [something I *do* often do].

difference #2 (at least I) have an objective that one day - hopefully not too far away, we will be able to cross-build for darwin ( > 9 ;) ) from other platforms, e.g. Linux.

To that end I think we need a coherent design to cater for GCC's needs.

My initial suggestion is that we don't try to (ab-)use sysroot for this, but instead add a --with-SDK-root= option that may be specified multiple times.  We might eventually need the driver to try and find the best match for the SDK given a User "-mmacosx-version-min" and maybe even (one day) -mmacosx-version-max= ..

This should have fall-backs as follows:

  xcrun … where that's available
  /Developer/SDKs (Darwin <= 9)
  / - essentially 'hope for the best' with /usr/{include,lib}

I think there are adequate hooks in config/darwin-c.c to deal with this without impacting any part of the compiler outside the port [but that's without having tried it].

====

I tend to agree that developers have to be prepared to understand a little about what their doing - but IMO the User of the compiler (someone just trying to build her code) should not have to jump through hoops to achieve that - at least for a host-native compile ;)

I know Mike is not a fan of new C/L options, so I'm open to counter-proposals.