FindDCMTK.cmake 10.3 KB
Newer Older
1 2 3
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

4 5 6 7
#[=======================================================================[.rst:
FindDCMTK
---------

8
Find DICOM ToolKit (DCMTK) libraries and applications
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

The module defines the following variables::

 DCMTK_INCLUDE_DIRS  - Directories to include to use DCMTK
 DCMTK_LIBRARIES     - Files to link against to use DCMTK
 DCMTK_FOUND         - If false, don't try to use DCMTK
 DCMTK_DIR           - (optional) Source directory for DCMTK

Compatibility
^^^^^^^^^^^^^

This module is able to find a version of DCMTK that does or does not export
a *DCMTKConfig.cmake* file. It applies a two step process:

* Step 1:  Attempt to find DCMTK version providing a *DCMTKConfig.cmake* file.
* Step 2:  If step 1 failed, rely on *FindDCMTK.cmake* to set `DCMTK_*` variables details below.


`Recent DCMTK
<http://git.dcmtk.org/web?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_
provides a *DCMTKConfig.cmake* :manual:`package configuration file
<cmake-packages(7)>`. To exclusively use the package configuration file
(recommended when possible), pass the `NO_MODULE` option to
:command:`find_package`. For example, `find_package(DCMTK NO_MODULE)`.
This requires official DCMTK snapshot *3.6.1_20140617* or newer.


Until all clients update to the more recent DCMTK, build systems will need
to support different versions of DCMTK.

On any given system, the following combinations of DCMTK versions could be
considered:

+--------+---------------------+-----------------------+-------------------+
|        |   SYSTEM DCMTK      |      LOCAL DCMTK      |     Supported ?   |
+--------+---------------------+-----------------------+-------------------+
| Case A |   NA                |      [ ] DCMTKConfig  |         YES       |
+--------+---------------------+-----------------------+-------------------+
| Case B |   NA                |      [X] DCMTKConfig  |         YES       |
+--------+---------------------+-----------------------+-------------------+
| Case C |   [ ] DCMTKConfig   |      NA               |         YES       |
+--------+---------------------+-----------------------+-------------------+
| Case D |   [X] DCMTKConfig   |      NA               |         YES       |
+--------+---------------------+-----------------------+-------------------+
| Case E |   [ ] DCMTKConfig   |      [ ] DCMTKConfig  |         YES (*)   |
+--------+---------------------+-----------------------+-------------------+
| Case F |   [X] DCMTKConfig   |      [ ] DCMTKConfig  |         NO        |
+--------+---------------------+-----------------------+-------------------+
| Case G |   [ ] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
+--------+---------------------+-----------------------+-------------------+
| Case H |   [X] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
+--------+---------------------+-----------------------+-------------------+

 (*) See Troubleshooting section.

Legend:

  NA ...............: Means that no System or Local DCMTK is available

  [ ] DCMTKConfig ..: Means that the version of DCMTK does NOT export a DCMTKConfig.cmake file.

  [X] DCMTKConfig ..: Means that the version of DCMTK exports a DCMTKConfig.cmake file.


Troubleshooting
^^^^^^^^^^^^^^^

What to do if my project finds a different version of DCMTK?

Remove DCMTK entry from the CMake cache per :command:`find_package`
documentation.
#]=======================================================================]
81

82 83
#
# Written for VXL by Amitha Perera.
84
# Upgraded for GDCM by Mathieu Malaterre.
85 86 87
# Modified for EasyViz by Thomas Sondergaard.
#

88 89 90 91 92 93 94 95 96
set(_dcmtk_dir_description "The directory of DCMTK build or install tree.")

# Ensure that DCMTK_DIR is set to a reasonable default value
# so that DCMTK libraries can be found on a standard Unix distribution.
# It also overwrite the value of DCMTK_DIR after this one has been
# set by a successful discovery of DCMTK by the unpatched FindDCMTK.cmake module
# distributed with CMake (as of 0167cea)
if(NOT DCMTK_DIR OR DCMTK_DIR STREQUAL "/usr/include/dcmtk")
  set(DCMTK_DIR "/usr" CACHE PATH ${_dcmtk_dir_description} FORCE)
97 98
endif()

99
set(_SAVED_DCMTK_DIR ${DCMTK_DIR})
100

101 102 103
#
# Step1: Attempt to find a version of DCMTK providing a DCMTKConfig.cmake file.
#
104 105 106
if(NOT DCMTK_FIND_QUIETLY)
  message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake")
endif()
107 108 109 110
find_package(DCMTK QUIET NO_MODULE)
if(DCMTK_FOUND
    AND NOT "x" STREQUAL "x${DCMTK_LIBRARIES}"
    AND NOT "x" STREQUAL "x${DCMTK_INCLUDE_DIRS}")
111 112 113 114

  if(NOT DCMTK_FIND_QUIETLY)
    message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - ok")
  endif()
115 116
  return()
else()
117 118 119
  if(NOT DCMTK_FIND_QUIETLY)
    message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - failed")
  endif()
120 121
endif()

122 123 124
if(NOT DCMTK_FIND_QUIETLY)
  message(STATUS "Trying to find DCMTK relying on FindDCMTK.cmake")
endif()
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

# Restore the value reset by the previous call to 'find_package(DCMTK QUIET NO_MODULE)'
set(DCMTK_DIR ${_SAVED_DCMTK_DIR} CACHE PATH ${_dcmtk_dir_description} FORCE)


#
# Step2: Attempt to find a version of DCMTK that does NOT provide a DCMTKConfig.cmake file.
#

# prefer DCMTK_DIR over default system paths like /usr/lib
if(DCMTK_DIR)
  set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH
endif()

# Find all libraries, store debug and release separately
140 141 142
foreach(lib
    dcmpstat
    dcmsr
143
    dcmsign
144
    dcmtls
145 146 147 148 149 150 151 152
    dcmqrdb
    dcmnet
    dcmjpeg
    dcmimage
    dcmimgle
    dcmdata
    oflog
    ofstd
153 154 155
    ijg12
    ijg16
    ijg8
156
    )
157

158 159
  # Find Release libraries
  find_library(DCMTK_${lib}_LIBRARY_RELEASE
160 161 162 163 164
    ${lib}
    PATHS
    ${DCMTK_DIR}/${lib}/libsrc
    ${DCMTK_DIR}/${lib}/libsrc/Release
    ${DCMTK_DIR}/${lib}/Release
165 166 167 168 169 170 171 172 173 174 175 176
    ${DCMTK_DIR}/lib
    ${DCMTK_DIR}/lib/Release
    ${DCMTK_DIR}/dcmjpeg/lib${lib}/Release
    NO_DEFAULT_PATH
    )

  # Find Debug libraries
  find_library(DCMTK_${lib}_LIBRARY_DEBUG
    ${lib}${DCMTK_CMAKE_DEBUG_POSTFIX}
    PATHS
    ${DCMTK_DIR}/${lib}/libsrc
    ${DCMTK_DIR}/${lib}/libsrc/Debug
177
    ${DCMTK_DIR}/${lib}/Debug
178 179 180 181 182 183 184 185
    ${DCMTK_DIR}/lib
    ${DCMTK_DIR}/lib/Debug
    ${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug
    NO_DEFAULT_PATH
    )

  mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE)
  mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG)
186

187 188 189 190
  # Add libraries to variable according to build type
  if(DCMTK_${lib}_LIBRARY_RELEASE)
    list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE})
  endif()
191

192 193
  if(DCMTK_${lib}_LIBRARY_DEBUG)
    list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG})
194 195 196 197
  endif()

endforeach()

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
set(CMAKE_THREAD_LIBS_INIT)
if(DCMTK_oflog_LIBRARY_RELEASE OR DCMTK_oflog_LIBRARY_DEBUG)
  # Hack - Not having a DCMTKConfig.cmake file to read the settings from, we will attempt to
  # find the library in all cases.
  # Ideally, pthread library should be discovered only if DCMTK_WITH_THREADS is enabled.
  find_package(Threads)
endif()

if(CMAKE_THREAD_LIBS_INIT)
  list(APPEND DCMTK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()

#
# SPECIFIC CASE FOR DCMTK BUILD DIR as DCMTK_DIR
# (as opposed to a DCMTK install dir)
# Have to find the source directory.
if(EXISTS ${DCMTK_DIR}/CMakeCache.txt)
          load_cache(${DCMTK_DIR} READ_WITH_PREFIX "EXT"
          DCMTK_SOURCE_DIR)
  if(NOT EXISTS ${EXTDCMTK_SOURCE_DIR})
    message(FATAL_ERROR
      "DCMTK build directory references
luz.paz's avatar
luz.paz committed
220
nonexistent DCMTK source directory ${EXTDCMTK_SOURCE_DIR}")
221 222
  endif()
endif()
223 224 225 226 227 228 229 230 231 232 233 234 235

set(DCMTK_config_TEST_HEADER osconfig.h)
set(DCMTK_dcmdata_TEST_HEADER dctypes.h)
set(DCMTK_dcmimage_TEST_HEADER dicoimg.h)
set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h)
set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h)
set(DCMTK_dcmnet_TEST_HEADER assoc.h)
set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h)
set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h)
set(DCMTK_dcmsign_TEST_HEADER sicert.h)
set(DCMTK_dcmsr_TEST_HEADER dsrtree.h)
set(DCMTK_dcmtls_TEST_HEADER tlslayer.h)
set(DCMTK_ofstd_TEST_HEADER ofstdinc.h)
236 237 238 239
set(DCMTK_oflog_TEST_HEADER oflog.h)
set(DCMTK_dcmjpls_TEST_HEADER djlsutil.h)

set(DCMTK_INCLUDE_DIR_NAMES)
240 241 242 243 244 245 246

foreach(dir
    config
    dcmdata
    dcmimage
    dcmimgle
    dcmjpeg
247
    dcmjpls
248 249 250 251 252 253
    dcmnet
    dcmpstat
    dcmqrdb
    dcmsign
    dcmsr
    dcmtls
254 255 256 257 258 259
    ofstd
    oflog)
  if(EXTDCMTK_SOURCE_DIR)
    set(SOURCE_DIR_PATH
      ${EXTDCMTK_SOURCE_DIR}/${dir}/include/dcmtk/${dir})
  endif()
260 261 262 263 264
  find_path(DCMTK_${dir}_INCLUDE_DIR
    ${DCMTK_${dir}_TEST_HEADER}
    PATHS
    ${DCMTK_DIR}/${dir}/include
    ${DCMTK_DIR}/${dir}
265 266
    ${DCMTK_DIR}/include/dcmtk/${dir}
    ${DCMTK_DIR}/${dir}/include/dcmtk/${dir}
267 268
    ${DCMTK_DIR}/include/${dir}
    ${SOURCE_DIR_PATH}
269
    )
270
  mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR)
271
  list(APPEND DCMTK_INCLUDE_DIR_NAMES DCMTK_${dir}_INCLUDE_DIR)
272 273

  if(DCMTK_${dir}_INCLUDE_DIR)
274 275 276 277 278
    # add the 'include' path so eg
    #include "dcmtk/dcmimgle/dcmimage.h"
    # works
    get_filename_component(_include ${DCMTK_${dir}_INCLUDE_DIR} PATH)
    get_filename_component(_include ${_include} PATH)
279 280
    list(APPEND
      DCMTK_INCLUDE_DIRS
281 282
      ${DCMTK_${dir}_INCLUDE_DIR}
      ${_include})
283 284 285
  endif()
endforeach()

286 287
list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_DIR}/include)

288 289 290 291 292 293
if(WIN32)
  list(APPEND DCMTK_LIBRARIES netapi32 wsock32)
endif()

if(DCMTK_ofstd_INCLUDE_DIR)
  get_filename_component(DCMTK_dcmtk_INCLUDE_DIR
294
    ${DCMTK_ofstd_INCLUDE_DIR}
295 296 297 298 299 300 301 302
    PATH
    CACHE)
  list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_INCLUDE_DIR})
  mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR)
endif()

# Compatibility: This variable is deprecated
set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS})
303

304
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
305 306 307 308 309 310 311
find_package_handle_standard_args(DCMTK
  REQUIRED_VARS ${DCMTK_INCLUDE_DIR_NAMES} DCMTK_LIBRARIES
  FAIL_MESSAGE "Please set DCMTK_DIR and re-run configure")

# Workaround bug in packaging of DCMTK 3.6.0 on Debian.
# See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637687
if(DCMTK_FOUND AND UNIX AND NOT APPLE)
312
  include(${CMAKE_CURRENT_LIST_DIR}/CheckIncludeFiles.cmake)
313 314 315 316
  set(CMAKE_REQUIRED_FLAGS )
  set(CMAKE_REQUIRED_DEFINITIONS )
  set(CMAKE_REQUIRED_INCLUDES ${DCMTK_INCLUDE_DIRS})
  set(CMAKE_REQUIRED_LIBRARIES ${DCMTK_LIBRARIES})
317
  set(CMAKE_REQUIRED_QUIET ${DCMTK_FIND_QUIETLY})
318
  check_include_files("dcmtk/config/osconfig.h;dcmtk/ofstd/ofstream.h" DCMTK_HAVE_CONFIG_H_OPTIONAL LANGUAGE CXX)
319 320 321 322
  if(NOT DCMTK_HAVE_CONFIG_H_OPTIONAL)
    set(DCMTK_DEFINITIONS "HAVE_CONFIG_H")
  endif()
endif()