gcc LTO - 共享库 - 我是对的吗?

时间:2014-07-14 10:03:15

标签: c gcc shared-libraries lto

上下文:

试图了解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? 是否只需要优化链接?

由于

2 个答案:

答案 0 :(得分:13)

keltar时, LTO不会影响共享库。但是...

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