Compiling with Makefile

Directory structure  web51_manual.html  Linking order
The entire Web 51 software is divided into a number of files. It is necessary to use a compilation management system that takes the source files and libraries and links them into a single .HEX file, according to given rules.

MAKE - Makefile

To compile the project, a port of Unix-like make utility is used. It is in the binutils package, and operates under Win32 as well. Its control file, the Makefile, may be looked at as a smarter version of .BAT files found in DOS. Make performs quite a complicated compilation of all source files into the resulting code.
Detailed description is available for DOWNLOAD in the Related Documentation section.

The make utility is in the /bin directory which should be in your PATH. When it is run, it searches the current directory for a file called Makefile (no extension), which contains detailed rules for building the project.

If you work in Windows, be careful about Windows Commander software, which executes command line in a little non-standard way. We recommend to run make from a DOS Shell (Command Prompt).

Let's take the LED2 project as an example.

Makefile Structure

Comments follow. You may find it useful to open the actual Makefile of the LED2 project in a new window. Makefile comments follow (Makefile contents are monospaced, comments are below code portions).

PROJ = www8051
PROJFILE = Makefile

SCRIPT = ../../bin INCDIR = ../../include LIBDIR = ../../lib CGIDIR = ../../cgi BINDIR = ../../bin
CA = $(BINDIR)/mcs51-as LINKER = $(BINDIR)/mcs51-ld OBJCOPY = $(BINDIR)/mcs51-objcopy PERL = $(BINDIR)/perl BIN2HEX = $(BINDIR)/bin2hex RM = $(BINDIR)/rm

Definitions of system variables (contain locations of individual files) and global parameters, if any. Make sets paths; however, it is comfortable to add the /bin directory of the Web51 project into your PATH variable. It makes running other utilities of the development system (including make itself) easier.

FILES = www8051.asm index.html LEDsetup.asm
OBJS  = www8051.obj index.obj LEDsetup.obj
CGI   = $(CGIDIR)/testP3.obj

This is a list of .ASM files that the project needs and that will be compiled to .OBJ files. If you add another .CGI script to the project, add it to the Makefile here. Note that .html files are also listed. If you use your own CGIs, you can leave them in project directory, but don't forget to add them to OBJS and FILES.

A list of rules for compiling follows. The basic syntax is:

What_do_I_want: What_does_it_depend_on

The target (what_do_I_want) can be specified when running make. If no target is specified, make uses the first rule. For example, if the first rule in Makefile is:

hex: www8051.hex

make will try to create www8051.hex. File dates are used to determine which files need to be compiled. Make always recompiles sources which the target file depends on if the source is newer than the target. BIN files can also be created; however, since HEX is easier to verify and program, it is preferred.

One Makefile can contain several different targets; one of them can even delete temporary files. For example:

.PHONY: clean
        $(BASH) -c "rm -f *.obj"
        $(BASH) -c "rm -f *.lst"
        $(BASH) -c "rm -f"
        $(BASH) -c "rm -f"
        $(BASH) -c "rm -f index.asm"
        $(BASH) -c "rm -f www8051.o"
        $(BASH) -c "rm -f www8051.rom"
        $(BASH) -c "rm -f www8051.eep"
        $(BASH) -c "rm -f www8051.hex"
        $(BASH) -c "rm -f map"

Whenever make is called with "make clean", this part of Makefile is executed. The above part deletes all generated files. This cleans up the directory, and is useful e.g. before distributing the project directory to other users.

.SUFFIXES: .obj .c .asm .inc .h .ina .html

www8051.obj : www8051.asm $(INCDIR)/ $(INCDIR)/ ip ether $(BASH) -c "rm -f" $(BASH) -c "rm -f" $(PERL) $(SCRIPT)/ -v -equ -binutils - <ether > $(PERL) $(SCRIPT)/ -v -equ -binutils - <ip > $(CA) www8051.asm -o www8051.obj $(CAOPT) -a=www8051.lst

This portion of Makefile compiles www8051.asm. The result, www8051.obj, depends on a number of other files, which need to be recompiled in case of any changes. They are listed after the colon.

If make detects that a source has been updated, it executes this part of Makefile which builds www8051.obj (one of the files that the final www8051.hex consists of). In this case, it is necessary to include necessary constant and parameter definitions in the code; this is ensured by and (inserted into www8051.asm). Other included definitions are in and For better clarity, these are generated from a textual configuration file by Perl scripts.

At this point, ether and ip, with the following syntax (ether)


are converted with the scripts to and and then inserted into the assembly source code. See the Description of and

.equ    MAC_MSB, 0x0000            ; MAC address 
.equ    MAC_NSB, 0xE8EE
.equ    MAC_LSB, 0x1034

