makefile常用编译选项

2023-11-07

我们习惯创建一个环境变量文件Inc.mk来定义常用的变量

CC = gcc
CXX = g++ -std=c++11
AR ?= ar
ARFLAGS = -scurv
RANLIB ?= ranlib

CFLAGS ?=
CXXFLAGS ?=
INCLUDE ?=
LDFLAGS ?=

CFLAGS   += -Wall -g -fPIC -pipe -Wl,-z -Wl,defs -DDEBUG
CXXFLAGS += -Wall -g -fPIC -pipe -Wl,-z -Wl,defs -DDEBUG

%.o: %.cpp 
	$(CXX) $(CXXFLAGS) $(INCLUDE) -c $<

%.o: %.c
	$(CC) $(CFLAGS) $(INCLUDE) -c $<

ar命令:

-s 创建归档索引(等同ranlib)

-c 如果必须创建库,请不要发出警告

-u 仅替换比当前存档内容更新的文件

-r 替换现有文件或将新文件插入存档

-v 详细说明

ar -s其实等同于ranlib,由于早期linux系统ar只是单纯打包多个.o文件到.a静态库,而不处理.o的符号表,所以需要ranlib来生成链接所需要的符号信息。现在其实不需要第二步ranlib。

编译选项:

-w 关闭所有警告信息

-Wall 提供有用的警告信息

-Werror 警告信息变成错误,必须处理

-g 产生调试信息,给调试器用,可以用-g3这个级别可以调试宏;如果调试器是gdb,建议使用-ggdb或者-ggdb3

-fPIC 是生成动态库使用的,编译器就输出位置无关目标码,适用于动态连接,即使分支需要大范围转移

-pipe 编译会有几个阶段,每个阶段生成临时文件给下一个阶段使用,使用这个选项避免了文件读写而使用管道在内存中进行

-Wl,-z -Wl,defs 链接编辑器生成共享库输出文件时,允许在链接编辑结束时仍存在未定义符号。此缺省行为允许共享库从将其定义为依赖性的动态可执行文件导入符号。-z defs选项强制在存在任何未定义符号的情况下生成致命错误

-DDEBUG 相当于定义了宏DEBUG,代码中可以用#ifdef DEBUG来控制调试输出信息等

现在来看下正文Makefile文件

include ../Inc.mk

DIR_MODULES=crypto \
            net

SRC := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp, %.o, $(SRC))
SO_NAME = libcomm.so
SO_BIN = $(LIB_DIR)/$(SO_NAME)
A_NAME = libcomm.a
A_BIN = $(LIB_DIR)/$(A_NAME)

INCLUDE += -I$(XML_INC) 
LDFLAGS += -L$(LIB_DIR) -ltinyxml2

all : clean $(SO_BIN) $(A_BIN)
	@for dir in $(DIR_MODULES); \
	do \
		make -C $$dir; \
		echo; \
	done

$(SO_BIN) : $(OBJS)
	$(CXX) $(CXXFLAGS) -shared -Wl,-soname,$(SO_NAME) -o $@ $^ $(LDFLAGS)

$(A_BIN) : $(OBJS)
	$(AR) $(ARFLAGS) $@ $?
	$(RANLIB) $@

clean :
	@for dir in $(DIR_MODULES); \
	do \
		make -C $$dir clean; \
		echo; \
	done
	rm -rf $(OBJS) $(SO_BIN) $(A_BIN)

静态库的生成一般是两步:

ar -scurv libcomm.a *.o

ranlib libcomm.a

这是早期linux做法,现在可以省去ranlib这一步

动态库的生成需要用到-shared

-Wl,-soname 是为了提高新老版本库的兼容性,通过soname指定我们所希望的库版本

include ../Inc.mk

SRC := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp, %.o, $(SRC))
BIN = $(BIN_DIR)/server

INCLUDE += -I$(COMM_INC) -I$(XML_INC)
LDFLAGS += -L$(LIB_DIR) -ltinyxml2 -lcomm

all : clean $(BIN)

$(BIN) : $(OBJS)
	$(CXX) $(CXXFLAGS) -Wl,--export-dynamic -Wl,-rpath=$(LIB_DIR) -o $@ $^ $(LDFLAGS)

clean :
	rm -rf $(OBJS) $(BIN)

