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

Change linking of CGDisplayCreateUUIDFromDisplayID on macos #1626

Merged
merged 3 commits into from
Feb 5, 2021

Conversation

Imberflur
Copy link
Contributor

@Imberflur Imberflur commented Jul 17, 2020

This fixes an issue where cross compilation to macos was failing in our CI.

the error we were getting is

error: linking with `/dockercache/osxcross/target/bin/x86_64-apple-darwin17-clang` failed: exit code: 1
  |
  = note: "/dockercache/osxcross/target/bin/x86_64-apple-darwin17-clang" "-m64" "-L" "/root/.rustup/toolchains/nightly-2020-06-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "-L" "/root/.rustup/toolchains/nightly-2020-06-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/self-contained" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps/veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o" "-o" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps/veloren_voxygen" "-Wl,-dead_strip" "-nodefaultlibs" "-L" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps" "-L" "/builds/veloren/veloren/target/release/deps" "-L" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/build/ring-2aacac616f7faeea/out" "-L" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/build/libsqlite3-sys-1d15bda449b01580/out" "-L" "/root/.rustup/toolchains/nightly-2020-06-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "/tmp/rustcfFquQR/liblibsqlite3_sys-82177fd657bac30b.rlib" "/tmp/rustcfFquQR/libring-72c42f30f281984c.rlib" "/tmp/rustcfFquQR/libbacktrace_sys-63abd5899e0d7e6b.rlib" "/root/.rustup/toolchains/nightly-2020-06-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-e166c2d904273814.rlib" "-framework" "AppKit" "-framework" "AppKit" "-framework" "Foundation" "-framework" "Foundation" "-framework" "QuartzCore" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-lSystem" "-framework" "OpenGL" "-framework" "Security" "-framework" "CoreGraphics" "-framework" "CoreFoundation" "-lSystem" "-framework" "CoreVideo" "-framework" "AppKit" "-framework" "AppKit" "-framework" "Foundation" "-framework" "Foundation" "-framework" "QuartzCore" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreGraphics" "-framework" "CoreFoundation" "-framework" "IOKit" "-framework" "CoreFoundation" "-framework" "AudioUnit" "-framework" "CoreAudio" "-framework" "Security" "-framework" "CoreServices" "-framework" "CoreServices" "-framework" "AppKit" "-framework" "Foundation" "-lSystem" "-lobjc" "-lSystem" "-lresolv" "-lc" "-lm"
  = note: ld: warning: directory not found for option '-L/root/.rustup/toolchains/nightly-2020-06-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/self-contained'
          Undefined symbols for architecture x86_64:
            "_CGDisplayCreateUUIDFromDisplayID", referenced from:
                winit::window::Window::set_fullscreen::h0862d839c2379539 in veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o
                winit::platform_impl::platform::window::UnownedWindow::new::hd640451e51837ba2 in veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o
                _$LT$winit..window..Window$u20$as$u20$core..ops..drop..Drop$GT$::drop::h502664d3c6f4fdff in veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o
                winit::platform_impl::platform::window::UnownedWindow::set_fullscreen::hd2d38c24de2b5e7d in veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o
                winit::platform_impl::platform::monitor::MonitorHandle::ns_screen::h33221360728abfd3 in veloren_voxygen.veloren_voxygen.7quxxn1k-cgu.4.rcgu.o
          ld: symbol(s) not found for architecture x86_64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

The CI is setup using 10.13 from https://github.com/phracker/MacOSX-SDKs
The relevant docker file is here https://gitlab.com/veloren/veloren-docker-ci/-/blob/master/base/Dockerfile
The cross compilation was setup using this guide https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html

I don't know enough to tell whether this change will impact regular users. However, we have had two macos users able to build with this change without any issues.

Please let me know if there is a better way to fix this 🙂

  • Tested on all platforms changed
  • Compilation warnings were addressed
  • cargo fmt has been run on this branch
  • cargo doc builds successfully
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

@kuviman
Copy link

kuviman commented Jul 19, 2020

This is what I also tried myself.

But it looks like ColorSync is only available in 10.13+. I've been using 10.11 in my cross compile scripts, so that did not fix the issue for me. I guess I can upgrade myself easily, but I don't know if winit aims to only support latest versions of MacOS or no.

@francesca64 francesca64 added DS - macos C - waiting on maintainer A maintainer must review this code labels Aug 19, 2020
@francesca64
Copy link
Member

francesca64 commented Aug 19, 2020

@Imberflur thanks for the PR, and sorry for the delay!

So, if I'm understanding correctly, CGDisplayCreateUUIDFromDisplayID supports 10.4+, but as of ColorSync's addition in 10.13+, CGDisplayCreateUUIDFromDisplayID moved from CoreGraphics to ColorSync.

However, the existing code has worked fine for several people in my company on both Mojave (10.14) and Catalina (10.15). It smells like macOS is more liberal with this than your cross compilation setup is. I'm not sure if it'd be fair to consider that a bug on your end, since there might not be anything you can realistically do about that?

The changes you made are strictly correct either way, so no worries.

