Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCC-13/14 bottle not working with newer MacOSX SDKs #194778

Closed
4 tasks done
anddebol opened this issue Oct 17, 2024 · 20 comments
Closed
4 tasks done

GCC-13/14 bottle not working with newer MacOSX SDKs #194778

anddebol opened this issue Oct 17, 2024 · 20 comments
Labels
needs response Needs a response from the issue/PR author

Comments

@anddebol
Copy link

brew gist-logs <formula> link OR brew config AND brew doctor output

No logs.

Verification

  • My brew doctor output says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update and am still able to reproduce my issue.
  • I have resolved all warnings from brew doctor and that did not fix my problem.
  • I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.

What were you trying to do (and why)?

Updating CLT to 16 will break gcc includes

What happened (include all command output)?

since latest gcc bottle is not built vs. CLT 16.0 it compiling with it will produce stdio.h errors similar to this issue (similar issue)

What did you expect to happen?

Bottle is updated to use (https://github.com/iains/gcc-14-branch/releases/tag/gcc-14.2-darwin-r2)

Step-by-step reproduction instructions (by running brew commands)

(assuming you have MacOSX15.sdk as current)
any c++ code which includes stdio.h
@anddebol anddebol added the bug Reproducible Homebrew/homebrew-core bug label Oct 17, 2024
@carlocab
Copy link
Member

carlocab commented Oct 17, 2024

Works for me:

❯ cat <<C | gcc-14 --sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk -xc - -o test
#include <stdio.h>
int main(void) {
  printf("test\n");
  return 0;
}
C

❯ ./test
test

That said, passing --sysroot above was redundant:

❯ gcc-14 -v '-###' 2>&1 | tr ' ' '\n' | rg sysroot
--with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk

What's the output of your brew config and brew doctor?

@carlocab carlocab added needs response Needs a response from the issue/PR author and removed bug Reproducible Homebrew/homebrew-core bug labels Oct 17, 2024
@Bo98
Copy link
Member

Bo98 commented Oct 17, 2024

r2 release only just came out. We will update GCC 14 to use it soon and build a macOS 15 bottle.

GCC 13 is probably further away, but patches could probably be applied without too much work. GCC 12 and earlier is harder.

@saschasc
Copy link
Contributor

saschasc commented Oct 17, 2024

@Bo98 Is somewhere described how the patch file can be created? I was testing/helping Iains and it would be easier for me to adapt the Homebrew recipe. Right now I was hacking/adapting several locations in my project such that the path, etc. were right.

This said, there are some important fixes (e.g. iains/gcc-14-branch#12) in r2 and I am looking forward for an updated official gcc bottle.

@saschasc
Copy link
Contributor

@anddebol Which OS are you running the tests?

@Bo98
Copy link
Member

Bo98 commented Oct 17, 2024

@Bo98 Is somewhere described how the patch file can be created?

@fxcoudert might have the command. On a basic level it's a diff between gcc-14.2-darwin-r* and releases/gcc-14.2.0 with I think markdown files and certain testsuite-only commits removed to slim down the diff. Will need to check with FX exactly how it's constructed, but the overall result is not functionally different than a direct gcc-14.2-darwin-r* tarball.

We use diffs because we also ship for Linux and only want to apply the changes to macOS at this time.

@fxcoudert
Copy link
Member

Also importantly, we will need to rebuild the new bottles when CI machines have been updated to latest Xcode on each macOS version.

The diff file is as @Bo98 explained: I remove some readme files, testsuite changes, and other things that are irrelevant to homebrew (to keep the size minimal).

@anddebol
Copy link
Author

@carlocab

Works for me:

It doesn't work (stdio errors) for me with --sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk (which is now is default on my system)
it does work with --sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk though

Maybe it is Intel and not AppleSilicon issue?

What's the output of your brew config and brew doctor?

brew config:

brew config
HOMEBREW_VERSION: 4.4.1-46-g1fdbc6f
ORIGIN: https://github.com/Homebrew/brew
HEAD: 1fdbc6fe5a1e3700aea3ac1d167c90a19782a2b8
Last commit: 66 minutes ago
Core tap HEAD: 3a67f18a7e886c897298971adef3990c08669f75
Core tap last commit: 80 minutes ago
Core tap JSON: 17 Oct 16:00 UTC
Core cask tap HEAD: 37788e070ae3e8091770c46515ff64b86043468a
Core cask tap last commit: 61 minutes ago
Core cask tap JSON: 17 Oct 16:00 UTC
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.pv9EdHLio6/org.xquartz:0
HOMEBREW_MAKE_JOBS: 16
HOMEBREW_SORBET_RUNTIME: set
Homebrew Ruby: 3.3.5 => /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.5/bin/ruby
CPU: 16-core 64-bit kabylake
Clang: 16.0.0 build 1600
Git: 2.47.0 => /usr/local/bin/git
Curl: 8.7.1 => /usr/bin/curl
macOS: 14.7-x86_64
CLT: 16.0.0.0.1.1724870825
Xcode: 16.0

brew doctor:

Your system is ready to brew.

@fxcoudert
Copy link
Member

fxcoudert commented Oct 17, 2024

GCC does not guarantee compatibility between major macOS SDK versions. You need to use the SDK that it was built against. Other configurations are (sadly) not always working, because Apple introduces incompatible changes in their SDK headers.

Homebrew builds each GCC against the SDK headers for that macOS version. So on macOS 14 you will need to use the macOS 14 SDKs.

@fxcoudert
Copy link
Member

Updating to latest patch release in #194797

But the root cause remains this:

GCC does not guarantee compatibility between major macOS SDK versions

We try and do as best we can, but it does not always work.

@anddebol
Copy link
Author

Thanks, @fxcoudert!

@saschasc
Copy link
Contributor

@anddebol I assume you are still running on macOS Sonoma? When you install the Command Line Tools 16 it actually adds two folders: MacOSX14.x.sdk and MacOSX15.y.sdk. I was also not aware of this, but when compiling on macOS Sonoma you need to explicitly pass the correct sysroot folder.

@Bo98
Copy link
Member

Bo98 commented Oct 17, 2024

GCC (or at least the way we build it) should default to the SDK it was built against so you shouldn't need to explicitly set the SDK as long as you have the Command Line Tools installed.

If you are building GCC itself from source yourself, then yes you should provide --with-sysroot correctly. We set /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk on macOS 14. The built GCC will use this as a default for --sysroot and you should stick with that default.

@saschasc
Copy link
Contributor

@Bo98 You are right. I still have an issue, but this doesn't seem to be gcc related, but eventually CMake and/or Conan related. When I've installed both XCT 15 and 16 on macOS Sonoma it seems that the sysroot gets overridden somehow and I must explicitly set the SDKROOT variable to the correct path.

Why does e.g. the following command on macOS 14 show to the macOS 15.x SDK and not the 14.x SDK directory?

~ % xcrun -sdk macosx --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX15.1.sdk

@carlocab
Copy link
Member

Could be a CMake bug. Try passing

-DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/MacOSX14.sdk

to CMake.

As for what xcrun is doing, I suggest trying

unset DEVELOPER_DIR SDKROOT
xcrun --kill-cache

and see if that helps.

@Bo98
Copy link
Member

Bo98 commented Oct 18, 2024

For CMake, the default is it chooses the latest SDK, so either set the SDKROOT or -DCMAKE_OSX_SYSROOT.

The correct SDK can be subjective so tools using the latest aren't necessarily wrong - but can be risky for certain use cases. If you are writing in Swift using only Apple Frameworks and not low-level APIs, the latest SDK is often desirable and the best choice as it supports availability attributes, gives errors on APIs that Apple have decided they want to stop using even on older macOS (e.g. in macOS 15 they obsoleted the old screen sharing API and really don't want you to use it anymore even on macOS 14) and it allows you to do things like if #available(OSX 15.0, *) { to enable new macOS 15 features. The moment however you touch low-level APIs, this is very harmful. If you use libcurl from a newer SDK, there's a chance your program may crash at runtime if you do compile-time feature/version checking.

This is sort of why Xcode.app only ships with the macOS 15 SDK, but the Command Line Tools ships with both macOS 14 SDK and macOS 15 SDK. If you're developing in Xcode.app, you're probably making a macOS app. For everything else, you're probably aware of the command line anyway.

For Homebrew, we always use the host SDK for everything except for software written in Swift and other software that only works with the full Xcode.app (e.g. things using xcodebuild) where we use the latest SDK. If in doubt, the SDK matching the running OS is the safest option.

xcrun is unfortunately very confusing. First of all, it depends on xcode-select -p which for many is Xcode.app. You need to set DEVELOPER_DIR=/Library/Developer/CommandLineTools for CLT SDKs to be picked.

Secondly, xcrun with and without --sdk macosx changes behaviour.

  • --sdk macosx will select the latest SDK.
  • Omitting it and just doing xcrun --show-sdk-path will select the system/host SDK, or the latest SDK if it cannot find the system SDK.

However, the behaviour of selecting the system/host SDK is broken when it comes to minor versions. The latest SDK for macOS 14 is 14.5, but the latest OS version for macOS 14 is 14.7. If you run 14.7, xcrun --show-sdk-path will try to find MacOSX14.7.sdk before giving up and returning the latest SDK instead. This is obviously totally incorrect.

What about libxcselect's xcselect_host_sdk_path (https://developer.apple.com/documentation/xcselect/xcselect_host_sdk_path?language=objc)? Don't even bother. The host selection still only checks for SDKs starting with MacOSX10.

TLDR: don't bother trying to get it to work and just do /Library/Developer/CommandLineTools/SDKs/MacOSX$(sw_vers -productVersion | cut -d'.' -f1).sdk, potentially falling back to xcrun/libxcselect if the CLT isn't installed and using a newer SDK is acceptable for your use case.

If you're embedding the SDK into a build (e.g. you are building GCC itself), the CLT's MacOSX14.sdk symlink is beneficial over MacOSX14.5.sdk anyway as it's stable across minor versions.

@carlocab
Copy link
Member

What about libxcselect's xcselect_host_sdk_path (developer.apple.com/documentation/xcselect/xcselect_host_sdk_path?language=objc)? Don't even bother. The host selection still only checks for SDKs starting with MacOSX10.

They might have finally fixed this...

❯ cat <<'C' | clang -xc - -lxcselect -o test; ./test
#include <xcselect.h>
#include <stdio.h>
int main(void) {
    char *path = NULL;
    xcselect_host_sdk_path(XCSELECT_HOST_SDK_POLICY_MATCHING_PREFERRED, &path);
    printf("%s\n", path);
    return 0;
}
C
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk

@Bo98
Copy link
Member

Bo98 commented Oct 18, 2024

Haven't checked macOS 15, so will be nice if they have.

You want to check XCSELECT_HOST_SDK_POLICY_MATCHING_ONLY however. PREFERRED will fallback to latest (which has always worked) so is inconclusive what it's doing in your case.

@carlocab
Copy link
Member

❯ cat <<'C' | /usr/bin/clang -xc - -lxcselect -o test; ./test
#include <xcselect.h>
#include <stdio.h>
int main(void) {
    char *path = NULL;
    xcselect_host_sdk_path(XCSELECT_HOST_SDK_POLICY_MATCHING_ONLY, &path);
    printf("%s\n", path);
    return 0;
}
C
/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk

But I didn't check the return value of xcselect_host_sdk_path so this may just well be UB.

@anddebol
Copy link
Author

I assume you are still running on macOS Sonoma?

@saschasc yes. I figured to use proper systemroot for CMAKE, thanks for the help @Bo98 and @carlocab
Was totally unaware of any of this since I mostly use CLion.

@anddebol
Copy link
Author

I also experience some bugs with ldd (not linking shared hdf5_hl and netcdf properly), and a bit afraid to update to Sequoia now. Can the miss match of OS/SDK version be also a culprit, and I actually need to update the OS? What would be and a safer option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs response Needs a response from the issue/PR author
Projects
None yet
Development

No branches or pull requests

5 participants