Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So... to try and get an answer to the unanswered question in the blogpost. The files are probably hardlinks to a single "superbinary" image somewhere. The actual code is probably checking the value of argv[0] to dispatch to the actual git code (or whatever command name was invoked). The question is, why is Apple doing this? Is it some sort of diskspace saving scheme (to avoid duplicating common boilerplate code)? I suspect some part of this answer includes the words "for security" but it's already been proven to be BS at this point.


Nah, the binary doesn't actually contain git. It's just a stub (in /usr/bin) that locates Xcode on the system (in /Applications/Xcode.app by default but configurable) and execs the real git binary from there. See also:

https://developer.apple.com/library/mac/documentation/Darwin...


OK great. So now the question is why? I've seen this "multiplexed binary" scheme implemented elsewhere in more constrained circumstances but it doesn't really make sense to me for a desktop OS to be doing it.


Based on some Googling and my memory... the history of toolchain installation on OS X is a big mess.

In the old days, pre-2011, you would manually download the Xcode installer from Apple's site (after a free registration), and it would install stuff into both /Developer and /usr. IIRC /usr/bin/gcc was good enough for native compilation, but for iOS you would have to locate the compiler under /Developer/Platforms/something-or-other. (Today, with LLVM's ability to target multiple architectures in one compiler, the toolchain binaries are the same and only the sysroot depends on target.)

Then in 2011, Xcode was moved to the then-new Mac App Store, but the app you got on the store was just an installer (blatantly ignoring the App Store rules, and later sandboxing restrictions, that apply to everyone else), and the installation path was the same. Oh, and the store version was initially $4.99, which pissed everyone off until it was made free in the next minor update.

In 2012, Xcode was overhauled so that /Applications/Xcode.app was directly installed by the App Store and the toolchain was located inside the app bundle. This was a big improvement in part because it made the App Store's delta app updates work properly for Xcode - previously you had to keep the installer app around so it could delta update that, which doubled disk cost, and then you still had to run the installer and wait for it to re-copy the whole IDE and toolchain. It also made it easier to have multiple copies of Xcode installed side by side, and uninstallation was now a matter of dragging the app to the trash, like any other. But if you wanted standard Unix builds to work (as opposed to building within Xcode or manually specifying the compiler path), you now had to download the separate "Command Line Tools Package", which could be done either from within Xcode or directly from Apple's developer site (the latter welcomed as it saved bandwidth and disk for anyone who didn't want to download the several-GB Xcode package), and it would install a duplicate toolchain to /usr.

Finally, in 2013, the shim binaries in /usr/bin were introduced; this system has lasted to the present and has a few advantages:

- The Command Line Tools can now be mostly segregated into /Library/Developer/CommandLineTools rather than getting mixed up in /usr with the rest of the OS - however, the installer still dumps headers into /usr/include.

- If the user has the full Xcode installed, it isn't necessary to install the Command Line Tools, as the shims will just execute the binary from /Applications/Xcode.app (or wherever Xcode is installed - you can switch globally or using an environment variable). That is, unless you need /usr/include to exist.

- Of course, installing outside of /usr/bin made it easier to introduce SIP.

- Convenience: the shims are shipped with the base OS, so if you try to run a developer command and neither Xcode nor the Command Line Tools are installed, rather than 'command not found', you get a nice GUI dialog that downloads and installs the latter in one click. (Well, "nice"; if you have a configure script that probes for the compiler by trying to run it, but doesn't depend on it, and you don't want to install it, you now have to deal with a GUI dialog popping up every time you run configure. At least, this is my experience with the similar shim that exists for javac. This should be improved.)

I suppose the advantages of the first three points could mostly have also been accomplished if Apple built some system into /etc/profile or whatever to automatically add the relevant toolchain to the PATH. Why Apple decided to go with shims instead I can only guess at, but all in all it's a decent system, and it's nice that each toolchain is now mostly self-contained in one directory so they're easy to manage. Compared to most Linux distros, where compilers are just distro packages but there's no easy way to install a package to an alternate path or have multiple versions installed simultaneously (unless you build from source), I'd say it's an improvement.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: