1#
2# The script to detect Intel(R) Integrated Performance Primitives (IPP)
3# installation/package
4#
5# By default, ICV version will be used.
6# To use standalone IPP update cmake command line:
7# cmake ... -DIPPROOT=<path> ...
8#
9# Note: Backward compatibility is broken, IPPROOT environment path is ignored
10#
11#
12# On return this will define:
13#
14# HAVE_IPP          - True if Intel IPP found
15# HAVE_IPP_ICV_ONLY - True if Intel IPP ICV version is available
16# IPP_ROOT_DIR      - root of IPP installation
17# IPP_INCLUDE_DIRS  - IPP include folder
18# IPP_LIBRARIES     - IPP libraries that are used by OpenCV
19# IPP_VERSION_STR   - string with the newest detected IPP version
20# IPP_VERSION_MAJOR - numbers of IPP version (MAJOR.MINOR.BUILD)
21# IPP_VERSION_MINOR
22# IPP_VERSION_BUILD
23#
24# Created: 30 Dec 2010 by Vladimir Dudnik (vladimir.dudnik@intel.com)
25#
26
27unset(HAVE_IPP CACHE)
28unset(HAVE_IPP_ICV_ONLY)
29unset(IPP_ROOT_DIR)
30unset(IPP_INCLUDE_DIRS)
31unset(IPP_LIBRARIES)
32unset(IPP_VERSION_STR)
33unset(IPP_VERSION_MAJOR)
34unset(IPP_VERSION_MINOR)
35unset(IPP_VERSION_BUILD)
36
37if (X86 AND UNIX AND NOT APPLE AND NOT ANDROID AND BUILD_SHARED_LIBS)
38    message(STATUS "On 32-bit Linux IPP can not currently be used with dynamic libs because of linker errors. Set BUILD_SHARED_LIBS=OFF")
39    return()
40endif()
41
42set(IPP_X64 0)
43if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
44    set(IPP_X64 1)
45endif()
46if(CMAKE_CL_64)
47    set(IPP_X64 1)
48endif()
49
50# This function detects IPP version by analyzing .h file
51macro(ipp_get_version VERSION_FILE)
52  unset(_VERSION_STR)
53  unset(_MAJOR)
54  unset(_MINOR)
55  unset(_BUILD)
56
57  # read IPP version info from file
58  file(STRINGS ${VERSION_FILE} STR1 REGEX "IPP_VERSION_MAJOR")
59  file(STRINGS ${VERSION_FILE} STR2 REGEX "IPP_VERSION_MINOR")
60  file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_BUILD")
61  if("${STR3}" STREQUAL "")
62    file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_UPDATE")
63  endif()
64  file(STRINGS ${VERSION_FILE} STR4 REGEX "IPP_VERSION_STR")
65
66  # extract info and assign to variables
67  string(REGEX MATCHALL "[0-9]+" _MAJOR ${STR1})
68  string(REGEX MATCHALL "[0-9]+" _MINOR ${STR2})
69  string(REGEX MATCHALL "[0-9]+" _BUILD ${STR3})
70  string(REGEX MATCHALL "[0-9]+[.]+[0-9]+[^\"]+|[0-9]+[.]+[0-9]+" _VERSION_STR ${STR4})
71
72  # export info to parent scope
73  set(IPP_VERSION_STR   ${_VERSION_STR})
74  set(IPP_VERSION_MAJOR ${_MAJOR})
75  set(IPP_VERSION_MINOR ${_MINOR})
76  set(IPP_VERSION_BUILD ${_BUILD})
77endmacro()
78
79macro(_ipp_not_supported)
80  message(STATUS ${ARGN})
81  unset(HAVE_IPP)
82  unset(HAVE_IPP_ICV_ONLY)
83  unset(IPP_VERSION_STR)
84  return()
85endmacro()
86
87# This macro uses IPP_ROOT_DIR variable
88# TODO Cleanup code after ICV package stabilization
89macro(ipp_detect_version)
90  set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include)
91
92  set(__msg)
93  if(EXISTS ${IPP_ROOT_DIR}/include/ippicv_redefs.h)
94    set(__msg " (ICV version)")
95    set(HAVE_IPP_ICV_ONLY 1)
96  elseif(EXISTS ${IPP_ROOT_DIR}/include/ipp.h)
97    # nothing
98  else()
99    _ipp_not_supported("Can't resolve IPP directory: ${IPP_ROOT_DIR}")
100  endif()
101
102  ipp_get_version(${IPP_INCLUDE_DIRS}/ippversion.h)
103  ocv_assert(IPP_VERSION_STR VERSION_GREATER "1.0")
104
105  message(STATUS "found IPP${__msg}: ${_MAJOR}.${_MINOR}.${_BUILD} [${IPP_VERSION_STR}]")
106  message(STATUS "at: ${IPP_ROOT_DIR}")
107
108  if(${IPP_VERSION_STR} VERSION_LESS "7.0")
109    _ipp_not_supported("IPP ${IPP_VERSION_STR} is not supported")
110  endif()
111
112  set(HAVE_IPP 1)
113
114  macro(_ipp_set_library_dir DIR)
115    if(NOT EXISTS ${DIR})
116      _ipp_not_supported("IPP library directory not found")
117    endif()
118    set(IPP_LIBRARY_DIR ${DIR})
119  endmacro()
120
121  if(APPLE)
122    _ipp_set_library_dir(${IPP_ROOT_DIR}/lib)
123  elseif(IPP_X64)
124    _ipp_set_library_dir(${IPP_ROOT_DIR}/lib/intel64)
125  else()
126    _ipp_set_library_dir(${IPP_ROOT_DIR}/lib/ia32)
127  endif()
128
129  macro(_ipp_add_library name)
130    # dynamic linking is only supported for standalone version of IPP
131    if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
132      set(IPP_LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
133      set(IPP_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
134    else ()
135      set(IPP_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
136      set(IPP_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
137    endif ()
138    if (EXISTS ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
139      if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
140        # When using dynamic libraries from standalone IPP it is your responsibility to install those on the target system
141        list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
142      else ()
143        add_library(ipp${name} STATIC IMPORTED)
144        set_target_properties(ipp${name} PROPERTIES
145          IMPORTED_LINK_INTERFACE_LIBRARIES ""
146          IMPORTED_LOCATION ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
147        )
148        list(APPEND IPP_LIBRARIES ipp${name})
149        # CMake doesn't support "install(TARGETS ${IPP_PREFIX}${name} " command with imported targets
150        install(FILES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
151                DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
152        string(TOUPPER ${name} uname)
153        set(IPP${uname}_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_3P_LIB_INSTALL_PATH}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}" CACHE INTERNAL "" FORCE)
154        set(IPP${uname}_LOCATION_PATH "${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}" CACHE INTERNAL "" FORCE)
155      endif()
156    else()
157      message(STATUS "Can't find IPP library: ${name} at ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}")
158    endif()
159  endmacro()
160
161  set(IPP_PREFIX "ipp")
162  if(${IPP_VERSION_STR} VERSION_LESS "8.0")
163    if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
164      set(IPP_SUFFIX "")      # dynamic not threaded libs suffix IPP 7.x
165    else ()
166      set(IPP_SUFFIX "_l")    # static not threaded libs suffix IPP 7.x
167    endif ()
168  else ()
169    if(WIN32)
170      if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
171        set(IPP_SUFFIX "")    # dynamic not threaded libs suffix IPP 8.x for Windows
172      else ()
173        set(IPP_SUFFIX "mt")  # static not threaded libs suffix IPP 8.x for Windows
174      endif ()
175    else()
176      set(IPP_SUFFIX "")      # static not threaded libs suffix IPP 8.x for Linux/OS X
177    endif()
178  endif()
179
180  if(HAVE_IPP_ICV_ONLY)
181    _ipp_add_library(icv)
182  else()
183    _ipp_add_library(core)
184    _ipp_add_library(s)
185    _ipp_add_library(i)
186    _ipp_add_library(cc)
187    _ipp_add_library(cv)
188    _ipp_add_library(vm)
189    _ipp_add_library(m)
190
191    if(UNIX)
192      get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH)
193      if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
194        get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../compiler/lib REALPATH)
195      endif()
196      if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
197        _ipp_not_supported("IPP configuration error: can't find Intel compiler library dir ${INTEL_COMPILER_LIBRARY_DIR}")
198      endif()
199      if(NOT APPLE)
200        if(IPP_X64)
201          if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
202            message(SEND_ERROR "Intel compiler EM64T libraries not found")
203          endif()
204          set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
205        else()
206          if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
207            message(SEND_ERROR "Intel compiler IA32 libraries not found")
208          endif()
209          set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
210        endif()
211      endif()
212
213      macro(_ipp_add_compiler_library name)
214        if (EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
215          list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
216        else()
217          message(STATUS "Can't find compiler library: ${name} at ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
218        endif()
219      endmacro()
220
221      _ipp_add_compiler_library(irc)
222      _ipp_add_compiler_library(imf)
223      _ipp_add_compiler_library(svml)
224    endif(UNIX)
225  endif()
226
227  #message(STATUS "IPP libs: ${IPP_LIBRARIES}")
228endmacro()
229
230# OPENCV_IPP_PATH is an environment variable for internal usage only, do not use it
231if(DEFINED ENV{OPENCV_IPP_PATH} AND NOT DEFINED IPPROOT)
232  set(IPPROOT "$ENV{OPENCV_IPP_PATH}")
233endif()
234if(NOT DEFINED IPPROOT)
235  include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/downloader.cmake")
236  if(DEFINED OPENCV_ICV_PATH)
237    set(IPPROOT "${OPENCV_ICV_PATH}")
238  else()
239    return()
240  endif()
241endif()
242
243file(TO_CMAKE_PATH "${IPPROOT}" __IPPROOT)
244if(EXISTS "${__IPPROOT}/include/ippversion.h")
245  set(IPP_ROOT_DIR ${__IPPROOT})
246  ipp_detect_version()
247endif()
248
249
250if(WIN32 AND MINGW AND NOT IPP_VERSION_MAJOR LESS 7)
251    # Since IPP built with Microsoft compiler and /GS option
252    # ======================================================
253    # From Windows SDK 7.1
254    #   (usually in "C:\Program Files\Microsoft Visual Studio 10.0\VC\lib"),
255    # to avoid undefined reference to __security_cookie and _chkstk:
256    set(MSV_RUNTMCHK "RunTmChk")
257    set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_RUNTMCHK}${IPP_LIB_SUFFIX})
258
259    # To avoid undefined reference to _alldiv and _chkstk
260    # ===================================================
261    # NB: it may require a recompilation of w32api (after having modified
262    #     the file ntdll.def) to export the required functions
263    #     See http://code.opencv.org/issues/1906 for additional details
264    set(MSV_NTDLL    "ntdll")
265    set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_NTDLL}${IPP_LIB_SUFFIX})
266endif()
267