c++shared-librariesubuntu-16.04fpic

c++ shared library fPIC or undefined library ubuntu 16.04


I am trying to compile a code as a shared library (it compiles well on windows but I can't make it compiles on ubuntu 16.04).

If I try to compile "as on windows", I get the error:

relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

so to compile the static libraries that are linked to my code, I added the -fPIC option (it seems to be by default on windows but not on linux but I am not sure):

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")

and in my code, which is compiled using qmake I added:

QMAKE_CXXFLAGS += -fPIC

and now I get these errors:

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 »

etc ...

if I add the -fPIC option only for my code, and not for compiling the static libraries that it uses, I still get the error:

relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

even if the qmake_cxxflags -fPIC is added.

what am I doing wrong ?* (I put the Make file here in case it helps: https://github.com/pdeman/mevislabFetalMRI/blob/master/Makefile.CHUVTools.Release )


Solution

  • With the Makefile, I have a chance of debugging the issue.

    The LIBS links in ITKCommon-4.13, so that's correct; it's needed to resolve typeinfo for itk::MetaDataObjectBase; which is being requested by libITKIOGDCM-4.13.

    the LIBS line contains:

    -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
    

    Link resolution will happen, by default from left-to-right, which means that because the reference to ITKCommon-4.13 happens before the reference to ITKIOGDCM-4.13, the typeinfo does not get resolved.

    There are two solutions to this - the first one is to determine the link dependency order of all the libraries and sort them in reverse order. I don't know enough about the dependencies in the libraries to even come close to suggesting an order that might work, considering the number of libraries that are referenced here - it's got all the hallmarks of linking the kitchen sink.

    The second solution is to wrap all the link options in a linker flag which says to treat all these files together for link purposes. It will probably slow down the link, but it guarantees that out-of-order or cross-dependencies will be resolved.

    At the start of the list of -l items for ITK libraries, you add the option:-

    -Wl,--start-group
    

    and at the end of the list of -l items for ITK libraries, you add the option:-

    --Wl,--end-group
    

    so, to abbreviate the LIBS line, it would look somewhat like (the ellipsis indicates missing text):

    -Wl,--start-group -lITKIOSiemens-4.13 … -lITKznz-4.13 -Wl,--end-group