• makefile 中命令包及eval的使用


    info make 中的一个例子, 拿它来分析分析

    1. 1 PROGRAMS = server client
    2. 2
    3. 3 server_OBJS = server.o server_priv.o server_access.o
    4. 4 server_LIBS = priv protocol
    5. 5
    6. 6 client_OBJS = client.o client_api.o client_mem.o
    7. 7 client_LIBS = protocol
    8. 8
    9. 9 # Everything after this is generic
    10. 10
    11. 11 .PHONY: all
    12. 12 all: $(PROGRAMS)
    13. 13
    14. 14 define PROGRAM_template =
    15. 15 $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
    16. 16 ALL_OBJS += $$($(1)_OBJS)
    17. 17 endef
    18. 18
    19. 19 $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
    20. 20
    21. 21 $(PROGRAMS):
    22. 22 $(LINK.o) $^ $(LDLIBS) -o $@
    23. 23
    24. 24 clean:
    25. 25 rm -f $(ALL_OBJS) $(PROGRAMS)

    前面几个赋值我们是看得懂的,到了14行,定义了一个命令包.PROGRAM_template
    观察其dbase 中定义: 原来就是字符串照印, 是滞后求值。
    # makefile (从“Makefile”,行 14)
    define PROGRAM_template
    $(1):

    ($(1)OBJS)" role="presentation" style="text-align: center; position: relative;">($(1)OBJS)
    ($(1)_LIBS:%=-l%)
    ALL_OBJS   += $$($(1)_OBJS)
    endef

    第19行,对所有$(PROGRAMS) 进行展开,就是对server client进行操作,
    观察dbase中定义:
    # makefile (从“Makefile”,行 19)  执行时会递归求值.
    ALL_OBJS = $(server_OBJS) $(client_OBJS) 

    是的,第一遍代人server 为$(server_obj),第二遍为$(client_OBJS)
    那第一条命令依赖跑哪里去了?
    原来它跟21行$(PROGRAMS) 合并了
    以client为例,client 依赖$(client_OBJS) $(client_LIBS:%=-l%),第二次展开即得到下面结果


    第21条多目标规则被展开为2条规则
    client: client.o client_api.o client_mem.o libprotocol.so
    #  要执行的配方 (从“Makefile”,行 22):
        $(LINK.o) $^ $(LDLIBS) -o $@


    server: server.o server_priv.o server_access.o libpriv.so libprotocol.so
    #  要执行的配方 (从“Makefile”,行 22):
        $(LINK.o) $^ $(LDLIBS) -o $@

    其中$(LINK.o) 是默认变量
    # 默认
    LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
    使用时递归展开为 cc, 因为LDFLAGS,TARGET_ARCH都为空

    第24行clean 规则比较容易

    clean:
    #  要执行的配方 (从“Makefile”,行 25):
        rm -f $(ALL_OBJS) $(PROGRAMS)

    如此分析清楚了这个Makefile 到底是怎样工作的.

    总结:
    make 是制造之意. 解决的是制造问题,管理的是一个工程,所以make是工程管理工具
    管理的文件比较少,可以用小的makefile,
    管理的文件比较多,可以用大的makefile,
    如果只是一个文件,那几乎就不用管理了。
    大的工程,成千上万个文件怎么来管理生成自己的目标,这是make要考虑的.
    上面是个小工程。所作的工作是
    1. 枚举了各个obj, 各个lib
    2. 说明了由哪些obj,lib构成执行文件1,执行文件2
    3. ....
    (大工程也是这样的,可以想像大工程会定义更多的编译工具,编译flag,枚举文件等等事项)

    其中那个命令包,定义了每个执行文件依赖与哪些obj文件及库文件.
    由于其对每一个执行文件具有通用性,所以定义为宏包来简化书写过程.

  • 相关阅读:
    Java JVM 内存垃圾回收机制
    树形动态规划
    【英语:基础高阶_经典外刊阅读】L3.长句子扒皮—如何快速寻找主干
    网课答案公众号零基础怎么制作(内含详细教程)
    图解-虚拟机使用NAT方式连网
    【大学英语视听说上】Topic Presentation
    如何找回回收站清空的文件?三种方法帮助你解决问题
    【论文阅读】基于混淆的加强网络安全的方法
    基于jsp+ssm的家庭理财系统
    Ubuntu 图形界面查看Mysql 数据库内容
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/126335354