2016-08-30 6 views
17

Я пытаюсь использовать оптимизацию времени привязки с флагом -flto GCC (6.1.1).Использование оптимизации времени соединения GCC со статическими связанными библиотеками

Хотя он отлично работает с моим кодом, он не связан со статической связанной библиотекой, которую я также создаю и свяжу с моим проектом (это Engine, а библиотека glsl-optimizer, только для справки).

Вот результат:

... 
/usr/bin/ranlib: ir_expression_flattening.cpp.o: plugin needed to handle lto object 
/usr/bin/ranlib: opt_function_inlining.cpp.o: plugin needed to handle lto object 
/usr/bin/ranlib: opt_copy_propagation_elements.cpp.o: plugin needed to handle lto object 
... 

И после этого, конечно же, я получаю несколько «неопределенные ссылки» к некоторым функциям.

Я провел некоторое исследование и выяснил, что это может быть из-за ar, и я должен попытаться использовать gcc-ar, но я не уверен, как это сделать.

Кроме того, я использую CMake, который не поддерживает lto (кроме компилятора Intel на некоторых платформах, поэтому я читаю ...). Несмотря на это, я пробовал использовать:

set_property(TARGET glsl_optimizer PROPERTY INTERPROCEDURAL_OPTIMIZATION True) 

Какой из них не работает.

Кроме того, я пробовал флаг GCC -fuse-linker-plugin, который не работал.

Я думаю, мне придется вручную вручную использовать старый способ, используя gcc-ar, или, может быть, есть какой-то другой метод?

+0

