• Makefile入门(三)


    上一篇讲了Makefile一些预定义的宏。这一篇会介绍另外两个比较有用推理规则,能够增强描述模块的功能。 

    推理规则 Inference rules

    根据前两篇的内容,已经可以自己编写一个Makefile用来构建一个小型项目了。但是当项目变得很大的时候会发现要是给每个项目都是写一个命令来编译整个Makefile会变得很大。

    于是Makefile中加入了推论规则,可以用来根据target,推断出相应出对应的依赖文件。再配合$<宏,就能够减少依赖文件的书写。

    先来看一个例子

    1. # makefile 内容
    2. all: file.obj file1.obj
    3. .cpp.obj:
    4. echo $<
    5. # 输出
    6. file.cpp
    7. file1.cpp

    这个例子中并没有给出依赖项file.obj和file1.obj所需要的源文件。但是仍然生成了两行command,分别操作了file.cpp和file1.cpp。这就是推理规则的作用。以此类推可以只定义一次我们想要的依赖项就能对每个依赖项执行对应的操作。其语法如下

    1. .from_ext.to_ext:
    2. commands
    3. # search path
    4. {from_path}.from_ext{to_path}.to_ext:
    5. commands
    6. # batch
    7. {from_path}.from_ext{to_path}.to_ext::
    8. commands

    有一点需要注意的是推论规则只适用于真正存在的文件,nmake在进行推理时会真正的去 检查相应目录中是否真正存在符合的文件。以上面的makefile为例,实际上file.cpp和file1.cpp真正存在,否则就会报错。

    也可以加上指定的路径。这样就可以给不同路径下面的文件执行不同的命令。如下例子,

    1. all: file.obj folder1\file2.obj
    2. .cpp.obj:
    3. echo $<
    4. {folder1\}.cpp.obj:
    5. echo search path $<
    6. # 输出
    7. file.cpp
    8. search path folder1\file2.cpp

    可以看到最终被search path模式匹配到的file2.obj和file.obj执行的是不同的命令。注意的是

    上面两种用法所执行的命令都是为每个依赖项执行一遍完整的指令。但是实际使用中编译器能够批量接受多个文件进行编译。只需要将文件名同时列在同一行即可。batch模式正是这种用途,使用时执行一次命令,从而加速了构建。看如下例子

    1. all: file.obj file2.obj
    2. .cpp.obj::
    3. echo $<
    4. # 输出
    5. file.cpp folder1\file2.cpp

    因为进行编译的源文件通常就只有c,cpp,rc之类的文件,而且编译命令往往也是固定的,因此预定义了很多的推理规则。先看看这个makefile上并没有告诉nmake如何执行命令来生成obj,但是nmake也能很好的编译文件。

    1. all: file.obj
    2. # 输出
    3. cl /c file.cpp

    因为nmake预定义了大部分常用的后缀名文件的生成命令,会自动生成相应的命令。

    .asm.exe$(AS) $(AFLAGS) $<ml $<
    .asm.obj$(AS) $(AFLAGS) /c $<ml /c $<
    .asm.exe$(AS) $(AFLAGS) $<ml64 $<
    .asm.obj$(AS) $(AFLAGS) /c $<ml64 /c $<
    .c.exe$(CC) $(CFLAGS) $<cl $<
    .c.obj$(CC) $(CFLAGS) /c $<cl /c $<
    .cc.exe$(CC) $(CFLAGS) $<cl $<
    .cc.obj$(CC) $(CFLAGS) /c $<cl /c $<
    .cpp.exe$(CPP) $(CPPFLAGS) $<cl $<
    .cpp.obj$(CPP) $(CPPFLAGS) /c $<cl /c $<
    .cxx.exe$(CXX) $(CXXFLAGS) $<cl $<
    .cxx.obj$(CXX) $(CXXFLAGS) /c $<cl /c $<
    .rc.res$(RC) $(RFLAGS) /r $<rc /r $<

    另外也有预定的点指令.SUFFIXES其中也有预定义一些常见的后缀名,.exe .obj .asm .c .cpp .cxx .bas .cbl .for .pas .res .rc .f .f90 可以用来作为ext来匹配。

  • 相关阅读:
    【脑机接口】基于运动想象的康复指导在脑卒中偏瘫患者中的应用
    Python Selenium unittest+HTMLTestRunner实现 自动化测试及发送测试报告邮件
    netty系列之:在netty中使用proxy protocol
    nginx参数调优能提升多少性能
    计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)
    ROS实现话题的发布与订阅
    GEE python——将GEE ASSETS中存储的影像或者矢量转化为数据格式XEE()
    (免费领源码)Java&springboo&Mysql儿童疫苗预约系统 12222-计算机毕业设计
    Windows下网络编程及多线程模型
    EasyNVR平台级联到EasyCVR,视频播放一会就无法播放是什么原因?
  • 原文地址:https://blog.csdn.net/wupeng4389151/article/details/126898737