(3)Makefie:C语言编译标志、通配符、CFLAGS、LDFLAGS、LDLIBS

目录

一、C编译器标志

二、基本知识

1、常用的变量

2、通配符/预处理

3、添加宏和链接库进行编译和链接

a、CFLAGS(宏定义、包含路径、编译过程信息)

 b、LDFLAGS(指定库路径、链接的库)

c、LDLIBS(指定连接的库)

d、-Wl,--start-group 和 -Wl,--end-group

e、$(LDLIBS_$@)

f、$^和$@的使用

g、句子前面加@:不输出到终端

h、目标文件依赖于头文件

i、%_output的使用

j、%_only

k、以"-"开头用于忽略错误或警告

一、C编译器标志

  • -c:只进行编译而不进行链接,生成目标文件。
  • -o <filename>:指定输出文件名。
  • -I <directory>:添加头文件搜索路径。
  • -L <directory>:添加库文件搜索路径。
  • -l <library>:链接指定的库。
  • -g:生成调试信息。
  • -Wall:开启所有警告信息。
  • -Werror:将警告视为错误。
  • -O<level>:优化级别,例如-O0表示关闭优化,-O2表示启用中等级别优化。
  • -std=<standard>:选择C语言的标准版本,如-std=c89表示使用C89标准,-std=c99表示使用C99标准。
  • -pedantic:对于严格遵循标准的代码,给出额外的警告信息。
  • -D<macro>:定义宏。
  • -U<macro>:取消已定义的宏。
  • -E:只进行预处理,输出预处理结果。

二、基本知识

1、常用的变量

$^   所有依赖文件

$@  所有目标文件

$<   第一个依赖文件

2、通配符/预处理

SRC = $(wildcard *.c)                //当前目录下所有的.c文件

OBJ=$(patsubst %c,%o,$(SRC))        //所有的.c文件替换成.o文件

include $(PARAMETER)     //预处理,把该文件的信息都导入进来

3、添加宏和链接库进行编译和链接

a、CFLAGS(宏定义、包含路径、编译过程信息)

CFLAGS=-DDEBUG -DVERBOSE -DENABLE_FEATURE_X

  • 定义了名字为DEBUG、VERBOSE、ENABLE_FEATURE_X的宏
  • 在代码中可以用#ifdef DEBUG、#ifdef VERBOSE、#ifdef ENABLE_FEATURE_X分别判断是否开启调试模式、是否开启详细输出模式、是否启用特定功能X

CFLAGS += -g  -Wall -Wno-unused-parameter   

  • "-g":生成调试信息,使得程序可以被调试器跟踪和调试。
  • "-Wall":显示所有的警告信息,
  • "-Wno-unused-parameter":禁止显示关于未使用函数参数的警告信息,因为在某些情况下,函数参数可能未被使用。

CFLAGS += -I/path/to/include   # 告诉编译器在编译过程中包含位于该目录下的头文件

 b、LDFLAGS(指定库路径、链接的库)

LDFLAGS=-L/path/to/lib -lexample  #-L后面跟着路径,-l后面跟着库文件的名字
gcc -o myprogram myprogram.o $(LDFLAGS)

c、LDLIBS(指定连接的库)

LDLIBS= -lmath -lio -lstring  #链接三个库文件libmath.a, libio.alibstring.a
gcc -o myprogram myprogram.o $(LDLIBS)

d、-Wl,--start-group-Wl,--end-group

target: main.o lib1.a lib2.a
    gcc -o $@ main.o -Wl,--start-group -l1 -l2 -Wl,--end-group

lib1.a: lib1.o
    ar rcs $@ lib1.o

lib2.a: lib2.o
    ar rcs $@ lib2.o

-Wl,--start-group-Wl,--end-group

1、对于解决循环依赖或交叉依赖的库文件非常有用。

2、通过将依赖的库文件放置在 -Wl,--start-group-Wl,--end-group 之间,可以确保所有库文件都被正确处理,并且符号解析不会因为依赖关系而失败。

3、链接器会正确处理 lib1.alib2.a 中的符号依赖关系,并生成最终的可执行文件。

e、$(LDLIBS_$@)

target1: file1.o file2.o
    gcc -o $@ $^ -Wl,--start-group $(LDLIBS) $(LDLIBS_$@) -Wl,--end-group

target2: file3.o
    gcc -o $@ $^ -Wl,--start-group $(LDLIBS) $(LDLIBS_$@) -Wl,--end-group

LDLIBS_target1 = lib1.a lib2.a

target1中:$(LDLIBS_$@)展开为lib1.a lib2.a

target2中:由于LDLIBS_target2没有定义,所以$(LDLIBS_$@)展开为空

