一步一步写一个简单通用的makefile(一)

经常会用写一些小的程序有的是作为测试,但是每次都需要写一些简单的GCC 命令,有的时候移植一些项目中的部分代码到小程序里面进行测试,这个时候GCC 命令并不好些,如果写啦一个比较常用的makefile的模板,然后把文件添加进来,简单的修改一下makefile即可以完成测试任务何乐而不为。

源代码有三个文件,三个文件在同一个目录下面/hellomake
hellomake .c:

#include "hellofunc.h"
#include<stdio.h>
#include<math.h>
int main() {
// call a function in another file
myPrintHelloMake();
double value =;
printf("Value:%f\n",log(value));
return();
}

hellofunc.c:

#include "hellofunc.h"
#include<stdio.h>
void myPrintHelloMake(void) { printf("Hello makefiles!\n");
return;
}

hellofunc.h

/*
example include file
*/ void myPrintHelloMake(void);

编译,执行gcc 命令如下:

gcc -Wall -o hellomake hellomake.c hellofunc.c -lm

编译生成可执行文件hellomake.

执行命令:"./hellomake",结果如下:

Hello makefiles!
Value:2.708050

gcc 的命令执行顺序应该编译源文件生成目标文件,然后链接目标文件生成可执行文件,执行命令如下:

gcc -Wall -c hellomake.c hellofunc.c
gcc -o hellomake hellomake.o hellofunc.o -lm

gcc -Wall -o hellofunc.o hellofunc.c

gcc -Wall -o hellomake.o hellomake.c

在当前目录下添加makefile文件:

#Hellomake
#Magnum, --
# 指令编译器和选项
CC=gcc
CFLAGS=-Wall
LIBS=-lm # 目标文件
TARGET=hellomake
SRCS = hellofunc.c \
hellomake.c # 依赖目标
OBJS =$(SRCS:.c=.o) $(TARGET):$(OBJS)
#@echo TARGET:$(OBJS)
# @echo OBJECTS:$^
$(CC) -o $@ $^ $(LIBS) clean:
rm -rf $(TARGET) $(OBJS) $(OBJS):$(SRCS)
$(CC) $(CFLAGS) -o $@ -c $<

执行make,报错:

gcc   -Wall  -o hellofunc.o -c hellofunc.c
gcc -Wall -o hellomake.o -c hellofunc.c
gcc -o hellomake hellofunc.o hellomake.o -lm
hellomake.o: In function `myPrintHelloMake':
hellofunc.c:(.text+0x0): multiple definition of `myPrintHelloMake'
hellofunc.o:hellofunc.c:(.text+0x0): first defined here
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation has invalid symbol index
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned exit status
make: *** [hellomake] Error

错自第二句:

gcc   -Wall  -o hellomake.o -c hellofunc.c

使用$(OBJS):$(SRCS)并不会自动推进,修改makefile文件:

#Hellomake
#Magnum, --
# 指令编译器和选项
CC=gcc
CFLAGS=-Wall
LIBS=-lm # 目标文件
TARGET=hellomake
SRCS = hellofunc.c \
hellomake.c # 依赖目标
OBJS =$(SRCS:.c=.o) $(TARGET):$(OBJS)
# @echo TARGET:$(OBJS)
# @echo OBJECTS:$^
$(CC) -o $@ $^ $(LIBS) #$@指目标文件,这里是hellomake,$^指所有依赖文件,这里指hellofunc.o,hellomake.o clean:
rm -rf $(TARGET) $(OBJS) %.o:%.c
$(CC) $(CFLAGS) -o $@ -c $< #$<指第一个依赖文件此处以此为hellofunc.c,hellomake.c

执行make,编译OK。

如果有更多的源文件,一个个加很麻烦,可以用wildcard 来解决这个问题,进一步版本的makefile如下:

#Hellomake
#Magnum, --
# 指令编译器和选项
CC=gcc
CFLAGS=-Wall
LIBS=-lm # 目标文件
TARGET=hellomake
SRCS = $(wildcard *.c) #当前文件夹下面的所有.c文件
#SRCS = hellofunc.c \
# hellomake.c # 依赖目标
OBJS =$(SRCS:.c=.o) # $(TARGET):$(OBJS)
# @echo TARGET:$(OBJS)
# @echo OBJECTS:$^
$(CC) -o $@ $^ $(LIBS) #$@指目标文件,这里是hellomake,$^指所有依赖文件,这里指hellofunc.o,hellomake.o clean:
rm -rf $(TARGET) $(OBJS) %.o:%.c
$(CC) $(CFLAGS) -o $@ -c $< #$<指第一个依赖文件此处以此为hellofunc.c,hellomake.c

这里到这结束,下一篇是跨多个文件夹的makefile 如何编写。

上一篇:高级测试工程师面试必问面试基础整理——python基础(一)(首发公众号:子安之路)


下一篇:互联网公司面试必问的mysql题目(上)