2013-03-07 76 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参数
  • 不链接静态库到共享库,但将它们链接到应用程序。如果在共享库中使用静态库的函数,这可能是不可能的。