• 《笨办法学C》笔记之Makefile


    使用gcc编译C语言源码

    在Linux系统中,C语言源码需要用gcc编译为二进制可执行文件,才能够运行。

    $ gcc test.c -o test
    

    这句命令就将test.c文件编译为test二进制可执行文件。

    $ ./test
    

    如此可以直接执行编译后的test二进制可执行文件。

    如何编译多个.c文件

    例1 需要将test1.c、test2.c、test3.c合并编译为一个test可执行文件。

    一种办法是:

    $ gcc test1.c test2.c test3.c -o test
    

    这个办法的缺陷是,每次会将所有.c文件编译一次。如果下次编译时,只有test3.c文件发生变动,那么重复编译test1.c和test2.c文件显得有些多余。

    另一个办法则是:

    $ gcc -c test1.c 
    $ gcc -c test2.c 
    $ gcc -c test3.c 
    $ gcc -c test test1.o test2.o test3.o
    

    gcc使用-c选项,可以将.c文件编译为.o对象文件。对象文件是gcc将源码编译为二进制文件的中间结果,省去了最后的链接阶段

    最后一行命令里,gcc将各个.o对象文件组合链接为完整的二进制可执行文件。

    如果能够做到:

    在编译.o文件之前检查对应的.c文件的最后修改日期是否在.o文件的生成日期之后,如果是,才会再次编译

    那整个编译过程会大大减少耗时。

    而Make系统就可以做到这一点。

    Makefile

    例2 考虑一个小型的C语言项目:

    tmp/
       +---- include/
       |      +---- f1.h
       |      +----f2.h
       +----f1.c    #include "include/f1.h"
       +----f2.c    #include"include/f2.h"
       +---main.c   #include"include/f1.h", #include"include/f2.h"
    

    对应makefile如下所示:

    #Makefile,Create testmf from f1.c f2.c main.c
    
    all: main.o f1.o f2.o
            gcc -o testmf main.o f1.o f2.o
    f1.o: f1.c
            gcc -c -o file1.o file1.c
    f2.o: f2.c
            gcc -c -o file2.o file2.c
    main.o
            gcc -c -o main.o main.c
    clean:
            rm -rf f1.o f2.o main.o testmf
    
    

    如果在tmp目录下直接执行make all,那么make系统首先会搜索all标签,并执行其对应的命令:gcc -o testmf main.o f1.o f2.o。接着,make会去递归查找这一命令对应的参数文件main.o、f1.o、f2.o:

    • 如果文件不存在,直接执行对应的编译命令;
    • 如果存在但对应.c文件已经更新,仍然会执行对应的编译命令;
    • 如果存在而已经是最新,那么就会直接调用编译好的.o对象文件。

    回过头来考虑例1——如果下次编译时,只有test3.c文件发生变动,如果调用makefile,那么整个过程仅仅会执行gcc -c test3.cgcc -c test test1.o test2.o test3.o两个命令。

    其他

    1. 调用make命令后,系统会搜索Makefile或者makefile文件;也可以使用make -f指定自定义文件名。
    2. 其实make后面的参数就是个makefile里的标签,至于标签里的填的是什么并不重要。把第一行的all改成main,那么执行make main就和原先的make all是同样的效果。
    3. 可以使用$()来表示变量,方便构建复杂的makefile

    参考资料

    延伸阅读

  • 相关阅读:
    如何禁用Xcode7下iOS9 App传输安全,并修复无法连接服务器错误
    iOS单例清除
    Git忽略规则及.gitignore规则不生效的解决办法
    javascript 在ie8中报“缺少标识符、字符串或数字“问题再现:
    树莓派 远程桌面 设置显示中文
    在IIS Express中调试时无法读取配置文件 错误
    Win7 下IIS(7.5)发布 ASP.NET MVC
    .Net中使用com组件后发生System.ArithmeticException异常的解决办法(Message=算术运算中发生溢出或下溢。)
    CodeSimth
    windows 开机启动 CassiniDev(IIS替代软件)
  • 原文地址:https://www.cnblogs.com/rim99/p/6219807.html
Copyright © 2020-2023  润新知