比较简单的Generic Makefile for C/C++ Program

来源:互联网 发布:mac http 抓包工具 编辑:程序博客网 时间:2024/06/09 23:51

比较简单的Generic Makefile for C/C++ Program

参考网上资料写的一个简单的能够编译C/C++混合工程的Makefile【网上大多通用Makefile很长且未有解释,故写此文档】

暂未遇到问题,本人不甚精通,文件未经实际使用锤炼,如有问题请联系:liyanbin0027@163.com 墙裂欢迎指正与交流!

本Makefie需要读者有一定的Makefile基础知识

本Makefile可实现多级目录编译,使用者需要根据自己的项目自己设置,主要设置变量如下:
# CFLAGS/CXXFLAGS  用于设置编译器参数、头文件路径【包括动态库头文件路径如果有使用到】
# LDFLAGS    用于设置动态库文件所在路径【如果有使用到】
# SRCDIRS          用于设置源代码所在文件夹
# SRCEXTS          用于设置工程中用到的文件类型,比如.c .cxx

序-结果演示

首先建立文件如下:

 

各文件内容如下:

hello.c

/* File name: hello.c * c source file  */#include "hello.h"#include "stdio.h" void print_hello(){printf("Hello, world!\n");}

hello.h

/* File name: hello.h * c header file */ #ifndef HELLO_H#define HELLO_H #ifdef __cplusplusextern "C" {#endifvoid print_hello();#ifdef __cplusplus}#endif#endif

main.cxx

/* File naem: main.cxx * c++ source file */ #include "hello.h" int main(){print_hello();return 0;}

Makefile

############################################################################# ## Generic Makefile for C/C++ Program## Author: Yanbin Lee# Date  : 2017/07/05#============================================================================# The C/C++ program compiler.CC=gccCXX=g++# 编译器在编译时的参数设置,包含头文件路径设置CFLAGS:=-Wall -O2 -gCFLAGS+=-I $(shell pwd)/includeCXXFLAGS:=-Wall -O2 -gCXXFLAGS+=-I $(shell pwd)/include# 库文件添加LDFLAGS:=LDFLAGS+=# 指定源程序存放位置SRCDIRS:=.SRCDIRS+=dir# 设置程序中使用文件类型SRCEXTS:=.c .cxx# 设置运行程序名PROGRAM:=hello#t1=$(addprefix $(SRCDIRS)/*,$(SRCEXTS))#t2=$(foreach d,$(SRCDIRS),echo $(d))#t3=$(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))#all:#@echo $(t3)SOURCES=$(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))OBJS=$(foreach x,$(SRCEXTS),$(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES)))).PHONY: all clean distclean install%.o: %.c$(CC) -c $(CFLAGS) -o $@ $<%.o: %.cxx$(CXX) -c $(CXXFLAGS) -o $@ $<$(PROGRAM): $(OBJS)ifeq ($(strip $(SRCEXTS)),.c)$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)else$(CXX) -o $(PROGRAM) $(OBJS) $(LDFLAGS)endifinstall:install -m 755 -D -p $(PROGRAM) ./binclean:rm -f $(shell find -name "*.o")rm -f $(PROGRAM)distclean:rm -f $(shell find -name "*.o")rm -f $(shell find -name "*.d")rm -f $(PROGRAM)all:@echo $(OBJS)


本示例工程代码可到此下载:点击打开链接


获取root权限,输入make得到可执行文件hello,然后运行:

 

 

 

1. 部分makefile函数

该小节介绍了使用到的部分函数,完整的函数介绍可参考:

【Makefile常用函数总结】http://blog.csdn.net/ustc_dylan/article/details/6963248

filter:过滤函数

sources := foo.c bar.c baz.s ugh.h

$(filter %.c %.s,$(sources))

数返回值为“foo.c bar.c baz.s

patsubst:模式替换函数

$(patsubst %.c,%.o,x.c.c bar.c)

#把字串“x.c.c bar.c”中以.c结尾的单词替换成以.o结尾的字符。函数的返回结果是“x.c.o bar.o

wildcard:模式匹配文件名

Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表

foreach:循环函数

$(foreach VAR,LIST,TEXT)

执行时把“LIST”中使用空格分割的单词依次取出赋值给变量“VAR”,然后执行“TEXT”表达式

a.o b.o

string:去空格函数,去掉<string>字串中开头和结尾的空字符

$(strip a b c )

把字串“abc”去到开头和结尾的空格,结果是“abc”。

$(findstring <find>,<in> )

addprefix :加前缀函数

$(addprefix src/,foo bar)返回值是“src/foosrc/bar

 

 

2. 难点解释

本Makefile 中比较难理解的可能是【SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))】这句,单纯从语法理解会比较难理解,可逐步拆解

测试1

文件夹下新建文件

root@ubuntu:/home/share/task002# ls

hello.c  hello.h  Makefile  mian.cxx

Makefile:

SRCDIRS:=.

SRCEXTS:=.c .cxx

 

t1=$(addprefix $(SRCDIRS)/*,$(SRCEXTS))

all:

@echo $(t1)

输出:./hello.c ./mian.cxx(一开始以为输出的会是./*.c、./*cxx)

测试2

在测试1的基础上添加一个dir文件夹

SRCDIRS:=.

SRCDIRS+=dir

 

t2=$(foreach d,$(SRCDIRS),echo $(d))

all:

@echo $(t2)

输出:echo . echo dir【注意不是结果不是由all得到的,而是由foreach的规则输出的】

测试3

在测试2的基础上添加一个a.c文件

SRCDIRS:=.

SRCDIRS+=dir

SRCEXTS:=.c .cxx

 

t3=$(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))

all:

@echo $(t3)

输出:./hello.c ./mian.cxx dir/a.c(单纯的去理解很难,还是自己测试一下比较合理

测试4

同理对OBJS=$(foreach x,$(SRCEXTS),$(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))进行处理,同时在dir目录下新建一个文件a.o

最终的输出:./hello.o dir/a.o ./mian.o

 

 

 

3. 注意事项

 

l 在windows下编辑的时候注意空格、注意Tab键、注意换行符,这些都是坑

l 时间有限,未测试添加动态库时Makefile文件是否可用

 

 

 

 

 

 

 

 

原创粉丝点击