在为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,...
标志旁边,这些标志的重复和顺序是否有任何含义?
答案 0 :(得分:2)
在GCC命令行中看到重复的选项并不罕见 由某些工具堆栈(通常是IDE)生成的 人工输入“在顶部”。
您发现的任何重复都不会对 命令行的含义。通常,这样的重复只是无害的 冗余,他们可以有一个理性 动机。逐步向GCC命令行添加内容的工具可能 希望确保此时启用了某个选项,即使它已启用 自从上次启用它以来,可能已通过附加的选项以某种方式禁用了它。重覆 冗余选择可能比检查它是否冗余便宜。
但是重复不一定是无害的...
如果在命令行中的某个位置出现选项OPT
:
... OPT ...
然后用2个或多个替换该事件不会有什么作用。
但是,如果命令行的格式为:
... OPT1 ... OPT2 ...
然后在OPT1
之后的任何地方添加OPT2
可能会导致
区别。同样,在OPT2
之前的任何位置添加OPT1
。
这是因为在其中经常出现选项的 order 差异。
一个选项通常由一个 flag 和一个 value 组成,例如
-O3 -> Flag = -O, value = 3
-I./inc -> Flag = -I, value = ../inc
某些标记,例如-O
可以采用一组相互之间的任何一个
排他值。简称为这些 mutex标志。当互斥标志反复出现时
抵消值,以命令行中的 last 为准:
-O1 -O2 -O3 = -O3
-O3 -O2 -O1 = -O1
其他标记(例如-I
)可以任意使用
非排它性的值,按照出现的顺序依次累加,形成一个序列
是编译或链接的参数之一。例如
-I./foo -I./bar
在用户指定的包含目录后附加./foo
和./bar
搜索编译顺序。称这些累积标志。
其他标志为布尔型,具有启用形式和禁用形式
表格-fstack-protector
,
-fno-stack-protector
。这些可以等同于具有
排除可能的值True和False。
还有另一种标志,例如-l
,可以接受任意的非排他值
依次 not 累积,但每个只是成为标志的值
此时在命令行中 。据我所知,-l
是这种类型的唯一标志,
这是一种异常类型:-lfoo
实际上不是 option ,而实际上是 position参数
标志附加了一种解释方法。它说一个文件
此时将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
对于累积标志,更容易设想混淆含义 通过在出现的之前之后的位置重复选项
-I./foo -I./bar
表示它的意思。而
-I./bar -I./foo -I./bar
表示与以下内容相同:
-I./bar -I./foo
但是在实践中几乎不会发生这种混乱,因为重复 选项几乎总是由 append 生成的 在增量构造过程中重复执行命令行。
根据定义,位置标记对 order 都很敏感 以及其他选项和位置参数。
的每个排列 ... -lfoo -lbar main.o ...
产生不同的联系。以及带有位置标志的选项的重复 也可以轻松地有所作为。众所周知,
... -lfoo main.o ...
可能会导致链接失败,
... -lfoo main.o -lfoo
将修复
。因此,很重要,是的,标志的重复和排序很重要。