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

Fix regular macOS build by passing -isysroot to compiler so correct system headers are found #21339

Merged
merged 1 commit into from
Nov 20, 2018

Conversation

alcroito
Copy link
Contributor

Hi.

I tried building master branch of Godot, and failed due to a compilation issue.
Here is the invocation and error message:

$ scons platform=osx target=release_debug verbose=true

Initial build] clang -o platform/osx/os_osx.osx.opt.tools.64.o -c -g1 -O2 -DDEBUG_ENABLED -arch x86_64 -w -Werror=return-type -DZSTD_STATIC_LINKING_ONLY -DFT2_BUILD_LIBRARY -DZLIB_DEBUG -DFREETYPE_ENABLED -DFT_CONFIG_OPTION_USE_PNG -DSVG_ENABLED -DOSX_ENABLED -DUNIX_ENABLED -DGLES_ENABLED -DAPPLE_STYLE_KEYS -DCOREAUDIO_ENABLED -DCOREMIDI_ENABLED -mmacosx-version-min=10.9 -DGLAD_ENABLED -DGLES_OVER_GL -DPTRCALL_ENABLED -DTOOLS_ENABLED -DGDSCRIPT_ENABLED -DMINIZIP_ENABLED -DXML_ENABLED -Icore -Icore/math -Ieditor -Idrivers -I. -Iplatform/osx -Ithirdparty/zstd -Ithirdparty/zstd/common -Ithirdparty/zlib -Ithirdparty/glad -Ithirdparty/freetype -Ithirdparty/freetype/include -Ithirdparty/libpng -Ithirdparty/nanosvg platform/osx/os_osx.mm

