h6. [[Developer documentation]] h6(. » Overview of the Build Tool !Builder is the program that's at the heart of the RISC OS build system. Whether you're building a ROM image, a hard disc image, a collection of standalone programs, or even the build tools themselves, you'll be doing it with the help of Builder. * "Build directories":#build_directories * "Build Environments, Components, and Products":#environments * "Build stages":#build_stages * "Other options":#other_options * "Performing a build":#building * "See also":#see_also h2(#build_directories). Build directories All builds occur inside a _build directory_. The build directory contains all the source files, all the build tools, all the intermediate files, and all the final output files. The first time you run Builder a window will pop up asking you to register the initial build directory. The build directory is the directory which contains the "Apps", "BuildSys", "Sources", "Tools", etc. sub-directories, so drag that into the window in order to register it. If you want to change the location of your build directory or register additional directories, you can do so by selecting the "Register build tree" option from the iconbar menu. h2(#environments). Build Environments, Components, and Products Each _build directory_ allows you to build one or more _products_. E.g. the Tungsten source archive contains the files needed to build the 'Tungsten' product, which is an Iyonix ROM image. What a product is and how it should be built is described in three separate places: * The _git superproject_, which is in the "Products group in gitlab":https://gitlab.riscosopen.org/Products. Each project/repository in that group is little more than a collection of git submodules, where each submodule corresponds to a Component of the product. In some cases the project specifies which branch or version of a component should be fetched (e.g. stable builds will pin their components to specific versions). Note that the submodule configuration is only used by git; Builder and the other build tools use other files to work out what components to include in the build. These git superprojects are the modern version of the "product files" that were used when CVS was used for source control. * The _environment file_, which is located in the Env.ROOL folder of the build tree. When run, the environment file will configure your machine so that it's ready to perform a build of the corresponding product. This file also indicates which _components file_ should be used. * The _components file_, which is located in the BuildSys.Components.ROOL folder. The components file contains a list of _components_, their build options, and the order in which they should be built. Generally this will have the same name as the environment file. Knowledge of the above three systems and their role in the build system is important if you want to be able to understand the rest of this document. Note that because all the environment and component files are located alongside each other in the same folders in git, any sources you download (whether via git or a source archive) will contain the full set of environment + component files. When selecting the environment in Builder, you need to be careful to only select an environment that is supported by your source tree, otherwise the build is likely to fail (components may be missing or may be on the wrong versions) For more information about products, environments, and components, see the [[Developer's guide to RISC OS builds]] page. h2(#build_stages). Build stages Clicking on Builder's iconbar icon will open the main window. In the 'Build options' section of this window are a number of check boxes for selecting the different build stages. It's important to know what each stage does and when it must be used (not all stages are applicable to all product types). Build stages are executed in the following order: # "List":#list # "Clean":#clean # "Clean All":#clean_all # "Export headers":#export_headers # "Export libraries":#export_libraries # "Export resources":#export_resources # "Make ROM":#make_rom # "Install ROM":#install_rom # "Join ROM":#join_rom # "BBE":#bbe (Binary Build Environment) # "Install disc":#install_disc h4(#list). The 'List' stage This stage simply causes Builder to output a list of each component in the components file, together with the components build options. This may not seem like a very useful feature to you or me, but presumably it was an important feature at some point in time! h4(#clean). The 'Clean' stage For each component in the components file, Builder will invoke AMU on the component's makefile, specifying the 'clean' target. As you can probably guess, this has the effect of cleaning the source folder for each component. This will typically delete all the object files, cmhg-generated header files, and linked output files. It will also delete the contents of Sources.Internat.Messages.Resources (a folder that's used as a staging area for the contents of ResourceFS) However, the Clean phase doesn't clean everything, hence the presence of the 'Clean All' stage... h4(#clean_all). The 'Clean All' stage For each component in the components file, Builder will invoke AMU on the component's makefile, specifying the 'clean_all' target. This is very similar to the 'clean' target, but cleans extra stuff which clean does not. For example it will strip the dynamic dependencies from the makefiles. TODO - Document any other things which clean_all does. Even though this is the 'Clean All' stage. there are still parts of the build tree that don't get cleaned. E.g. the Export folder and the Install folder are left intact (more on the purpose of these folders later). h4(#export_headers). The 'Export headers' stage This stage causes Builder to build the 'export' target of each makefile, with PHASE=hdrs. Or in laymans terms, it populates the Export folder with all the shared headers that the other components rely upon. The main source of headers is the HdrSrc component (located in Sources.Programmer.HdrSrc), but many other components will provide headers too (e.g. each module will typically have a header listing all its SWI numbers and reason codes). h4(#export_libraries). The 'Export libraries' stage This stage causes Builder to build the 'export' target of each makefile, with PHASE=libs. Or in laymans terms, it builds all the static libraries that the other components rely upon. For example many C modules use the callx library to make it easier to use callbacks. After each library is built, it will be copied to the Export.<APCS>.Lib folder, ready for linking with other components. h4(#export_resources). The 'Export resources' stage This stage causes Builder to build the 'resources' target of each makefile. For components which store files in ResourceFS, this causes those files to be copied into the Sources.Internat.Messages.Resources folder, ready for being built into the locale-specific Messages module. h4(#make_rom). The 'Make ROM' stage This stage causes Builder to build the 'rom' target of each makefile. This will compile, but not link, each component that is destined to be placed in a ROM image. Apart from the HAL, all the components which get built during this stage will be modules. h4(#install_rom). The 'Install ROM' stage This stage causes Builder to build the 'rom_link' target of each makefile. For assembler modules and the HAL, this simply involves copying the module into the 'Install' folder, ready for placing into a ROM image. For C modules this will also involve performing a partial static linking of the module with the ROM Shared C Library. The way this works is that as the install_rom phase progresses, Builder keeps track of the base address of each module. Each C module is then statically linked to run at that address, and special C library stubs are used which allow the modules to call directly into the ROM Shared C Library. Although this eliminates the "relocatable" aspect of the relocatable module, it is currently the only way in which ROM C modules can function (due to the Norcroft compiler not supporting read-only position-independent code). During the install_rom phase, most components will also copy debug symbols to the 'Install' folder. The ROM linker and other debug tools know to look for these symbols and make them available for debugging purposes (e.g. by embedding them into the ROM image) At the end of the stage, Builder will print out a table listing each module and its intended location within the ROM image. h4(#join_rom). The 'Join ROM' stage This stage uses the 'romlinker' tool to link the contents of the Install folder into a ROM image, with the items linked in the order denoted in the components file. For the most part this linking process just involves concatenating the files together, but romlinker also performs some important additional functions: * Adding padding where necessary, e.g. to ensure the HAL is 64K in size, or to pad the ROM image to the required size * Adding the debug symbols to the ROM image, to provide basic function-level debugging information to the [[Debugger]] module * Placing a checksum and timestamp in the last few bytes of the image If the link operation succeeded then the finished ROM image will be placed in the Images folder. h4(#bbe). The 'BBE' (Binary Build Environment) stage This stage causes Builder to build the 'bbe' target of each makefile. TODO - What does this do? h4(#install_disc). The 'Install disc' stage This stage causes Builder to build the 'install' target of each makefile. For the HardDisc4 disc image, this will build each disc-based component and copy it into the Install.HardDisc4 folder. For the build tools (BuildHost product) this will build each build tool and copy it into the appropriate location within the live build tree. Other products (e.g. CTools, Printers) install their files to differing locations. h2(#other_options). Other options The other options available in Builder's main window aren't very significant any more, and are best left alone. h2(#building). Performing a build If you've registered a "build directory":#build_directories with Builder then clicking select on the iconbar icon will open the main window. The first thing you'll want to do is to make sure the right build directory and "environment":#environments are selected. Select the build directory first and then the build environment second, as the contents of the environment list is dependent upon which build directory you have selected. Selecting an environment will cause Builder to run the corresponding environment file, thus setting up your machine so that it's ready for the build. This configuration step is vitally important, even if you plan on using the numerous !Mk, !MkSA, etc. scripts to build components individually. Without selecting an environment in Builder (or running the corresponding Env file manually) the code may be compiled for the wrong CPU type, be linked against the wrong libraries, or use the wrong set of header files, etc. Once you've got the right build directory and environment selected, you're ready to select which "build stages":#build_stages you want to run. Generally speaking: table(bordered). |_<^. Type of Build |_<^. Additional Info |_<^{width:12em}. Build Stages to Run | |<^. Build a ROM Image |<^. From a clean source tree |<^. <ul> <li>Export headers</li> <li>Export libraries</li> <li>Export resources</li> <li>Make ROM</li> <li>Install ROM</li> <li>Join ROM</li></ul> | |<^. Rebuild a ROM Image |<^. After making some code changes |<^. <ul> <li>Make ROM</li> <li>Install ROM</li> <li>Join ROM</li></ul> | |<^. Rebuild a ROM Image |<^. After changing a exported header (and have not exported it manually) |<^. <ul> <li>Export headers</li> <li>Make ROM</li> <li>Install ROM</li> <li>Join ROM</li></ul> | |<^. Rebuild a ROM Image |<^. After changing a file which goes in [[ResourceFS]] |<^. <ul> <li>Export resources</li> <li>Make ROM</li> <li>Install ROM</li> <li>Join ROM</li></ul> | |<^. Rebuild a ROM Image |<^. After changing a library sources |<^. <ul> <li>Export libraries</li> <li>Make ROM</li> <li>Install ROM</li> <li>Join ROM</li></ul> | |<^. Build a HardDisc4 disc image |<^. From a clean source tree |<^. <ul> <li>Export headers</li> <li>Export libraries</li> <li>Install disc</li></ul> | |<^. Build a HardDisc4 disc image |<^. Subsequent disc image builds (unless a shared header or library has been changed) |<^. <ul> <li>Install disc</li></ul> | Once you've selected the right options, simply hit the 'Build' button and wait for the build to complete. While the build is in progress a taskwindow should open displaying the build log. The log also gets saved to the BuildSys.Logs folder, should you need to refer to it later on. Although you can use the computer while the build is in progress, make sure that you don't do anything that will cause the currently selected directory (CSD) to change, otherwise the build will most likely break, sometimes in subtle ways that don't result in the build failing with an error message. h2(#see_also). See also Here are some other pages containing information about the RISC OS build system: * [[How to build RISC OS]] * [[Developer's guide to RISC OS builds]] * [[Build FAQ]]