我正在尝试将代码编译为共享库(它在Windows上可以很好地编译,但不能在ubuntu 16.04上进行编译)。
如果我尝试“像在Windows上一样”进行编译,则会收到错误消息:
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
因此,为了编译链接到我的代码的静态库,我添加了-fPIC选项(默认情况下,它在Windows上似乎默认,但在Linux上不是,但是我不确定):
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
在我的代码中,该代码是使用我添加的qmake编译的:
QMAKE_CXXFLAGS += -fPIC
现在我得到这些错误:
itkGDCMImageIO.cxx:(.text+0xf9e) : undefined reference to « typeinfo for itk::MetaDataObjectBase »
itkGDCMImageIO.cxx:(.text+0xfb5) : undefined reference to « itk::MetaDataObject<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::GetMetaDataObjectValue() const »
等...
如果仅为我的代码添加-fPIC选项,而不为编译其使用的静态库添加-fPIC选项,我仍然会收到错误消息:
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
即使添加了qmake_cxxflags -fPIC。
我做错了什么?* (我把Make文件放在这里,以防它https://github.com/pdeman/mevislabFetalMRI/blob/master/Makefile.CHUVTools.Release)
答案 0 :(得分:1)
有了Makefile,我就有机会调试该问题。
ITKCommon-4.13中的LIBS链接,因此是正确的;需要解决typeinfo for itk::MetaDataObjectBase
; libITKIOGDCM-4.13
正在请求。
LIBS行包含:
-lITKIOSiemens-4.13 -lITKBiasCorrection-4.13 -lITKIOSpatialObjects-4.13 -lITKBioCell-4.13 -lITKIOStimulate-4.13 -lITKCommon-4.13 -lITKIOTIFF-4.13 -lITKDICOMParser-4.13 -lITKIOTransformBase-4.13 -litkdouble-conversion-4.13 -lITKIOTransformHDF5-4.13 -lITKEXPAT-4.13 -lITKIOTransformInsightLegacy-4.13 -lITKFEM-4.13 -lITKIOTransformMatlab-4.13 -litkgdcmcharls-4.13 -lITKIOVTK-4.13 -litkgdcmCommon-4.13 -lITKIOXML-4.13 -litkgdcmDICT-4.13 -litkjpeg-4.13 -litkgdcmDSED-4.13 -lITKKLMRegionGrowing-4.13 -litkgdcmIOD-4.13 -lITKLabelMap-4.13 -litkgdcmjpeg12-4.13 -litklbfgs-4.13 -litkgdcmjpeg16-4.13 -lITKMesh-4.13 -litkgdcmjpeg8-4.13 -lITKMetaIO-4.13 -litkgdcmMEXD-4.13 -litkminc2-4.13 -litkgdcmMSFF-4.13 -litknetlib-4.13 -litkgdcmopenjp2-4.13 -litkNetlibSlatec-4.13 -litkgdcmsocketxx-4.13 -lITKniftiio-4.13 -litkgdcmuuid-4.13 -lITKNrrdIO-4.13 -lITKgiftiio-4.13 -lITKOptimizers-4.13 -litkgtest-4.13 -lITKOptimizersv4-4.13 -litkgtest_main-4.13 -lITKPath-4.13 -litkhdf5 -litkpng-4.13 -litkhdf5_cpp -lITKPolynomials-4.13 -lITKIOBioRad-4.13 -lITKQuadEdgeMesh-4.13 -lITKIOBMP-4.13 -lITKSpatialObjects-4.13 -lITKIOBruker-4.13 -lITKStatistics-4.13 -lITKIOCSV-4.13 -litksys-4.13 -lITKIOGDCM-4.13 -litktestlib-4.13 -lITKIOGE-4.13 -litktiff-4.13 -lITKIOGIPL-4.13 -lITKTransform-4.13 -lITKIOHDF5-4.13 -lITKTransformFactory-4.13 -lITKIOImageBase-4.13 -litkv3p_netlib-4.13 -lITKIOIPL-4.13 -litkvcl-4.13 -lITKIOJPEG-4.13 -lITKVideoCore-4.13 -lITKIOLSM-4.13 -lITKVideoIO-4.13 -lITKIOMesh-4.13 -litkvnl-4.13 -lITKIOMeta-4.13 -litkvnl_algo-4.13 -lITKIOMINC-4.13 -lITKVNLInstantiation-4.13 -lITKIOMRC-4.13 -lITKVTK-4.13 -lITKIONIFTI-4.13 -lITKWatersheds-4.13 -lITKIONRRD-4.13 -litkzlib-4.13 -lITKIOPNG-4.13 -lITKznz-4.13
默认情况下,链接解析将从左到右发生,这意味着因为对ITKCommon-4.13
的引用发生在对ITKIOGDCM-4.13
的引用之前,所以typeinfo不会得到解析。
对此有两种解决方案-第一种是确定所有库的链接依赖关系顺序,并以相反的顺序对其进行排序。考虑到这里引用的库的数量,我对库中的依赖项了解甚少,甚至无法建议一个可能可行的顺序-拥有连接厨房水槽的所有标志。
第二种解决方案是将所有链接选项包装在链接器标记中,该标记表示将所有这些文件一起对待以用于链接目的。可能会减慢链接的速度,但可以保证解决乱序或交叉依赖关系。
在ITK库的-l
项目列表的开头,您添加了以下选项:-
-Wl,--start-group
,然后在ITK库的-l
项列表的末尾,添加以下选项:-
--Wl,--end-group
因此,为了简化LIBS
行,它看起来有点像(省略号表示缺少文本):
-Wl,--start-group -lITKIOSiemens-4.13 … -lITKznz-4.13 -Wl,--end-group