工程Makefile实例

来源:互联网 发布:腾讯视频数据分析 编辑:程序博客网 时间:2024/06/04 17:46
日期: 2015、4、19
目的: 熟悉Makefile

项目文件结构:
============================================================================
project                  --> 顶层路径
|
|                
include lib src Makefile 1级 ---> 生成可执行文件
|
|
|
app_main.c   basic Makefile2级 ---> 主逻辑模块 子模块basic
|
|
comm ioMakefile 3级 ---> 编译生成动态库并复制到project/lib目录
|                    
io.c Makefile4级 ---> 编译目录下所有文件,并生成.a文件        
           
============================================================================


1级Makefil:

====================
SUBDIRS := src
TARGET := app
export LIB_PATH := $(strip $(CURDIR)/lib) #export传递变量给子Make,实际上就是lib的绝对路径
export CCG := gcc #编译版本传递给子Make


all:
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make all); \
done


.PHONY: clean:
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make clean); \
done

2级Makefile:
==============
SUBDIRS := basic
TARGET := app
app_HEADERS := ../include/app
iconv_HEADERS := ../include/iconv
opencc_HEADERS := ../include/opencc
C_FLAGS += -g -Wall -O3 
C_FLAGS += -MD 
LIB_FLAGS := -Wl,-rpath=$(LIB_PATH) # 指定运行动态库加载路径
# -I 包含头文件
C_FLAGS += -I$(app_HEADERS) -I$(opencc_HEADERS) -I$(iconv_HEADERS)
L_FLAGS += -L$(LIB_PATH) # -L 编译加载库路径
L_FLAGS += -lbasic -lpthread -lopencc -liconv_hook 
SOURCE := $(wildcard *.c) $(wildcard *.cc) 
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE))) 
DEPS := $(patsubst %.o,%.d,$(OBJS)) 


all:$(TARGET)
    -cp $(TARGET) ../


$(TARGET):$(OBJS)
    $(CCG) $(SOURCE) $(C_FLAGS) $(LIB_FLAGS) -o $@ $(L_FLAGS) 
    
$(OBJS):$(SOURCE)
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make all); \
done
    
.PHONY: clean:
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make clean); \
done
    
3级Makefile:
==================
SUBDIRS := time comm io log net pthread 
TARGET := lib$(notdir $(CURDIR)).so # 该模块下的所有静态库文件
SRC_OBJECT = time/libtime.a pthread/libpthread.a \
net/libnet.a log/liblog.a io/libio.a comm/libcomm.a


all:$(TARGET)
-cp $(TARGET) ../../lib
-rm $(TARGET)
   
$(TARGET): $(SRC_OBJECT) 
$(CCG) -shared -fPIC -Wl,--whole-archive $(SRC_OBJECT) \
-Wl,--no-whole-archive -Wl,-soname -Wl,$@ -o $@


$(SRC_OBJECT): 
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make all); \
done

.PHONY: clean:
@for subdir in $(SUBDIRS); do \
(cd $$subdir && make clean); \
done

4级Makefile:
================
TARGET := lib$(notdir $(CURDIR)).a
app_HEADERS := ../../../include/app
opencc_HEADERS := ../../../include/opencc
iconv_HEADERS := ../../../include/iconv
C_FLAGS += -fPIC -g -Wall -O3 # 几个静态库合并成动态库,需每个静态库加 -fPIC选项
C_FLAGS += -MD 
C_FLAGS += -I$(app_HEADERS) -I$(opencc_HEADERS) -I$(iconv_HEADERS)
AR := ar
SOURCE := $(wildcard *.c) $(wildcard *.cc) 
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE))) 


all:$(OBJS)


$(OBJS):$(SOURCE)
    $(CCG) $(C_FLAGS) -c  $(SOURCE)
    $(AR) rcs $(TARGET) $(OBJS)
    
.PHONY: clean install 
clean : 
    $(RM) *.a *.o *.d




总结:
1、 通过export 定义变量,自动传递给子目录Makefile。 unexport停止传递。
2、 保存了$(CURDIR)当前目录路径。
3、 -Wl,-rpath=$(LIB_PATH) 通过编译时选项,可执行程序加载动态库时,默认搜索此路径。 如无此选项,默认搜索/usr/lib  /usr/local/lib
4、 -L$(LIB_PATH) -lxxx       # -L 编译库选项
5、 -I$(app_HEADERS)        # 包含头文件选项
6、 当需要几个静态库合并成动态库里, 通过以下选项可以解决:
      $(CCG) -shared -fPIC -Wl,--whole-archive $(SRC_OBJECT)  -Wl,--no-whole-archive  -Wl,-soname -Wl,$@ -o $@
      且所有的静态库编译里需加入-fPIC选项。


关于嵌入式Makefile:
①级Makefile:
SUBDIRS  := GeneralFunction db_data protocol network business reader ADC \
libiconv led_beep spi_flash consume obj
SOURCE     := $(wildcard *.c)  
OBJS       := $(patsubst %.c, %.o, $(SOURCE))
TARGET     := $(notdir $(CURDIR))
HEADER     := $(patsubst %.c, %.h, $(SOURCE))
AR         := arm-linux-ar
AR_FLAGS   := rcs
export     ARG     := 1
export     DEBUG 
ifdef DEBUG
export     C_FLAGS := -g -Wall -Os
else
export     C_FLAGS :=  -Wall -Os
endif


export     CCG     := arm-linux-gcc


LIB         += -lm
LIB         += -lpthread
LIB         += -L./db_data/lib -ldb
LIB         += -L./obj -lobj
LIB         += -L./ucGUI -lucgui
LIB         += -L./libiconv/lib -liconv
LIB         += -L./button_and_ledv1.0/lib -lch452
LIB         += -L./led_beep -lbase 


INC         += -I./db_data


all:$(OBJS)


$(OBJS):$(SOURCE)$(HEADER)
@for dir in $(SUBDIRS); do \
    (cd $$dir && make all); \
done
$(CCG) $(C_FLAGS)  $(SOURCE) -o $(TARGET)  $(LIB) $(INC) 




.PHONY: clean install
clean:
@for dir in $(SUBDIRS); do \
(cd $$dir && make clean);\
done
$(RM) *.o $(TARGET)


install:



②级Makefile:
TARGET     := lib$(notdir $(CURDIR)).a
OBJS       := $(wildcard *.o)
CC_FLAGS    += -fPIC -MD # 静态库合成动态库选项
AR         := arm-linux-ar
AR_FLAGS   := rcs


ifdef ARG
else
export C_FLAGS := -g -Wall -O3
export CCG := arm-linux-gcc
endif


all:$(OBJS)
$(AR) $(AR_FLAGS) $(TARGET) $(OBJS)


.PHONY: clean 
clean:
rm -rf *.o *.a


嵌入式Makefile总结:
1、优化代码空间 使用-Wall -Os选项。
2、使用export传递编译器选项参数。
3、静态库编译时已经添加到可执行文件中。
4、几个静态库一起链接时,如果有依赖关系,则需先链接被依赖库。
4、动态库需在目标机库中加入.so文件。
5、几个静态库如果需合并成一个静态库,则ar x libxxx.a   ar cru libxx.a *.o即可。
6、注释不能#开头,不然复制会乱码。


















0 0
原创粉丝点击