|
|
Using eCos with CMake
2006-11-27
Foreword: This detailed, technical how-to explains how eCos developers can use CMake to simplify and streamline the chore of writing makefiles manually. It discusses both simple, single-application eCos build environments, as well as those with multiple targets, such as production and debug builds for actual and virtual hardware.
A CMake-based build system for embedded development with eCos by Alexander Neundorf Introduction eCos is an open source, royalty-free, real-time operating system intended for deeply embedded applications. The highly configurable nature of eCos allows the operating system to be customized to precise application requirements, delivering the best possible run-time performance and an optimized hardware resource footprint. A thriving net community has grown up around the operating system ensuring on-going technical innovation and wide platform support. eCos is not a rival to Linux in embedded space, instead it complements it ideally at the low end. When developing an embedded application with eCos, you write an application, which links to the static eCos libraries (libtarget.a, libextras.a). These libraries provide the operating system and support libraries, and so the resulting executable is a completely self-contained application that can run on the target hardware. eCos comes with tools to generate a Makefile for the eCos libraries. But in order to compile your own sources, link them to the eCos libraries and produce an executable for the target, you still have to write a Makefile yourself. Now in the days of graphical IDE's like XCode or MS Visual Studio on one side and autoconf/automake and friends on the other side, most people will agree: having to write Makefiles manually for non-trivial tasks sucks. However, here comes CMake into play, a buildsystem that has been picking up a lot of steam in the last months. CMake is a cross-platform, open-source make system that can generate Makefiles from simple descriptive script files and other sources. I have known CMake for approximately two years now, and since then I have been using it basically for everything I have to compile on any platform, be it Linux, Mac OS X, MS Windows with MSVC 6, MS Windows with cygwin, and also for cross-compiling eCos under both Linux and MS Windows. CMake reads files named CMakeLists.txt and produces either Makefiles for UNIX or cygwin, project files for KDevelop 3, MS Visual Studio, Apple XCode and others. So by writing one CMakeLists.txt you can compile your software with all these different build environments. Here is probably the most simple CMakeLists.txt:
And that's it. Running CMake on this file will generate a Makefile which builds helloworld(or a XCode project file if you prefer). CMake 2.4.4 was released just a few days ago. With this new release, building eCos applications can be done very comfortably using CMake. With CMake 2.4.4 it has become easy to build single eCos applications, as well as managing big project trees consisting of multiple eCos applications, optionally each built in different configurations, and accompanying host tools. It offers the following features:
How to build eCos applications using CMake We'll start with a simple example application for the Intel XScale IQ80321 evaluation board, which is supported by eCos. It consists of the source files main.c, utils/foo.c, and utils/bar.c (and the accompanying headers). Additionally to the actual sources some more files are required, the layout is as follows:
main.c and friends are the application source files, not much to say about them, you know them best. ecos/ecos.ecc is the eCos configuration file, which describes how your eCos will be built. You can edit it manually or using ecosconfig or configtool, just as you prefer. It is important that it must be named "ecos.ecc" and that it must reside in the subdirectory named "ecos/". CMakeLists.txt is the most important file for us (in this article). This file will be read by CMake and used to create the Makefiles for your application. Let's have a look at this file line by line:
That's all there is to it. For more information about the CMake syntax visit e.g. www.cmake.org or have a look at the CMake man page. So what to do next? Enter the directory sampleapp/ and run CMake:
Please note the dot after CMake, which tells CMake that the CMakeLists.txt file is located in the current directory. This is required, otherwise it won't work. As you see, CMake checks for the availability of ecosconfig. This succeeds if ecosconfig is in the PATH, otherwise it will stop with an error message. In this case you can either extend the system path so that it also includes the directory where ecosconfig is located or you can the ccmake tool coming with CMake and enter the path to ecosconfig there. CMake also checks that the ECOS_REPOSITORY environment variable is set correctly and gives an error message if this is not the case. If everything is ok now there should be a Makefile in this directory, if not, something went wrong. Let's suppose everything went fine, and you have now a Makefile in sampleapp/. Before you run make, make sure that your cross compiling toolchain is also available in the PATH. If this is set up correctly, enter make. At first eCos will be built in ~/src/sampleapp/ecos/ and then the application sampleapp will be built and linked with the eCos libraries to create a complete executable. If there were no problems, you should now find a the "sampleapp.elf" ELF file, the "sampleapp.bin" binary file and the "sampleapp.srec" file in the sampleapp/ directory. More things you should know Compiler options A bunch of compiler options, which are appropriate for embedded applications, are added automatically by UseEcos.cmake:
If you prefer other switches, you can either edit the file or remove the flags using REMOVE_DEFINITIONS(). Supported toolchains UseEcos.cmake comes with support for three crosscompiling toolchains:
Available Makefile targets The generated Makefiles offer the following targets:
The build system works under MS Windows with cygwin and under Linux (tested: several versions of Slackware, SUSE, and kubuntu). Under Linux you can also use the KDevelop3 project generator of CMake, which will create Makefiles as usual and additionally project files for KDevelop3. To have CMake generate project files for KDevelop 3, you have to execute the following:
As you see, problems may occur. If CMake was run before and generated normal Makefiles, it will complain if you try to specify a different "generator." In this case do what CMake tells you, delete the file CMakeCache.txt and then run the command as given above again. Then it should complete without errors and will produce a project file named "Project.kdevelop". If you would prefer a better name for the project than "Project," this can be easily achieved, simply by adding the following line to the CMakeLists.txt:
Then run CMake again and it will generate a project file named "sampleapp.kdevelop." This makes the combination of eCos and KDevelop a very comfortable free software development environment for embedded real time systems. When do you have to run CMake manually? Usually you only have to invoke CMake explicitly as shown above only when initially creating the Makefiles (or project files). Once the Makefiles exist, they contain appropriate rules and dependencies to run CMake automatically again if required. More information If you need more information about CMake, here are some tips:
Using CMake to manage complex project trees Now that you know how to build an eCos application using CMake, we'll proceed to the next level. Let's say you have a family of devices running with eCos applications. In this case you might need some more support from the build system. So we'll have a look at how to manage complex a source tree. It contains several eCos applications. Each application will be built in a release and a debug configuration, and each application can be built for the real target and for the Linux synthetic target. Additionally there is a directory where source files used by all applications will reside. It also offers a directory where eventually required custom host applications can be compiled. With all this in place, it is possible to compile all applications (embedded and host) in all configurations with a single "make" invocation from the top level. The directory structure for that looks like this:
Again, let's have a look at the directory tree. As you may have noticed it is considerably more complex than in the first example. In every subdirectory there is a CMakeLists.txt. If in the specific directory nothing is actually built but it only branches into more subdirectories, the CMakeLists.txt files in these directories are all quite simple, e.g. bigproject/CMakeLists.txt looks like this:
The CMakeLists.txt in bigproject/firmware/ and in bigproject/host/ are equivalent. Below the bigproject/host/ directory you can add arbitrary directories for building host tools. There you can use the "normal" CMake functions for building "normal" applications. All the firmware source files are located below the bigproject/firmware/ directory. The bigproject/firmware/common/ directory is the place where sources shared by different applications can be put. bigproject/firmware/helloworld/ contains an eCos application comparable to the sampleapp from the beginning. Let's have a closer look at this directory. You'll notice there are subdirectories starting with "ecos-". These are the directories where the eCos application will be built for the different configurations and/or targets. This means when bigproject/firmware/helloworld/ is built, the helloworld application will be built for the Linux synthetic target under ecos-synth/, for a PowerPC target under ecos-ppc/ and for the XScale under ecos-iq80321/. So you can view bigproject/firmware/helloworld/ as the "home" directory of your application where you put all the application specific files, the "ecos-XXX" directories are used "only" for compiling. This is the CMakeLists.txt in bigproject/firmware/:
Here UseEcos.cmake is included, so that the eCos-specific CMake functions are available in the CMakeLists.txt in all subdirectories below this directory. Then it branches deeper into all application subdirectories (in this case only helloworld). This is the CMakeLists.txt in bigproject/firmware/helloworld/:
Nothing is compiled here, it just branches further into the "ecos-XXX" compile directories. Notable is the IF (WIN32), this is used to differentiate between compiling under MS Windows/cygwin and Linux. As you can see the ecos-synth/ directory is not compiled under MS Windows/cygwin, for obvious reasons. Next to the CMakeLists.txt there is the file name ProjectSources.txt. This one is important, here you list all source files of your application.
As you can see, you can mix C and C++ files as you want, and you can use files from this directory and from other directories (e.g. the common/ directory). This file, ProjectSources.txt is used in the "ecos-XXX" compile directories, where the actual compilations take place. Now finally, the contents of bigproject/firmware/helloworld/ecos-iq80321/CMakeLists.txt:
Now this file looks quite similar to the CMakeLists.txt from the sampleapp example above. Actually there are only two differences: the INCLUDE(../ProjectSources.txt) command and the ECOS_ADJUST_DIRECTORY() call. ProjectSources.txt contains the list of source files, that's why it has to be included here. In ProjectSources.txt the source files can be listed with relative paths, e.g. "main.cpp." The relative paths are relative to the location of ProjectSources.txt, but now this file is included one directory level deeper and so the the relative paths to the source files aren't correct, e.g. "main.cpp" doesn't exist, but "../main.cpp" would be the correct path to this file. This adjustment is done by calling the ECOS_ADJUST_DIRECTORY() macro. It adjusts all relative paths accordingly and puts the resulting list of source files into a new variable, here named target_SRCS. These target_SRCS are then used for building the eCos executable. As in the first example, at first CMake has to be executed once:
Or "cmake . -GKDevelop3" if you intend to use KDevelop. After that you can enter make in this directory and it will compile the complete source tree with all eCos applications in all configurations and also the host tools. Of course you can also enter make in any of the subdirectories and build only that. So, I hope I have helped to make your eCos-experience even better, and that you'll have a lot of fun with CMake and eCos :-) If you have comments, problems, fixes, improvements, feel free to contact me: neundorf@kde.org. Further details on eCos and CMake are available here: About the author: Alexander Neundorf is a longtime KDE developer who has contributed to free software development since 1997. He is known for writing the LISA LAN browser and for maintaining SMB support in KDE. He also ported kdelibs to the CMake build system earlier in 2006. Neundorf earned a degree in Computer Science in Engineering in 2002 from the Technische Universitat in Ilmenau, Germany. He currently works at Jenoptik LOS, GmbH, developing professional digital cameras and infrared cameras.Related stories:
|