Building in Linux using IPP-enhanced Zlib

asked 2018-12-20 05:29:41 -0500

I'm attempting a build of OpenCV 3.4 using gcc in Linux, linking statically with Intel's standalone IPP library and also the Intel-enhanced version of Zlib (which I've compiled separately). This means that as well as OpenCVs direct dependencies on the IPP, there are also three additional IPP libraries that Zlib depends upon.Therefore, as well as setting -DWITH_IPP=ON and -DIPPROOT="my path to IPP" on the CMake command line, I've also added the following section to the main CMakeLists.txt file:

include(cmake/OpenCVFindLibsGrfmt.cmake)
include(cmake/OpenCVFindLibsGUI.cmake)
include(cmake/OpenCVFindLibsVideo.cmake)
include(cmake/OpenCVFindLibsPerf.cmake)
include(cmake/OpenCVFindLAPACK.cmake)
include(cmake/OpenCVFindProtobuf.cmake)

#---------------------------My changes start here-------------------------
# We insert this code here because this is the point where ZLIB_LIBRARIES 
# has just become defined, and by putting it here we ensure that our 
# changes are propagated throughout the rest of the project.
if (MSVC)

    add_library(ippdcmt STATIC IMPORTED)
    add_library(ippsmt STATIC IMPORTED)
    add_library(ippcoremt STATIC IMPORTED)
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        # We are compiling 64-bit code
        set_target_properties(ippdcmt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64_win/ippdcmt.lib")
        set_target_properties(ippsmt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64_win/ippsmt.lib")
        set_target_properties(ippcoremt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64_win/ippcoremt.lib")
    else()
        # We are compiling 32-bit code
        set_target_properties(ippdcmt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32_win/ippdcmt.lib")
        set_target_properties(ippsmt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32_win/ippsmt.lib")
        set_target_properties(ippcoremt PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32_win/ipcoremt.lib")
    endif()
    list(APPEND ZLIB_LIBRARIES ippdcmt ippsmt ippcoremt)

elseif(CMAKE_COMPILER_IS_GNUCC)

    add_library(libippdc STATIC IMPORTED)
    add_library(libipps STATIC IMPORTED)
    add_library(libippcore STATIC IMPORTED)
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        # We are compiling 64-bit code
        set_target_properties(libippdc PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64/libippdc.a")
        set_target_properties(libipps PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64/libipps.a")
        set_target_properties(libippcore PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/intel64/libippcore.a")        
    else()
        # We are compiling 32-bit code
        set_target_properties(libippdc PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32/libippdc.a")
        set_target_properties(libipps PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32/libipps.a")
        set_target_properties(libippcore PROPERTIES IMPORTED_LOCATION "${IPP_ROOT_DIR}/lib/ia32/libippcore.a")  
    endif()
    list(APPEND ZLIB_LIBRARIES libippdc libipps libippcore)

endif()
#---------------------------My changes end here---------------------------

In Windows, compiling with MSVC 2017, this works perfectly. In Linux, compiling with gcc, it comes tantalizingly close to working - in fact after about two hours the build process gets to 98% complete - but then it fails when compiling opencv_annotation.

The reason for the failure is that CMake constructs the makefile in such a way that, just for this particular component, libz.a is placed as the last item on the list of linked libraries, and since the linker parses the list from left to right that means it can't find any of the IPP functions that zlib needs.

I've spent a great deal of time delving into the OpenCV CMake build suite and playing about with CMake options such as INTERFACE_LINK_LIBRARIES to try to force the library order to be what it should be, but so far nothing I've tried has worked. What am I missing?

edit retag flag offensive close merge delete

Comments

I've found a smoking gun; the offending package, opencv_annotation, uses IlmImf and the dependencies of this, which include zlib, are set before the block of code given above gets executed. I now need to chase down where within the main CMakeLists.txt file the IlmImf dependencies are set. I'll report back when I've done so.

Eos Pengwern gravatar imageEos Pengwern ( 2018-12-20 11:11:38 -0500 )edit