您的位置:首页 > 其它

工程Makefile实例

2015-06-05 21:28 330 查看
日期: 2015、4、19

目的: 熟悉Makefile

项目文件结构:

============================================================================
project                  --> 顶层路径
|
|                
include
lib src
Makefile 1级 ---> 生成可执行文件
|
|
|
app_main.c  
basic Makefile
2级 ---> 主逻辑模块 子模块basic
|
|
comm io
Makefile 3级 ---> 编译生成动态库并复制到project/lib目录
|                    
io.c Makefile
4级 ---> 编译目录下所有文件,并生成.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
$
9413
(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、注释不能#开头,不然复制会乱码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: