• 4 min read
Decisions You No Longer Regret
A psychological thriller about teamwork, new Xcode, working extra during the Run, macOS versioning, backward compatibility, and regrets, but not how you think about it.
Sometimes you make decisions you regret. And I, like any other human, have made such decisions. Today I want to share one with you.
In November 2020, Apple released the M1 chip with arm64 architecture. We at Setapp needed to update our library to support the new architecture, as our vendors relied on it. For vendors, having a dependency that doesn’t support new architecture would mean their entire project cannot support Apple Silicon. Our inaction was a blocker for app creators, so we had to act.
We had two approaches to solving the problem: one was easy, and the other was complicated.
- Easy option — Update the deployment plan and make a Universal Static Library (fat library) combining two architectures.
- Complicated option — Add the ability to choose between the "fat library” and the library with only one architecture.
The first option was a perfect zero-cost solution; we only had to update one script. Moreover, a standalone old library had no use: the “fat library” contained both architectures. Xcode — the integrated development environment for macOS and iOS developers — could easily handle the “fat library.” We could even link apps with x86_64 (Intel CPU) architecture. In this case, Xcode just stripped away redundant arm64 symbols.
Looking back, the first option sounded too good to be true. Therefore, our team decided to move with the second option spending several weeks on the task.
Hours after the release, besides some excitement, we received the following messages:
I’m confused why there are two versions. Despite its name, the “For Silicon (ARM)” library looked universal, supporting both x86_64 and arm64.
I think there is no need for the Intel-only version, even if somebody is targeting Intel-only. Since it’s a static library, the linker should ignore architectures not pertinent to the binary being created. The binary code is copied into the main app’s executable. There’s nowhere to copy the arm code if the target app is Intel-only.
Additionally, we doubled the load on our CI, which caused problems.
Several times, we discussed the possibility of reverting to one "fat library.”
Five stages of grief, or Living with the consequences
I always knew the decision we made was suboptimal. It lived rent-free in my head for the whole year. Whenever we had problems linked to the library, I would question our decision. The more I thought about it, the more I regretted it.
I was perplexed when the vendor success manager informed me about an app creator having issues integrating our library using the old Xcode version.
“What the heck?”
I thought our library was backward compatible as we had set the minimum OS target in it. If you thought finding what doesn't work in the IDE released a year ago was hard, I had to work out the 5-year gap across five major versions.
However, after several days of trying to figure it out, I realized that our library was indeed Xcode backward compatible, but not so far as we thought. Some changes were made with the new macOS versioning (from 10.15 to 11) that didn't allow integrating the library using an older Xcode version. Moreover, I removed some extra test-related binary leftovers in the library.
But it still wasn't working, and I faced numerous "Undefined symbols for architecture x86_64" failures.
Change, build, check — fail ❌.
“Undefined symbols for architecture x86_64.”
You know how frustrating it is when you want to get things done.
After examining the logs, I noticed I was testing the "fat" version. At first, I thought it couldn’t be a problem because Xcode would strip everything else.
“Why not give it a chance? I’m stuck anyway!”
Five years of updates do make a difference. Finally, I got the "Build Success ✅" message.
No more regrets
I managed to befriend Setapp library built with modern Xcode 13.1 and a project created with old Xcode 8.3.3. This success was a significant relief and taught me an important lesson. Although I still think about this decision, I no longer regret it.
PS. We will probably remove the "thin" framework with the x86_64 architecture someday. But doing it, I'll mumble the song “Still Got The Blues” by Gary Moore:
Was more than just a game You're playin' to win but you lose just the same