RTEMS Source Builder ==================== :doctype: book :toc2: :toclevels: 5 :icons: :numbered: image:images/rtemswhitebg.jpg["RTEMS",width="30%"] Chris Johns 1.0, February 2013 RTEMS Tools From Source ----------------------- The RTEMS Source Builder is a tool to aid building packages from source. It is not a package manager. It helps consolidate the details you need to build a package from source in a controlled and verifiable way. The tool is aimed at developers of software who use tool sets for embedded type development. Embedded development typically uses cross-compiling tool chains, debuggers, and debugging aids. Together we call these a 'tool set'. The RTEMS Source Builder is not limited to this role but designed to fit with-in this specific niche. It can be used outside of the RTEMS project and we welcome this happening in other open source or commercial projects. The RTEMS Source Builder is typically used to build a set of tools or a 'build set'. A 'build set' is a collection of packages and a package is a specific tool, for example gcc or gdb. The RTEMS Source Builder attempts to support any host environment that runs Python and you can build the package on. It is not some sort of magic that can take any piece of source code and make it build. Someone at some point in time has figured out how to build that package from source and taught this tool. The RTEMS Source Builder has been tested on: * FreeBSD * MacOS (Mountain Lion) * Ubuntu * Centos * Fedora * Raspbian Windows support is being added how-ever there are issues with the Python threading used in the RTEMS Source Builder and the MinGW project's MSYS process handling of `make`. The RTEMS Source Builder has two types configuration data. The first is the 'build set'. A _build set_ describes a collection of packages that define a set of tools you would use when developing software for RTEMS. For example the basic GNU tool set is binutils, gcc, and gdb and is the typical base suite of tools you need for an embedded cross-development type project. The second type of configuration data is the configuration files and they define how a package is built. Configuration files are scripts loosely based on the RPM spec file format and detail the steps needed to build a package. The steps are 'preparation', 'building', and 'installing'. Scripts support macros, shell expansion, logic, includes plus many more features useful when build packages. The RTEMS Source Builder does not interact with any host package management systems. There is no automatic dependence checking between various packages you build or packages and software your host system you may have installed. We assume the build sets and configuration files you are using have been created by developers who do. If you have a problem please ask on the RTEMS Users mailing list. Quick Start ----------- The quick start will show you how to build a set of RTEMS tools for a supported architecture. There is no need to become root or the administrator and we recommend you avoid doing this. You can build and install the tools anywhere on the host's file system you, as a standard user, have read and write access too. I recommend you use your home directory and work under the directory `~/development/rtems`. The examples shown here will do this. You can use the build _prefix_ to install and maintain different versions of the tools. Doing this lets you try a new set of tools while not touching your proven working production set of tools. Once you have proven the new tools are working rebuild with the 'production' prefix switching your development to them. I also suggest you keep your environment to the bare minimum, particularly the path variable. Using environment variables has been proven over the years to be difficult to manage in production systems. Setup ~~~~~ Setup a development work space: ------------------------------------------------------------- $ cd $ mkdir -p development/rtems/src $ cd development/rtems/src ------------------------------------------------------------- The RTEMS Source Builder is distributed as source. It is Python code so all you need to do is head over to the RTEMS GIT repository and clone the code directly from git: ------------------------------------------------------------- $ git clone git://git.rtems.org/chrisj/rtems-source-builder.git $ cd rtems-source-builder ------------------------------------------------------------- Checking ~~~~~~~~ The next step is to check if your host is set up correctly. The RTEMS Source Builder provides a tool to help: ------------------------------------------------------------- $ source-builder/sb-check warning: exe: absolute exe found in path: (__objcopy) /usr/local/bin/objcopy <1> warning: exe: absolute exe found in path: (__objdump) /usr/local/bin/objdump error: exe: not found: (_xz) /usr/local/bin/xz <2> RTEMS Source Builder environment is not correctly set up $ source-builder/sb-check RTEMS Source Builder environment is ok <3> ------------------------------------------------------------- <1> A tool is in the environment path but does not match the expected path. <2> The executable 'xz' is not found. <3> The host's environment is set up correct. The checking tool will output a list of executable files not found if problems are detected. Locate those executable files and install them. You may also be given a list of warnings about executable files not in the expected location how-ever the executable was located somewhere in your environment's path. You will need to check each tool to determine if this is an issue. An executable not in the standard location may indicate it is not the host operating system's standard tool. It maybe ok or it could be buggy, only you can determine this. The <<_host_setups,Host Setups>> section lists packages you should install for common host operating systems. It maybe worth checking if you have those installed. Build Sets ~~~~~~~~~~ The RTEMS tools can be built within the RTEMS Source Builder's source tree. We recommend you do this so lets change into the RTEMS directory in the RTEMS Source Builder package: ------------------------------------------------------------- $ cd rtems ------------------------------------------------------------- If you are unsure how to specify the build set for the architecture you wish to build ask the tool: ------------------------------------------------------------- $ ../source-builder/sb-set-builder --list-bsets <1> RTEMS Source Builder - Set Builder, v0.1 Examining: config <2> Examining: ../source-builder/config <2> 4.11/rtems-all.bset <3> 4.11/rtems-arm.bset <4> 4.11/rtems-avr.bset 4.11/rtems-bfin.bset 4.11/rtems-h8300.bset 4.11/rtems-m32c.bset 4.11/rtems-m32r.bset 4.11/rtems-m68k.bset 4.11/rtems-microblaze.bset 4.11/rtems-mips.bset 4.11/rtems-moxie.bset 4.11/rtems-nios2.bset 4.11/rtems-powerpc.bset 4.11/rtems-sh.bset 4.11/rtems-sparc.bset gnu-tools-4.6.bset rtems-4.11-base.bset unstable/4.11/rtems-all.bset <5> unstable/4.11/rtems-arm.bset unstable/4.11/rtems-avr.bset unstable/4.11/rtems-bfin.bset unstable/4.11/rtems-h8300.bset unstable/4.11/rtems-m32c.bset unstable/4.11/rtems-m32r.bset unstable/4.11/rtems-m68k.bset unstable/4.11/rtems-microblaze.bset unstable/4.11/rtems-mips.bset unstable/4.11/rtems-moxie.bset unstable/4.11/rtems-powerpc.bset unstable/4.11/rtems-sh.bset unstable/4.11/rtems-sparc.bset ------------------------------------------------------------- <1> Only option needed is +--list-bsets+ <2> The paths inspected. See <> variable. <3> Build all the architectures. <4> The build set for the ARM architecture. <5> Unstable tool sets are used by RTEMS developers to test new tool sets. You are welcome to try them but you must remember they are unstable, can change at point in time and your application may not work. If you have an issue with a production tool it may pay to try the unstable tool to see if it has been resolved. Building ~~~~~~~~ In this quick start I will build a SPARC tool set. ------------------------------------------------------------- $ ../source-builder/sb-set-builder --log=l-sparc.txt <1> \ --prefix=$HOME/development/rtems/4.11 <2> 4.11/rtems-sparc <3> Source Builder - Set Builder, v0.1 Build Set: 4.11/rtems-sparc config: expat-2.1.0-1.cfg <4> package: expat-2.1.0-x86_64-freebsd9.1-1 building: expat-2.1.0-x86_64-freebsd9.1-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 <5> config: tools/rtems-binutils-2.22-1.cfg <6> package: sparc-rtems4.11-binutils-2.22-1 building: sparc-rtems4.11-binutils-2.22-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 config: tools/rtems-gcc-4.7.2-newlib-1.20.0-1.cfg <7> package: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 building: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 config: tools/rtems-gdb-7.5.1-1.cfg <8> package: sparc-rtems4.11-gdb-7.5.1-1 building: sparc-rtems4.11-gdb-7.5.1-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 cleaning: expat-2.1.0-x86_64-freebsd9.1-1 <9> cleaning: sparc-rtems4.11-binutils-2.22-1 cleaning: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 cleaning: sparc-rtems4.11-gdb-7.5.1-1 Build Set: Time 0:13:43.616383 <10> ------------------------------------------------------------- <1> Providing a log file redirects the build output into a file. Logging the build output provides a simple way to report problems. <2> The prefix is the location on your file system the tools are installed into. Provide a prefix to a location you have read and write access. You can use the prefix to install different versions or builds of tools. Just use the path to the tools you want to use when building RTEMS. <3> The build set. This is the SPARC build set. <4> The SPARC build set first builds the expat library as is used in GDB. This is the expat configuration used. <5> Installing the expat package to the install prefix. <6> The binutils build configuration. <7> The GCC and Newlib build configuration. <8> The GDB build configuration. <9> All the packages built are cleaned at the end. If the build fails all the needed files are present. You may have to clean up by deleting the build directory if the build fails. <10> The time to build the package. This lets you see how different host hardware or configurations perform. Your SPARC RTEMS 4.11 tool set will be installed and ready to build RTEMS and RTEMS applications. When the build runs you will notice the tool fetch the source code from the internet. These files are cached in a directory called +source+. If you run the build again the cached files are used. This is what happened in the show example before. The installed tools: ------------------------------------------------------------- $ ls $HOME/development/rtems/4.11 bin include lib libexec share sparc-rtems4.11 $ ls $HOME/development/rtems/4.11/bin sparc-rtems4.11-addr2line sparc-rtems4.11-cpp sparc-rtems4.11-gcc-ar sparc-rtems4.11-gprof sparc-rtems4.11-objdump sparc-rtems4.11-size sparc-rtems4.11-ar sparc-rtems4.11-elfedit sparc-rtems4.11-gcc-nm sparc-rtems4.11-ld sparc-rtems4.11-ranlib sparc-rtems4.11-strings sparc-rtems4.11-as sparc-rtems4.11-g++ sparc-rtems4.11-gcc-ranlib sparc-rtems4.11-ld.bfd sparc-rtems4.11-readelf sparc-rtems4.11-strip sparc-rtems4.11-c++ sparc-rtems4.11-gcc sparc-rtems4.11-gcov sparc-rtems4.11-nm sparc-rtems4.11-run xmlwf sparc-rtems4.11-c++filt sparc-rtems4.11-gcc-4.7.2 sparc-rtems4.11-gdb sparc-rtems4.11-objcopy sparc-rtems4.11-sis $ $HOME/development/rtems/4.11/bin/sparc-rtems4.11-gcc -v Using built-in specs. COLLECT_GCC=/home/chris/development/rtems/4.11/bin/sparc-rtems4.11-gcc COLLECT_LTO_WRAPPER=/usr/home/chris/development/rtems/4.11/bin/../ \ libexec/gcc/sparc-rtems4.11/4.7.2/lto-wrapper Target: sparc-rtems4.11 Configured with: ../gcc-4.7.2/configure --prefix=/home/chris/development/rtems/4.11 --bindir=/home/chris/development/rtems/4.11/bin --exec_prefix=/home/chris/development/rtems/4.11 --includedir=/home/chris/development/rtems/4.11/include --libdir=/home/chris/development/rtems/4.11/lib --libexecdir=/home/chris/development/rtems/4.11/libexec --mandir=/home/chris/development/rtems/4.11/share/man --infodir=/home/chris/development/rtems/4.11/share/info --datadir=/home/chris/development/rtems/4.11/share --build=x86_64-freebsd9.1 --host=x86_64-freebsd9.1 --target=sparc-rtems4.11 --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --verbose --with-newlib --with-system-zlib --disable-nls --without-included-gettext --disable-win32-registry --enable-version-specific-runtime-libs --disable-lto --enable-threads --enable-plugin --enable-newlib-io-c99-formats --enable-newlib-iconv --enable-languages=c,c++ Thread model: rtems gcc version 4.7.2 20120920 (RTEMS) (GCC) ------------------------------------------------------------- Installing and Tar Files ~~~~~~~~~~~~~~~~~~~~~~~~ The RTEMS Source Builder can install the built packages directly and optionally it can create a build set tar file or a tar file per package built. The normal and default behaviour is to let the RTEMS Source Builder install the tools. The source will be downloaded, built, installed and cleaned up. The tar files are created with the full build prefix present. This can cause problems if you are installing on a host you do not have super user or administrator rights on if the prefix path references part you do not have write access t0o. You can use the +--strip-components+ option in tar if your tar file supports it to remove the parts you do not have write access too or you may need to unpack the tar file somewhere and copy the file tree from the level you have write access from. Embedding the full prefix path in the tar files lets you know what the prefix is. A build set tar file is created by adding `--bset-tar-file` option to the `sb-set-builder` command. ------------------------------------------------------------- $ ../source-builder/sb-set-builder --log=l-sparc.txt \ --prefix=$HOME/development/rtems/4.11 \ --bset-tar-file <1> 4.11/rtems-sparc Source Builder - Set Builder, v0.1 Build Set: 4.11/rtems-sparc config: expat-2.1.0-1.cfg package: expat-2.1.0-x86_64-freebsd9.1-1 building: expat-2.1.0-x86_64-freebsd9.1-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 <2> config: tools/rtems-binutils-2.22-1.cfg package: sparc-rtems4.11-binutils-2.22-1 building: sparc-rtems4.11-binutils-2.22-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 config: tools/rtems-gcc-4.7.2-newlib-1.20.0-1.cfg package: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 building: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 config: tools/rtems-gdb-7.5.1-1.cfg package: sparc-rtems4.11-gdb-7.5.1-1 building: sparc-rtems4.11-gdb-7.5.1-1 installing: rtems-4.11-sparc-rtems4.11-1 -> /home/chris/development/rtems/4.11 tarball: tar/rtems-4.11-sparc-rtems4.11-1.tar.bz2 <3> cleaning: expat-2.1.0-x86_64-freebsd9.1-1 cleaning: sparc-rtems4.11-binutils-2.22-1 cleaning: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 cleaning: sparc-rtems4.11-gdb-7.5.1-1 Build Set: Time 0:15:25.92873 ------------------------------------------------------------- <1> The option to create a build set tar file. <2> The installation still happens. <3> Creating the build set tar file. You can also suppress installing the files using the `--no-install` option to the `sb-set-builder` command. ------------------------------------------------------------- $ ../source-builder/sb-set-builder --log=l-sparc.txt \ --prefix=$HOME/development/rtems/4.11 \ --bset-tar-file --no-install <1> 4.11/rtems-sparc Source Builder - Set Builder, v0.1 Build Set: 4.11/rtems-sparc config: expat-2.1.0-1.cfg package: expat-2.1.0-x86_64-freebsd9.1-1 building: expat-2.1.0-x86_64-freebsd9.1-1 config: tools/rtems-binutils-2.22-1.cfg package: sparc-rtems4.11-binutils-2.22-1 building: sparc-rtems4.11-binutils-2.22-1 config: tools/rtems-gcc-4.7.2-newlib-1.20.0-1.cfg package: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 building: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 config: tools/rtems-gdb-7.5.1-1.cfg package: sparc-rtems4.11-gdb-7.5.1-1 building: sparc-rtems4.11-gdb-7.5.1-1 tarball: tar/rtems-4.11-sparc-rtems4.11-1.tar.bz2 <2> cleaning: expat-2.1.0-x86_64-freebsd9.1-1 cleaning: sparc-rtems4.11-binutils-2.22-1 cleaning: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 cleaning: sparc-rtems4.11-gdb-7.5.1-1 Build Set: Time 0:14:11.721274 $ ls tar rtems-4.11-sparc-rtems4.11-1.tar.bz2 ------------------------------------------------------------- <1> The option to supressing installing the packages. <2> Create the build set tar. A package tar file can be created by adding the +--pkg-tar-files+ to the +sb-set-builder+ command. This creates a tar file per package built in the build set. ------------------------------------------------------------- $ ../source-builder/sb-set-builder --log=l-sparc.txt \ --prefix=$HOME/development/rtems/4.11 \ --bset-tar-file --pkg-tar-files <1> --no-install 4.11/rtems-sparc Source Builder - Set Builder, v0.1 Build Set: 4.11/rtems-sparc config: expat-2.1.0-1.cfg package: expat-2.1.0-x86_64-freebsd9.1-1 building: expat-2.1.0-x86_64-freebsd9.1-1 config: tools/rtems-binutils-2.22-1.cfg package: sparc-rtems4.11-binutils-2.22-1 building: sparc-rtems4.11-binutils-2.22-1 config: tools/rtems-gcc-4.7.2-newlib-1.20.0-1.cfg package: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 building: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 config: tools/rtems-gdb-7.5.1-1.cfg package: sparc-rtems4.11-gdb-7.5.1-1 building: sparc-rtems4.11-gdb-7.5.1-1 tarball: tar/rtems-4.11-sparc-rtems4.11-1.tar.bz2 cleaning: expat-2.1.0-x86_64-freebsd9.1-1 cleaning: sparc-rtems4.11-binutils-2.22-1 cleaning: sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1 cleaning: sparc-rtems4.11-gdb-7.5.1-1 Build Set: Time 0:14:37.658460 $ ls tar expat-2.1.0-x86_64-freebsd9.1-1.tar.bz2 sparc-rtems4.11-binutils-2.22-1.tar.bz2 sparc-rtems4.11-gdb-7.5.1-1.tar.bz2 <2> rtems-4.11-sparc-rtems4.11-1.tar.bz2 <3> sparc-rtems4.11-gcc-4.7.2-newlib-1.20.0-1.tar.bz2 ------------------------------------------------------------- <1> The option to create packages tar files. <2> The GDB package tar file. <3> The build set tar file. All the others in a single tar file. Why Build from Source ? ----------------------- The RTEMS Source Builder is not a replacement for the binary install systems you have with commercial operating systems or open source operating system distributions. Those products and distributions are critically important and are the base that allows the Source Builder to work. The RTEMS Source Builder sits somewhere between you manually entering the commands to build a tool set and a tool such as +yum+ or +apt-get+ to install binary packages made specifically for your host operating system. Building manually or installing a binary package from a remote repository are valid and real alternatives while the Source Builder is attempting to provide a specific service of repeatably being able to build tool sets from source code. If you are developing a system or product that has a long shelf life or is used in a critical piece of infrastructure that has a long life cycle being able to build from source is important. It insulates the project from the fast ever changing world of the host development machines. If your tool set is binary and you have lost the ability to build it you have lost a degree of control and flexibility open source gives you. Fast moving host environments are fantastic. We have powerful multi-core computers with huge amounts of memory and state of the art operating systems to run on them how-ever the product or project you are part of may need to be maintained well past the life time of these host. Being able to build from source an important and critical part of this process because you can move to a newer host and create an equivalent tool set. Building from source provides you with control over the configuration of the package you are building. If all or the most important dependent parts are built from source you limit the exposure to host variations. For example the GNU C compiler (gcc) currently uses a number of 3rd party libraries internally (gmp, mpfr, etc). If your validated compiler generating code for your target processor is dynamically linked against the host's version of these libraries any change in the host's configuration may effect you. The changes the host's package management system makes may be perfectly reasonable in relation to the distribution being managed how-ever this may not extend to you and your tools. Building your tools from source and controlling the specific version of these dependent parts means you are not exposing yourself to unexpected and often difficult to resolve problems. On the other side you need to make sure your tools build and work with newer versions of the host operating system. Given the stability of standards based libraries like 'libc' and ever improving support for standard header file locations this task is becoming easier. The RTEMS Source Builder is designed to be audited and incorporated into a project's verification and validation process. If your project is developing critical applications that needs to be traced from source to executable code in the target, you need to also consider the tools and how to track them. If your IT department maintains all your computers and you do not have suitable rights to install binary packages, building from source lets you create your own tool set that you install under your home directory. Avoiding installing any extra packages as a super user is always helpful in maintaining a secure computing environment. Configuration ------------- The RTEMS Source Builder has two types of configuration data: . Build Sets . Package Build Configurations By default these files can be located in two separate directories and searched. The first directory is +config+ in your current working directory (+_topdir+) and the second is +config+ located in the base directory of the RTEMS Source Builder command you run (+_sbdir+). The RTEMS directory +rtems+ located at the top of the RTEMS Source Builder source code is an example of a specific build configuration directory. You can create custom or private build configurations and if you run the RTEMS Source Builder command from that directory your configurations will be used. [[X1]] The configuration search path is a macro variable and is reference as +%\{_configdir\}+. It's default is defined as: ------------------------------------------------------------- _configdir : dir optional %{_topdir}/config:%{_sbdir}/config <1> ------------------------------------------------------------- <1> The +_topdir+ is the directory you run the command from and +_sbdir+ is the location of the RTEMS Source Builder command. Build set files have the file extension +.bset+ and the package build configuration files have the file extension of +.cfg+. The +sb-set-builder+ command will search for _build sets_ and the +sb-builder+ commands works with package build configuration files. Both types of configuration files use the \'#' character as a comment character. Anything after this character on the line is ignored. There is no block comment. Macros and Defaults ~~~~~~~~~~~~~~~~~~~ The RTEMS Source Builder uses a table of _macros_ called the _defaults_. The values the _defaults_ are initialised to is dependent on your host. This lets the Source Builder handle differences in the hosts. Build set and configuration files can define new values extending the defaults. For example builds are given a release number. This is typically a single number at the end of the package name. For RTEMS this is set in the top level build set configuration file with: ------------------------------------------------------------- %define release 1 ------------------------------------------------------------- Once defined if can be accessed in a build set or package configuration file with: ------------------------------------------------------------- %{release} ------------------------------------------------------------- The +sb-defaults+ command lists the defaults for your host. I will not include the output of this command becauses of its size. ------------------------------------------------------------- $ ../source-builder/sb-defaults ------------------------------------------------------------- Build Set Files ~~~~~~~~~~~~~~~ Build set files lets you list the packages in the build set you are defining and have a file extension of +.bset+. Build sets can define macro variables, inline include other files and reference other build set or package configuration files. Defining macros is performed with the +%define+ macro: ------------------------------------------------------------- %define _target m32r-rtems4.11 ------------------------------------------------------------- Inline including another file with the +%include+ macro continues processing with the specified file returning to carry on from just after the include point. ------------------------------------------------------------- %include rtems-4.11-base.bset ------------------------------------------------------------- This includes the RTEMS 4.11 base set of defines and checks. The configuration paths as defined by +_configdir+ are scanned. The file extension is optional. You reference build set or package configuration files by placing the file name on a single line. ------------------------------------------------------------- tools/rtems-binutils-2.22-1 ------------------------------------------------------------- The +_configdir+ path is scanned for +tools/rtems-binutils-2.22-1.bset+ or +tools/rtems-binutils-2.22-1.cfg+. Build set files take precedent over package configuration files. If +tools/rtems-binutils-2.22-1+ is a build set a new instance of the build set processor is created and if the file is a package configuration the package is built with the package builder. This all happens once the build set file has finished being scanned. Configuration Control ~~~~~~~~~~~~~~~~~~~~~ The RTEMS Souce Builder is designed to fit within most verification and validation processes. All of the RTEMS Source Builder is source code. The Python code is source and comes with a commercial friendly license. All configuration data is text and can be read or parsed with standard text based tools. File naming provides configuration management. A specific version of a package is captured in a specific set of configuration files. The top level configuration file referenced in a _build set_ or passed to the +sb-builder+ command relates to a specific configuration of the package being built. For example the RTEMS configuration file +rtems-gcc-4.7.2-newlib-2.0.0-1.cfg+ creates an RTEMS GCC and Newlib package where the GCC version is 4.7.2, the Newlib version is 2.0.0, plus any RTEMS specific patches that related to this version. The configuration defines the version numbers of the various parts that make up this package: ------------------------------------------------------------- %define gcc_version 4.7.2 %define newlib_version 2.0.0 %define mpfr_version 3.0.1 %define mpc_version 0.8.2 %define gmp_version 5.0.5 ------------------------------------------------------------- The package build options, if there are any are also defined: ------------------------------------------------------------- %define with_threads 1 %define with_plugin 0 %define with_iconv 1 ------------------------------------------------------------- The generic configuration may provide defaults in case options are not specified. The patches this specific version of the package requires can be included: ------------------------------------------------------------- Patch0: gcc-4.7.2-rtems4.11-20121026.diff ------------------------------------------------------------- Finally including the GCC 4.7 configuration script: ------------------------------------------------------------- %include %{_configdir}/gcc-4.7-1.cfg ------------------------------------------------------------- The +gcc-4.7-1.cfg+ file is a generic script to build a GCC 4.7 compiler with Newlib. It is not specific to RTEMS. A bare no operating system tool set can be built with this file. The +-1+ part of the file names is a revision. The GCC 4.7 script maybe revised to fix a problem and if this fix effects an existing script the file is copied and given a +-2+ revision number. Any dependent scripts referencing the earlier revision number will not be effected by the change. This locks down a specific configuration over time. Scripting ~~~~~~~~~ Configuration files specify how to build a package. Configuration files are scripts and have a +.cfg+ file extension. The script format is based loosely on the RPM spec file format how-ever the use and purpose in this tool does not compare with the functionality and therefore the important features of the spec format RPM needs and uses. The script language is implemented in terms of macros. The built-in list is: [horizontal] +%{}+:: Macro expansion with conditional logic. +%()+:: Shell expansion. +%prep+:: The source preparation shell commands. +%build+:: The build shell commands. +%install+:: The package install shell commands. +%clean+:: The package clean shell commands. +%include+:: Inline include another configuration file. +%name+:: The name of the package. +%summary+:: A brief package description. Useful when reporting about a build. +%release+:: The package release. A number that is the release as built by this tool. +%version+:: The package's version string. +%buildarch+:: The build architecture. +%setup+:: Setup a source package. +%source+:: Define a source code package. This macro has a number appended. +%patch+:: Define a patch. This macro has a is number appended. +%echo+:: Print the following string as a message. +%warning+:: Print the following string as a warning and continue. +%error+:: Print the following string as an error and exit. +%define+:: Define a macro. Macros cannot be redefined, you must first undefine it. +%undefine+:: Undefine a macro. +%if+:: Start a conditional logic block that ends with a +%endif+. +%ifn+:: Inverted start of a conditional logic block. +%ifarch+:: Test the architecture against the following string. +%ifnarch+:: Inverted test of the architecture +%ifos+:: Test the host operating system. +%else+:: Start the _else_ conditional logic block. +%endfi+:: End the conditional logic block. +%bconf_with+:: Test the build condition _with_ setting. This is the +--with-*+ command line option. +%bconf_without+:: Test the build condition _without_ setting. This is the +--without-*+ command line option. Expanding ^^^^^^^^^ A macro can be `%{string}` or the equivalent of `%string`. The following macro expansions supported are: `%{string}`;; Expand the 'string' replacing the entire macro text with the text in the table for the entry 'string . For example if 'var' is 'foo' then `${var}` would become `foo`. `%{expand: string}`;; Expand the 'string' and then use it as a ``string'' to the macro expanding the macro. For example if _foo_ is set to 'bar' and 'bar' is set to 'foovar' then `%{expand:foo}` would result in `foobar`. Shell expansion can also be used. `%{with string}`;; Expand the macro to '1' if the macro `with_`'string' is defined else expand to _0_. Macros with the name `with_`'string' can be define with command line arguments to the RTEMS Source Builder commands. `%{defined string}`;; Expand the macro to '1' if a macro of name 'string' is defined else expand to '0'. `%{?string: expression}`;; Expand the macro to 'expression' if a macro of name 'string' is defined else expand to `%{nil}`. `%{!?string: expression}`;; Expand the macro to 'expression' if a macro of name 'string' is not defined. If the macro is define expand to `%{nil}`. `%(expression)`;; Expand the macro to the result of running the 'expression' in a host shell. It is assumed this is a Unix type shell. For example `%(whoami)` will return your user name and `%(date)` will return the current date string. %prep ^^^^^ The +%prep+ macro starts a block that continues until the next block macro. The _prep_ or preparation block defines the setup of the package's source and is a mix of RTEMS Source Builder macros and shell scripting. The sequence is typically +%setup+ macros for source, +%patch+ macros to patch the source mixed with some shell commands to correct any source issues. A +%prep+ section starts with a +%setup+ command. This creates the package source top level directory then is followed by the first source file. ------------------------------------------------------------- <1> <2> %setup -q -c -T -n %{name}-%{version} %setup -q -T -D -n %{name}-%{version} -a0 ------------------------------------------------------------- <1> The package's name. <2> The version of the package. The source for a package is declared with the +%source*+ macro where +*+ is a number. For example +%source0+ is the source 0 tar file and is defined with something similar to this: ------------------------------------------------------------- Source0: http://ftp.gnu.org/gnu/gdb/gdb-%{gdb_version}.tar.bz2 ------------------------------------------------------------- This URL is the primary location of the GNU GCC source code and the RTEMS Source Builder can download the file from this location and by inspecting the file extension use +bzip2+ decompression. When the +%prep+ section is processed a check of the local +source+ directory is made to see if the file has already been downloaded. If not found in the source cache directory the package is downloaded from the URL. You can append other base URLs via the command line option +--url+. This option accepts a comma delimited list of sites to try. You can combine the source macro with conditional logic to implement a default that can be over-riden in the top level files. This lets you reuse a generic build script with different sources. This happens if you have a private source package with local modifications. The following example is taken from the +gcc-4.8-1.cfg+ build script. ------------------------------------------------------------- %ifn %{defined Source0} Source0: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-%{gcc_version}.tar.bz2 VersionContro0: git clone git://gcc.gnu.org/git/gcc.git <1> %endif ------------------------------------------------------------- <1> The version control macro is currently not implemented. You could optionally have a few source files that make up the package. For example GNU's GCC was a few tar files for a while and it is now a single tar file. Support for multiple source files can be conditionally implemented with the following scripting: ------------------------------------------------------------- %{?source1:%setup -q -T -D -n %{name}-%{version} -a1} ------------------------------------------------------------- The +source1+ macro value is checked and if present the command string after the +:+ is executed. It is common to see a number of these present allowing top level configuration files including a base configuration the ability to define a number of source packages. ------------------------------------------------------------- %{?source1:%setup -q -T -D -n %{name}-%{version} -a1} %{?source2:%setup -q -T -D -n %{name}-%{version} -a2} %{?source3:%setup -q -T -D -n %{name}-%{version} -a3} ------------------------------------------------------------- Patching also occurs during the preparation stage. Patches are handled in a similar way to the source packages. Most patches are based around the top of the source tree. This is an example of the patch scripting for the GCC 4.8 series of compilers: ------------------------------------------------------------- cd gcc-%{gcc_version} <1> %{?patch0:%patch0 -p1} <2> %{?patch1:%patch1 -p1} %{?patch2:%patch2 -p1} %{?patch3:%patch3 -p1} %{?patch4:%patch4 -p1} %{?patch5:%patch5 -p1} %{?patch6:%patch6 -p1} %{?patch7:%patch7 -p1} %{?patch8:%patch8 -p1} %{?patch9:%patch9 -p1} cd .. <3> ------------------------------------------------------------- <1> Change from the top of the source tree into the package being patched's top directory. <2> The conditional macro expansion checks if +%patch0+ is defined and if defined issues the +%patch0" macro giving +-p1+ to the patch command. <3> Return back to the top of the source tree. %build ^^^^^^ The +%build+ macro starts a block that continues until the next block macro. The build block is a series of shell commands that execute to build the package. It assumes all source code has been unpacked, patch and adjusted so the build will succeed. The following is an example take from the GutHub STLink project: NOTE: STLink is a JTAG debugging device for the ST ARM family of processors. ------------------------------------------------------------- %build export PATH="%{_bindir}:${PATH}" <1> cd texane-stlink-%{stlink_version} <2> ./autogen.sh <3> %if "%{_build}" != "%{_host}" CFLAGS_FOR_BUILD="-g -O2 -Wall" \ <4> %endif CPPFLAGS="-I $SB_TMPPREFIX/include/libusb-1.0" \ <5> CFLAGS="$SB_OPT_FLAGS" \ LDFLAGS="-L $SB_TMPPREFIX/lib" \ ./configure \ <6> --build=%{_build} --host=%{_host} \ --verbose \ --prefix=%{_prefix} --bindir=%{_bindir} \ --exec-prefix=%{_exec_prefix} \ --includedir=%{_includedir} --libdir=%{_libdir} \ --mandir=%{_mandir} --infodir=%{_infodir} %{__make} %{?_smp_mflags} all <7> cd .. ------------------------------------------------------------- <1> Setup the PATH environment variable. This is not always needed. <2> This package builds in the source tree so enter it. <3> The package is actually checked directly out from the github project and so it needs its autoconf and automake files generated. <4> Flags for a cross-compiled build. <5> Various settings passed to configure to customise the build. In this example an include path is being set to the install point of _libusb_. This package requires _libusb_ is built before it. <6> The +configure+ command. The RTEMS Source Builder provides all the needed paths as macro variables. You just need to provide them to +configure+. <7> Running make. Do not use +make+ directly, use the RTEMS Source Builder's defined value. This value is specific to the host. A large number of packages need GNU make and on BSD systems this is +gmake+. You can optionally add the SMP flags if the packages build system can handle parallel building with multiple jobs. The +_smp_mflags+ value is automatically setup for SMP hosts to match the number of cores the host has. %install ^^^^^^^^ The +%install+ macro starts a block that continues until the next block macro. The install block is a series of shell commands that execute to install the package. You can assume the package has build correctly when this block starts executing. Never install the package to the actual _prefix_ the package was built with. Always install to the RTEMS Source Builder's temporary path defined in the macro variable +\__tmpdir+. The RTEMS Source Builder sets up a shell environment variable called +SB_BUILD_ROOT+ as the standard install point. Most packages support adding +DESTDIR=+ to the _make install_ command. Looking at the same example as in <<_build, %build>>: ------------------------------------------------------------- %install export PATH="%{_bindir}:${PATH}" <1> rm -rf $SB_BUILD_ROOT <2> cd texane-stlink-%{stlink_version} <3> %{__make} DESTDIR=$SB_BUILD_ROOT install <4> cd .. ------------------------------------------------------------- <1> Setup the PATH environment variable. This is not always needed. <2> Clean any installed files. This make sure the install is just what the package installs and not any left over files from a broken build or install. <3> Enter the build directory. In this example it just happens to be the source directory. <4> Run +make install+ to install the package overriding the +DESTDIR+ make variable. %clean ^^^^^^ The +%clean+ macro starts a block that continues until the next block macro. The clean block is a series of shell commands that execute to clean up after a package has been built and install. This macro is currenly not been used because the RTEMS Source Builder automatically cleans up. %include ^^^^^^^^ The +%include+ macro inline includes the specific file. The +\__confdir+ path is searched. Any relative path component of the include file is appended to each part of the +\__configdir+. Adding an extension is optional as files with +.bset+ and +.cfg+ are automatically searched for. Inline including means the file is processed as part of the configuration at the point it is included. Parsing continues from the next line in the configuration file that contains the +%include+ macro. Including files allow a kind of configuration file reuse. The outer configuration files provide specific information such as package version numbers and patches and then include a generic configuration script which builds the package. ------------------------------------------------------------- %include %{_configdir}/gcc-4.7-1.cfg ------------------------------------------------------------- %name ^^^^^ The name of the package being built. The name typically contains the components of the package and their version number plus a revision number. For the GCC with Newlib configuration the name is typically: ------------------------------------------------------------- Name: %{_target}-gcc-%{gcc_version}-newlib-%{newlib_version}-%{release} ------------------------------------------------------------- %summary ^^^^^^^^ The +%summary+ is a brief description of the package. It is useful when reporting. This information is not capture in the package anywhere. For the GCC with Newlib configuration the summary is typically: ------------------------------------------------------------- Summary: GCC v%{gcc_version} and Newlib v%{newlib_version} for target %{_target} on host %{_host} ------------------------------------------------------------- %release ^^^^^^^^ The +%release+ is packaging number that allows revisions of a package to happen where none package versions change. This value typically increases when the configuration building the package changes. ------------------------------------------------------------- %define release 1 ------------------------------------------------------------- %version ^^^^^^^^ The +%version% macro sets the version the package. If the package is a single component it tracks that component's version number. For example in the _libusb_ configuration the +%version+ is the same as +%libusb_version+, how-ever in a GCC with Newlib configuration there is no single version number. In this case the GCC version is used. ------------------------------------------------------------- Version: %{gcc_version} ------------------------------------------------------------- %buildarch ^^^^^^^^^^ The +%buildarch+ macro is set to the architecture the package contains. This is currently not used in the RTEMS Source Builder and may go away. This macro is more important in a real packaging system where the package could end up on the wrong architecture. %setup ^^^^^^ The +%setup+ macro sets up the source code tree and is used in the +%prep+ section of the script. The options are: [horizontal] *Switch*:: *Description* +-n+:: The -n option is used to set the name of the software's build directory. This is necessary only when the source archive unpacks into a directory named other than +-+. +-c+:: The -c option is used to direct %setup to create the top-level build directory before unpacking the sources. +-D+:: The -D option is used to direct %setup to not delete the build directory prior to unpacking the sources. This option is used when more than one source archive is to be unpacked into the build directory, normally with the +-b+ or +-a+ options. +-T+:: The -T option is used to direct %setup to not perform the default unpacking of the source archive specified by the first Source: macro. It is used with the +-a+ or +-b+ options. +-b +:: The -b option is used to direct %setup to unpack the source archive specified on the nth Source: macro line before changing directory into the build directory. +-a +:: The -a option is used to direct %setup to unpack the source archive specified on the nth Source: macro line after changing directory into the build directory. %source ^^^^^^^ The +%source+ macro is numbered and defines a source tar file used in the package. The +%setup+ macro references the packages defined here. A macro is defined as: ------------------------------------------------------------- Source0: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-%{gcc_version}.tar.bz2 ------------------------------------------------------------- The setup script is: ------------------------------------------------------------- %setup -q -T -D -n %{name}-%{version} -a0 ------------------------------------------------------------- The +-a0+ means use +%source0+. %patch ^^^^^^ The +%patch+ macro is numbered and can define a patch and in the +%prep+ section applies the patch. To define a patch append a +:+ followed by the patch filename: ------------------------------------------------------------- Patch0: gcc-4.7.2-rtems4.11-20121026.diff ------------------------------------------------------------- The +__patchdir+ path is search. Placing +%patch+ in the +%prep+ section will apply it with any trailing options passed to the +patch+ command. This allows the +-p+ option to be passed to strip any leading path components from the patch contents. ------------------------------------------------------------- %patch0 -p1 ------------------------------------------------------------- You will typically see the patch conditionally used as: ------------------------------------------------------------- %{patch0:%patch0 -p1} ------------------------------------------------------------- In this case the patch will only be applied if it is defined. %echo ^^^^^ The +%echo+ macro outputs the following string to stdout. This can also be used as `%{echo: message}`. %warning ^^^^^^^^ The +%warning+ macro outputs the following string as a warning. This can also be used as `%{warning: message}`. %error ^^^^^^ The +%error+ macro outputs the follow string as an error and exits the RTEMS Source Builder. This can also be used as `%{error: message}`. %define ^^^^^^^ The +%define+ macro defines a new macro. If the macro being defined already exists a warning is raised. If you value is given it is assumed to be 1. ------------------------------------------------------------- %define foo bar %define one_plus_one 2 %define one <1> ------------------------------------------------------------- <1> The macro _one_ is set to 1. %undefine ^^^^^^^^^ The +%undefine+ macro removes a macro if it exists. Any further references to it will result in an undefine macro error. %if ^^^ The +%if+ macro starts a conditional logic block that can optionally have a _else_ section. A test follows this macro and can have the following operators: [horizontal] *Operator*:: *Description* +%{}+:: Check the macro is set or _true_, ie non-zero. + ------------------------------------------------------------- %if ${foo} %warning The test passes, must not be empty or is non-zero %else %error The test fails, must be empty or zero %endif ------------------------------------------------------------- +!+:: The _not_ operator inverts the test of the macro. + ------------------------------------------------------------- %if ! ${foo} %warning The test passes, must be empty or zero %else %error The test fails, must not be empty or is non-zero %endif ------------------------------------------------------------- +==+:: The left hand size must equal the right hand side. For example: + ------------------------------------------------------------- %define one 1 %if ${one} == 1 %warning The test passes %else %error The test fails %endif ------------------------------------------------------------- + You can also check to see if a macro is empty: + ------------------------------------------------------------- %if ${nothing} == %{nil} %warning The test passes %else %error The test fails %endif ------------------------------------------------------------- +!=+:: The left hand size does not equal the right hand side. For example: + ------------------------------------------------------------- %define one 1 %if ${one} != 2 %warning The test passes %else %error The test fails %endif ------------------------------------------------------------- + You can also check to see if something is set: + ------------------------------------------------------------- %if ${something} != %{nil} %warning The test passes %else %error The test fails %endif ------------------------------------------------------------- +>+:: The left hand side is numerically greater than the right hand side. +>=+:: The left hand side is numerically greater than or equal to the right hand side. +<+:: The left hand side is numerically less than the right hand side. +\<=+:: The left hand side is numerically less than or equal to the right hand side. %ifn ^^^^ The +%ifn+ macro inverts the normal +%if+ logic. It avoids needing to provide empty _if_ blocks followed by _else_ blocks. It is useful when checking if a macro is defined: ------------------------------------------------------------- %ifn %{defined foo} %define foo bar %endif ------------------------------------------------------------- %ifarch ^^^^^^^ The +%ifarch+ is a short cut for "+%if %{\_arch} == i386+". Currently not used. %ifnarch ^^^^^^^^ The +%ifnarch+ is a short cut for "+%if %{\_arch} != i386+". Currently not used. %ifos ^^^^^ The +%ifos+ is a short cut for "+%if %{\_os} != mingw32+". It allows conditional support for various operating system differences when building packages. %else ^^^^^ The +%else+ macro starts the conditional _else_ block. %endfi ^^^^^^ The +%endif+ macro ends a conditional logic block. %bconf_with ^^^^^^^^^^^ The +%bconf_with+ macro provides a way to test if the user has passed a specific option on the command line with the +--with-