• 第18课


    1. 问题一:当 VPATH 和 vpath 同时出现,make 会如何处理?

      工程项目的目录结构如下图所示,src1 和 src2 中都包含了 func.c 文件,如果在 makefile 中使用 VPATH 指定了 src1 ,使用 vpath 指定了 src2当 VPATH 和 vpath 同时存在时,make 会做出怎样的处理?

        

    【编程实验】

    makefile.1

    VPATH := src1
    CFLAGS := -I inc
    
    vpath %.c src2
    vpath %.h inc
    
    app.out : func.o main.o
        @gcc -o $@ $^
        @echo "Target File ==> $@"
    
    %.o : %.c func.h
        @gcc $(CFLAGS) -o $@ -c $<
        

    执行 make 后的输出结果:

      

    【实验结论】

    make 搜索文件的次序如下:

      make 首先在当前文件夹搜索需要的文件;如果搜索失败,make 优先 vpath 指定的文件夹中搜索目标文件;当 vpath 搜索失败时,转而搜索 VPATH 指定的文件夹。

        

     

    2. 问题二:当使用 vpath 对同一个 Pattern 指定多个文件夹时,make 会如何处理?

    工程项目的目录结构与问题一相同,src1 和 src2 中都包含了 func.c 文件,如果在 makefile 中使用 vpath 同时指定了两个src1 和 src2 两个目录,make 会做出怎样的处理?

      

    【编程实验】

    makefile.2

    CFLAGS := -I inc
    
    vpath %.c src1
    vpath %.c src2
    
    vpath %.h inc
    
    app.out : func.o main.o
        @gcc -o $@ $^
        @echo "Target File ==> $@"
    
    %.o : %.c func.h
        @gcc $(CFLAGS) -o $@ -c $<
        

    执行 make 后的输出结果:(src1 出现在 src2 之前)

      

    【实验结论】

    makefile 中使用 vpath 对同一个 Pattern 指定了多个目录时,make 会以自上而下的顺序搜索 vpath 指定的文件夹,当找到目标文件时,搜索结束。

      

     

    3. 问题三: 通过 VPATH 指定搜索路径后,make 如何决定目标文件最终位置

    工程项目的目录结构如下图所示,查看 make 编译后当前目录下的内容,发现生成的可执行程序 app.out 在当前目录下

        

    makefile.3

    GPATH := src
    VPATH := src
    CFLAGS := -I inc
    
    app.out : func.o main.o
        @gcc -o $@ $^
        @echo "Target File ==> $@"
    
    %.o : %.c inc/func.h
        @gcc $(CFLAGS) -o $@ -c $<

    如果此时把 app.out 移到 src 目录下,再次 make 编译,会出现什么样的情况?

        

    当 make 编译时,发现 app.out 在当前目录下不存在,会搜索 VPATH 变量指定的路径,发现里面存在 app.out ,因此出现了上面的情况。

    改动 fun.c 这个源文件,重新编译,发现在当前目录下生成了新的 app.out。

      

    【实验结论】

    (1)当 app.out 完全不存在

    • make 在当前文件下创建 app.out

    (2)当 src 文件夹中存在 app.out

    • 所有目标和依赖的新旧关系不变,make 不会重新创建 app.out
    • 当依赖文件被更新,make 在当前文件夹下创建 app.out 

    【问题】

      当依赖改变时,如何使得 src 下的 app.out 被更新?

    【解决方案】

      使用 GPATH 特殊变量指定目标文件夹

         GPATH := src

    • 当 app.out 完全不存在时(当前目录和 src 中都不存在时),make 默认在当前文件夹创建 app.out。

    • 当 app.out 存在于 src 中,且依赖文件被更新,make 在 src 中创建 app.out

    【工程项目中的几点建议】

    (1)尽量使用 vpath 为不同文件指定搜索路径

    (2)不要在源码文件中生成目标文件

    (3)为编译得到的结果创建独立的文件夹

    (4)避免 VPATH 和 GPATH 特殊变量的使用

     

    4. 补充

    make 的一个隐式规则以及 VPATH 变量可能会触发这个隐式规则。

      

    假如当前目录下没有 main.c 这个文件,而有 main.cpp 这个文件,make 会有什么样的行为?

      

      可以看到当 make 找不到 main.c 文件时,发现依赖是 .o 文件,这就触发了 make 的隐式规则,寻找 main.cpp 文件并使用 g++ 进行编译。正好当前目录下有一个 main.cpp 文件,就产生了上图所示的结果。

      这一结果与 vpath 和 VPATH 联系起来,如果项目中使用 VPATH 指定的路径下有 xx.cpp ,而恰好又触发了上述的隐式规则,在原本应该报错的地方,make 却正常执行了。

      如果使用 vpath 就不会产生这种情况, vpath  %.c  dir这种方式只会寻找 .c 文件,因此 make 触发的隐式规则不会找到 xx.cpp 文件,程序会报错。

      从这个实验中可以得到一个项目经验,在实际的工程开发中,尽量使用 vpath 关键字而不使用 VPATH 变量,否则可能会产生意想不到的结果

  • 相关阅读:
    codesmith 连接mysql
    数据库 价格字段 设置 decimal(8,2),价格为100W,只显示999999.99
    AOP和IOC
    Android Studio 每次运行都会再下载一遍,修改
    gradle 的jar下载到哪里了
    遇到的坑
    Error:Failed to resolve: :Base:
    re-download dependencies and 无法下载jar 的解决
    DI是实现面向切面和面向抽象的前提
    基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美
  • 原文地址:https://www.cnblogs.com/hoiday/p/9265762.html
Copyright © 2020-2023  润新知