试图了解lto(链接时间编译)的工作原理
我有这些文件:
julia.h:
#ifndef JULIA_H
#define JULIA_H
#include <stdio.h>
int julian();
#endif // JULIA_H
julia.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
和我的主要计划:
的main.c
#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? 是否只需要优化链接?
由于
答案 0 :(得分:13)
在keltar时, LTO不会影响共享库。但是...
只需将ar
替换为gcc-ar
,然后添加--plugin gccpath/liblto_plugin.so
选项即可。此LTO插件会将declarations, types, callgraph and GIMPLE representation从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 [{3}}中引入(否则使用-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
(和CXXFLAGS
)移到LDFLAGS
;-)还有一件事,调试信息和LTO在GCC-4.9中仍然是实验性的。 GCC-5.0应该改善这一点......
答案 1 :(得分:1)
LTO不会影响共享库;它们被动态链接器链接,动态链接器不知道LTO并且无法在运行时修改代码。
此外,LTO甚至不能使用静态库,但有一天它可能会(在gcc wiki上是TODO)。
但是,是的,启用的是在 编译和链接阶段使用-flto
。