3

语境 :

试图了解 lto(链接时间编译)是如何工作的

代码:

我有这些文件:

朱莉娅.h:

#ifndef JULIA_H
#define JULIA_H
#include <stdio.h>
int julian();

#endif // JULIA_H

朱莉娅.c:

#include "julia.h"

int julian()
{
    printf("Hello Worldu!\n");
    return 0;
}

像这样编译为共享库: gcc -O3 -fPIC -shared julia.c -o libjulia.so -L$PWD -I$PWD -flto

和我的主程序:

主程序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "julia.h"

int main()
{

    julian();

    return 0;
}

编译:gcc -O3 main.c -I/path/to/inc -L/path/to/lib -Wl,-rpath=/path/to/lib -ljulia -flto

它编译罚款。

问题 :

所以,这是一个 hello world 程序,但我用 LTO 做得对吗?是否只需要优化链接?

谢谢

4

2 回答 2

13

正如keltar所说,LTO 不会影响共享库。但...

LTO 与静态库一起使用

只需替换argcc-ar添加选项--plugin gccpath/liblto_plugin.so。这个 LTO 插件会将声明、类型、调用图和 GIMPLE 表示从LTO编译的对象复制到静态库中。(同样ranlib被替换gcc-ranlib

在你的例子中

# First retrieve the GCC path
gccpath=$(gcc -print-search-dirs | awk '/install/{print $2}')

# Compile the static library
gcc julia.c -o julia.o -flto -ffat-lto-objects
gcc-ar rcs libjulia.a julia.o --plugin $gccpath/liblto_plugin.so

# Compile & link the executable
gcc main.c libjulia.a -flto -Ofast -march=native

注意:-Ofast在 GCC-4.6 [ref]中引入(其他使用-03

更新Makefile

GCCPATH = $(shell gcc -print-search-dirs | awk '/install/{print $$2}')
AR      = gcc-ar
RANLIB  = gcc-ranlib
ARFLAGS     += --plugin $(GCCPATH)/liblto_plugin.so
RANLIBFLAGS += --plugin $(GCCPATH)/liblto_plugin.so
CFLAGS      += -flto -ffat-lto-objects
CXXFLAGS    += -flto -ffat-lto-objects
LDFLAGS     += -flto=8    # 8 -> compiles using 8 threads

不要忘记,真正的编译将在链接时完成。因此,将优化标志从CFLAGS(and CXXFLAGS) 移至LDFLAGS;-) 还有一件事,调试信息和 LTO 在 GCC-4.9 中仍处于试验阶段。GCC-5.0 应该改进这一点......

于 2015-02-26T19:14:49.433 回答
2

LTO 不影响共享库;它们由动态链接器链接,该链接器不知道 LTO 并且无法在运行时修改代码。

此外,LTO 甚至不适用于静态库,但总有一天它可能会(它是 gcc wiki 上的 TODO)。

但是,是的,启用需要-flto在编译和链接阶段都使用。

于 2014-07-14T10:14:41.470 回答