-Wl,--export-dynamic此时链接器产生可执行文件时会将所有全局符号导出到动态符号表。如果在创建动态链接的可执行文件不加-Wl,--export-dynamic选项,则它所export的动态符号仅仅包括在链接时动态对象所用到的。因为dlopen是自行加载动态库,并不存在与可执行文件动态符号解析的过程,所以如果dlopen加载的动态库使用了主模块中定义的函数,则会出现找不到符号的情况。默认链接器在产生可执行文件时,只会将那些链接时被其他共享模块引用到的符号放到动态符号表中,这样可以减少动态符号表的大小,也就是说,在共享模块中反向引用主模块中的符号时,只有那些在链接时被共享模块引用到的符号才会被导出,(主模块的符号表中依赖的共享模块主模块才会去链接,否则不会去链接,不被链接的模块引用了主模块的符号就不会被导出到动态符号表中,导致运行时报错)。但是使用--export-dynamic参数后由于将所有的全局符号导出到动态符号表中导致可执行程序会变大。

-Wl,-rpath 是为了指定我们链接的库路径,就不需要再去修改LD_LIBRARY_PATH变量了

这里我们看到每个Makefile文件都include ../Inc.mk

1. 在Inc.mk中,我们定义了固定的几个参数,gcc,g++还有编译选项等,在Makefile中include之后就可以直接使用,但是INCLUDE和LDFLAGS我们并没有固定,而是在Makefile中自定义,因为它们要引用的头文件,库文件都是各取所需。

2. 在Inc.mk中,我们定义了.c生成.o和.cpp生成.o的规则,在Makefile中include之后就可以直接使用了,所以我们在Makefile中只需要写.o生成可执行文件的规则就行了,生成可执行文件需要包含的头文件INCLUDE和需要链接的库LDFLAGS我们自定义,就配合完美了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

makefile常用编译选项 的相关文章

  • 区块链中的密码学应用

    区块链中应用到的密码学主要包括以下几方面 数字摘要 区块链本质上是一种分布式数据存储方式 每一个数据区块之间靠数字摘要建立起联系 比如比特币中每一个区块都包含了它前一个区块的摘要值 因此数字摘要是区块链中应用最广泛的密码学技术 也是区块链的
  • SQL删除语句

    1 delete 可指定删除一行或多行 不改变表结构 语句 delete from table where 2 drop 完全删除 包括表结构 语句 drop table 表名称 drop database 数据库名 drop index
  • matlab给定状态方程用欧拉法_基于SPH法的水滴入钢板仿真

    光滑粒子流体动力学 SPH Smoothedparticle hydrodynamics 方法是近30年发展起来的一种新的纯拉格朗日无网格粒子法 它最初是用于解决三维开放空间的天体物理学问题 现已被广泛地研究和扩展 并被应用于具有材料强度的
  • 注解@Qualifier的使用

    近期在整理一些spring的知识点 遇到关于 Qualifier这个注解的使用 记录一下 先说这个注解的作用 和autowired对比 Autowired默认是根据类型进行注入的 因此如果有多个类型一样的Bean候选者 则需要限定其中一个候
  • LeetCode第283题解法与思考

    第283题的要求如下 给定一个数组 nums 编写一个函数将所有 0 移动到数组的末尾 同时保持非零元素的相对顺序 示例 输入 0 1 0 3 12 输出 1 3 12 0 0 说明 必须在原数组上操作 不能拷贝额外的数组 尽量减少操作次数
  • python——时间绑定

    一个Tkinter主要跑在mainloop进程里 Events可能来自多个地方 比如按键 鼠标 或是系统事件 Tkinter提供了丰富的方法来处理这些事件 对于每一个控件Widget 你都可以为其绑定方法function widget bi
  • stm32——定时器之中断

    TIM 定时器 是STM32中比较重要的外设 定时器分为三种 分为为高级定时器 通用定时器 和基本定时器 本节就以通用定时器讲解 定时器中断 就是指每隔一段确定的时间 cpu就自动进入中断 执行响应的事件 那它是怎样实现这个功能的呢 首先它
  • 数据结构(C语言版 第2版)课后习题答案 严蔚敏 编著

    转自 https blog csdn net Bamboo shui article details 72433523 原文没第八章答案 数据结构 C语言版 第2版 课后习题答案 严蔚敏 等 编著 仅供参考 还是自己认真做了再看 第1章 绪
  • 油猴(Tampermonkey)安装教程

    油猴简介 Tampermonkey 油猴 是一款免费的浏览器扩展和最为流行的用户脚本管理器 它适用于 Chrome Microsoft Edge Safari Opera Next 和 Firefox 虽然有些受支持的浏览器拥有原生的用户脚
  • Informer讲解PPT介绍【超详细】--AAAI 2021最佳论文:比Transformer更有效的长时间序列预测

    文章目录 Abstract 一 informer重温讲解PPT简洁 超详细 1 1 title 1 2 Background 1 3 LSTF 问题的提出 1 4 Transformer in LSTF problem 1 5 问题阐述 1
  • 常见的内存数据库有哪些

    Redis 键值存储数据库 常用于缓存 消息代理和应用程序数据处理 Memcached 分布式内存对象缓存系统 用于缓存Web应用程序数据 VoltDB 高速内存数据库 用于实时数据处理和实时决策 Aerospike 高性能的键值存储和文档
  • 基于Ribbon自定义负载均衡策略

    微服务间通过FeignClient互相调用默认使用的是ribbon的轮询负载均衡策略 而实际场景中我们可能需要自定义一些规则或者约束来实现特定的负载均衡策略 背景 微服务开发 多租户 API接口隔离 这些在现在开发过程中会经常遇到的问题 服
  • 第2章 R语言编程基础(超详细)

    目录 2 1 数据管理 2 1 1 变量重命名 2 1 2 缺失 异常与重复值的清洗 2 1 3 数据转换 排序 抽样与概率统计 2 1 4 案例分析 工程管理 2 1 5 字符串处理 2 2 控制语句与函数编写 2 2 1 控制语句 分值
  • Python3 数据类型转换

    目录 Python3 数据类型转换 隐式类型转换 显式类型转换 Python3 数据类型转换 有时候 我们需要对数据内置的类型进行转换 数据类型的转换 一般情况下你只需要将数据类型作为函数名即可 Python 数据类型转换可以分为两种 隐式
  • js中int与string之间的转换

  • 关系型数据库和非关系型数据库

    数据库总结 关系型数据库和非关系型数据库 NOSQL 关系型数据库和非关系型数据库 NOSQL NoSQL 指的是非关系型的数据库 NoSQL有时也称作Not Only SQL的缩写 是对不同于传统的关系型数据库的数据库管理系统的统称 No
  • 护网HVV(蓝队)小白必知必会

    前言 在HVV期间 蓝队主要就是通过安全设备看告警信息 后续进行分析研判得出结论及处置建议 在此期间要注意以下内容 内网攻击告警需格外谨慎 可能是进行内网渗透 1 攻击IP是内网IP 攻击行为不定 主要包括 扫描探测行为 爆破行为 命令执行
  • 小金的2019年终总结

    文章目录 一 各平台年报 简书 中国移动 微信读书 支付宝 建设银行 二 值得说一说的事 我的舒适区 刷海贼王 致敬特斯拉惊叹达芬奇 小柠檬降世 当舅舅 换mac电脑 总结 一 各平台年报 简书 研究区块链 gt gt 投资简书 gt gt

随机推荐

  • 万字长文解析!复现和使用GPT-3/ChatGPT,你所应该知道的

    关于作者 英文原版作者 杨靖锋 现任亚马逊科学家 本科毕业于北大 硕士毕业于佐治亚理工学院 师从 Stanford 杨笛一教授 杨昊桐 译 王骁 修订 感谢靳弘业对第一版稿件的建议 感谢陈三星 符尧的讨论和建议 英文原版 https jin
  • 10.Vue简单项目之crud+表单验证

    Vue简单项目之crud 表单验证 1 准备工作 配置action js 2 新增书籍前台页面编写 3 修改和删除 4 表单验证 1 准备工作 配置action js 启动前端项目 启动后端项目 在action js中添加下列接口 BOOK
  • tomcat如何进行优化?

    对于tomcat的调优 可以从两个方面来进行调整 内存和线程 1 首先启动tomcat 实际上就是启动了一个jvm 所以可以jvm调优的方式来进行调整 从而达到tomcat调优的目的 另外tomcat中设计了一些缓存区 比如aappRead
  • npm link用法总结

    npm link用法总结 npm link用来在本地项目和本地npm模块之间建立连接 可以在本地进行模块测试 具体用法 1 项目和模块在同一个目录下 可以使用相对路径 npm link module 2 项目和模块不在同一个目录下 cd到模
  • Android 01:AutoCompleteTextView-简单实现实现自动输入文本效果

    在Android中 可以使用控件AutoCompleteTextView实现自动输入的文本功能 当用户输入一个字符 能够根据其字符提示显示出与之相关的数据 举大家一个熟悉的例子 当我们在百度中输入关键字 android 在列表中会出现相关的
  • C++程序分多文件编写

    为了让一个项目的结构更加清晰 需要学习函数的分文件编写 一般是4个步骤 创建后缀名为 h的头文件 创建后缀名为 cpp的源文件 在头文件中写函数的声明 在源文件中写函数的定义 主函数所在的源文件 要包含必要的头文件和这句using name
  • 测试用例逻辑梳理

    拿到一个页面怎么测 先看页面的整体布局 包括的内容是什么 页面之间的交互逻辑 按照总 分 总的逻辑测试 总 即总体概括页面的整体布局 包含的内容是什么 分 即是分模块对页面进行描述 页面包括的配置项是什么 输入框 搜索框 下拉框 分页 是否
  • 添加TAP虚拟网卡

    方法一 1 如果需要不同的Mac地址 可以添加虚拟网卡TAP 2 先安装uml utilities sudo apt get install uml utilities 3 使用tunctl添加虚拟网卡 sudo tunctl b 4 激活
  • stm32 web服务器实现

    最在做stm32 web服务器的东西 忙了一段时间终于弄完了 把这几天关于stm32服务器的工作记录一下 刚接到这个任务的时候 不知道怎么下手 网上资料似乎不是很多 于是在下载了一个官方demo测试了一下 看了一下代码 不是很懂 于是继续百
  • AWS EC2入门指南中创建和配置云虚拟机实例的基本步骤

    文章目录 创建 AWS 账户 登录 AWS 控制台 导航到 EC2 控制台 启动 EC2 实例 选择 AMI Amazon Machine Image 选择实例类型 配置实例 添加存储 审查和启动实例 创建密钥对 连接到 EC2 实例 管理
  • Python中的Lambda函数:简洁而强大的匿名函数

    引言 Python是一种功能强大且易于学习的编程语言 它提供了许多方便的语法和功能 以简化代码的编写和理解 其中之一就是Lambda函数 Lambda函数是Python中的一种匿名函数 它使得在需要函数对象的任何地方都能使用函数表达式 本文
  • 嵌入式系统开发项目管理

    项目生命周期五大阶段 1 项目启动阶段 1 项目可行性分析 一个成功的产品 应该从以下3个方面来观察评估 设计产品 商业行为 产品设计前 要做好市场调查和评估 要考虑产品的时效性 市场需求和技术可行性 产品设计结束后要写下详细的产品规格 技
  • L2TP详解(一)

    今天继续给大家介绍HCIE安全 本文给大家介绍的是L2TP相关内容 包括L2TP的特点和应用场景 一 L2TP简介 L2TP是一种二层的VPN技术 它提供了对PPP链路层数据帧的隧道传输支持 允许二层链路端点和PPP会话驻留在不同设备上 扩
  • 论文笔记:Constructing spatiotemporal speed contour diagrams: usingrectangular or non-rectangular paralle

    Constructing spatiotemporal speed contour diagrams using rectangular or non rectangular parallelogram cells 2019 Transpo
  • c++求模运算的应用

    在 C C 中 符号为求模运算符 即 a b 表示 a 除以 b 的余数 周期问题 我们在奥数中经常遇到这样的问题 给你一串数字 4 5 6 4 5 6 4 5 6 求这里的第 1000 个数字是几 我们发现这是一个周期数列 周期为 3 a
  • 华为OD机试真题 Java 实现【获取字符串中连续出现次数第k多的字母的次数】【2023Q1 100分】,附详细解题思路

    一 题目描述 给定一个字符串 只包含大写字母 求在包含同一字母的子串中 长度第 k 长的子串的长度 相同字母只取最长的那个子串 二 输入描述 第一行有一个子串 1 lt 长度 lt 100 只包含大写字母 第二行为 k的值 三 输出描述 输
  • 六款常用的linux C/C++ IDE

    摘要 一 AnjutaAnjuta是一个多语言的IDE 它最大的特色是灵活 同时打开多个文件 内嵌代码级的调试器 调用gdb 应用程序向导 Application wizards 可以方便的帮助你创建GNOME程序而不需要你自己写一些与你兴
  • 迁移MongoDB数据库及数据(MongoDB数据库的备份与恢复)

    备份 在有数据的地方使用mongodump h connection d 数据库名 o 保存的文件夹 比如 mongodump h 127 0 0 1 27017 d my db o my back dir 恢复 在想要覆盖的地方使用mon
  • windows环境中使用goland构建linux二进制文件并运行

    大家都知道 go语言可打包成目标平台二进制文件是它的一大优势 如此一来 go项目在服务器不需要配置go环境和依赖就可以运行 操作方式 需求 在windows环境中打包部署golang项目到Centos 7 运行 打包环境 windows 1
  • makefile常用编译选项

    我们习惯创建一个环境变量文件Inc mk来定义常用的变量 CC gcc CXX g std c 11 AR ar ARFLAGS scurv RANLIB ranlib CFLAGS CXXFLAGS INCLUDE LDFLAGS CFL