Linux Make & Makefile
about me
EE degree back in 1982
Z80 was the most popular CPU
Pascal/Fortran/COBOL were popular languages
Apple ][ + BASIC and CP/M
intel 80386SX PC mother board designer
......
Interested in Linux since 2016

Z80 CPU

intel 80386SX CPU
photo source: wikipedia.org

Apple ][
marconi.jiang@gmail.com
References
- C example code from Computer Systems - A Programmer's Perspective
WHAT ARE MAKE & MAKEFILE
Make & Makefile
make (Reminder: Linux is case sensitive. "Make" will be treated as Command not found.)
- A compiler tool embedded in Linux Shell (GNU project)
- Usually stored in /usr/bin/
- To prepare to use make, user must create a file called "makefile" that describes the relationships among files in your program and provides commands for updating each file.
makefile
- A user created file for make to follow compiler instructions
- Makefile is saved in the same directory of the source files you intend to compiler. Users might create one or many Makefile's for different projects
- By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile, makefile and Makefile.
- You can also specify your own makefile by -f parameter
$ make
$ make -f MyMakefileExample of C Code
- Let me use the following C code (show_byes.c) as an example to demonstrate the use of makefile.
Example : show_byes.c accept your input in 'int' (decimal) format, and display in hex format in int, (type cast to) float, and physical address
Usage: ./show_byes int_number
#include <stdio.h>
#include <unistd.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len) {
int i;
for (i = 0; i < len; i++)
printf(" %.2x", start[i]);
printf("\n");
}
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}
int main(int argc, char *argv[]) {
int ival = atoi(argv[1]);
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
return 0;
}Using gcc w/o makefile
$ gcc -Wall -o main show_bytes.c
$ ./main 65537
01 00 01 00
80 00 80 47
2c ca 54 51 ff 7f 00 00
$
* the 3rd lines will be different each time you run the program, as the program address changes
It is simple and straight forward....
... for a single program,
but maybe not for complex programs when you don't want to waste time to re-compile all source codes if you only modify few of the programs
make + makefile is smart enough to decide what (modified) needs re-compile and what not (unchanged)
C Example for makefile
#include <stdio.h>
#include <unistd.h>
extern void show_int(int x);
extern void show_float(float x);
extern void show_pointer(void *x);
int main(int argc, char *argv[]) {
int ival = atoi(argv[1]);
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
return 0;
}
Split into 2 files to demonstrate makefile usage
main.c
show_byte.c
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len) {
int i;
for (i = 0; i < len; i++)
printf(" %.2x", start[i]);
printf("\n");
}
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}
Makefile Template
#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#source
SRCS = main.c show_bytes.c
#object
OBJS = $(SRCS:.c=.o)
all: main
main: $(OBJS)
$(CC) $(OBJS) -o $@
main.o: main.c
show_bytes.o: show_bytes.c
clean:
-rm -f *.oUsing gcc w/ makefile
$ make
gcc -Wall -ansi -g -c -o show_bytes.o show_bytes.c
gcc main.o show_bytes.o -o main
$ ./main 65537
01 00 01 00
80 00 80 47
2c 1a 86 5e ff 7f 00 00
$* the 3rd lines will be different each time you run the program, as the program address changes
Using 'make' is more efficient when you get familiar with it
makefile Rules
Rule #1: "Tab" is a must ≠ multiple "spaces"
#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#source
SRCS = main.c show_bytes.c
#object
OBJS = $(SRCS:.c=.o)
all: main
main: $(OBJS)
$(CC) $(OBJS) -o $@
main.o: main.c
show_bytes.o: show_bytes.c
clean:
-rm -f *.oLinux Make
By Marconi Jiang
Linux Make
Personal user guide of Linux Make
- 259