美文网首页
构建Makefile

构建Makefile

作者: 靖哥哥编程 | 来源:发表于2021-09-02 14:57 被阅读0次

构建Makefile(一)

linux/Cygwin下构建Makefile的第一步是做工具链和命令的环境设置,一般在项目根创建一个buildenv.mk文件,内容如下:

ifeq "$(PHYROOT)" " "
     $(error "$$PHYROOT environment variable is not defined!")
endif 

PHYROOT:/$(subst \,/,$(PHYROOT))

ifeq "$(strip $(OSTYPE))" "cygwin"
    ifeq "$(strip $(NOCYGWIN))" "yes"
        ifeq "$(shell uname -m)"  "x86_64"
            PREFIX=x86_64-w64-mingw32-
        else
            PREFIX=i686-w64-mingw32-
        endif
    else
        PREFIX?=
    endif
else
    PREFIX?=
endif

GCC=$(PREFIX)gcc
CC =  $(PREFIX)gcc
CPP=$(PREFIX)g++
AR=$(PREFIX)ar
NM=$(PREFIX)nm
DUMP=$(PREFIX)objdump
AS=$(PREFIX)as
LD=$(PREFIX)ld

# Common UNIX utilities
BINFIX= /usr/bin
MKDIR=$(BINFIX)/mkdir -p
RM=$(BINFIX)/rm -rf
CAT=$(BINFIX)/cat
ECHO=$(BINFIX)/echo
MV=$(BINFIX)/mv
CP=$(BINFIX)/cp
OD=$(BINFIX)/od
XXD=$(BINFIX)/xxd

其中的PHYROOT一般是本项目的目录位置,也可以用个判断设置为当前路径,像这样:

       ifeq "$(PHYROOT)"  " "
             PHYROOT:=$(pwd)
       endif

放在本文件的最前面。
有了这个buildenv.mk文件就可以在Makefile里制作编写各种编译规则了。

构建Makefile(二)

首先要有buildenv.mk文件,在准备编译所需要的文件及目录条件,下面是Makefile的前面半截内容

include ../buildenv.mk

TARGET=libBase.a
SRC_DIR=.

SRCS=$(wildcard $(SRC_DIR)/*.c)
HEADS=$(wildcard $(SRC_DIR)/*.h)

OBJS=$(patsubst $(SRC_DIR)/%.c, %.o, $(SRCS))
DEPS=$(patsubst %.o, %.d, $(OBJS))

ADEP=Makefile.dep

COMMON_DIR=../phy/common
INSTALL_HEADS=$(patsubst %.h, $(COMMON_DIR)/%.h, $(notdir $(HEADS)))

CFLAGS ?= -ggdb --std=gnu99 -Wall
CINCS = -I$(SRC_DIR)
CDEFS =
CLIBS = -lm

需要逐个解释一下:

最开始是包含引用buildenv.mk文件

定义编译目标,此处是一个静态库.a文件,静态库的命名习惯是libXXX.a

定义源码目录,这里简单地放在同一级目录下了

源码文件列表,这里使用了个make文件的内嵌宏wildcard,它扫描源码目录,将全部.c文件包含其中

头文件列表,使用内嵌宏将全部.h文件包含其中

目标文件列表,使用内嵌替换宏,patsubst将后缀为.c的列表改为后缀为.o的列表

依赖文件列表,使用宏将后缀为.o的改为.d的列表

工程依赖文件命名为Makefile.dep,这只是遵循习惯

COMMON_DIR此处其实是安装的目的目录, 就是编译完成后的结果放置路径

INSTALL_HEADS是把本地的头文件列表转换为目标文件列表,先用notdir去掉列表中的文件目录前缀,再用patsubst将.h加上固定的目录前缀

CC编译设置 CFLAGS,会有:调试代码-g-ggdb; 代码规范--std,推荐用gnu99;编译报警,建议全部打开-Wall

CC包含设置CINCS,增加包含源码目录

CC预定义设置CDEFS,有时会用到类似-DTEST,相当于源码中设置“#define TEST”

CC库设置CLIBS,经常情况下会包含math,可视需要增加pthread或其他在/usr/lib下使用的库,有时还会加入自己编译出来的库

构建Makefile(三)

下面编写Makefile内部的规则项,只给出最简单的一些规则:

install: all
        $(CP) $(HEADS) $(COMMON_DIR)
        $(CP) $(TARGET) $(COMMON_DIR)

all: $(ADEP) $(DEPS) $(TARGET)

$(TARGET): $(OBJS)

        $(AR) -rv $@ $(OBJS)

%.o: $(SRC_DIR)/%.c

        $(CC) $(CFLAGS) $(CINCS) $(CDEFS) -c $< -o $@

%.d: $(SRC_DIR)/%.c

        $(CC) $(CFLAGS) $(CINCS) $(CDEFS) -MM -MQ -c $< > $@

        $(ADEP): $(DEPS)
        $(CAT) $< > $@

clean:
        $(RM) $(addprefix *., o a s v d dep exe log stackdump ini)

clobber: clean
        $(RM) $(INSTALL_HEADS) $(COMMON_DIR)/$(TARGET)

注意按Makefile规则要求,每行开始字符串为规则名,执行命令内容以\t开始,辅助(预执行规则或是输入条件)写在规则名的":"

这里的目标是个libBase.a静态库文件,所以对$(TARGET)的生成规则使用了$AR库打包命令。

相关文章

网友评论

      本文标题:构建Makefile

      本文链接:https://www.haomeiwen.com/subject/tbpqwltx.html