Apple brings a lot of new things to the world. Successful innovations take root, and unsuccessful innovations die off. By the way, unsuccessful decisions are not so few 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 the last
post I wrote about a nonstandard algorithm for searching for header files in Xcode. Today I want to elaborate 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 the SDK in the sense of xCode?
- Each SDK resides in its own folder and coexists painlessly in other SDKs - this allows you to develop for different OSes on the same computer. Previously, the SDK lay in / Developer / SDKs; for the fourth xCode series, they moved inside xCode.app.
- Setting up a project for a specific OS version is a trifling 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 appended as a prefix in the path to search for headers and libraries. Both standard paths (ex: / usr / include) and user paths added by the -I and -L keys are subject to this modification.
It works as follows. Suppose the SDK macosx10.6 is selected in the Xcode settings. Xcode sends the compiler key --sysroot = / Developer / SDKs / MacOSX10.6.sdk. As a result, / usr / include turns into /Developer/SDKs/MacOSX10.6.sdk/usr/include. The same thing happens with paths for searching libraries and frameworks. As you can guess, inside the SDK there is usr / include and usr / lib with the appropriate content.
')
Now it's time to move on to the mysterious “Additional SDKs” option in Xcode.
Why do you need it? Suppose you are a middleware company. You design your libraries and frameworks as XCode SDK. To use your middleware in a project, it is enough to specify the full path to your SDK in the Additional SDKs section in the Xcode settings. Header files and libraries become available automatically.
By the way, you can use a lot of additional SDK at the same time.
Unfortunately, as is often the case, a beautiful idea is ruined by the implementation.
To support Additional SDKs, Xcode has to do a lot of extra work, which is shown by the 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 passed 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. Check out the 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 paths to search for hiders, libraries, and frameworks.
Bonus: SDK and OS versions
For each new OS version, a new SDK is released. However, this does not mean that a project compiled with macosx10.8 SDK will work only on Mac OS X 10.8 and will not run on earlier operating systems.
SDK version 10.8 means that the SDK includes all APIs that are available on Mac OS X 10.8 and
earlier systems (with the exception of the deprecated API). If the project does not use features that are missing in OS X 10.6, then the project will work without any problems on 10.6.
A more interesting situation is when we use new features, if they are available, and for old systems we use an alternative implementation. For this we use weak linking. “Weakly Linked” can be either an entire dynamic library or a separate function from a dynamic library. If a weakly linked library cannot be found at startup, the program will continue to run as indifferently, 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 the call, we compare the address of the function with NULL, and if the function is not available, 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.