| 1 | Darwinbuild |
|---|
| 2 | Updated 2009-02-17 |
|---|
| 3 | |
|---|
| 4 | Kevin Van Vechten <kvv@apple.com> |
|---|
| 5 | William Siegrist <wsiegrist@apple.com> |
|---|
| 6 | |
|---|
| 7 | 1. Overview |
|---|
| 8 | 1.1 Availability, Bug Reports, Contributions, and Discussion |
|---|
| 9 | 2. Installation |
|---|
| 10 | 2.1 Creating the Build Directory |
|---|
| 11 | 3. Building Darwin Projects (darwinbuild) |
|---|
| 12 | 3.1 Install Headers |
|---|
| 13 | 3.2 Chroot Builds |
|---|
| 14 | 4. Build Environment Variables |
|---|
| 15 | 4.1 Build Aliases and Alternate Targets |
|---|
| 16 | 5. Tips and Techniques |
|---|
| 17 | 5.1 Private Headers |
|---|
| 18 | 5.2 Build Tools |
|---|
| 19 | 5.3 Static Libraries |
|---|
| 20 | 5.4 Alternate BuildRoot Storage |
|---|
| 21 | Appendix |
|---|
| 22 | A. darwinxref |
|---|
| 23 | |
|---|
| 24 | =========== |
|---|
| 25 | 1. Overview |
|---|
| 26 | =========== |
|---|
| 27 | |
|---|
| 28 | Darwinbuild is a collection of tools that assist compilation of |
|---|
| 29 | the many projects contained in Darwin[1], the open source base of Apple's |
|---|
| 30 | Mac OS X operating system[2]. Apple publishes the sources of these projects |
|---|
| 31 | in an archive format (.tar.gz). An archive is published for each project |
|---|
| 32 | version on Apple's site[3]. |
|---|
| 33 | |
|---|
| 34 | These tools will provide the proper build environment as well as help to |
|---|
| 35 | resolve any necessary dependencies prior to building. |
|---|
| 36 | |
|---|
| 37 | [1] <http://developer.apple.com/darwin/> |
|---|
| 38 | [2] <http://www.apple.com/macosx/> |
|---|
| 39 | [3] <http://www.opensource.apple.com/> |
|---|
| 40 | |
|---|
| 41 | |
|---|
| 42 | 1.1 Availability, Bug Reports, Contributions, and Discussion |
|---|
| 43 | |
|---|
| 44 | Due to the constant development of darwinbuild, the only version you should |
|---|
| 45 | be working with is trunk of the subversion repository[1]. Trunk should |
|---|
| 46 | always be stable enough for building projects. If you find a problem or have |
|---|
| 47 | a enhancement in mind, file a ticket at the website[2]. |
|---|
| 48 | |
|---|
| 49 | Discussion about darwinbuild, or building Darwin projects in |
|---|
| 50 | general, should take place on the darwinbuild-dev[3] mailing list. |
|---|
| 51 | |
|---|
| 52 | [1] <http://svn.macosforge.org/repository/darwinbuild/trunk> |
|---|
| 53 | [2] <http://darwinbuild.macosforge.org/report/1> |
|---|
| 54 | [3] <http://lists.macosforge.org/mailman/listinfo/darwinbuild-dev> |
|---|
| 55 | |
|---|
| 56 | =============== |
|---|
| 57 | 2. Installation |
|---|
| 58 | =============== |
|---|
| 59 | |
|---|
| 60 | You can install the latest version of darwinbuild using MacPorts. |
|---|
| 61 | |
|---|
| 62 | % port install darwinbuild |
|---|
| 63 | |
|---|
| 64 | Or, you can also install by checking out the source and building |
|---|
| 65 | darwinbuild yourself. The included Xcode project will compile the tools and install |
|---|
| 66 | them into the location specified by the PREFIX environment parameter. If the |
|---|
| 67 | PREFIX parameter is not specified, the files will be installed into /usr/local. |
|---|
| 68 | |
|---|
| 69 | By default, darwinbuild will build for x86_64 and i386. You can override this with |
|---|
| 70 | the ARCHS environment variable. However, building trunk for ppc is not supported |
|---|
| 71 | since trunk is targeted for Darwin 10. The release branches for Darwin 8 and 9 do |
|---|
| 72 | support building for ppc. |
|---|
| 73 | |
|---|
| 74 | To build and install darwinbuild to the boot partition: |
|---|
| 75 | |
|---|
| 76 | % cd <path to top of source> |
|---|
| 77 | % sudo xcodebuild install DSTROOT=/ |
|---|
| 78 | |
|---|
| 79 | 2.1 Creating the Build Directory |
|---|
| 80 | |
|---|
| 81 | After installation, you must initialize the build directory using darwinbuild. |
|---|
| 82 | Assuming you wanted to build projects from 9G55 in your home directory: |
|---|
| 83 | |
|---|
| 84 | # mkdir ~/9G55 |
|---|
| 85 | # cd ~/9G55 |
|---|
| 86 | # sudo -s |
|---|
| 87 | # darwinbuild -init 9G55 |
|---|
| 88 | Creating build root disk image ... |
|---|
| 89 | Attempting to download http://svn.macosforge.org/repository/darwinbuild/trunk/plists//9G55.plist ... |
|---|
| 90 | Download complete |
|---|
| 91 | Attempting to download http://svn.macosforge.org/repository/darwinbuild/trunk/plists//9F33.plist ... |
|---|
| 92 | Download complete |
|---|
| 93 | ... |
|---|
| 94 | Attempting to download http://svn.macosforge.org/repository/darwinbuild/trunk/plists//9A581.plist ... |
|---|
| 95 | Download complete |
|---|
| 96 | Initialization Complete |
|---|
| 97 | # ls |
|---|
| 98 | .build Headers Logs Roots Sources Symbols |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | After initialization, the build directory will contain the following: |
|---|
| 102 | .build contains private data for the darwinbuild system |
|---|
| 103 | Headers contains the resulting header files from previous builds |
|---|
| 104 | Logs contains logs of previous build attempts |
|---|
| 105 | Roots contains the finished products of previous successful builds |
|---|
| 106 | Sources contains sources downloaded from the web |
|---|
| 107 | Symbols contains debug symbol versions of previous build products |
|---|
| 108 | |
|---|
| 109 | When using the darwinbuild command, it is necessary that the current |
|---|
| 110 | working directory be this build directory, or alternatively, |
|---|
| 111 | that the DARWIN_BUILDROOT environment variable be set to the absolute |
|---|
| 112 | path of the destination directory. The example usages in this document |
|---|
| 113 | assume the current working directory is this build directory. |
|---|
| 114 | |
|---|
| 115 | |
|---|
| 116 | ========================================= |
|---|
| 117 | 3. Building Darwin Projects (darwinbuild) |
|---|
| 118 | ========================================= |
|---|
| 119 | |
|---|
| 120 | To build a Darwin project, for example xnu, the darwinbuild script can be |
|---|
| 121 | used in the following manner: |
|---|
| 122 | # darwinbuild xnu |
|---|
| 123 | |
|---|
| 124 | The darwinxref tool is consulted to find the version that corresponds to the |
|---|
| 125 | build specified when the build directory was initialized. It is necessary |
|---|
| 126 | to run the darwinbuild tool as root so that projects can set the proper |
|---|
| 127 | ownership and permissions on the build results. |
|---|
| 128 | |
|---|
| 129 | darwinbuild first looks in the Sources directory for a directory containing |
|---|
| 130 | the sources to be built (Sources/xnu-517.11.1), or a .tar.gz archive |
|---|
| 131 | containing the sources (Sources/xnu-517.11.1.tar.gz). If neither is found, |
|---|
| 132 | darwinbuild will attempt to download the sources from the web. |
|---|
| 133 | |
|---|
| 134 | If it does not already exist, a BuildRoot directory will be created. This |
|---|
| 135 | is where the build will actually take place. During the build, darwinbuild |
|---|
| 136 | will change the root directory to BuildRoot (see the chroot(8) man page for |
|---|
| 137 | details). Darwinbuild is capable of copying the required tools, libraries |
|---|
| 138 | and headers from the Roots directory into the BuildRoot prior to building. |
|---|
| 139 | If a necessary dependency is not found in the Roots directory, it will be |
|---|
| 140 | downloaded from the web. |
|---|
| 141 | |
|---|
| 142 | The build output will be written to the console, and additionally logged |
|---|
| 143 | into a file in the Logs directory. The above example produces the |
|---|
| 144 | following file: |
|---|
| 145 | Logs/xnu/xnu-517.11.1.log~1 |
|---|
| 146 | |
|---|
| 147 | The ~1 indicates that this log file corresponds to the first attempt to |
|---|
| 148 | build xnu version 517.11.1. Each subsequent attempt will add one to this |
|---|
| 149 | build number. |
|---|
| 150 | |
|---|
| 151 | If the build succeeds, the finished product will be copied out of the |
|---|
| 152 | BuildRoot directory and into the Roots directory: |
|---|
| 153 | Roots/xnu/xnu-517.11.1.root~1 |
|---|
| 154 | After the copy, darwinbuild traverses the directory and records all files |
|---|
| 155 | found in the darwinxref database. This makes it possible to query which |
|---|
| 156 | project a file is produced by. When a Mach-O executable, library, or bundle |
|---|
| 157 | is found during the traversal, the dynamic library load commands are recorded |
|---|
| 158 | in the darwinxref database. This makes it possible to query which additional |
|---|
| 159 | projects are required to run an executable produced by the project. |
|---|
| 160 | |
|---|
| 161 | Additionally, any products containing debug symbols will be placed into |
|---|
| 162 | the Symbols directory. |
|---|
| 163 | |
|---|
| 164 | |
|---|
| 165 | 3.1 Install Headers |
|---|
| 166 | |
|---|
| 167 | Passing the -headers flag to darwinbuild will start an alternative build |
|---|
| 168 | style where only the project's headers are produced. This is useful for |
|---|
| 169 | working around various circular dependencies while compiling low level |
|---|
| 170 | projects like xnu, cctools, Libc, etc. |
|---|
| 171 | |
|---|
| 172 | The results of a -headers build are placed in the Headers directory, in |
|---|
| 173 | the same style as the Roots directory for a regular build. For example: |
|---|
| 174 | % sudo darwinbuild -headers IOKitUser |
|---|
| 175 | % ls Headers/IOKitUser/IOKitUser-184.hdrs~1 |
|---|
| 176 | |
|---|
| 177 | |
|---|
| 178 | 3.3 Logging Dependencies |
|---|
| 179 | |
|---|
| 180 | Passing the -logdeps flag to darwinbuild will build the specified project |
|---|
| 181 | while recording the paths of all files openened and all executables invoked. |
|---|
| 182 | These paths are written into the Logs directory, and if the build is |
|---|
| 183 | successful, will be imported into the darwinxref database. |
|---|
| 184 | |
|---|
| 185 | |
|---|
| 186 | ============================== |
|---|
| 187 | 4. Build Environment Variables |
|---|
| 188 | ============================== |
|---|
| 189 | |
|---|
| 190 | At the minimum, the build environment consists of the creation of SRCROOT, |
|---|
| 191 | OBJROOT, SYMROOT, and DSTROOT environment variables. These variables contain |
|---|
| 192 | an absolute path to a directory which must exist prior to invoking the Makefile. |
|---|
| 193 | User configurable environment variables, such as the target architecture, |
|---|
| 194 | can be set in the build plist file that is loaded via loadIndex. The |
|---|
| 195 | darwinbuild script creates the aforementioned directories, sets the environment |
|---|
| 196 | variables, and issues the appropriate make command. |
|---|
| 197 | |
|---|
| 198 | Within the plist file, the RC_ARCHS variable indicates which target |
|---|
| 199 | architectures should be included in the build. Currently only ppc and i386 |
|---|
| 200 | are available. For each architecture in RC_ARCHS, and equivalent RC_{arch} |
|---|
| 201 | should be set to YES (i.e. RC_ARCHS="ppc" RC_ppc=YES). |
|---|
| 202 | |
|---|
| 203 | The RC_NONARCH_CFLAGS specify additional command line flags to be passed to the C |
|---|
| 204 | compiler during the build. On Darwin, the -no-cpp-precomp flag should be |
|---|
| 205 | passed since cpp-precomp is not available. During the build, the RC_ARCHS and |
|---|
| 206 | RC_NONARCH_CFLAGS variables will be combined to create the RC_ARCHS environment |
|---|
| 207 | variable; a -arch flag will be appended for each architecture listed in RC_ARCHS. |
|---|
| 208 | |
|---|
| 209 | The MACOSX_DEPLOYMENT_TARGET variable should match the major Mac OS X release |
|---|
| 210 | that is being targeted, such as 10.2 or 10.3. |
|---|
| 211 | |
|---|
| 212 | |
|---|
| 213 | 4.1 Build Aliases and Alternate Targets |
|---|
| 214 | |
|---|
| 215 | Some projects may produce different results based on the contents of |
|---|
| 216 | the RC_ProjectName variable. When the same source archive is used |
|---|
| 217 | to create more than one component of Darwin, it's referred to as a build |
|---|
| 218 | alias. Because of this, it is important to always provide accurrate |
|---|
| 219 | project name and version information in the environment. By default, |
|---|
| 220 | darwinbuild sets these variables appropriately. |
|---|
| 221 | |
|---|
| 222 | By default, "install" (for non-headers builds) is the first argument passed |
|---|
| 223 | to the make tool (gnumake or xcodebuild). However, some projects produce |
|---|
| 224 | different results based on alternate targets. If the project in the property |
|---|
| 225 | list contains a "target" attribute, that string will be passed instead. |
|---|
| 226 | |
|---|
| 227 | |
|---|
| 228 | ====================== |
|---|
| 229 | 5. Tips and Techniques |
|---|
| 230 | ====================== |
|---|
| 231 | |
|---|
| 232 | |
|---|
| 233 | 5.1 Private Headers |
|---|
| 234 | |
|---|
| 235 | Many open source header files are not present in a standard Mac OS X install. |
|---|
| 236 | These "private headers" are not needed by application developers, and are not |
|---|
| 237 | part of any SDK officially supported by Apple. However, Darwin projects are |
|---|
| 238 | part of the operating system itself and these headers are required. The |
|---|
| 239 | darwinbuildheaders command uses the darwinxref tool and darwinbuild -headers |
|---|
| 240 | commands to produce all header files for a given darwin release. |
|---|
| 241 | % bin/darwinbuildheaders |
|---|
| 242 | |
|---|
| 243 | The resulting header files from each project are placed into the Headers |
|---|
| 244 | directory. The headers can be subsequently installed into the BuildRoot |
|---|
| 245 | directory using the installheaders command. |
|---|
| 246 | % bin/installheaders |
|---|
| 247 | |
|---|
| 248 | By modifying the build plist file, it is possible to include these headers |
|---|
| 249 | instead of the default system headers, giving more accurate build results and |
|---|
| 250 | avoiding failures. Edit the RC_NONARCH_CFLAGS variable to provide the following |
|---|
| 251 | include paths to gcc (substituting the actual installation directory). |
|---|
| 252 | -I/usr/local/darwinbuild/BuildRoot/usr/include |
|---|
| 253 | -I/usr/local/darwinbuild/BuildRoot/usr/local/include |
|---|
| 254 | |
|---|
| 255 | |
|---|
| 256 | 5.2 Build Tools |
|---|
| 257 | |
|---|
| 258 | In addition to private headers, there are numerous command line tools which |
|---|
| 259 | are used exclusively to build Darwin projects. These tools are placed in |
|---|
| 260 | /usr/local/bin. For example, building xnu requires kextsymboltool, |
|---|
| 261 | relpath, and decomment. |
|---|
| 262 | |
|---|
| 263 | |
|---|
| 264 | 5.3 Static Libraries |
|---|
| 265 | |
|---|
| 266 | Several projects require static libraries from other projects. These libraries |
|---|
| 267 | are usually placed in /usr/local/lib/system. The most notable examples are |
|---|
| 268 | xnu's usage of libkld.a which is produced by cctools_ofiles, and Libsystem's |
|---|
| 269 | use of many static libraries from Libc, Libinfo, and more. |
|---|
| 270 | |
|---|
| 271 | |
|---|
| 272 | 5.4 Alternate BuildRoot Storage |
|---|
| 273 | |
|---|
| 274 | By default, "darwinbuild -init" will setup your environment to use a HFSX |
|---|
| 275 | sparsebundle to host your BuildRoot. A sparsebundle is used to work around |
|---|
| 276 | problems with using xcodebuild inside of a chroot. There are two other |
|---|
| 277 | storage methods to choose from: NFS Loopback and Legacy Directory. |
|---|
| 278 | |
|---|
| 279 | 1. NFS Loopback (ex: darwinbuild -init 9G55 -nfs) |
|---|
| 280 | The NFS loopback method places a directory under .build and adds that |
|---|
| 281 | directory to /etc/exports. When you try to build a project, darwinbuild |
|---|
| 282 | will mount the NFS export on localhost. The NFS mount also works around |
|---|
| 283 | the xcodebuild problems. |
|---|
| 284 | |
|---|
| 285 | 2. Legacy Directory (ex: darwinbuild -init 9G55 -nodmg) |
|---|
| 286 | This is just the way darwinbuild worked before the sparsebundle and NFS |
|---|
| 287 | support was added. It just makes a directory for BuildRoot and builds |
|---|
| 288 | on whatever filesystem you are on at the time. If you are on HFS or ZFS, |
|---|
| 289 | this storage will cause problems for Xcode-based projects. |
|---|
| 290 | |
|---|
| 291 | |
|---|
| 292 | ============= |
|---|
| 293 | A. darwinxref |
|---|
| 294 | ============= |
|---|
| 295 | |
|---|
| 296 | The darwinxref tool allows you to query which source version of a Darwin |
|---|
| 297 | project is present in a particular Mac OS X build. It also stores information |
|---|
| 298 | about what dependencies a particular project has, and what files the project |
|---|
| 299 | produces. As each Mac OS X release is made available, Apple publishes a |
|---|
| 300 | property list file containing the project names and versions in that release. |
|---|
| 301 | These property lists are read by the darwinxref tool to seed its internal |
|---|
| 302 | database. Property lists are available via Subversion[1]. |
|---|
| 303 | |
|---|
| 304 | The darwinxref tool uses SQLite[2] to maintain its database of projects, |
|---|
| 305 | versions, files and dependencies. This distribution includes a pre-built |
|---|
| 306 | version of the sqlite library in the file libsqlite3.a, and its associated |
|---|
| 307 | header file, sqlite3.h. |
|---|
| 308 | |
|---|
| 309 | [1] <http://svn.macosforge.org/repository/darwinbuild/trunk/plists> |
|---|
| 310 | [2] <http://www.sqlite.org/> |
|---|
| 311 | |
|---|
| 312 | An example of downloading, installing, and querying a property list: |
|---|
| 313 | % curl http://svn.macosforge.org/repository/darwinbuild/trunk/plists/7U16.plist > \ |
|---|
| 314 | plists/7U16.plist |
|---|
| 315 | % bin/darwinxref loadIndex plists/7U16.plist |
|---|
| 316 | 268 of 268 projects loaded. |
|---|
| 317 | % bin/darwinxref -b 7U16 version xnu |
|---|
| 318 | xnu-517.11.1 |
|---|
| 319 | |
|---|
| 320 | To list all projects in a build, use the special project name '*': |
|---|
| 321 | % bin/darwinxref -b 7U16 version '*' |
|---|
| 322 | |
|---|
| 323 | To register the results of a previous build with the database use the |
|---|
| 324 | register command. Note this is done automatically by darwinbuild: |
|---|
| 325 | % bin/darwinxref register adv_cmds 63 Roots/adv_cmds/adv_cmds-63.root~1 |
|---|
| 326 | /bin |
|---|
| 327 | /bin/ps |
|---|
| 328 | /bin/stty |
|---|
| 329 | ... |
|---|
| 330 | |
|---|
| 331 | To find which project produces the 'whois' command by searching the |
|---|
| 332 | list of previously registered files: |
|---|
| 333 | % bin/darwinxref findFile whois |
|---|
| 334 | adv_cmds-63: |
|---|
| 335 | /usr/bin/whois |
|---|
| 336 | |
|---|
| 337 | |
|---|