platform/osx/os_osx.mm:1421:41: error: use of undeclared identifier 'NSAppKitVersionNumber10_12'; did you mean 'NSAppKitVersionNumber'?
                                if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) {
                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                    NSAppKitVersionNumber
/System/Library/Frameworks/AppKit.framework/Headers/NSApplication.h:26:28: note: 'NSAppKitVersionNumber' declared here
APPKIT_EXTERN const double NSAppKitVersionNumber;

This is on macOS 10.12.6, XCode Version 9.2 (9C40b)

It seems that the headers found in Appkit.framework under /System/Library/Frameworks/ are not up-to-date with respect with what is present in the SDK that comes with Xcode.

My pull request fixes that by passing -isysroot to point to the Xcode SDK.
This allows me to build successfully on my machine.
Thought it might make sense to fix it upstream as well.

@akien-mga
Copy link
Member

akien-mga commented Aug 24, 2018

Nobody else seems to report such issues building on macOS, so it would be better to diagnose why it's not working on your system when it works for others. If we can avoid hardcoding such paths, that's better.

CC @bruvzg

@alcroito
Copy link
Contributor Author

alcroito commented Aug 24, 2018

Well it's semi-hardcoding. The same is done in the iphone/detect.py file.
You could say it's hardcoded to the default location of Xcode. But it's still overridable given it's exposed as an option.

The highest NSAppKitVersionNumber defined for me in /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSApplication.h
is
#define NSAppKitVersionNumber10_11_3 1404.34

And the highest one in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSApplication.h

is

static const NSAppKitVersion NSAppKitVersionNumber10_12_2 = 1504.76;

A wild assumption is that because my mac initially came with 10.11 installed, and then I updated to 10.12, for some reason the headers files in /System/Library/Frameworks/ were not updated.

To be fair I'm not sure why appkit headers are shipped in both the xcode sdk and in the root.

@bruvzg
Copy link
Member

bruvzg commented Aug 24, 2018

I'm using macOS 10.13.6 and can't check whats going on 10.12, but NSApplication.h on my system doesn't have NSAppKitVersionNumber10_13 constant defined, and 10.14 SDK doesn't have NSAppKitVersionNumber10_14, so it's probably true that none have constant for current version defined.

Xcode can be installed anywhere outside of /Applications/Xcode.app and SDK can be also located in /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/ if someone is using Command Line Tools for Xcode instead of full Xcode.

Setting -isysroot to specific SDK is ok, but probably we should use xcode-select -p command output to get active Xcode/Command Line Tools installation path instead of hardcoded path.

@alcroito
Copy link
Contributor Author

alcroito commented Aug 24, 2018

Looks like $ xcodebuild -version -sdk macosx Path returns the current highest installed sdk path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk

Same with xcrun --sdk macosx --show-sdk-path
Not sure which one is preferred, but I recall xcrun not being available in some context.

I am not particularly experienced with scons, but other build systems like cmake, qmake specify an isysroot by default.
Is there no such facility in scons, and it has to be done manually? Searching didn't uncover much in regards to default compilation flags.

@bruvzg
Copy link
Member

bruvzg commented Aug 24, 2018

Looks like $ xcodebuild -version -sdk macosx Path returns the current highest installed sdk path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk

Same with xcrun --sdk macosx --show-sdk-path

Same can be used with --sdk iphoneos for iOS in iphone/detect.py

I am not particularly experienced with scons, but other build systems like cmake, qmake specify an isysroot by default.

CMake use xcrun: ios.cmake, osx.cmake

@akien-mga
Copy link
Member

Another way to fix the issue would be to add

#ifndef NSAppKitVersionNumber10_12
// Happens when building against SDK from 10.12 or lower
#define NSAppKitVersionNumber10_12 <whatever it should be>
#endif

@akien-mga
Copy link
Member

CC @BastiaanOlij @endragor

@bruvzg
Copy link
Member

bruvzg commented Aug 25, 2018

Besides checking NSAppKitVersionNumber constants there also another way to check macOS version in runtime, I didn't tested how it would behave on 10.12 and earlier, but it may be more compatible.

if (@available(macOS 10.12, *)) {
      // macOS 10.12 or later code path
} else {
      // code for earlier than 10.12
}

Previously the compiler would use system headers located at
/System/Library/Frameworks, which could result in compilation failures
due to the headers not always being up-to-date in regards to the
latest installed macOS SDK headers that come with Xcode.

Fix the issue by passing the SDK path via the -isysroot option to the
compiler and linker invocations.

If no custom SDK path is given, the build system queries the SDK path
via xcrun --show-sdk-path, which returns something similar to

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/
 /Developer/SDKs/MacOSX.sdk/

Querying via xcrun is now also done for iphone (and simulator)
platforms as well.

Here is an example of a compilation failure message due to outdated
headers:

platform/osx/os_osx.mm:1421:41: error: use of undeclared identifier 'NSAppKitVersionNumber10_12'; did you mean 'NSAppKitVersionNumber'?
                                if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) {
                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
                                                                    NSAppKitVersionNumber
/System/Library/Frameworks/AppKit.framework/Headers/NSApplication.h:26:28: note: 'NSAppKitVersionNumber' declared here
@alcroito
Copy link
Contributor Author

alcroito commented Aug 27, 2018

Updated PR to query macOS / iOS / Simulator SDK path via xcrun, and pass the result as -isysroot.
Doesn't affect the macOS cross-build config.
And it doesn't look like ios cross building is supported from a cursory review of platform/iphone/detect.py.

@akien-mga
Copy link
Member

The original issue is fixed by #23822, so this should no longer be needed. Thanks for the proposal nevertheless!

@bruvzg
Copy link
Member

bruvzg commented Nov 20, 2018

The original issue is fixed by #23822, so this should no longer be needed. Thanks for the proposal nevertheless!

It's still a good idea to select correct SDK, even if it's building without error, default SDK may cause problems.

  1. Build will produce tons of "ld: warning: text-based stub file X.tbd and library file X are out of sync. Falling back to library file for linking." warnings.
  2. Binaries built on macOS 10.13 with Xcode 10 will not use correct OS theme on 10.14.

@akien-mga akien-mga reopened this Nov 20, 2018
@akien-mga
Copy link
Member

Ok, merging then :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants