# Building in Linux using IPP-enhanced Zlib

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)

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)

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 close merge delete