2017-10-01 26 views
0

this exampleの次に、実行可能ファイルと静的ライブラリをリンクしようとしていますが、MinGW-w64ではリンクしています。リンク時の最適化で未定義の参照

マイCMakeListsファイル:(これはその答えのものと同一であることに注意してください)

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

構成は正常に動作します。

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

そのままコンパイルする場合、しかし、次のエラーが生成され:

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 

CMakeLists.txtファイルにSET(CMAKE_C_ARCHIVE_FINISH true)行を削除し、この「未定義参照」エラーで結果を再コンパイル:

[ 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 

nm libhello.aを実行すると、libhello.cがLTOでコンパイルされていることが示されます。

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 

これはMinGW上でのみ問題になっているようですが、コードは以前にリンクされた回答で正常に動作していたようです(自分でテストすることはできませんでしたが)。何がうまくいかないかに関するアイデア/それを回避する方法は?

+0

@HansPassant gcc-ar.exeは、gcc LTOプラグインを提供するar.exeのラッパーです(http://www.tin.org/bin/man.cgi?section=1&topic=gcc-ar-5を参照)。 ) – cpdt

+0

@HansPassantうん、それは見つけることができます(私はチェックして、さらに、私はそれができない場合は未知のexeを言及するエラーを期待したい)。 – cpdt

答えて

0

ranlibのラッパーを使用する必要があることをさらに指摘し、より多くの研究を行い、this pageを見つけましたか?

以下の内容にCMakeLists.txtを変え、案の定、プロジェクトが正常に構築することができます:SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")行は必要ありませんように

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) 

(新しいSET(CMAKE_RANLIB "gcc-ranlib")ラインに気づく)

さらに、それはように、思えますこれはCMAKE_C_ARCHIVE_FINISHのデフォルト値です。

+1

gcc docuには、 'binutilsの次のバージョンはliblto_pluginの自動読み込みをサポートしているので、最近のbinutilsではラッパーは必要ないはずです。 – ssbssa