f、$^和$@的使用

target: file1.c file2.c
    gcc -o $@ $^

上面会展开为:gcc -o target file1.c file2.c

g、句子前面加@:不输出到终端

   @cp $@ $@.c

        表示将所有的所有的目标文件复制,并在原来的名字后面加上.c

        cp前面加了@:表示不输出到终端

h、目标文件依赖于头文件

OBJS = main.o func.o

$(OBJS): a.h b.h

target: $(OBJS)
    gcc -o $@ $(OBJS)

(1)$(OBJS): a.h b.h 告诉 Make,当 a.hb.h 发生变化时,需要重新编译 main.ofunc.

(2)在$(OBJS): a.h b.h中:main.c 文件发生变化时,Make 工具会自动检测到 main.o 需要重新编译。这是因为 Make 在构建过程中会根据文件的时间戳(timestamp)比较源文件和目标文件的最后修改时间,从而确定是否需要重新编译目标文件

(3)因此,在基于规则 $(OBJS): a.h b.h 的情况下,.c 文件的变化已经被隐式地考虑在内,并且 Make 会相应地处理源文件到目标文件的重新编译。

i、%_output的使用

%_output.txt: %.txt
    cp $< $@

如果存在一个名为 example.txt 的源文件,执行该规则后会生成一个名为 example_output.txt 的文件,内容与 example.txt 相同。

j、%_only

文件目录结构如下

- Makefile
- src/
  - module1/
    - file1.c
    - file2.c
  - module2/
    - file3.c
    - file4.c

Makefile中

%_only:
    echo Building $@ in $(@:_only=) directory.
    $(MAKE) -j$(HOST_NCPU) -C $(@:_only=)

当在终端输入make module1_only 命令,将会触发 %_only 规则

Building module1_only in module1 directory.
make -j<host_ncpu> -C module1

其他解释:

$(@:_only=)表示将目标名字去掉_only

$(HOST_NCPU):如果 $(HOST_NCPU) 的值为4,那么 -j$(HOST_NCPU) 就相当于 -j4,表示使用4个线程进行构建操作。

k、以"-"开头用于忽略错误或警告

clean:
    -rm *.o

"-rm *.o"表示在执行"rm *.o"命令时,即使出现文件不存在或其他错误,也会继续执行后续的命令,而不会停止整个Make过程。这样可以避免由于某个命令执行失败而导致整个Make过程中断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/55228.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression--论文学习笔记

超越GIoU/DIoU/CIoU/EIoU MPDIoU让YOLOv7和YOLACT双双涨点 目标检测上的指标对比&#xff1a; 论文地址&#xff1a; [2307.07662] MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression (arxiv.org) 摘要 边界框回归&#xff08;Bounding Box Regression&am…

随机森林构造有哪些步骤?随机森林构造案例

在机器学习中&#xff0c;随机森林是一个包含多个决策树的分类器&#xff0c;并且其输出的类别是由个别树输出的类别的众数而定。 随机森林 Bagging 决策树 例如, 如果你训练了5个树, 其中有4个树的结果是True, 1个树的结果是False, 那么最终投票结果就是True随机森林够造过…

【Docker】Docker应用部署之Docekr容器安装Nginx

目录 一、搜索镜像 二、拉取镜像 三、创建容器 四、测试使用 一、搜索镜像 docker search nginx 二、拉取镜像 docker pull nginx # 不加冒号版本号 默认拉取最新版 三、创建容器 首先我们需要在宿主机创建数据卷目录 mkdir nginx # 创建目录 cd nginx # 进入目录 mkd…

JAVA开发工具-maven的安装与配置(最新最详细教程)

引言 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具 软件。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较 高的可重用性&#xff0c;所以常常用两…

【已解决】标签死活不响应单击事件

大家好&#xff0c;我是执念斩长河。今天在公司写代码的时候突然遇到一个问题&#xff0c;这个问题困扰了我不久&#xff0c;就是html中li标签不能响应我的单击事件。最后在仔细分析下&#xff0c;解决了这个问题。 文章目录 1、问题来源2、问题解决方案3、问题解决效果4、总结…

如何安装、部署、启动Jenkins

一、测试环境 Linux系统 Centos 7 二、安装步骤&#xff1a; 1、安装jdk 我安装的是jdk8&#xff0c;此处就不多说了&#xff0c;自己百度哈&#xff0c;很简单 2、安装jenkins 首先依次执行如下三个命令&#xff1a; 2.1、导入镜像&#xff1a; [rootcentos7 ~]# sudo …

下载JMeter的历史版本——个人推荐5.2.1版本

官网地址&#xff1a;https://archive.apache.org/dist/jmeter/binaries/

记一次centos 磁盘挂载过程