Note the file that contains settings of the xtal oscillator (used by UART for RS232). It also defines basic symbols such as SDA, SCL (I2C pins), etc. However, it does not contain the .global reset definition of initial port status after reset. This part of the code, as well as timer interrupt control, is in web51.asm in the LIB directory.

Have a look at the .LST files. For example, open index.lst and www8052.lst and note that they contain code addresses - useful if you need to locate an error at a certain address.

LEDsetup.obj : LEDsetup.asm $(INCDIR)/
        $(CA) LEDsetup.asm -o LEDsetup.obj $(CAOPT) -a=LEDsetup.lst

index.obj : index.html $(BASH) -c "rm -f index.asm" $(PERL) $(SCRIPT)/ -binutils -cpueeprom -index 0 index.html $(CA) index.asm -o index.obj $(CAOPT) -a=index.lst

HTML files must be somehow embedded into the final .HEX file. This is ensured through assembler. The HTML document is converted into a series of assembler pseudoinstructions. This is ensured by another Perl script,

The cpueeprom parameter specifies location of the compiled code. Don't forget to change it if you need to move data around in the memory.

www8051.o : $(OBJS) $(CGI) $(LIBDIR)/libw80.a $(LIBDIR)/libk80.a $(LIBDIR)/web51.obj
        $(BASH) -c "rm -f www8051.o"
        $(LINKER) --script $(LIBDIR)/ -L $(LIBDIR) $(LIBDIR)/web51.obj $(OBJS)\ 
        $(CGI) -lk80 -lw80 -M -o www8051.o --no-check-sections >map

At this point, all .OBJ files are ready and final linking begins. The "www8051.o" depends on .OBJ files of the project as well as on libraries libw80.a and libk80.a (or libw23.a and libk23.a). The first line specifies just that.

All input files, CGI scripts from the library, etc. are ready (see Linking order). Now, missing library functions need to be added and the entire project linked together. The linker is controlled by the file in the /lib directory. This file defines linking order of individual segments and their names. The -L parameters specifies location of libraries. Linking must start with web51.obj from the /lib directory since it contains definitions of interrupt vectors and therefore must begin at address 0. After this file, .OBJ files are linked in the order specified by the OBJS variable. Then, .OBJ files specified by the CGI variable are processed. Both variables are defined at the beginning of Makefile (don't forget to add other scripts that you use). Backslash means that the command continues on the next line. After linking files in OBJS and CGI, missing library functions are added from libk80 and libw80.

The full name of the "libw80.a" library is shortened to -lw80. See the library descriptions in Linking order. Linking progresses from left to right and is not recursive; therefore, we recommend to specify -lk80 first, followed by -lw80.

The -M parameter generates a MAP file that contains information about the final build. Have a look at it and note its structure and contents.

The final result is stored in www8051.o (different from www8051.obj that contains compiled www8051.asm).

www8051.rom : www8051.o
	$(RM) -f www8051.rom
	$(OBJCOPY) -j .text -O binary www8051.o www8051.rom
	$(RM) -f www8051.eep
	$(OBJCOPY) -j .eeprom -O binary www8051.o www8051.eep

The www8051.o is similar to .obj files. The mcs51-objcopy utility (part of BINUTILS) extracts program code and EEPROM contents from it. Both parts, www8051.rom and www8051.eep, are binary. However, programmers usually want a single .HEX file with EEPROM contents starting at 2000h (for 8252 CPU). So, the binaries are converted to HEX with bin2hex utility and concatenated together. In a similar way, data for an I2C memory can be generated.

www8051.hex : www8051.rom
	$(RM) -f www8051.hex
	$(BIN2HEX) -q -t www8051.rom www8051.hex
	$(BIN2HEX) -q -o 8192 -a www8051.eep www8051.hex

It is uncomfortable to load separate files for FlashROM and EEPROM to the programmer. This part generates www8051.hex that contains both. In some examples we may generate only .ROM and .EEP files. If you need a .HEX file, set the target to www8051.hex at the beginning and add the above paragraph to the end. Finally, don't forget to include .EEP and .ROM files in the list of files to be deleted by the "clean" Makefile target.

This concludes the entire process of building the final machine code. If your /bin directory is not in your PATH variable, you can run make by typing ..\..\make in the project directory (as long as you use the recommended directory structure).
If you use Windows, we recommend to include make in your PATH and run it from a DOS shell (Command Prompt) from the project directory. Some file managers (such as Volkov Commander) redirect all output to the screen causing generated files to contain unwanted output intended for the screen.

Sponzored by LPhard Ltd. Graphics by GIMP Created by EasyPad

(c)Copyright 2000 - 2002, HW server & Radek Benedikt,
Directory structure  Obsah  Linking order