Additional Xcode SDK - what it is and why you don't need it

  • Tutorial
Apple brings a lot to the world. Successful innovations take root, and unsuccessful little by little die. By the way, there are not so few unsuccessful decisions and I think this is absolutely normal. In the end, we respect Apple for its willingness to take risks and experiment :)

All this fully applies to development tools. In a previous post, I wrote about a non-standard algorithm for finding header files in Xcode. Today I want to dwell on the so-called SDKs - in Xcode this term refers to a set of libraries and header files for a specific version of iOS or Mac OS. Why do we need an SDK in the understanding of xCode?
  • Each SDK is in its own separate folder and painlessly coexists in other SDKs - this allows you to conduct development for different operating systems on one computer. Previously, the SDKs were in / Developer / SDKs; by the fourth xcode series, they moved inside xCode.app.
  • Setting up a project for a specific version of OS is a trivial matter. It is enough to specify the SDK in the project settings.

Technically, this is implemented as follows. Apple added the --sysroot switch to the compiler. The sysroot value is added as a prefix in the path to search for header files and libraries. Both standard paths (ex: / usr / include) and user paths added with the -I and -L options are affected by this modification.

It works as follows. Let's say the macosx10.6 SDK is selected in the Xcode settings. Xcode passes the --sysroot = / Developer / SDKs / MacOSX10.6.sdk switch to the compiler. As a result, / usr / include turns into /Developer/SDKs/MacOSX10.6.sdk/usr/include. The same thing happens with paths for finding libraries and frameworks. As you might guess, inside the SDK there are usr / include and usr / lib with the corresponding contents.

Now is the time to move on to the cryptic “Additional SDKs” option in Xcode.

Why is this needed? Suppose you are a middleware company. You design your libraries and frameworks as an Xcode SDK. To use your middleware in the project, just specify the full path to your SDK in the Additional SDKs section in the Xcode settings. Header files and libraries are automatically available.

By the way, you can use many additional SDKs at the same time.

Unfortunately, as often happens, implementation is ruining a beautiful idea.

To support Additional SDKs, Xcode has to do a lot of additional work, which is manifested by brakes when building the project. For each combination of base and additional SDKs used, a combined tree of files from all SDKs is created in the temporary folder and the path to this folder is transferred to --sysroot. Instead of honestly copying files, symlinks are used, but still the process is not fast.

For those who want to experiment with the Additional SDK, I prepared a project on github. Pay attention to SDKSettings.plist. This file is required for Xcode to “recognize” the SDK.

In my projects, I do not use the Additional SDK and instead manually configure the paths to search for headers, libraries, and frameworks.

Bonus: SDK and OS versions

For each next version of the OS, a new SDK is released. However, this does not mean that a project compiled with the macosx10.8 SDK will only work on Mac OS X 10.8 and will not start on earlier OSs.

SDK version 10.8 means that the SDK includes all APIs that are available on Mac OS X 10.8 and earlier systems (except for the deprecated API). If the project does not use features that are not available in OS X 10.6, then the project will work without problems on 10.6.

A more interesting situation is when we use new features, if they are available, and for older systems we use an alternative implementation. We use weak linking for this. “Weakly linked” can be either a whole dynamic library or a separate function from a dynamic library. If at start it is not possible to find a weakly linked library, the program will continue to run as if nothing had happened, and the linker will substitute NULL as the address of the missing functions. Of course, if you call a function that is not there, the program will crash.

Therefore, before calling, we compare the address of the function with NULL, and if the function is not available, we use an alternative implementation.

The minimum supported version of Mac OS is specified in the project settings (MACOSX_DEPLOYMENT_TARGET). All later APIs are automatically flagged for weak linking. This is done using macros that are declared in /usr/include/Availability.h.

Also popular now: