gcc 标志重复和排序重要吗?
Posted
技术标签:
【中文标题】gcc 标志重复和排序重要吗?【英文标题】:Is gcc flags repetition and ordering important? 【发布时间】:2018-10-18 12:43:42 【问题描述】:在为 python 构建 C 扩展时,我看到一些 gcc
标志重复出现。当我跑步时:
python setup.py build_ext
正在运行的构建命令如下所示:
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -fPIC -I/usr/include/python3.7m -c /tmp/src/source.c -o build/temp.linux-x86_64-3.7/tmp/src/source.o
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.7/tmp/src/source.o -L/usr/lib -lpython3.7m -o build/lib.linux-x86_64-3.7/source.cpython-37m-x86_64-linux-gnu.so
好的,这很长。但是,正如您所看到的,有些标志是重复的。这是第一个命令中的重复:
-O3
重复 4 次。
-fno-plt
重复 3 次。
-fstack-protector-strong
重复 3 次。
-march=x86-64
重复 3 次。
-mtune=generic
重复 3 次。
-pipe
重复 3 次。
除了传递给链接器的-Wl,...
标志之外,这些标志的重复和排序是否有任何意义?
【问题讨论】:
【参考方案1】:在 GCC 命令行中看到重复选项并不罕见 由某些工具堆栈(通常是 IDE)生成的,带有 人工输入“在顶部”。
您发现的所有重复都不会对 命令行的含义。通常这样的重复只是无害的 冗余,他们可以有一个合理的 动机。向 GCC 命令行增量添加某些内容的工具可能 希望确保此时启用某个选项,即使它 自上次启用它以来附加的选项可能以某种方式被禁用。重复 冗余选项可能比检查它是否冗余更便宜。
但重复不一定无害……
如果选项OPT
出现在命令行中的某个位置:
... OPT ...
然后用 2 个或更多替换一个匹配项不会有任何影响。
但是,如果命令行的格式为:
... OPT1 ... OPT2 ...
然后在OPT2
之后的任何位置添加另一个OPT1
可能会产生
不同之处。同样,在 OPT1
之前的任何位置添加另一个 OPT2
。
这是因为选项经常出现的顺序 区别。
一个选项通常由一个标志和一个值组成,例如
-O3 -> Flag = -O, value = 3
-I./inc -> Flag = -I, value = ../inc
一些标志,如-O
可以取一组相互之间的任何一个
独家价值观。简称为这些互斥标志。当互斥标志重复出现时
反补贴值,命令行中的 last 为准:
-O1 -O2 -O3 = -O3
-O3 -O2 -O1 = -O1
其他标志,如-I
,可以任意
非排他值按其出现顺序连续累积,形成一个序列
是编译或链接的参数之一。例如
-I./foo -I./bar
将./foo
和./bar
附加到用户指定的包含目录
搜索顺序编译。调用这些累积标志。
其他标志是布尔值,具有启用形式和禁用形式
形式,例如-fstack-protector
,
-fno-stack-protector
。这些可以等同于互斥锁选项
排除可能的值 True 和 False。
还有另一种标志,如-l
,接受任意非独占值
连续 没有 累积,但每个都只是成为标志的值
此时在命令行中。据我所知,-l
是唯一的此类标志,
这是一种异常类型:-lfoo
并不是真正的 选项,而是 位置参数
旗帜附有解释方法。它说一个文件
libfoo.so|a
将被输入到链接此时,其绝对路径名
链接器是通过算法发现的(参考-L
选项)。让我们
调用此类标志位置标志。
对于互斥标志,命令行的含义可以改变,如果一个选项 发生在某处,稍后重复。例如
-fno-stack-protector -O1 -O3 -fstack-protector
看起来好像有太多厨师把肉汤弄坏了,而且 相当于:
-O3 -fstack-protector
但如果我们追加一些重复:
-fno-stack-protector -O1 -O3 -fstack-protector -fno-stack-protector -O1
它等同于:
-O1 -fno-stack-protector
对于累积标志,更容易设想混淆含义 通过重复一个选项before 一些比after 出现的命令行:
-I./foo -I./bar
意思是它所说的。而
-I./bar -I./foo -I./bar
意思相同:
-I./bar -I./foo
但这种混乱在实践中几乎不会发生,因为重复 选项几乎总是由附加生成 在增量构造期间重复命令行。
根据定义,位置标志对 order 敏感,两者都在它们之间 以及与其他选项和位置参数有关。的每一个排列
... -lfoo -lbar main.o ...
产生不同的链接。以及带有位置标志的选项重复 也可以很容易地有所作为。众所周知,
... -lfoo main.o ...
很可能会导致链接失败,
... -lfoo main.o -lfoo
会解决的。
所以强调,是的,标志的重复和排序可能很重要。
【讨论】:
以上是关于gcc 标志重复和排序重要吗?的主要内容,如果未能解决你的问题,请参考以下文章
glUniformBlockBinding 和 glBindBufferBase 之间的排序重要吗?