2013-03-07 75 views
0

我正在修改一個在Windows上運行的CMake文件,以在Linux中創建一個共享對象。CMake在Linux中編譯失敗

CMake文件生成一個makefile,當我在Linux上「make」時,它建立了foo庫的對象,並顯示了所有四個庫的鏈接。例如:

鏈接CXX靜態庫lib_foo_d.a

和最終共享對象

鏈接CXX靜態庫lib_scen_files_d.a

但在端部它顯示

/usr/bin/ld:lib_foo3/lib_foo3_d.a(chap_alt_scence_defs.cpp.o):
在創建共享對象時,無法使用針對`.rodata'的重定位R_X86_64_32;
重新編譯-fPIC
lib_foo3/lib_foo3_d.a:看不懂的符號:壞值
collect2:LD返回1個退出狀態

我已經嘗試了一些其他選項,但沒有喜悅。以下是我的CMakeLists.txt。任何幫助/批評都會對我有益。

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
CMAKE_POLICY(SET CMP0017 NEW) 

PROJECT(disk_space_model) 
INCLUDE(../libs/helper_functions.cmake) 
INCLUDE_THIRD_PARTY_SFC() 
find_path_for_libs() 

add_s_library(lib_foo1) 
add_s_library(lib_foo2) 
add_s_library(lib_foo3) 
add_s_library(lib_foo4) 

SET( HEADER_FILES 
     stdafx.h 
     INS_sensor_model.h 
) 

SET( SOURCE_FILES 
     Disk_space_model.cpp 
) 

SET( RESOURCE_FILES 
     "Disk Space DLL.rc" 
     resource.h 
) 

COMMON_SETUP() 
set(LIB_FILES 
     lib_foo 
     lib_foo1 
     lib_foo3 
     lib_foo4) 

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols") 
ADD_LIBRARY(disk_space_model SHARED ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES} ${CMAKE_HELPER_FILES}) 
SET_OUTPUT_DIRS(disk_space_model) 
TARGET_LINK_LIBRARIES(disk_space_model ${LIB_FILES}) 

謝謝...

+0

您使用了太多我們不知道的自定義宏(因爲它們在外部文件中).... – 2013-03-07 15:23:05

回答

1

鏈接器告訴你什麼是錯誤的:該對象用於共享庫中,但未編譯爲-fPIC。您需要以某種方式添加此標誌。

使用CMake 2.8.9或更高版本時,您可以簡單地在目標(靜態庫)上設置屬性POSITION_INDEPENDENT_CODE。使用CMake的早期版本,您需要將標誌直接添加到目標的COMPILE_FLAGS屬性(編譯器的正確拼寫,可能只是-fPIC)。

+0

感謝您的評論。那麼我使用2.8.7版本的cmake-gui,所以我認爲第一個選項不適合我。關於第二個選項,你的意思是在我的情況下,它抱怨foo3,所以我應該在foo3目錄的CmakeLists中添加「COMPILE_FLAGS屬性」? – samprat 2013-03-07 15:46:34

+0

@samprat是;進入Linux共享庫的對象必須編譯爲位置獨立代碼(PIC)。 – Angew 2013-03-07 16:04:36

+0

..它的工作原理。非常感謝您的幫助。這是有點痛苦的步驟,因爲我需要在很多庫中進行更改,我有點懷疑,但最終它的工作非常好。謝謝你挽救我。 – samprat 2013-03-08 09:25:48

0

爲了建立共享庫Linux上的所有來源,誰是鏈接到它的目標文件,必須(如連接器抱怨-fPIC選項)被編譯爲重定位。您嘗試將靜態庫lib_foo1 lib_foo2 lib_foo3等鏈接到共享庫中,並且失敗。 所以可能的解決方案:

  • 構建共享版本(的.so)每個庫lib_foo1 lib_foo2的。除了靜態的(.a)中
  • 構建靜態庫與-fPIC參數
  • 不鏈接靜態庫到共享庫,但將它們鏈接到應用程序。如果在共享庫中使用靜態庫的函數,這可能是不可能的。