Makefile

Makefile关系到了整个工程的编译规则。一个工程中的源文件不计其数,并且按类型、功能、模块分 别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译, 哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可 以执行操作系统的命令。

Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极 大的提高了软件开发的效率。 make是一个命令工具,是一个解释makefile中指令的命令工具。

在Unix下进行软件编译,需要学会自己写makefile。会不会 写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

下面这个非常详细的教程,包含几乎GNU make的Makefile的所有细节:
跟我一起写Makefile

Makefile小模板

适用于纯 C 语言

# 指令编译器和选项
CC=gcc
CFLAGS=-Wall -std=gnu99
 
# 目标文件
TARGET=main
SRCS = main1.c \
            main2.c  \
            main3.c  
INC = -I./
OBJS = $(SRCS:.c=.o)

$(TARGET):$(OBJS)
    $(CC) -o $@ $^
 
clean:
    rm -rf $(TARGET) $(OBJS)
 
%.o:%.c
    $(CC) $(CFLAGS) $(INC) -o $@ -c $<

注意:Makefile有个规则就是命令行是以tab键开头,4个空格或其他则会报错:
Makefile:2: *** missing separator。stop

  • 相比于单个文件和多个文件的makefile,通过变量INC制定了头文件路径。头文件路径之间通过空格隔开。
  • 编译规则%.o:%.c中加入了头文件参数(CFLAGS) @ -c $<,
  • 单个文件和多个文件的makefile相比增加了头文件路径参数。
  • SRCS变量中,文件较多时可通过“\”符号续行。
  • $@ --代表目标文件
  • $^ --代表所有的依赖文件
  • $< --代表第一个依赖文件(最左边的那个)。

适用于 C/C++ 混合编译

目录结构如下:

httpserver
│   main.cpp
│   Makefile  
└─────inc
│      │   mongoose.h
│      │   http_server.h
│   
──────src
│       │   http_server.cpp
│       │   mongoose.c
│       │   ...

Makefile 如下:

CC=gcc
CXX=g++

# 编译器在编译时的参数设置,包含头文件路径设置
CFLAGS:=-Wall -O2 -g 
CFLAGS+=-I $(shell pwd)/inc
CXXFLAGS:=-Wall -O2 -g -std=c++11
CXXFLAGS+=-I $(shell pwd)/inc

# 库文件添加
LDFLAGS:=
LDFLAGS+=

# 指定源程序存放位置
SRCDIRS:=.
SRCDIRS+=src

# 设置程序中使用文件类型
SRCEXTS:=.c .cpp

# 设置运行程序名
PROGRAM:=httpserver

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)
endif


install:
    install -m 755 -D -p $(PROGRAM) ./bin

clean:
    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)

你可能感兴趣的:(Makefile)