I don't know enough to tell whether this change will impact regular users. However, we have had two macos users able to build with this change without any issues.

It looks like this PR would fix cross-compilation for users on 10.13+ at the expense of making winit completely unusable for anyone below that, which isn't ideal. However, I'm probably comfortable with that, pending any counterarguments.

@kuviman

I don't know if winit aims to only support latest versions of MacOS or no

High Sierra (10.13) came out in 2017, which is a fairly long time ago by Apple standards. I think it'd be a reasonable minimum, especially since older versions are unlikely to receive much testing, so we wouldn't be able to make any support guarantees anyway. Would you be able to use a more recent version?

@francesca64
Copy link
Member

@chrisduerr do you know if many Alacritty users are below macOS 10.13? I don't want to be unpopular.

@chrisduerr
Copy link
Contributor

It seems strange to force a breaking change like this when macOS is likely backwards compatible in some way. At least it has worked great for us, might be related to the MACOSX_DEPLOYMENT_TARGET (see alacritty/alacritty@dfc30ee)?

Of course I do not know how many users are below macOS 10.13, since we have no intention to track that. I haven't seen any issues with a reported macOS version that low for a while, but people very rarely report their macOS versions in issues they create unfortunately.

@Imberflur
Copy link
Contributor Author

Since actual macOS systems appear to be far more lenient with this, I wonder if there is some way we could bring that into the cross-compilation setup?

@francesca64 francesca64 added C - needs investigation Issue must be confirmed and researched and removed C - waiting on maintainer A maintainer must review this code labels Aug 20, 2020
@francesca64
Copy link
Member

francesca64 commented Aug 20, 2020

@Imberflur

I wonder if there is some way we could bring that into the cross-compilation setup?

I think @chrisduerr gave you a good lead / basis for comparison there. I can't investigate this myself, but I wish you the best of luck in finding a solution. We can revisit merging this if it turns out to be intractable or infeasible, but I'm quite optimistic.

@kchibisov
Copy link
Member

