[转帖]gcc与makefile常用操作(绝对常用,也绝对够用)

gcc,makefile,常用,操作,绝对,够用 · 浏览次数 : 0

小编点评

**自定义变量** ```bash NAME=main ``` **系统常量** ```bash SRC=$(wildcard ./*.c) OBJ=\\((</span>patsubst %.c, %.o, <span class=\"token punctuation\">\\)(SRC)) ``` **条件判断** ```bash ifeq ($(A),aa) TMP1:=aaelse TMP1:=no-aaendif endif ``` **循环** ```bash foreach v,集合,对v进行重命名或拼接等 目标名称=$(foreach v,集合,对v进行重命名或拼接等) ... end ``` **赋值** ```bash = 和 := ``` **循环** ```bash foreach v,集合,对v进行重命名或拼接等 目标名称=$(foreach v,集合,对v进行重命名或拼接等) ... end ``` **结论** ```bash NAME=main SRC=$(wildcard ./*.c) OBJ=\\((</span>patsubst %.c, %.o, <span class=\"token punctuation\">\\)(SRC)) ifeq ($(A),aa) TMP1:=aaelse TMP1:=no-aaendif endif foreach v,集合,对v进行重命名或拼接等 目标名称=$(foreach v,集合,对v进行重命名或拼接等) ... end ```

正文

一、温故知新

1、可执行程序的生成过程

在这里插入图片描述

2、gcc的常用操作

