ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Makefile实例详解

Makefile实例详解

原创 Linux操作系统 作者:夜溪 时间:2015-04-19 10:57:21 1 删除 编辑

日期: 2015、4、19
目的: 熟悉Makefile

项目文件结构:
============================================================================
                                 project                                       --> 顶层路径
                                    |
               |                    |            |
            include              lib          src      --->    Makefile             1级
               |                    |            |
         所需头文件        所需库         |
                                                  |
                                              basic      app_main.c   Makefile    2级 ---> 主逻辑模块 子模块basic 
                                                 |
                                                 |
                                 comm        io       Makefile                      3级 --->把目标下所有的静态库文件, 编译生成动态库并复制到project/lib目录
                                                 |                    
                                                 io.c     Makefile                      4级--> 编译目录下所有文件,并生成.a文件                   
============================================================================


1级Makefile:
===========================================================

点击(此处)折叠或打开

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

  5. all:
  6.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  7.     echo \"Making all in $$list\"; \\
  8.     (cd $$subdir && make all); \\
  9.     done
  10.     
  11. .PHONY: clean
  12. clean:
  13.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  14.     $(RM) $(TARGET) *.o *.d \\
  15.     echo \"Clean in $$subdir\"; \\
  16.     (cd $$subdir && make clean); \\
  17.     done




2级Makefile:
===========================================================


点击(此处)折叠或打开

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

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

  18. $(TARGET):$(OBJS)
  19.     $(CCG) $(SOURCE) $(C_FLAGS) $(LIB_FLAGS) -o $@ $(L_FLAGS)
  20.     
  21. $(OBJS):
  22.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  23.     echo \"Making all in $$list\"; \\
  24.     (cd $$subdir && make all); \\
  25.     done
  26.     
  27.     
  28. .PHONY: clean
  29. clean:
  30.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  31.     $(RM) $(TARGET) *.o *.d \\
  32.     echo \"Clean in $$subdir\"; \\
  33.     (cd $$subdir && make clean); \\
  34.     done


3级Makefile:
===========================================================

点击(此处)折叠或打开

  1. SUBDIRS := time comm io log net pthread
  2. TARGET := lib$(notdir $(CURDIR)).so
  3. # 该模块下的所有静态库文件
  4. SRC_OBJECT = time/libtime.a pthread/libpthread.a \\
  5. net/libnet.a log/liblog.a io/libio.a comm/libcomm.a

  6. all:$(TARGET)
  7.     -cp $(TARGET) ../../lib
  8.     -rm $(TARGET)

  9. # 几个静态库文件合并成一个动态库    
  10. $(TARGET): $(SRC_OBJECT)
  11.     $(CCG) -shared -fPIC -Wl,--whole-archive $(SRC_OBJECT) \\
  12.     -Wl,--no-whole-archive -Wl,-soname -Wl,$@ -o $@

  13. # 进入子目录    
  14. $(SRC_OBJECT):
  15.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  16.     echo \"Making all in $$list\"; \\
  17.     (cd $$subdir && make all); \\
  18.     done
  19.     
  20. .PHONY: clean
  21. clean:
  22.     @list=\'$(SUBDIRS)\'; for subdir in $$list; do \\
  23.     (cd $$subdir && make clean); \\
  24.     done



4级Makefile:
===========================================================

点击(此处)折叠或打开

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

  11. all:$(TARGET)

  12. $(TARGET):$(OBJS)

  13. $(OBJS):
  14.     $(CCG) $(C_FLAGS) -c -o $(OBJS) $(SOURCE)
  15.     $(AR) rcs $(TARGET) $(OBJS)
  16.     
  17. .PHONY: clean install
  18. clean :
  19.     $(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选项。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30115060/viewspace-1585523/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2015-01-23

  • 博文量
    1
  • 访问量
    11582