在Linux上使用链接时间代码生成构建静态库的正确方法是什么? [英] Which is the correct way to build a static library with link time code generation on Linux?

查看:526
本文介绍了在Linux上使用链接时间代码生成构建静态库的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在游荡,这是在Linux上用GCC编译静态库的正确方式,这样当链接时间优化(LTO)应用于可执行文件时,库可以被消费并可能实现最佳性能。 / p>

当仅使用 -flto 编译库时,无论是否使用<$ c,该可执行文件都无法链接到该库$ c> -flto 或不。错误是:


对'hello'的未定义引用


其中 hello 是函数库中定义的函数。 根据堆栈溢出问题一个可能的解决方案如下:

  set(CMAKE_AR gcc-ar)
set(CMAKE_C_ARCHIVE_CREATE< CMAKE_AR> qcs< TARGET>< LINK_FLAGS>< OBJECTS>)
set(CMAKE_C_ARCHIVE_FINISH true)

-flto 和没有 -flto 传递给链接器标志链接到可执行文件。



但根据堆栈溢出问题静态库以这种方式进行编译,可以使用LTO或不使用LTO,而不必使用 -ffat -lto-objects 。如果我们再次将这个标志添加到库编译标志中,那么库可以通过 -flto 和没有 -flto 传递给链接标志。



我的问题是:


  1. 什么第一个解决方案的确切含义是 gcc-ar

  2. 当不同工作变体编译时使用 -flto



    <2.1>不带 -flto
    $ ul
  3. 库仅使用 gcc-ar

  4. 库仅使用 -ffat -lto-objects

  5. 库同时使用 gcc-ar -ffat -lto-objects



  6. 2.2使用 -flto 和库中的相同3个变体可执行。


这是我的测试项目的最小,完整和可验证示例,它是示例的修改版本从堆栈溢出问题。我正在使用GCC版本 7.2.0



CMakeLists.txt

  cmake_minimum_required(VERSION 3.9)

项目(lto)

集合(CMAKE_C_FLAGS_RELEASE$ {CMAKE_C_FLAGS_RELEASE} -g -O3)

add_subdirectory(lib)
add_subdirectory(exe)

exe / CMakeLists.txt

  set(TARGET_NAME exe)