gcc/g++ 命令的基本格式为
gcc -[选项] [文件名]
例如:
gcc -c -I /home/inc/ test.c -o test.o
gcc -I /home/inc/ -O2 -g3 main.c test.o -o main

    在这里插入图片描述

    二、make操作

    make 的基本格式为:
    make -[选项] [文件名]
    例如:
    make -v
    make -n
    make -C /home/erc/ -f Makefile02 -s
    

      在这里插入图片描述

      三、编写Makefile文件时常用操作

      下面会着重介绍编写Makefile文件时经常用到的操作,对于makef的执行规则等更细致全面的知识可以参考Makefile教程(绝对经典,所有问题看这一篇足够了)

      注意:在Makefile文件中 空格和缩进是完全不同的,不可以相互转换。

      1、框架格式

      目标1:依赖
      	命令
      目标2:依赖
      	命令
      目标3:依赖
      	命令
      

        2、举例

        假如说我现在有这么一个程序需要编译:

        所需的 .h 头文件在 /home/inc/ 目录下
        所需的 .c 源文件在 /home/src/ 目录下
        #include "myadd.h" 
        #include "mysub.h"
        

        主函数在当前目录下的 main.c 里
        int main()
        {
        return 0;
        }

          那么Makefile文件应该这么编写

          main:/home/inc/myadd.o /home/inc/mysub.o ./main.o
          	gcc -I /home/inc/ /home/inc/myadd.o /home/inc/mysub.o ./main.o -o main
          

          /home/inc/myadd.o:/home/src/myadd.c
          gcc -c -I /home/inc/ /home/src/myadd.c -o /home/src/myadd.o

          /home/inc/mysub.o:/home/src/mysub.c
          gcc -c -I /home/inc/ /home/src/mysub.c -o /home/src/mysub.o

          ./main.o:./main.c
          gcc -c -I /home/inc/ ./main.c -o ./main.o

          clean:
          rm -rf /home/inc/mysub.o /home/inc/myadd.o ./main.o main

            3、优化

            以下是优化后的代码

            NAME=main
            

            SRC=\((</span>wildcard ./*.c<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">\)(wildcard /home/src/*.c)

            OBJ=\((</span>patsubst %.c, %.o, <span class="token punctuation">\)(SRC))

            INC=-I"/home/inc/"

            \((</span>NAME<span class="token variable">)</span></span><span class="token builtin class-name">:</span><span class="token variable"><span class="token variable">\)(OBJ)
            @ \((</span>CC<span class="token variable">)</span></span> <span class="token parameter variable">-g</span> <span class="token variable"><span class="token variable">\)(INC) \((</span>OBJ<span class="token variable">)</span></span> <span class="token parameter variable">-o</span> <span class="token variable"><span class="token variable">\)(NAME)

            %.o:%.c
            @ \((</span>CC<span class="token variable">)</span></span> <span class="token parameter variable">-c</span> <span class="token variable"><span class="token variable">\)(INC) \(^ <span class="token parameter variable">-o</span> <span class="token variable">\)@

            .PHONY:clean

            clean:
            @ rm -f \((</span>OBJ<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">\)(NAME)

              1). 伪目标 .PHONY

              声明目标成伪目标之后,make会无条件执行该目标,
              且不会判断目标是否存在或者是否需要更新。

              例如:常常把 clean声明为伪目标

              	.PHONY:clean
              
              clean:
              <span class="token function">rm</span> <span class="token parameter variable">-rf</span> <span class="token variable"><span class="token variable">$(</span>OBJ<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">$(</span>NAME<span class="token variable">)</span></span> 
              

                2). $ 和 @ 符号的作用

                @ :运行命令时,隐藏命令
                例如:@ rm -f $(OBJ) $(NAME) 会删除这些文件,但终端上不会有rm -r 输出

                $ :使用变量,(定义变量的时候不需要加$)
                例如 echo $(NAME)

                3). 变量

                注意:

                不管是自定义变量或者是系统变量,使用方法都一样

                使用方法即: $(变量名称)

                变量的工作原理和 C语言中的 define类似,是会直接替换的,
                所以一定要处理好空格。

                变量种类

                自定义变量:
                定义: NAME=main
                使用: echo $(NAME)

                系统常量:
                优点:与设备无关,全平台通用,使 makefile 可以跨平台。
                常见系统常量:
                在这里插入图片描述

                Makefile 中常见系统变量:
                (加 星号 的是使用频率较高的)
                在这里插入图片描述

                4). 匹配模式

                目标前缀名和依赖前缀名相同时,可以使用匹配模式缩减代码长度
                例如:
                myadd.o : myadd.c 可以被替换为
                %.o : %.c

                $(wildcard /home/src/*.c)
                获取某目录下的所有.c文件名称

                $(patsubst %.c, %.o, $(SRC))
                获取某些 .c 文件对应的 .o 文件

                使用方法

                获取当前目录下的所有 .c 文件的全名,获取 /home/src/目录下的所有 .c 文件的全名
                并把文件名储存到 SRC 变量里
                SRC=$(wildcard ./*.c) $(wildcard /home/src/*.c)
                

                获取SRC变量里的 .c 文件对应的 .o 文件的全名
                并把文件名储存到 OBJ 变量里
                OBJ=\((</span>patsubst %.c, %.o, <span class="token punctuation">\)(SRC))

                  此时再回头看优化代码,OvO,原来是这样。

                  4、Makefile中的条件判断 ifeq ifdef

                  使用:

                  ifeq 判断两个变量是否相等
                  括号里是要判断的两个变量

                  A=aa
                  TMP:=
                  ifeq ($(A),aa)
                      TMP1:=aa
                  else    
                      TMP1:=no-aa
                  endif 
                  

                    ifdef 判断某变量是否定义且赋值(如果没有赋值也是false)

                    B=
                    TMP2:=
                    ifdef (B)
                        TMP2:=def-B
                    else
                        TMP2:=ndef-B
                    endif
                    

                      注意事项:

                      注意书写格式,ifeq 或者 ifdef 和括号之间有一个空格!!!

                      Makefile中不存在 elif 但可以嵌套调用 ifeq 或 ifdef 来实现elif的功能

                      5、Makefile中的循环 foreach

                      语法

                      命令 $(foreach v, 集合, 对v进行重命名或拼接等)
                      

                        例子

                        TARGET=t1 t2 t3 t4
                        

                        all:
                        mkdir \((</span>foreach v, <span class="token punctuation">\)(TARGET), $v_dir)
                        说明:
                        遍历TARGET变量,然后在每个变量名后面拼接_dir组成新的名称,
                        然后以新的名称创建目录

                          演示结果:

                          在这里插入图片描述

                          6、Makefile中的赋值 = 和 :=

                          = 是最终赋值,
                          := 是临时赋值,
                          实际上 := 类似 C++中的变量引用,
                          对于 = 和 := 具体的区别,大家可以自己动手实操感受下。

                          总结

                          纸上谈来终觉浅,绝知此事要躬行!

                          与[转帖]gcc与makefile常用操作(绝对常用,也绝对够用)相似的内容:

                          [转帖]gcc与makefile常用操作(绝对常用,也绝对够用)

                          makefile与gcc常用操作 一、温故知新1、可执行程序的生成过程2、gcc的常用操作 二、make操作三、编写Makefile文件时常用操作注意:在Makefile文件中 空格和缩进是完全不同的,不可以相互转换。1、框架格式2、举例3、优化1). 伪目标 .PHONY2). $ 和 @ 符号的

                          [转帖]axel 下载与安装

                          一.安装必要的库 yum -y install openssl-devel gcc 二.下载源码包 wget -O axel-2.17.11.tar.gz http://github.com/axel-download-accelerator/axel/releases/download/v2.17

                          [转帖]redis-cluster-proxy安装使用尝试

                          https://www.cnblogs.com/gered/p/15210509.html 【1】gcc 4.9+安装 【2】redis-cluster-proxy 介绍与安装 下载安装: 配置文件: 启动 【3】连接核验 【4】故障转移 【4.0】查看集群状态 【4.1】集群挂一个主库的影响 【4

                          [转帖]GCC的优化的情况

                          25.1 Design Overview Link time optimization is implemented as a GCC front end for a bytecode representation of GIMPLE that is emitted in special secti

                          [转帖]gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化

                          相关博客http://blog.chinaunix.net/uid-24954950-id-2956476.html 相关博客http://blog.csdn.net/misiter/article/details/7514428 相关博客http://blog.chinaunix.net/uid-

                          [转帖]GCC 编译及编译选项

                          俗话说:'工欲善其事,必先利其器',一直在工作中使用GNU C编译器(以下简称GCC),这里对GCC的一些警告选项细致的分析,并列举几个简单的例子[注1]供分析参考。 1、 -Wall集合警告选项我们平时可能大多数情况只使用-Wall编译警告选项,实际上-Wall选项是一系列警告编译选项的集合。下面

                          [转帖]使用GCC编译器实测兆芯KX-U6780A的SPEC CPU2006成绩

                          https://baijiahao.baidu.com/s?id=1722775453962904303 兆芯KX-U6780A是一款8核2.7GHz的使用x86/AMD64指令集(架构)的国产CPU,于2019年发布。兆芯于2013年成立,不久之后就使用VIA的CPU成品成功申请了“核高基”重大专

                          [转帖]linux系统gcc编译过程

                          https://www.jianshu.com/p/09c8edd86a96 姓名:曾国强 学号:19021210984 【嵌牛导读】GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、 Objective-C、 F

                          [转帖]CentOS7/完美升级gcc版本方法

                          https://zhuanlan.zhihu.com/p/535657060 在某些应用场景中,需要特定的gcc版本支持,但是轻易不要去编译gcc、不要去编译gcc、不要去编译gcc,我这里推荐使用红帽提供的开发工具包来管理gcc版本,这样做的好处是随时切换版本,并且可以并存多个版本,不破坏原有gc

                          [转帖]CentOS8完美升级gcc版本方法

                          https://blog.whsir.com/post-6114.html 在CentOS8系统中,默认gcc版本已经是8.x.x版本,但是在一些场景中,还是需要高版本的gcc,网上一些作死的文章还在复制粘贴的告诉你如何编译升级gcc版本。 之前吴昊也写过CentOS完美升级gcc版本方法:http