-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Set minimum deployment target for macOS builds #8004
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
Conversation
10.13 (High Sierra) for x86_64, and 11.0 (Big Sur) for arm64
OH MY GOD THANK YOU SO MUCH YOU ARE AMAZING also can you explain how you did this I really want to know :) Edit: Just checked the nightly and it still says that it requires MacOS 13.7 for whatever reason. |
@Mr-Emoticon63 Thanks! I just had to set a compiler option to allow support for older macOS versions. This isn't in nightly yet (since this PR hasn't been merged), but you can try it out here: https://lmms.io/download/pull-request/8004 If you do try it out, please let me if it worked for you. I don't have a Mac so I can't test it myself. |
it’s not loading for whatever reason. |
it just says “504 Gateway Time-out” |
uh oh none of the lmms website is loading 🥲 |
The website is down currently, but the latest build in this PR (as of when this comment is uploaded) can be grabbed from here: https://github.com/LMMS/lmms/actions/runs/16230943390#artifacts |
yeah it worked. Now we just wait for the review. |
I got an idea @tresf we need a review for this to be merged :) thanks |
Sadly, I don't believe this does anything useful because the Homebrew dependencies are pre-compiled for the target macOS version, which is currently set to lmms/.github/workflows/build.yml Line 184 in 74759c7
Also -- in my experience -- even if this did work, the deployment target is just one piece of the puzzle and we should also use the target's SDK which must be fetched manually. In the past, I was able to create a Homebrew environment on a VM which targeted an older OS, but Homebrew all-but-killed this strategy, so I fear that this will be yet-another-vcpkg-style-candidate, if we're to support it. Here's a thread about using an old snapshot of Homebrew, but I'm not sure if this strategy works. It'll also suspend any dependencies in time for that particular OS, so if there's new features we plan to use in a dependency since, they won't be available. Homebrew does allow custom "taps" for these types of strategic forking (and Homebrew will automatically build a Tap from source when it can't find a precompiled binary) but influencing the default Homebrew build environment will be some work (and we'll always be maintaining the taps moving forward to get lastest-on-oldest style dependencies. This is a long-winded way to say, we should probably NOT support older macOS versions unless we have a volunteer that understands the above to add such a system to the CI. In the past myself or @PhysSong would do this on our own PCs, but this process was continually breaking and was eventually removed. My advice to those using older macOS versions is to use older LMMS versions until the above can be addressed. I'm happy to be proven wrong though. 🍻 |
It worked for me on MacOS 12, so I don’t see why this couldn’t be useful. I’d be glad to volunteer for testing if you need anyone though. |
@tresf Is there any reason why we're using Homebrew instead of MacPorts or vcpkg? From what I understand, MacPorts and vcpkg have much better support for older systems, while Homebrew just assumes everyone uses the latest 2-3 macOS versions. If it's just because Homebrew packages are pre-built, we can probably work around that through caching or creating our own pre-built packages. |
Right because Homebrew likely uses something similar, but this PR doesn't set the target to 12, it sets it to 11 which I don't think we can promise. If we merge this, we should do so knowing it's a lie. 😅 |
My latest attempts at MacPorts weren't successful but speed is a terrific reason to keep using Homebrew. The initial reason we switched to Homebrew was popularity (which brings other benefits such as speed, reliability) but these can quickly be outweighed. Regardless we should probably keep our tutorials for Homebrew even if our official builds diverge because developers are generally more familiar/happy with it. If MacPorts or vcpkg can do the job better for our official builds, that would be welcome. |
FYI, vcpkg supports specifying macOS deployment target by adding |
I mean if we want to future-proof this problem than yeah, we should switch to vcpkg or MacPorts, but if we just need a quick and easy solution, changing the compiler flag does at least make it work most of the time on MacOS 12. |
There is already LMMS on MacPorts, maintained by @barracuda156 so really all we have to do is make a script updating the port whenever a new nightly happens! (ok so I have yet to check but almost immediately after I posted this comment I found out that the branches aren’t even that old (ranging from yesterday to 2019)) |
I'm not sure what this entails, but feel free to explore any avenues to make backwards compatibility better. The MacPorts community has been invaluable maintaining support for older systems, but this is a task that's quite adjacent to producing reliable builds for the most common 80% of users. Without more volunteers, we'll be spending less and less time with backwards compatibility, since the team maintaining macOS support is essentially one person (or at times, two). For example, this comment hasn't been fully addressed yet, quoting: @tresf wrote:
@Mr-Emoticon63 wrote:
At time of writing this, I'm on macOS 15 on a 5-year old Macbook Pro, so I'm not even sure what the purpose of targeting macOS 12 is. To be clear, I'm not at all opposed to this, and I do this for my other projects, but LMMS relies so heavily on prebuilt dependencies from Homebrew, any efforts to lower this should be spearheaded in the form of a plan (PR or dedicated issue). As always, thoughts/arguments/ideas welcome. |
Just please make sure not to force deployment target when building from source, since that will break builds for all systems below such a target. |
@tresf MacPorts works back to 10.5, though not much is properly tested. Still, it is far better than any popular alternative, since Homebrew is just broken on most macOS versions, fink hasn’t been updated for older systems, and pkgsrc will need substantial work to make it usable. LMMS builds at least on 10.6 via MacPorts. I think it will build on 10.5, but I need to verify that.
You seem to assume that everyone must prefer later OS to the earlier, but that needs not be the case for various reasons, not limited to hardware capabilities. (Though of course there is no way to install macOS 13 on a PowerMac LOL.) Specifically about macOS 12, I think that is the last one where FireFire was not yet broken by Apple? Users with FW interfaces may prefer to use the OS where those actually work. |
Well, our goal isn't to goal isn't to target 10.5. Compiler issues aside, we're migrating to Qt6 soon(ish) (per #7339) which will move to macOS needle to 12+ I believe. This needle will continue to slide as time goes on, so my purpose isn't to argue which macOS version is the best, it's to argue which macOS versions we can reasonable support on our downloads page. We're always receptive to patches from the MacPorts to keep support for older OSs.
Hmm... Perhaps the stable branch? That branch is 5 years old. Master would be a better comparison.
Correct, I always assume that OS upgrades are effectively compulsory; for this reason, we target newer Linux, newer Windows and newer macOS versions for our master branch. We do keep around compat for older OSs when we can, but ABI/API stability often forces us away eventually. In the case of macOS, we try to dogfood our build system... by that I mean, the fastest way to get a developer interested in sending us a patch is to target pre-built dependencies so that building is quick and painless. We use this same process for our CI to match. We'd happily accept a MacPorts CI job to run alongside with older compat. Also, to put things into context, I'm the one that added macOS support to LMMS 11 years ago (using MacPorts) so there's no bias here. MacPorts helped us considerably in our initial porting process, but as we lose valuable developers, any attempts to support older versions comes second to more pressing issues.
My experience has been the opposite... my M1 has been the most stable machine I've ever owned (which is why it's my main machine 5 years after purchase) and I've always kept it up-to-date. As for subjectivities such how "ugly" it has become, I believe the vast majority (95%) of our users do not choose an operating system based on this, and that's our target audience. If we can also provide older downloads, great, but we need help in this area, and building against Qt6 may eventually be a hard-requirement for this, so we need a person to run with this as well as a plan of attack.
I think the best we can do for PowerPC is to continue to accept small patches to our old stable branches. |
@tresf Whatever I said applies only to builds from source on user end or downstream package managers. I do not expect the upstream to provide pre-built apps for legacy platforms (or in fact any arbitrarily chosen platform). As for Qt6, well, there are some chances we get Qt6 on earlier macOS via X11 backend (Cocoa is broken, of course, beyond repair). Qt upstream doesn’t make life of users easy, and currently X11 backend is broken for any macOS. I am still hesitant which approach is better – to fix select apps of interest for Qt4, which uses native GUI, or fix Qt6, but that gonna rely on Xserver (which I am not a fan of). So far I have been doing the former, with decent success, but it is time-consuming. I made a brief effort at fixing Qt6, and was able to build qtbase on Sonoma, and get a working qmake6 on PowerPC, but I can’t say whether this is livable or whether I get motivation to pursue that… |
We don't do this currently, however I would argue that if we could calculate this value (e.g. |
With this said, I'd like to rephrase this statement...
😅 |
@Mr-Emoticon63 are you on Intel or Apple Silicon? |
So I dove a bit deeper into this... otool -l $(brew --prefix qt@5)/bin/qmake |grep minos
# minos 11.0 This matches this PR, so I think this is a sane value -- of which we can use in place of Note, I won't hard-code |
Ugh... maybe not... quoting:
I'll attempt to isolate it to the CI for now. |
Ok, here's the patch: tresf@078b31d. This will infer the SDK version based on whatever Homebrew used. It's effectively identical to the patch in this PR, but without hard-coding anything. @messmerd thoughts welcome. |
@tresf I don’t see a problem if this is done correctly: CMakeLists much first check if CMAKE_OSX_DEPLOYMENT_TARGET is already set, and if not, then use whatever value you find preferable. I.e. just do not override the environment. That avoids breaking any sane build systems, which are supposed to set deployment target correctly from their side. P. S. Deployment target does not exist for the purpose of ensuring to break the build on a system where the software is not being tested. Unfortunately, it is often used this way, and this is what I oppose to. I have seen too many instances where arbitrarily high hardcoded deployment target breaks configure (since CMake passes a flag which gcc does not accept), and then one needs to run grep on sources to find where to fix that, make patches and then keep rebasing them on every other release. |
This will only work for one version of the OS; the combinations (moving forward to new target SDKs and backwards to older target SDKs) would be virtually endless. Also, "working" is quite subjective since it's very API dependant, so reliability will depend on which Apple APIs the software and it's dependencies use. |
@tresf With some help from ChatGPT, I've found this: plutil -extract SupportedTargets.macosx.MinimumDeploymentTarget raw "$(xcrun --sdk macosx --show-sdk-path)/SDKSettings.plist" I've confirmed that it works on my Mac Mini |
This is very cool! On my M1 running macOS 15.6.1 this shows a staggeringly low 10.13. Do we really want that? I guess it won't hurt to try... |
Hmm... thinking out loud here... We really don't want a value that's lower than the lowest value of one of our dependencies, which is why |
According to https://developer.apple.com/xcode/cpp/#c++20, some C++20 features ( I don't think we're using those features yet, but we should keep the minimum deployment target >= 11.0 just in case. |
So we now have Homebrew dependency minimum deployment targets, Xcode minimum deployment targets, and C++20 minimum deployment targets. This is growing in complexity and makes me wonder whether we're over-engineering this by programmatically picking the minimum deployment target. Would it be any more reliable or maintainable to just manually pick the minimum deployment target (with a comment justifying that choice), and possibly repurpose the script to verify that the choice will work? Also, what happens if an unsupported minimum deployment target is passed to AppleClang? Will it fail to compile or silently error? |
I'm noticing some linker warnings, like this on x86_64:
And this on arm64:
It appears only Mallets has this issue. We should probably check that it still works despite the warning. |
This is why copying the target SDK version from a known-working binary (such as
From my understanding, it's not so much Clang as much as it's the SDK we link against... I was always under the impression that this SDK didn't offer much in regards to backwards compat, so for other projects, I explicitly download a legacy SDK to ensure maximum backwards compat however, this thread taught me that this is more nuanced. In the future when we choose to compile everything from scratch, I believe leveraging the old SDK becomes a solid strategy. Until then, this PR doesn't what it says it does and I think that's good enough. |
Maybe, but the more we hard-code the more we have to maintain, so my vote is no, if we can help it. 😅 |
I guess it's because no dynamic libraries for STK is available at least for Homebrew. Other dynamic libraries we're linking to might still exceed the macOS deployment target version. |
Yes, they will. In my tests against What we don't know yet is what will happen to the end-user when the application encounters a mix of targets within an application. I can simulate this on Intel if needed prior to merging this PR... Sadly on Apple Silicon/M1/ARM64, it's not possible to run a VM lower than macOS 12.0 . What's a bit more nuanced, is that If we really wanted to get fancy, we could script the DMG creation script to spit out all versions of all dependencies, but this would be analytical-only -- since this step is post-mortem -- as it's too late to use this as a value after we've compiled and packaged everything. Also, hi @PhysSong! We're hoping to ramp up for another alpha soon. 🍻 |
I still love this solution, even if it's for information purposes. I suppose we could use this as a sanity-check against the version we calculate, or just blindly ship with it and hope people don't actually try to run our binaries on this old of an OS. When @PhysSong and I did this in the past, the SDKs didn't seem to advertise (or at least our tests didn't suggest) such a wide-range of backwards compatibility, so I'm quite perplexed by this new finding. Back then, we'd maintain old VMs with old SDKs for compiling, but this would pin our dependencies to a particular point in time (and worse, place a single-point of failure on build production). This may still be the path forward if we're to switch to All that's to say, we should probably merge something to get @JMii63 happy. He's approved this PR in many forms up to this point and our nightly branch can immediately benefit from one of the solutions, even if it's misleading. |
Just in case, this syntax is invalid at least on < 10.7: |
Thanks for this reminder, I had a similar hesitation when I saw |
@tresf Isn’t it specifically targeting 10.4? It may be the best currently supported option there (I did not test it personally, but it is the only package manager which at least claims to support 10.4). |
I don't know the official stance... The author regularly contributes to upstream and it's often recommended when people complain. |
... here's a similar sentiment (comment) 😏 https://apple.stackexchange.com/a/418277/147537
|
As long as we talk specifically about 10.4, MacPorts dropped support for it in 2.11.x. More importantly, more or less nothing was tested on 10.4 for years, AFAIK, with two exceptions: |
Good to know. We'd target something much newer. |
Added the sdk version proposed in f87d65b as information-only.
Assuming there are no objections, this should be merged. A review would be greatly appreciated, but I'll bypass the approval if I don't receive feedback after a few days. |
and now we wait :) |
LGTM, though we should probably test that Mallets still works. |
I can probably test that if we need it. |
Out of curiosity, I ran the following, all show 15.0 for me... otool -l /opt/homebrew/lib/libfltk.a |grep minos
otool -l /opt/homebrew/lib/libfltk.a |grep minos
otool -l /opt/homebrew/lib/libfltk.dylib |grep minos ... so I'm not entirely sure why some linking issue warnings whereas others do not, however I also see this for libsamplerate, perhaps it only appears for statically linked libraries?
@JMii63 yes please do! |
Done. Post-merge testing is still fine though. 😅 |
yayyyy we did it!!! now all I gotta do is wait a couple days for the nightly branch! |
Nightly's already ready: https://lmms.io/download#mac |
Our macOS builds do not set a minimum deployment target, which (I believe) makes XCode/AppleClang default to the same version as the host. So on Nightly, this would mean the minimum macOS version is 13 (Ventura) on x86_64 and 14 (Sonoma) on arm64. This places an unnecessary restriction on users, which is a problem.
So I've lowered the minimum deployment target to the lowest values it will allow:
10.13 (High Sierra) for x86_64, and 11.0 (Big Sur) for arm64
NOTE: I added the minimum deployment target to the ccache key. I'm not really sure if this is necessary. If not, I can remove it.