2017-10-01 7 views
0

Ich versuche, eine statische Bibliothek mit einer ausführbaren Datei nach this example, aber auf MinGW-w64 zu verknüpfen.Nicht definierte Verweise mit Link-Time Optimization

Meine CMakeLists Datei: (beachten Sie, dass dies zu der in dieser Antwort identisch ist)

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) 

hello.c:

extern void hello(void); 

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

libhello.c:

#include <stdio.h> 

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

Die Konfiguration funktioniert wie erwartet:

-- The C compiler identification is GNU 7.1.0 
-- The CXX compiler identification is GNU 7.1.0 
-- Check for working C compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/gcc.exe 
-- Check for working C compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/gcc.exe -- 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: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/g++.exe 
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/g++.exe -- 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: C:/.../project 

Beim Kompilieren wie sie ist, wird jedoch der folgende Fehler generiert:

Scanning dependencies of target hello 
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.obj 
[ 50%] Linking C static library libhello.a 
Error running link command: The system cannot find the file specified 
mingw32-make.exe[3]: *** [CMakeFiles\hello.dir\build.make:95: libhello.a] Error 2 
mingw32-make.exe[3]: *** Deleting file 'libhello.a' 
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:67: CMakeFiles/hello.dir/all] Error 2 
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:116: CMakeFiles/hellow.dir/rule] Error 2 
mingw32-make.exe: *** [Makefile:130: hellow] Error 2 

die SET(CMAKE_C_ARCHIVE_FINISH true) Linie in CMakeLists.txt Datei und neu zu kompilieren Ergebnisse in diesen "undefined reference" Fehlern Entfernen:

[ 25%] Linking C static library libhello.a 
[ 50%] Built target hello 
Scanning dependencies of target hellow 
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.obj 
[100%] Linking C executable hellow.exe 
C:\...\Local\Temp\ccPctpZp.ltrans0.ltrans.o: In function `main': 
E:/Documents/MONAD/projects/ltotest/hello.c:4: undefined reference to `hello' 
collect2.exe: error: ld returned 1 exit status 
mingw32-make.exe[3]: *** [CMakeFiles\hellow.dir\build.make:97: hellow.exe] Error 1 
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:104: CMakeFiles/hellow.dir/all] Error 2 
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:116: CMakeFiles/hellow.dir/rule] Error 2 
mingw32-make.exe: *** [Makefile:130: hellow] Error 2 

Running nm libhello.a zeigt, dass libhello.c mit LTO kompiliert wird:

libhello.c.obj: 
00000000 b .bss 
00000000 d .data 
00000000 r .gnu.lto_.decls.d7da3e90 
00000000 r .gnu.lto_.inline.d7da3e90 
00000000 r .gnu.lto_.opts 
00000000 r .gnu.lto_.refs.d7da3e90 
00000000 r .gnu.lto_.symbol_nodes.d7da3e90 
00000000 r .gnu.lto_.symtab.d7da3e90 
00000000 r .gnu.lto_hello.d7da3e90 
00000000 r .rdata$zzz 
00000000 t .text 
00000001 C ___gnu_lto_slim 
00000001 C ___gnu_lto_v1 

Dies scheint nur ein Problem bei MinGW zu sein, da der Code in der zuvor verlinkten Antwort gut zu funktionieren schien (obwohl ich es selbst nicht testen konnte). Irgendwelche Ideen, was schief läuft/wie kann man damit umgehen?

+0

@HansPassant gcc-ar.exe ist ein Wrapper für ar.exe, der das gcc LTO-Plugin bereitstellt (siehe http://www.tin.org/bin/man.cgi?section=1&topic=gcc-ar-5) – cpdt

+0

@HansPassant Ja, es kann gefunden werden (ich habe überprüft, und außerdem würde ich erwarten, einen Fehler zu erhalten, der eine unbekannte exe erwähnt, wenn es nicht konnte). – cpdt

Antwort

0

Hat etwas mehr Forschung und stolperte über this page, die erwähnt, dass es auch notwendig ist, einen Wrapper für ranlib zu verwenden.

Sicher genug, CMakeLists.txt den folgenden Inhalt zu verändern ermöglicht das Projekt erfolgreich zu erstellen:

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_RANLIB "gcc-ranlib") 
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") 
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>") 
add_library(hello STATIC libhello.c) 
add_executable(hellow hello.c) 
target_link_libraries(hellow hello) 
add_dependencies(hellow hello) 

(beachten Sie die neue SET(CMAKE_RANLIB "gcc-ranlib") Linie)

Zusätzlich scheint es, wie die SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>") Linie nicht notwendig ist, da Dies ist der Standardwert für CMAKE_C_ARCHIVE_FINISH.

+1

Die gcc-Doku erwähnt auch 'Die nächste Version von binutils wird das automatische Laden von liblto_plugin' unterstützen, daher sollte der Wrapper bei neueren binutils nicht benötigt werden. – ssbssa