add_executable($ {TARGET_NAME }
target_link_libraries($ {TARGET_NAME} lib)

选项(EXE_LTO对可执行文件使用链接时间优化。OFF)

if($ {EXE_LTO})
target_compile_options($ {TARGET_NAME} PRIVATE-flto)
endif()

exe / src / main.c

  extern void hello(); 

int main()
{
hello();
返回0;
}

lib / CMakeLists.txt

  set(TARGET_NAME lib)

add_library($ {TARGET_NAME} STATIC src / lib.c)

选项(LIB_LTO OFF)
选项(LIB_FAT_LTO为库文件创建fat LTO对象OFF)
选项(LIB_USE_LTO_AR为LTO对象使用另一个AR程序OFF) ($ {LIB_LTO})
target_compile_options($ {TARGET_NAME} PRIVATE -flto)
endif()

if($ {LIB_FAT_LTO} )
target_compile_options($ {TARGET_NAME} PRIVATE -ffat -lto-objects)
endif()

if($ {LIB_USE_LTO_AR})
set(CMAKE_AR gcc- )
set(CMAKE_C_ARCHIVE_FINISH true)
endif()
qcs / code>



src / lib.c

  #include< stdio.h> 

void hello()
{
puts(Hello);


解决方案

- plugin /psth/to/lto-plugin.so * ar 参数,您将会得到未定义的参考链接时间,并在存档创建时发出警告。或者至少这是我得到的。您可能需要在此处添加它:

  set(CMAKE_C_ARCHIVE_CREATE< CMAKE_AR>  - 插件< LTO_PLUGIN_PATH> \ 
qcs< TARGET>< OBJECTS>)

LINK_FLAGS 可能不属于这里,所以我省略了它们)。



我不知道如何自动设置LTO_PLUGIN_PATH。



该插件使 ar 可以创建启用LTO的归档。所有其他方法根本不起作用(存档中的非胖对象)或实际上不会导致链接时间优化(存档中的胖对象 - 在这种情况下,仅使用传统对象代码,LTO信息被忽略)。


I'm wandering which is the right way to compile static library on Linux with GCC in such way that when link time optimizations (LTO) be applied to the executable the library to be consumable and possibly to be achieved optimal performance.

When library is compiled only with -flto the executable cannot be linked to it no matter whether it uses -flto or not. The error is:

undefined reference to `hello'

where hello is function defined in the library.

According to the answer to this Stack Overflow question one possible solution is the following:

set(CMAKE_AR gcc-ar)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_C_ARCHIVE_FINISH true)

Then the library can be linked to the executable both with -flto and without -flto passed to the linker flags.

But according to the answer to this Stack Overflow question if we want static library to be compiled in such way to be usable with and without LTO than we have to use -ffat-lto-objects. If we add this flag to the library compilation flags again the library can be linked to executables both with -flto and without -flto passed to the linker flags.

My questions are:

  1. What is the exact meaning of the first solution with gcc-ar?
  2. What is the difference between different working variants when library is compiled with -flto.

    2.1 Executable without -flto.

    • Library is using only gcc-ar.
    • Library is using only -ffat-lto-objects.
    • Library is using both gcc-ar and -ffat-lto-objects

    2.2 Executable with -flto and the same 3 variants for the library.

Here is Minimal, Complete, and Verifiable example with my test project which is modified version of the example from this Stack Overflow question. I'm using GCC version 7.2.0.

CMakeLists.txt

cmake_minimum_required(VERSION 3.9)

project(lto)

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -g -O3")

add_subdirectory(lib)
add_subdirectory(exe)

exe/CMakeLists.txt

set(TARGET_NAME exe)

add_executable(${TARGET_NAME} src/main.c)

target_link_libraries(${TARGET_NAME} lib)

option(EXE_LTO "Use link time optimizations for the executable." OFF)

if(${EXE_LTO})
  target_compile_options(${TARGET_NAME} PRIVATE "-flto")
endif()

exe/src/main.c

extern void hello();

int main()
{
  hello();
  return 0;
}

lib/CMakeLists.txt

set(TARGET_NAME lib)

add_library(${TARGET_NAME} STATIC src/lib.c)

option(LIB_LTO "Use link time optimizations for the library." OFF)
option(LIB_FAT_LTO "Create fat LTO objects for library files." OFF)
option(LIB_USE_LTO_AR "Use another AR program for LTO objects." OFF)

if(${LIB_LTO})
  target_compile_options(${TARGET_NAME} PRIVATE -flto)
endif()

if(${LIB_FAT_LTO})
  target_compile_options(${TARGET_NAME} PRIVATE -ffat-lto-objects)
endif()

if(${LIB_USE_LTO_AR})
  set(CMAKE_AR gcc-ar)
  set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
  set(CMAKE_C_ARCHIVE_FINISH true)
endif()

lib/src/lib.c

#include <stdio.h>

void hello()
{
  puts("Hello");
}

解决方案

If you don't add --plugin /psth/to/lto-plugin.so* to ar parameters, you will get undefined references at link time and a warning at archive creation time. Or at least that's what I'm getting. You probably need to add it here:

set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> --plugin <LTO_PLUGIN_PATH> \
  qcs <TARGET> <OBJECTS>")

(LINK_FLAGS probably don't belong here, so I omitted them).

I don't know how to set LTO_PLUGIN_PATH automatically.

The plugin enables ar to create LTO-enabled archives. All other methods either don't work at all (non-fat objects in the archive) or don't actually result in link time optimisation (fat objects in the archive — in this case only the traditional object code is used, the LTO information is ignored).

这篇关于在Linux上使用链接时间代码生成构建静态库的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