第一次使用CMake 卻出現了以下的error,奇怪的是在compiler time並沒有錯誤訊息,在 run的當下卻馬上出現了Exception,錯誤訊息如下:
java.lang.UnsatisfiedLinkError: dlopen failed: library “../../../../libXXX.so” not found
拿別的third party .so檔完全沒有此問題,偏偏想用的卻一直出現此錯誤訊息。
一開始會以為是路徑錯誤,但是路徑填錯的話在compiler時就該出錯,鑽研很久很走,正當我快要放棄之時,突然想到了是否是.so檔本身有問題呢?
跟身旁同事講了這個想法後,他推薦了一個dump .so file information的指令:
readelf -d filename.so
使用此指令後會出現:
Dynamic section at offset 0x1b6f0 contains 29 entries:
標記 類型 名稱/值
0x0000000000000001 (NEEDED) 共享函式庫:[libXXX.so]
0x0000000000000001 (NEEDED) 共享函式庫:[libm.so]
0x0000000000000001 (NEEDED) 共享函式庫:[liblog.so]
0x0000000000000001 (NEEDED) 共享函式庫:[libandroid.so]
0x0000000000000001 (NEEDED) 共享函式庫:[libc.so]
0x000000000000001a (FINI_ARRAY) 0x2af90
…
0x000000006ffffff9 (RELACOUNT) 79
0x0000000000000000 (NULL) 0x0
一開始看不太出有什麼差異,這時突然想到可以拿另一個可用的.so檔試試
Dynamic section at offset 0x2e4854 contains 33 entries:
標記 類型 名稱/值
0x00000003 (PLTGOT) 0x2e6ff4
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x98dc
0x00000004 (HASH) 0x7fd8
0x00000001 (NEEDED) 共享函式庫:[libandroid.so]
0x00000001 (NEEDED) 共享函式庫:[liblog.so]
0x00000001 (NEEDED) 共享函式庫:[libc.so]
0x00000001 (NEEDED) 共享函式庫:[libm.so]
0x0000000e (SONAME) 函式庫檔名:[libXXX.so]
0x0000001a (FINI_ARRAY) 0x2dae40
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000000 (NULL) 0x0
這時突然發現了兩者的差異在於有沒有SONAME這個東西, SONAME是什麼呢?
在我搜尋dump .so檔相關資訊時,不斷的出現SONAME這個名詞
這時我試著搜尋沒有 SONAME的so檔該如何解決,發現CMake早有提供一個參數解決此問題:
set_property(TARGET XXX-lib PROPERTY IMPORTED_NO_SONAME 1)
加入此行property 在CMakeLists.txt後,就能解決此問題了。
Author: jeanyang
Filed Under: TECHNOLOGY