1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindDCMTK
6---------
7
8Find DICOM ToolKit (DCMTK) libraries and applications
9
10The module defines the following variables::
11
12 DCMTK_INCLUDE_DIRS  - Directories to include to use DCMTK
13 DCMTK_LIBRARIES     - Files to link against to use DCMTK
14 DCMTK_FOUND         - If false, don't try to use DCMTK
15 DCMTK_DIR           - (optional) Source directory for DCMTK
16
17Compatibility
18^^^^^^^^^^^^^
19
20This module is able to find a version of DCMTK that does or does not export
21a *DCMTKConfig.cmake* file. It applies a two step process:
22
23* Step 1:  Attempt to find DCMTK version providing a *DCMTKConfig.cmake* file.
24* Step 2:  If step 1 failed, rely on *FindDCMTK.cmake* to set `DCMTK_*` variables details below.
25
26
27`Recent DCMTK
28<http://git.dcmtk.org/web?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_
29provides a *DCMTKConfig.cmake* :manual:`package configuration file
30<cmake-packages(7)>`. To exclusively use the package configuration file
31(recommended when possible), pass the `NO_MODULE` option to
32:command:`find_package`. For example, `find_package(DCMTK NO_MODULE)`.
33This requires official DCMTK snapshot *3.6.1_20140617* or newer.
34
35
36Until all clients update to the more recent DCMTK, build systems will need
37to support different versions of DCMTK.
38
39On any given system, the following combinations of DCMTK versions could be
40considered:
41
42+--------+---------------------+-----------------------+-------------------+
43|        |   SYSTEM DCMTK      |      LOCAL DCMTK      |     Supported ?   |
44+--------+---------------------+-----------------------+-------------------+
45| Case A |   NA                |      [ ] DCMTKConfig  |         YES       |
46+--------+---------------------+-----------------------+-------------------+
47| Case B |   NA                |      [X] DCMTKConfig  |         YES       |
48+--------+---------------------+-----------------------+-------------------+
49| Case C |   [ ] DCMTKConfig   |      NA               |         YES       |
50+--------+---------------------+-----------------------+-------------------+
51| Case D |   [X] DCMTKConfig   |      NA               |         YES       |
52+--------+---------------------+-----------------------+-------------------+
53| Case E |   [ ] DCMTKConfig   |      [ ] DCMTKConfig  |         YES (*)   |
54+--------+---------------------+-----------------------+-------------------+
55| Case F |   [X] DCMTKConfig   |      [ ] DCMTKConfig  |         NO        |
56+--------+---------------------+-----------------------+-------------------+
57| Case G |   [ ] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
58+--------+---------------------+-----------------------+-------------------+
59| Case H |   [X] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
60+--------+---------------------+-----------------------+-------------------+
61
62 (*) See Troubleshooting section.
63
64Legend:
65
66  NA ...............: Means that no System or Local DCMTK is available
67
68  [ ] DCMTKConfig ..: Means that the version of DCMTK does NOT export a DCMTKConfig.cmake file.
69
70  [X] DCMTKConfig ..: Means that the version of DCMTK exports a DCMTKConfig.cmake file.
71
72
73Troubleshooting
74^^^^^^^^^^^^^^^
75
76What to do if my project finds a different version of DCMTK?
77
78Remove DCMTK entry from the CMake cache per :command:`find_package`
79documentation.
80#]=======================================================================]
81
82#
83# Written for VXL by Amitha Perera.
84# Upgraded for GDCM by Mathieu Malaterre.
85# Modified for EasyViz by Thomas Sondergaard.
86#
87
88set(_dcmtk_dir_description "The directory of DCMTK build or install tree.")
89
90# Ensure that DCMTK_DIR is set to a reasonable default value
91# so that DCMTK libraries can be found on a standard Unix distribution.
92# It also overwrite the value of DCMTK_DIR after this one has been
93# set by a successful discovery of DCMTK by the unpatched FindDCMTK.cmake module
94# distributed with CMake (as of 0167cea)
95if(NOT DCMTK_DIR OR DCMTK_DIR STREQUAL "/usr/include/dcmtk")
96  set(DCMTK_DIR "/usr" CACHE PATH ${_dcmtk_dir_description} FORCE)
97endif()
98
99set(_SAVED_DCMTK_DIR ${DCMTK_DIR})
100
101#
102# Step1: Attempt to find a version of DCMTK providing a DCMTKConfig.cmake file.
103#
104if(NOT DCMTK_FIND_QUIETLY)
105  message(CHECK_START "Trying to find DCMTK expecting DCMTKConfig.cmake")
106endif()
107find_package(DCMTK QUIET NO_MODULE)
108if(DCMTK_FOUND
109    AND NOT "x" STREQUAL "x${DCMTK_LIBRARIES}"
110    AND NOT "x" STREQUAL "x${DCMTK_INCLUDE_DIRS}")
111
112  if(NOT DCMTK_FIND_QUIETLY)
113    message(CHECK_PASS "ok")
114  endif()
115  return()
116else()
117  if(NOT DCMTK_FIND_QUIETLY)
118    message(CHECK_FAIL "failed")
119  endif()
120endif()
121
122if(NOT DCMTK_FIND_QUIETLY)
123  message(STATUS "Trying to find DCMTK relying on FindDCMTK.cmake")
124endif()
125
126# Restore the value reset by the previous call to 'find_package(DCMTK QUIET NO_MODULE)'
127set(DCMTK_DIR ${_SAVED_DCMTK_DIR} CACHE PATH ${_dcmtk_dir_description} FORCE)
128
129
130#
131# Step2: Attempt to find a version of DCMTK that does NOT provide a DCMTKConfig.cmake file.
132#
133
134# prefer DCMTK_DIR over default system paths like /usr/lib
135if(DCMTK_DIR)
136  set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH
137endif()
138
139# Find all libraries, store debug and release separately
140foreach(lib
141    dcmpstat
142    dcmsr
143    dcmsign
144    dcmtls
145    dcmqrdb
146    dcmnet
147    dcmjpeg
148    dcmimage
149    dcmimgle
150    dcmdata
151    oflog
152    ofstd
153    ijg12
154    ijg16
155    ijg8
156    )
157
158  # Find Release libraries
159  find_library(DCMTK_${lib}_LIBRARY_RELEASE
160    ${lib}
161    PATHS
162    ${DCMTK_DIR}/${lib}/libsrc
163    ${DCMTK_DIR}/${lib}/libsrc/Release
164    ${DCMTK_DIR}/${lib}/Release
165    ${DCMTK_DIR}/lib
166    ${DCMTK_DIR}/lib/Release
167    ${DCMTK_DIR}/dcmjpeg/lib${lib}/Release
168    NO_DEFAULT_PATH
169    )
170
171  # Find Debug libraries
172  find_library(DCMTK_${lib}_LIBRARY_DEBUG
173    ${lib}${DCMTK_CMAKE_DEBUG_POSTFIX}
174    PATHS
175    ${DCMTK_DIR}/${lib}/libsrc
176    ${DCMTK_DIR}/${lib}/libsrc/Debug
177    ${DCMTK_DIR}/${lib}/Debug
178    ${DCMTK_DIR}/lib
179    ${DCMTK_DIR}/lib/Debug
180    ${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug
181    NO_DEFAULT_PATH
182    )
183
184  mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE)
185  mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG)
186
187  # Add libraries to variable according to build type
188  if(DCMTK_${lib}_LIBRARY_RELEASE)
189    list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE})
190  endif()
191
192  if(DCMTK_${lib}_LIBRARY_DEBUG)
193    list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG})
194  endif()
195
196endforeach()
197
198set(CMAKE_THREAD_LIBS_INIT)
199if(DCMTK_oflog_LIBRARY_RELEASE OR DCMTK_oflog_LIBRARY_DEBUG)
200  # Hack - Not having a DCMTKConfig.cmake file to read the settings from, we will attempt to
201  # find the library in all cases.
202  # Ideally, pthread library should be discovered only if DCMTK_WITH_THREADS is enabled.
203  find_package(Threads)
204endif()
205
206if(CMAKE_THREAD_LIBS_INIT)
207  list(APPEND DCMTK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
208endif()
209
210#
211# SPECIFIC CASE FOR DCMTK BUILD DIR as DCMTK_DIR
212# (as opposed to a DCMTK install dir)
213# Have to find the source directory.
214if(EXISTS ${DCMTK_DIR}/CMakeCache.txt)
215          load_cache(${DCMTK_DIR} READ_WITH_PREFIX "EXT"
216          DCMTK_SOURCE_DIR)
217  if(NOT EXISTS ${EXTDCMTK_SOURCE_DIR})
218    message(FATAL_ERROR
219      "DCMTK build directory references
220nonexistent DCMTK source directory ${EXTDCMTK_SOURCE_DIR}")
221  endif()
222endif()
223
224set(DCMTK_config_TEST_HEADER osconfig.h)
225set(DCMTK_dcmdata_TEST_HEADER dctypes.h)
226set(DCMTK_dcmimage_TEST_HEADER dicoimg.h)
227set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h)
228set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h)
229set(DCMTK_dcmnet_TEST_HEADER assoc.h)
230set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h)
231set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h)
232set(DCMTK_dcmsign_TEST_HEADER sicert.h)
233set(DCMTK_dcmsr_TEST_HEADER dsrtree.h)
234set(DCMTK_dcmtls_TEST_HEADER tlslayer.h)
235set(DCMTK_ofstd_TEST_HEADER ofstdinc.h)
236set(DCMTK_oflog_TEST_HEADER oflog.h)
237set(DCMTK_dcmjpls_TEST_HEADER djlsutil.h)
238
239set(DCMTK_INCLUDE_DIR_NAMES)
240
241foreach(dir
242    config
243    dcmdata
244    dcmimage
245    dcmimgle
246    dcmjpeg
247    dcmjpls
248    dcmnet
249    dcmpstat
250    dcmqrdb
251    dcmsign
252    dcmsr
253    dcmtls
254    ofstd
255    oflog)
256  if(EXTDCMTK_SOURCE_DIR)
257    set(SOURCE_DIR_PATH
258      ${EXTDCMTK_SOURCE_DIR}/${dir}/include/dcmtk/${dir})
259  endif()
260  find_path(DCMTK_${dir}_INCLUDE_DIR
261    ${DCMTK_${dir}_TEST_HEADER}
262    PATHS
263    ${DCMTK_DIR}/${dir}/include
264    ${DCMTK_DIR}/${dir}
265    ${DCMTK_DIR}/include/dcmtk/${dir}
266    ${DCMTK_DIR}/${dir}/include/dcmtk/${dir}
267    ${DCMTK_DIR}/include/${dir}
268    ${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    # add the 'include' path so eg
275    #include "dcmtk/dcmimgle/dcmimage.h"
276    # works
277    get_filename_component(_include ${DCMTK_${dir}_INCLUDE_DIR} PATH)
278    get_filename_component(_include ${_include} PATH)
279    list(APPEND
280      DCMTK_INCLUDE_DIRS
281      ${DCMTK_${dir}_INCLUDE_DIR}
282      ${_include})
283  endif()
284endforeach()
285
286list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_DIR}/include)
287
288if(WIN32)
289  list(APPEND DCMTK_LIBRARIES netapi32 wsock32)
290endif()
291
292if(DCMTK_ofstd_INCLUDE_DIR)
293  get_filename_component(DCMTK_dcmtk_INCLUDE_DIR
294    ${DCMTK_ofstd_INCLUDE_DIR}
295    PATH
296    CACHE)
297  list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_INCLUDE_DIR})
298  mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR)
299endif()
300
301# Compatibility: This variable is deprecated
302set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS})
303
304include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
305find_package_handle_standard_args(DCMTK
306  REQUIRED_VARS ${DCMTK_INCLUDE_DIR_NAMES} DCMTK_LIBRARIES
307  FAIL_MESSAGE "Please set DCMTK_DIR and re-run configure")
308
309# Workaround bug in packaging of DCMTK 3.6.0 on Debian.
310# See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637687
311if(DCMTK_FOUND AND UNIX AND NOT APPLE)
312  include(${CMAKE_CURRENT_LIST_DIR}/CheckIncludeFiles.cmake)
313  set(CMAKE_REQUIRED_FLAGS )
314  set(CMAKE_REQUIRED_DEFINITIONS )
315  set(CMAKE_REQUIRED_INCLUDES ${DCMTK_INCLUDE_DIRS})
316  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  if(NOT DCMTK_HAVE_CONFIG_H_OPTIONAL)
320    set(DCMTK_DEFINITIONS "HAVE_CONFIG_H")
321  endif()
322endif()
323