ли вы пытаетесь заменить '' ar' с GCC-ar' в 'кэшированной переменной CMAKE_AR' в' CMakeCache.txt' или через GUI CMake (в по дополнительным опциям)? Эта функция 'INTERPROCEDURAL_OPTIMIZATION' не работает для GCC - это [открытая проблема] (https://gitlab.kitware.com/cmake/cmake/issues/15939) на странице GitLab на CMake. – Florian

+0

@Florian: Я просто попробовал, и только настройка 'CMAKE_AR' не решает проблему. Вам также нужны 'CMAKE_CXX_ARCHIVE_CREATE' и' CMAKE_CXX_ARCHIVE_FINISH' (см. Ответ @Mike Kinghan) – CpCd0y

ответ

10

Вот MCVE CMake проект, который воспроизводит проблему:

$ ls -R hellow 
hellow: 
CMakeLists.txt hello.c libhello.c 

$ cat hellow/CMakeLists.txt 
cmake_minimum_required (VERSION 2.6) 
project (hellow) 
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") 
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") 
#SET(CMAKE_AR "gcc-ar") 
#SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") 
#SET(CMAKE_C_ARCHIVE_FINISH true) 
add_library(hello STATIC libhello.c) 
add_executable(hellow hello.c) 
target_link_libraries(hellow hello) 
add_dependencies(hellow hello) 


$ cat hellow/hello.c 
extern void hello(void); 

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

$ cat hellow/libhello.c 
#include <stdio.h> 

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

Конфигурация хороша:

$ mkdir build_hellow 
$ cd build_hellow/ 
$ cmake ../hellow 
-- The C compiler identification is GNU 5.4.0 
-- The CXX compiler identification is GNU 5.4.0 
-- Check for working C compiler: /usr/bin/cc 
-- Check for working C compiler: /usr/bin/cc -- works 
-- Detecting C compiler ABI info 
-- Detecting C compiler ABI info - done 
-- Detecting C compile features 
-- Detecting C compile features - done 
-- Check for working CXX compiler: /usr/bin/c++ 
-- Check for working CXX compiler: /usr/bin/c++ -- works 
-- Detecting CXX compiler ABI info 
-- Detecting CXX compiler ABI info - done 
-- Detecting CXX compile features 
-- Detecting CXX compile features - done 
-- Configuring done 
-- Generating done 
-- Build files have been written to: /home/imk/dev/so/build_hellow 

Сложение терпит неудачу в соответствии с проблемой:

$ make 
Scanning dependencies of target hello 
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o 
[ 50%] Linking C static library libhello.a 
/usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object 
/usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object 
[ 50%] Built target hello 
Scanning dependencies of target hellow 
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o 
[100%] Linking C executable hellow 
/tmp/ccV0lG36.ltrans0.ltrans.o: In function `main': 
<artificial>:(.text+0x5): undefined reference to `hello' 
collect2: error: ld returned 1 exit status 
CMakeFiles/hellow.dir/build.make:95: recipe for target 'hellow' failed 
make[2]: *** [hellow] Error 1 
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hellow.dir/all' failed 
make[1]: *** [CMakeFiles/hellow.dir/all] Error 2 
Makefile:83: recipe for target 'all' failed 
make: *** [all] Error 2 

Существует более одно решение. Один из них заключается в раскомстировании 3 прокомментированных строк в CMakeLists.txt выше. Затем:

$ cmake ../hellow/ 
-- The C compiler identification is GNU 5.4.0 
-- The CXX compiler identification is GNU 5.4.0 
-- Check for working C compiler: /usr/bin/cc 
-- Check for working C compiler: /usr/bin/cc -- works 
-- Detecting C compiler ABI info 
-- Detecting C compiler ABI info - done 
-- Detecting C compile features 
-- Detecting C compile features - done 
-- Check for working CXX compiler: /usr/bin/c++ 
-- Check for working CXX compiler: /usr/bin/c++ -- works 
-- Detecting CXX compiler ABI info 
-- Detecting CXX compiler ABI info - done 
-- Detecting CXX compile features 
-- Detecting CXX compile features - done 
-- Configuring done 
-- Generating done 
-- Build files have been written to: /home/imk/dev/so/build_hellow 

$ make 
Scanning dependencies of target hello 
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o 
[ 50%] Linking C static library libhello.a 
[ 50%] Built target hello 
Scanning dependencies of target hellow 
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o 
[100%] Linking C executable hellow 
[100%] Built target hellow 

$ ./hellow 
Hello 

В этом исправлении используются следующие факты.

Нарастание разрыва проблемы:

/usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object 
... 
/usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object 

банку решить, давая ar и ranlib вариант:

--plugin=$(gcc --print-file-name=liblto_plugin.so) 

Однако GNU ranlib это просто синоним ar -s и gcc-ar является обертка для ar, которая поставляет этот плагин.

шаблон сборки CMake для статической библиотеки C является:

CMAKE_C_ARCHIVE_CREATE (= <CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>) 
CMAKE_C_ARCHIVE_FINISH (= <CMAKE_RANLIB> <TARGET>) 

который для GNU ar эквивалентно:

CMAKE_C_ARCHIVE_CREATE (= <CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>) 
CMAKE_C_ARCHIVE_FINISH (= true) # Or any other no-op command 

Так с этими настройками плюс:

SET(CMAKE_AR "gcc-ar") 

мы «Хорошо.

Для C++ проект, конечно, установить CMAKE_CXX_ARCHIVE_CREATE и CMAKE_CXX_ARCHIVE_FINISH

+0

Спасибо за ваш ответ. Он отлично работал. Вы получаете галочку :) – CpCd0y

+0

Я пробовал эти шаги с GCC5.4, а он «компилируется с помощью LTO», вы не видите, что какие-либо из оптимизаций происходят, что вы ожидаете. – BlamKiwi

+0

@BlamKiwi В [это заархивированное сообщение] (https://lists.launchpad.net/kicad-developers/msg17690.html), измените 'CMAKE_AR',' CMAKE_NM' и 'CMAKE_RANLIB'. Это может быть причиной? Если это так, может кто-нибудь обновить ответ (моего технического уровня недостаточно, чтобы понять и объяснить его правильно). –

Смежные вопросы