I wonder if there's some way to check for things in build.rs and conditionally enable them? But I'm not sure that build.rs it that flexiable(that's how you do such things in C world with checking whether small programs could be compiled and set proper defines, etc). That could be a nice direction to investigate.

@francesca64
Copy link
Member

@kchibisov I'm worried that'd end up being a lot of complexity. It's definitely worth investigating if we end up needing to move forward with this, though.

@kuviman
Copy link

kuviman commented Aug 21, 2020

However, the existing code has worked fine for several people in my company on both Mojave (10.14) and Catalina (10.15). It smells like macOS is more liberal with this than your cross compilation setup is. I'm not sure if it'd be fair to consider that a bug on your end, since there might not be anything you can realistically do about that?

In this case, maybe its worth asking in osxcross repo since that is what both me and @Imberflur use, it seems? I don't know much about MacOS and how this all works and why is it different but maybe they do.

Would you be able to use a more recent version?

Yea, I'm using this patch and updated to 1.13 now in my scripts with success

@Imberflur
Copy link
Contributor Author

It looks like we are already setting the deployment target to a low value https://gitlab.com/veloren/veloren-docker-ci/-/blob/master/base/Dockerfile#L64

I think the issue may be with the SDK we are using. I'll probably need to wait for others to investigate this since I'm not the maintainer of our CI. @kuviman are you getting the SDK for cross compilation from the same source?

@kchibisov
Copy link
Member

Well, if we want to support old and a new platform winit can check the target we're compiling to in build.rs and pass proper cfg to rust, and in the code we'll just if/def. That seems like a natural solution and doesn't sound like something complex. The target detection in cross could be a bit of a 'deal', but it really doesn't sound that complicated.

winit can also define build time env variable like TARGET_MACOS_VERSION and pass cfg again.

@kchibisov
Copy link
Member

Just fyi, you can utilize conditional compilation with cargo in build.rs.

So you can define a custom cfg in build.rs script and use in macOS/ios code.

The basic idea looks like alacritty/crossfont@7134cd4 .

So in build.rs you should check if the thing you want to use is presented, assuming that your target platform is macos, which cargo will pass to you via env variable CARGO_CFG_TARGET_OS.

I'm just leaving it here, if your cross issue is still relevant, since solution like that should work. I'm not entirely sure how to check for target macos version automatically though, but adding winit specific env variable for build.rs could be valuable solution, but I'd prefer more automatic approaches to solve that problem.

@Imberflur
Copy link
Contributor Author

Maybe something like this?

// build.rs
fn main() {
    // If building for macos >=10.13 use CGDisplayCreateUUIDFromDisplayID from ColorSync instead of CoreGraphics
    if std::env::var("CARGO_CFG_TARGET").as_deref() == Ok("macos") {
        if let Ok(target) = std::env::var("MACOSX_DEPLOYMENT_TARGET") {
            let mut split = target.split('.').map(|s| s.parse::<u32>().ok());
            if let Some(major_version) = split.next().flatten() {
                let minor_version = split.next().flatten().unwrap_or(0);
                if (major_version, minor_version) >= (10, 13) {
                    println!("cargo:rustc-cfg=use_colorsync_cgdisplaycreateuuidfromdisplayid");
                }
            }
        }
    }
}

Personally I would be fine with more manual solutions.

@kchibisov
Copy link
Member

Maybe something like this?

That seems about fine for me.

@Imberflur
Copy link
Contributor Author

I tried this out, however we weren't already setting MACOSX_DEPLOYMENT_TARGET and setting it to 10.13 produces this unrelated error when compiling:

error: linking with `/dockercache/osxcross/target/bin/x86_64-apple-darwin17-clang` failed: exit code: 1
  |
  = note: "/dockercache/osxcross/target/bin/x86_64-apple-darwin17-clang" "-m64" "-arch" "x86_64" "-L" "/root/.rustup/toolchains/nightly-2020-08-15-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps/tools.tools.epwjksx2-cgu.1.rcgu.o" "-o" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps/tools" "-Wl,-dead_strip" "-nodefaultlibs" "-L" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/deps" "-L" "/builds/veloren/veloren/target/release/deps" "-L" "/builds/veloren/veloren/target/x86_64-apple-darwin/release/build/ring-ac05fe8c9a0a1688/out" "-L" "/root/.rustup/toolchains/nightly-2020-08-15-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "/tmp/rustcDbHCt2/libring-d6bf01e2a808afce.rlib" "/root/.rustup/toolchains/nightly-2020-08-15-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-56bf0be46b5f5195.rlib" "-framework" "Security" "-framework" "CoreServices" "-framework" "CoreServices" "-lSystem" "-lresolv" "-lc" "-lm"
  = note: osxcross: error: cannot find libc++ headers
          osxcross: error: while detecting target

I think this might be because we are setting the min version to something else when setting up the cross compiler: OSX_VERSION_MIN=10.7 ./build.sh https://gitlab.com/veloren/veloren-docker-ci/-/blob/master/base/Dockerfile#L64

So I think it would be easier and less hazardous to just have a winit specific env var. Especially, since the original linking error only occurs during cross compilation.

@Imberflur
Copy link
Contributor Author

Imberflur commented Jan 23, 2021

I changed it to a simple manually configurable env var. I avoided using the macos target version as the input for the env var since from my previous tests in our cross compilation setup the version we are targeting doesn't align with what conclusions we can reach from the documentation about the availability of the ColorSync API.

edit: confirmed using this env var works in our CI

Copy link
Contributor

@ArturKovacs ArturKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I'm concerned this is a fine solution. Although I do think that a note about the usage of this env var should be noted probably in the Readme under "Platform-specific usage".

@Imberflur Imberflur force-pushed the macos-linking branch 2 times, most recently from c4378b8 to 263ba1a Compare February 3, 2021 21:47
@Imberflur
Copy link
Contributor Author

Added a note to the readme

Copy link
Contributor

@ArturKovacs ArturKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! @francesca64 if you give your blessing, I think we can merge this.

Copy link
Member

@francesca64 francesca64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blessing given! Thanks a bunch to both of you.

@ArturKovacs ArturKovacs merged commit b9307a9 into rust-windowing:master Feb 5, 2021
madsmtm added a commit to madsmtm/winit that referenced this pull request Nov 29, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ColorSync (which AppKit uses internally) available to us (on macOS 10.13 or above).

Lately something changed in rustc so that this no longer works, see rust-lang/rust#91372. So instead, we link to AppKit directly within the `winit` crate, which, for now, allows us to use the private symbol.
madsmtm added a commit to madsmtm/winit that referenced this pull request Dec 1, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ColorSync (which AppKit uses internally) available to us (on macOS 10.13 or above).

Lately something changed in rustc so that this no longer works, see rust-lang/rust#91372. So instead, we link to AppKit directly within the `winit` crate, which, for now, allows us to use the private symbol.
madsmtm added a commit to madsmtm/winit that referenced this pull request Dec 1, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us (on macOS 10.8 or above).

However, this does not work on macOS 10.7; instead, we should just link to ApplicationServices directly!
madsmtm added a commit to madsmtm/winit that referenced this pull request Dec 1, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us (on macOS 10.8 to 10.13).

However, this does not work on macOS 10.7 (where AppKit doesn't link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit to madsmtm/winit that referenced this pull request Dec 6, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit to madsmtm/winit that referenced this pull request Dec 11, 2021
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit to madsmtm/winit that referenced this pull request Jan 2, 2022
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit that referenced this pull request Jan 3, 2022
See also #1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit to madsmtm/winit that referenced this pull request Jan 5, 2022
See also rust-windowing#1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
madsmtm added a commit that referenced this pull request Jan 5, 2022
See also #1626.

The `cocoa` crate links to AppKit, which made the symbol `CGDisplayCreateUUIDFromDisplayID` from ApplicationServices/ColorSync (which AppKit uses internally) available to us on macOS 10.8 to 10.13.

However, this does not work on macOS 10.7 (where AppKit does not link to ColorSync internally). Instead of relying on this, we should just link to ApplicationServices directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - needs investigation Issue must be confirmed and researched DS - macos
Development

Successfully merging this pull request may close these issues.

6 participants