zoukankan      html  css  js  c++  java
  • 第21课

    21.打造专业的编译环境_链接

    21.1.第二阶段任务

    • 完成整个工程的makefile文件

    • 调用makefile编译生成静态库文件

    • 链接所有模块的静态库文件,得到最终的可执行程序

        makefile(08)_打造专业的编译环境

    21.2.关键的实现要点

    • 如何自动创建build文件夹及其子文件夹?

    • 如何进入每一个模块文件夹进行编译

    • 编译成功后如何链接所有模块静态库

    21.3.开发中的经验假设

      项目中的各个模块在设计阶段就已经基本确定,因此,在之后的开发过程中模块不会频繁的增加或减少

    21.4.解决方案设计

    • 1.定义变量保存模块名列表模块名变量

    • 2.利用shell中的for循环遍历模块名变量

    • 3.在for循环进入模块文件夹进行编译

    • 4.循环结束后连接所有的模块静态库文件

    21.4.1.Makefile中嵌入shell的for循环

          makefile(08)_打造专业的编译环境

     

    21.4.2. 注意事项

      Makefile中嵌入shell代码时,如果需要使用shell变量的值必须在变量前面加$$譬如$$dir,用于区分该变量是shell变量而非Makefile中定义的变量


    21.4.3. shell中for循环实验

    编程实验:

    compile : $(DIR_BUILD) $(DIR_BUILD_SUB)
        @echo "Begin to compile ..."
        @set -e; 
        for dir in $(MODULES); 
        do 
            cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd .. ; 
        done
        @echo "Compile Success!"

    运行结果:

    工程makefile中的关键构成:编译 + 链接
          makefile(08)_打造专业的编译环境
    编译makefile:

    .PHONY : all compile
    
    MODULES := common 
               module 
               main
    
    MKDIR := mkdir
    RM := rm -fr
    
    DIR_PROJECT := $(realpath .)
    DIR_BUILD := build
    DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
    MODULE_LIB := $(addsuffix .a, $(MODULES))
    
    compile : $(DIR_BUILD) $(DIR_BUILD_SUB)
        @echo "Begin to compile ..."
        @set -e; 
        for dir in $(MODULES); 
        do 
            cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd .. ; 
        done
        @echo "Compile Success!"
    
    $(DIR_BUILD) $(DIR_BUILD_SUB) : 
        $(MKDIR) $@

    输出结果:
        makefile(08)_打造专业的编译环境
        编译成功,在build文件夹下生成了各个模块的打包文件。

     

    21.5. 链接时的注意事项

    (1)gcc 在进行静态库连接时,必须遵守严格的依赖关系

    • gcc -o app.out x.a y.a

    其中的依赖关必须为:x.a -> y.a , y.a -> z.a。默认情况下遵循自左向右的依赖关系。

     

    (2)如果不清楚库间的依赖,可以使用-Xlinker自动确定依赖关系

    • gcc -o app.out -Xlinker “-(”z.a y.a x.a -Xlinker”-)”

    link $(APP) : $(MODULE_LIB) @echo "Begin to link ..." $(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS) @echo "Link Success!"

     

    21.6. 最终方案

    .PHONY : all compile link clean rebuild
    
    MODULES := common 
               module 
               main
    
    MKDIR := mkdir
    RM := rm -fr
    
    CC := gcc
    LFLAGS := 
    
    DIR_PROJECT := $(realpath .)
    DIR_BUILD := build
    DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
    MODULE_LIB := $(addsuffix .a, $(MODULES))
    MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))
    
    APP := app.out
    APP := $(addprefix $(DIR_BUILD)/, $(APP))
    
    all : compile $(APP)
        @echo "Success! Target ==> $(APP)"
    
    compile : $(DIR_BUILD) $(DIR_BUILD_SUB)
        @echo "Begin to compile ..."
        @set -e; 
        for dir in $(MODULES); 
        do 
            cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd .. ; 
        done
        @echo "Compile Success!"
    
    link $(APP) : $(MODULE_LIB)
        @echo "Begin to link ..."
        $(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS)
        @echo "Link Success!"
    
    $(DIR_BUILD) $(DIR_BUILD_SUB) : 
        $(MKDIR) $@
    
    clean : 
        @echo "Begin to clean ..."
        $(RM) $(DIR_BUILD)
        @echo "Clean Success!"
    
    rebuild : clean all

    运行结果:

    思考:
      当前整个项目的makefile是否存在潜在的问题?是否需要重构

     

  • 相关阅读:
    浅谈HTTPS协议和SSL、TLS之间的区别与关系
    ECC加密算法原理入门介绍
    用实例给新手讲解RSA加密算法
    ECC椭圆曲线详解(有具体实例)
    设置VMware随系统开机自动启动并引导虚拟机操作系统
    Windows自带的端口转发工具netsh使用方法
    JAVA中使用P和Q分量计算N和D进行RSA运算
    VirtualBox虚拟机和主机之间的通信
    centos 系统管理维护指南
    页面找不到js方法的原因,关于EasyUI
  • 原文地址:https://www.cnblogs.com/hoiday/p/10301584.html
Copyright © 2011-2022 走看看