工程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、注释不能#开头,不然复制会乱码。
目的: 熟悉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、注释不能#开头,不然复制会乱码。
相关文章推荐
- Stochastic Gradient Descent 随机梯度下降法-R实现
- 随笔
- hdu 2795 Billboard 线段树 点更新
- 面试经历1
- SQLite数据库框架ORMLite与GreenDao的简单比较
- 内部类
- ViewPager实现页面滑动的学习与使用
- 工作十二载,第一次实施自己换工作的想法,面试总结
- Valid Parentheses
- AVL树旋转操作图解
- IO系统
- HDU 不容易系列之(4)——考新郎
- 【教材】 用Cheat Engine查找特殊码(简易版)
- Tomcat安全配置及优化
- HDU 钥匙计数之一
- 弗罗贝尼乌斯范数(Frobenius norm)
- 【HDU】1402 A * B Problem Plus 【FFT】
- 指针函数和函数指针
- SYNONYMS
- Codeforces Round #306 (Div. 2) B(dfs)