2016-08-30 5 views
17

Ich versuche, Link-Zeit-Optimierungen mit dem Flag von GCC (6.1.1) zu verwenden.Verwenden von GCC-Link-Zeit-Optimierung mit statischen verknüpften Bibliotheken

Während es funktioniert gut mit meinem Code, es verbindet sich nicht mit einer statischen verknüpften Bibliothek Ich baue und verlinke auch mit meinem Projekt (Engine und die Bibliothek ist glsl-optimizer, nur als Referenz). Hier

ist die Ausgabe:

... 
/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 
... 

Und danach, natürlich habe ich mehrere „undefinierte Referenzen“ auf einige Funktionen erhalten.

Ich habe etwas Forschung und herausgefunden, dass es wegen ar sein könnte, und ich sollte versuchen, gcc-ar zu verwenden, aber ich bin nicht sicher, wie ich das tun könnte.

Auch ich benutze CMake, die nicht unterstützt lto (mit Ausnahme von Intel Compiler auf einigen Plattformen, also lese ich ...). Obwohl ich versucht habe mit:

set_property(TARGET glsl_optimizer PROPERTY INTERPROCEDURAL_OPTIMIZATION True) 

Welche nicht funktioniert hat.

Auch versuchte ich GCC -fuse-linker-plugin Flag, die nicht funktionierte.

Ich denke, ich muss es manuell auf die alte Art und Weise direkt mit gcc-ar tun, oder vielleicht gibt es eine andere Methode? Hier

+0

Haben Sie versucht, GUI zu ersetzen 'ar' mit gcc-ar' in' CMAKE_AR' gecached Variable in 'CMakeCache.txt' oder über CMake ist (unter erweiterten Optionen)? Diese 'INTERPROCEDURAL_OPTIMIZATION' funktioniert nicht für GCC ist ein [offenes Problem] (https://gitlab.kitware.com/cmake/cmake/issues/15939) auf der CMake GitLab Seite. – Florian

+0

@Florian: Ich habe gerade versucht und nur die Einstellung 'CMAKE_AR' löst das Problem nicht. Sie brauchen auch 'CMAKE_CXX_ARCHIVE_CREATE' und' CMAKE_CXX_ARCHIVE_FINISH' (siehe @Mike Kinghans Antwort) – CpCd0y

Antwort

10

ist ein MCVE CMake Projekt, das das Problem reproduziert:

$ 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"); 
} 

Konfiguration ist gut:

$ 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 

Körperbau nicht per Problem:

$ 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 

Es gibt mehr als eine Lösung. Eine besteht darin, die 3 kommentierten Zeilen in CMakeLists.txt oben auskommentieren. Dann:

$ 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 

Dieser Fix verwendet die folgenden Fakten.

Das Build-breaking Problem:

/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 

gelöst durch ar und ranlib die Option geben:

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

jedoch GNU ranlib ist lediglich ein Synonym für ar -s und gcc-ar ist ein Wrapper für ar, die dieses Plugin liefert.

CMake Build-Vorlage für eine C statische Bibliothek ist:

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

mit diesen Einstellungen So Plus:

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

die für GNU ar äquivalent ist

SET(CMAKE_AR "gcc-ar") 

wir 'Du bist gut.

Für ein C++ Projekt, natürlich, setzen CMAKE_CXX_ARCHIVE_CREATE und CMAKE_CXX_ARCHIVE_FINISH

+0

Danke für Ihre Antwort. Es hat perfekt funktioniert. Sie erhalten das Häkchen :) – CpCd0y

+0

Ich habe diese Schritte mit GCC5.4 versucht, während es "mit LTO kompiliert" sehen Sie keine der Optimierungen stattfinden, die Sie erwarten würden. – BlamKiwi

+0

@BlamKiwi In [dieser archivierten Nachricht] (https://lists.launchpad.net/kicad-developers/msg17690.html) ändern Sie 'CMAKE_AR',' CMAKE_NM' und 'CMAKE_RANLIB'. Ist das vielleicht der Grund? Wenn dies der Fall ist, kann jemand die Antwort aktualisieren (mein technisches Wissen reicht nicht aus, um es zu verstehen und zu erklären). –

Verwandte Themen