2016-08-30 212 views
17

我試圖使用鏈接時優化與-flto標誌海灣合作委員會(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(除英特爾在某些平臺上的編譯器,所以我讀了...)。儘管如此,我試過使用:

set_property(TARGET glsl_optimizer PROPERTY INTERPROCEDURAL_OPTIMIZATION True) 

哪一個沒有工作。

而且,我試圖GCC的-fuse-linker-plugin標誌,沒有工作。

我想我得做手工直接使用gcc-ar的老路上,也許還有一些其他的方法?

+0

你有沒有試着用''中或CMakeCache.txt'通過的CMake的GUI(GCC-ar'在'CMAKE_AR'緩存變量替換'ar'在高級選項下)? 'INTERPROCEDURAL_OPTIMIZATION'不適用於GCC,因此在CMake的GitLab頁面是[open issue](https://gitlab.kitware.com/cmake/cmake/issues/15939)。 – 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 

可以通過給arranlib選項解決:

--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_CREATECMAKE_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。這可能是原因嗎?如果是這樣的話,是否有人可以更新答案(我的技術知識不足以解決問題並正確解釋)。 –