linuxep笔记20161116

本文介绍了一种从零开始编写Makefile的方法,旨在简化复杂的代码编译过程。通过实例展示了如何为库文件和可执行文件分别创建Makefile,并利用循环语句实现模块化的编译流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

底层运行的daemon想把系统命令(如iostat,top什么的)的代码集成进来,摆脱对系统工具的依赖。daemon之前的代码结构比较简单,但引入这些模块之后,代码路径需要重新组织一下。将c代码放到src中,h放到inc中,命令源码放到module中。


由于代码结构变复杂了,之前的编译语句,最好修改成makefile文件。以前都是在别人的基础修改makefile,这次是从头自己写两个,其中一个是模块的,编译成.a, 另一个是编译成可执行文件。


参考了网上的一些文档,以及陈皓的跟我一起写Makefile,这篇文章讲的相当详细,结合网上的一些例子,可以写一个简单的makefile文件了。


编译.a的相对简单:




DIR_INC = ./inc
DIR_SRC = ./src
DIR_OBJ = ./obj

SRC = $(wildcard ${DIR_SRC}/*.c)
OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC}))

TARGET = libsysstat.a


CFLAGS = -I$(DIR_INC) -Wall -static


${TARGET}:${OBJ}
        $(AR) rc $@ $^
        @mv $(TARGET) ../../libs
${DIR_OBJ}/%.o:${DIR_SRC}/%.c
        @mkdir -p $(DIR_OBJ)
        $(CC) $(CFLAGS) -c  $< -o $@


.PHONY:clean
clean:
        @rm -rf $(DIR_OBJ)


其实要是把c h o什么的文件都放在一起,写起来相对容易,但我比较喜欢将文件按类型放到不同的文件夹里,所以也增加了不小的难度。


可执行程序的makefile也差不多,但我想用循环语句先执行模块的makefile,这样一条命令可以将所有的makefile都嵌套执行了。见foreach语句


PROJECT_TOP_DIR=$(PWD)
PROJECT_BIN_DIR=./bin
PROJECT_SRC_DIR=./src
PROJECT_INC_DIR=./inc
PROJECT_LIB_DIR=$(PROJECT_TOP_DIR)/libs
PROJECT_OBJ_DIR=./objs
PROJECT_EV_DIR=./arm-libev
PROJECT_MODULE_DIR=./modules
PROJECT_SYSSTAT_DIR=$(PROJECT_MODULE_DIR)/sysstat-lite
PROJECT_BUSYBOX_DIR=$(PROJECT_MODULE_DIR)/busybox-lite
MKDIR := mkdir -p




ifeq ($(ARCH), x86)
CC=gcc
AR=ar
LD=ld
CFLAGS := -lev -lm -lrt -static -I$(PROJECT_INC_DIR) -D_SYSTEM_FUN
LDFLAG :=
else
CROSS_COMPILE=arm-linux-gnueabi-
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar
LD=$(CROSS_COMPILE)ld
CFLAGS := -lev -lm -lrt -static -I$(PROJECT_INC_DIR) -D_TOOLBOX_FUN
LDFLAG := -L$(PROJECT_EV_DIR)
endif


export CROSS_COMPILE CC AR LD
#DEFS = -DBUILDIN_FUNC


SUBDIRS := $(PROJECT_SYSSTAT_DIR) $(PROJECT_BUSYBOX_DIR)


TARGETS = lepd


src :=$(wildcard $(PROJECT_SRC_DIR)/*.c)
dir := $(notdir $(src))
PROJECT_OBJ := $(patsubst %.c,%.o,$(dir) )


PROJECT_ALL_OBJS := $(addprefix $(PROJECT_OBJ_DIR)/, $(PROJECT_OBJ))


all:$(PROJECT_ALL_OBJS)
        $(CC) $(wildcard $(PROJECT_SRC_DIR)/*.c) $(wildcard $(PROJECT_LIB_DIR)/*.a) $(CFLAGS) -o $(PROJECT_BIN_DIR)/$(TARGETS) $(LDFLAG)


prepare:
        cd $(foreach i, $(shell echo $(SUBDIRS)), $(i)) && $(MAKE)
        #cd $(SUBDIRS) && $(MAKE)
        $(MKDIR) $(PROJECT_OBJ_DIR)
        $(MKDIR) $(PROJECT_BIN_DIR)


$(PROJECT_OBJ_DIR)/%.o : $(PROJECT_SRC_DIR)/%.c prepare
        $(CC) -c $(CFLAGS) $< -o $@ 


clean:
        rm -fr $(PROJECT_OBJ_DIR)
        rm -fr $(PROJECT_BIN_DIR)
        -rm $(PROJECT_LIB_DIR)/*
        #cd $(SUBDIRS) && $(MAKE) clean
        cd $(foreach i, $(shell echo $(SUBDIRS)), $(i)) && $(MAKE) clean



总之,我觉得makefile还是挺难写的,各种语法函数,还是需要一个熟悉的过程。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值