makefile交叉编译helloworld主要需要修改的是在本地编译helloworld基础上修改本地工具链为交叉编译工具链。
1.本地使用makefile编译helloworld
如图为工程目录结构
.
├── hello.c
├── hello.h
├── main.c
├── Makefile
├── world.c
└── world.h
hello.c文件
#include<stdio.h>
#include"hello.h"
void hello()
{
printf("hello");
}
world.c文件
#include<stdio.h>
#include"world.h"
void world()
{
printf("world");
}
main.c
#include <stdio.h>
#include "hello.h"
#include "world.h"
int main()
{
//printf("hello world\n");
hello();
world();
return 0;
}
那么如何写MakeFile文件编译以上工程呢?
1.1简单的makefile文件如下
OBJS = main.o hello.o world.o
CC = gcc
CFLAGS = -Wall -O -g
helloworld : $(OBJS)
$(CC) $(OBJS) -o helloworld
main.o : main.c
$(CC) $(CFLAGS) -c main.c -o main.o
hello.o : hello.c hello.h
$(CC) $(CFLAGS) -c hello.c -o hello.o
world.o : world.c world.h
$(CC) $(CFLAGS) -c world.c -o world.o
clean:
rm -rf *.o helloworld
注意,如果报下面的错误
Makefile:17: *** missing separator. Stop
可能是Makefile格式不正确,注意要用tab,而不是空格键,Makefile有以下规则
A: B
(tab)<command>
(tab)<command>
1.2优化的makefile文件如下
主要的优化点为不用手动一个一个文件名写。
CC = gcc
LD = gcc
# 正则表达式表示目录下所有.c文件,相当于:SRCS = main.c a.c b.c
SRCS = $(wildcard *.c)
# OBJS表示SRCS中把列表中的.c全部替换为.o,相当于:OBJS = main.o a.o b.o
OBJS = $(patsubst %c, %o, $(SRCS))
# 可执行文件的名字
TARGET = helloworld
# .PHONE伪目标,具体含义百度一下一大堆介绍
.PHONY:all clean
# 要生成的目标文件
all: $(TARGET)
# 第一行依赖关系:冒号后面为依赖的文件,相当于Hello: main.o a.o b.o
# 第二行规则:$@表示目标文件,$^表示所有依赖文件,$<表示第一个依赖文件
$(TARGET): $(OBJS)
$(LD) -o $@ $^
# 上一句目标文件依赖一大堆.o文件,这句表示所有.o都由相应名字的.c文件自动生成
%.o:%.c
$(CC) -c $^
# make clean删除所有.o和目标文件
clean:
rm -f $(OBJS) $(TARGET)
函数1:wildcard
产生一个所有以’.c’ 结尾的文件的列表。
SOURCES = $(wildcard *.c *.cpp)表示产生一个所有以.c,.cpp结尾的文件的列表,然后存入变量SOURCES 里。
函数2:patsubst
匹配替换,有三个参数。第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的列表。
OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))
表示把文件列表中所有的.c,.cpp字符变成.o,形成一个新的文件列表,然后存入OBJS变量中。
2.makefile交叉编译helloworld
对于以上工程,需要交叉编译的时候主要需要修改c/c++编译工具链,以及设置环境变量使能够找到交叉编译工具链。
(1)修改c/c++编译工具链如下
CROSS_COMPILE ?= arm-linux-gnueabihf-
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
(2)设置环境变量,找到交叉编译工具链的路径
在控制台输入
export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/arm-linux-gnueabihf/bin
交叉编译能够成功。
交叉编译的makefile如下
CROSS_COMPILE ?= arm-linux-gnueabihf-
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
CFLAGS = -Wall -O -g
OBJS = main.o hello.o world.o
helloworld : $(OBJS)
$(CC) $(OBJS) -o helloworld
main.o : main.c
$(CC) $(CFLAGS) -c main.c -o main.o
hello.o : hello.c hello.h
$(CC) $(CFLAGS) -c hello.c -o hello.o
world.o : world.c world.h
$(CC) $(CFLAGS) -c world.c -o world.o
clean:
rm -rf *.o helloworld
参考文献
https://www.cnblogs.com/mfryf/p/4613504.html
https://blog.csdn.net/shaosunrise/article/details/79968921