>When I first visited one of our famous TV manufacturers in China, I had no idea about the software capability of their software team. When I demonstrated my company's TV software for their evaluation, the software leader was surprised to see the modular software programming in many individual files. The software manager even commented, "Your software structure is very stupid, why do you put all of these functions into so many smaller files, instead of one single file? It is very head to find the variables in different files and requires longer compiling time." I was almost choked by his words. But I could not argue with our customer face to face, it is very harmful to our business. So I let him to find the real answer, which way is stupid anyway?
I can figure out why they got such one big file approach and stuck on it. First of all, none of this software team had programming background in UNIX, they only knew about DOS and Windows. Basically their programming experiences were only MS C++ or Turbo C++, which has IDE tools. And they got their first code base from Toshiba, I do not know why Toshiba released one single source file for their development, maybe it was a business trick. However I realized I need to prove our software advantage over theirs. So I changed one file of my software and the big file of their software, and then compile them separately. It requires 3 minutes to compile their big source file. And it completed compiling of my software with a make command in 5 seconds. Even they saw the difference, they still insisted on their points, but I knew they re-organized the whole software structure after this training.
Most of the electronics engineers are not software experts, so they are innocent about many important software engineering concepts. Thanks Microsoft and Borland, this kind of innocent is all right for a PC programmer. These IDEs have already embedded make utilities. For example, nmake for MS C++, tmake for Borland Turbo C++. But most of the early embedded development tools did not offer make utility as a package, of course they did not offer IDEs as well. At that moment, or even today, a lot of engineers still use a batch file to compile their source code. They do not know about split the source into different head files and source files. They do not know how to use make to only compile the files changed, instead of whole project. They do not know how to use other utility to automatically generate head files from configuration files. They have no ideas how to manage a big project at all. I will like to discuss these topics in coming weeks, let us start it with makefile.
Makefile actually is an old concept from UNIX development. Makefile is based upon compiling rules for a project and improve the project development efficiency. In a big project, there are many files in different folders. Of course you can write a DOS batch file to build whole project. But makefile can judge which steps should be done first, which steps can be ignored, and even more complicated goals. All of these are decided by the rules in makefile, instead of manually specified. Of course, in order to utilize make features, a project should be written in modular programming method, one big file project can just be programmed once anyway. PS: The modular programming has many other benefits in software engineering, not only for makefile.
The rule of makefile is:
target ... : prerequisites ...
That means, in order to build a target (i.e. object files), we should have files of prerequisites (i.e. head files), the conversion tools are command (i.e. c compiler). This rules are core of a makefile. Here is a simple makefile for GNU make (gmake). One implicit rule is that the conversion takes place only if the one of prerequisites files is newer than the target. That means it changed since last make. By the way, you must type a table key before command, otherwise the gmake will not process it.
If defs.h changed, then all related targets, i.e. all *.o files will be generated, and finally edit file will be generated. If main.c changed, the makefile will only generate main.o and edit. That is rule of a makefile. You can also type "make clean" to remove all of the generated files on list by executing rm command. The example is small for demonstration purpose, it will be very efficient in a huge project like DTV project. If you still stick on DOS batch, every single change will test your patient.
Different make tools have different syntax, in order to unique our embedded system development, GNU gmake is a good tools for most of the embedded system. But GNU gmake is a quite complicated tool, you might have no interested in its 200-page manuals. Personally I recommend the makefile template from AVR freak for your reference, the makefile has been separated into common makefile and a project make. This offers a mature makefile starting point for your project. You can download the GCC tools from this site, the makefile and a demo project is included. You can easily port it to your existing projects on 8051, PIC, MSP... Don't bother for ARM or MIPS, their tool chains have already integrated gmake.
Makefile has its own issues, recursive make, which splits one central makefile into distributed makefile in different folders and sub folders. That is quite common is Linux project. The author of Safer C presented an article as Harmful Recursive Makefile. You can read it if you are interested in this topic. But AVRfreak's makefile is enough for medium size project.
In next blog, let us discuss how to use gawk to automatically generated the dependency rules of make file. It is funny. You can reuse that principle to generate document as well. I know you hate writing documents and synchronize the code changes to your documents in every time.
P.Miller's Safer C and makefile
AVRFreak web site