前言 最近买了云服务器磁盘&#xff0c;需要挂载&#xff0c;一下就由大猿来记录这次过程。 挂载过程 查看磁盘挂载情况 查看物理硬盘 lsblkfdisk -l标记分区 fdisk /dev/vdb格式化分区 xfs mkfs.xfs /dev/vdb mkfs.xfs -f /dev/vdbext4 mkfs.ext4 /dev/vdbxfs 和 ex…

基于opencv的几种图像滤波

一、介绍 盒式滤波、均值滤波、高斯滤波、中值滤波、双边滤波、导向滤波。 boxFilter() blur() GaussianBlur() medianBlur() bilateralFilter() 二、代码 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> …

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法 一、背景二、解决方法三、实现自动发现新的分区一、背景 生产环境Kafka集群压力大,Topic读写压力大,消费的lag比较大,因此通过扩容Topic的分区,增大Topic的读写性能理论上下…

IDEA开启并配置services窗口

前言&#xff1a; 一般一个spring cloud项目中大大小小存在几个十几个module编写具体的微服务项目。此时&#xff0c;如果要调试测需要依次启动各个项目比较麻烦。 方法一&#xff1a; 默认第一次打开项目的时候&#xff0c;idea会提示是否增加这个选项卡&#xff0c;如果你没…

【ArcGIS Pro二次开发】(55):给多个要素或表批量添加字段

在工作中可能会遇到这样的场景&#xff1a;有多个GDB要素、表格&#xff0c;或者是SHP文件&#xff0c;需要给这个要素或表添加相同的多个字段。 在这种情况下&#xff0c;手动添加就变得很繁琐&#xff0c;于是就做了这个工具。 需求具体如下图&#xff1a; 左图是待处理数据…

【iOS】多线程 锁问题总结

文章目录 前言1. 你理解的多线程优点缺点 2. atomic 和 nonatomic 的区别及其作用3. GCD的队列类型 - 三种队列类型4. GCD的死锁问题5. 多线程之间的区别和联系6. 进程和线程&#xff1f;进程间的通信方式线程间的通信方式 6. iOS的线程安全手段如何保证 前言 iOS 锁和多线程的…

HCIP——BGP基础

BGP 一、BGP基础二、BGP的发展历史三、BGP在企业中的应用四、距离矢量型协议和路径矢量型协议五、BGP的特征六、BGP的对等关系七、BGP的数据包八、BGP的状态机九、BGP的工作过程十、BGP的路由黑洞十一、BGP的环路问题EBGP水平分割IBGP水平分割 十二、BGP的基本配置1、BGP的对等…

【机器学习】Classification using Logistic Regression

Classification using Logistic Regression 1. 分类问题2. 线性回归方法3. 逻辑函数&#xff08;sigmod&#xff09;4.逻辑回归5. 决策边界5.1 数据集5.2 数据绘图5.3 逻辑回归与决策边界的刷新5.4 绘制决策边界 附录 导入所需的库 import numpy as np %matplotlib widget imp…

开源代码分享(9)—面向100%清洁能源的发输电系统扩展规划(附matlab代码)

1.背景介绍 1.1摘要 本文提出了一种新颖的建模框架和基于分解的解决策略&#xff0c;将随机规划&#xff08;SP&#xff09;和鲁棒优化&#xff08;RO&#xff09;相结合&#xff0c;以应对协调中长期电力系统规划中的多重不确定性。从独立系统运营商&#xff08;ISO&#xff…

测试|性能测试相关理论

测试|性能测试相关理论&#xff08;了解&#xff09; 文章目录 测试|性能测试相关理论&#xff08;了解&#xff09;1.什么是性能测试生活中遇到的软件性能问题&#xff1a;性能测试定义&#xff1a;性能测试和功能测试有什么区别&#xff1a;性能好坏的评价指标影响一个软件性…

Redis安装部署(基于windows平台)

redis简介 键值对存储数据库是NoSQL数据库的一种类型&#xff0c;也是最简单的NoSQL数据库。顾名思义&#xff0c;键值对存储数据库中的数据是以键值对的形式来存储的。常见的键值对存储数据库有Redis、Tokyo Cabinet/Tyrant、Voldemort以及Oracle BDB数据库。 Remote Diction…

一起学算法(二维数组篇)

1.概念定义 1.矩阵的定义 矩阵A(nm)的定义时按照长方形排列的复数或实数集合&#xff0c;其中n代表的是行数&#xff0c;m代表的是列数。如下所示&#xff0c;代表的是一个4x3的矩阵 在Java中&#xff0c;我们可以用A[n][m]来代表一个n*m的矩阵&#xff0c;其中A[i][j]代表的是…