CamiTKMacros.cmake 43.7 KB
Newer Older
1
2
3
4
5
6
7
8
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
#
# CamiTK Macros
#


# MACRO get_subdirectories 
#
# usage:
# get_subdirectories(Name)
#
# get the names of all the subdirectories that contains a CMakeLists.txt
macro(get_subdirectories Name)
  set(Name)
  file(GLOB LS *)
  foreach(FILENAME ${LS})
    if(IS_DIRECTORY ${FILENAME} AND EXISTS ${FILENAME}/CMakeLists.txt)
      get_directory_name(${FILENAME} DIRNAME)
      # ignore .svn
      if (NOT ${DIRNAME} STREQUAL ".svn")
          set(${Name} ${${Name}} ${DIRNAME})
      endif()
    endif()
  endforeach()
endmacro()

# MACRO gather_headers_and_sources 
#
# usage:
# gather_headers_and_sources(Name [BaseDirectory])
#
# find all headers, sources, including the qt ui, moc and resources
# and create two variables from it: ${Name}_HEADERS ${Name}_SOURCES, and define all needed commands for qt
# if BaseDirectory is specified, the glob recurse starts in directory DIR
34

35
36
37
38
macro(gather_headers_and_sources Name)
  # gather all possible C++ and Qt sources
  if (${ARGC} EQUAL 1)
    file(GLOB_RECURSE HEADERS *.h)
39
    file(GLOB_RECURSE SRCS *.cpp *.c)
40
41
42
43
44
    file(GLOB_RECURSE File_UI *.ui)
    file(GLOB_RECURSE File_QRC *.qrc)
  else()
    # if an optional parameter is used, gather everything from BaseDirectory
    file(GLOB_RECURSE HEADERS ${ARGV1}/*.h )
45
    file(GLOB_RECURSE SRCS ${ARGV1}/*.cpp *.c)
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
81
    file(GLOB_RECURSE File_UI ${ARGV1}/*.ui )
    file(GLOB_RECURSE File_QRC ${ARGV1}/*.qrc )
  endif()

  # manage Qt ui
  qt4_wrap_ui (UI ${File_UI})
  
  # manage Qt resources
  qt4_add_resources(QRC ${File_QRC})

  # find Q_OBJECT derived class
  foreach(HEADER ${HEADERS})
    file(READ ${HEADER} stream)
    if(stream MATCHES "Q_OBJECT")
      set(MOC_SOURCES ${MOC_SOURCES} ${HEADER})
    endif(stream MATCHES "Q_OBJECT")
  endforeach(HEADER)

  # manage Qt inherited sources
  qt4_wrap_cpp(QT_SRCS ${MOC_SOURCES})

  # name all headers
  set (${Name}_HEADERS
      ${HEADERS}
      ${UI}
      ${QRC}
  )

  # name all sources
  set (${Name}_SOURCES
      ${HEADERS}
      ${UI}
      ${QRC}
      ${SRCS}
      ${QT_SRCS}
  )
82
endmacro()
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

# MACRO parse_arguments
#
# usage, see: http://www.cmake.org/Wiki/CMakeMacroParseArguments
macro(parse_arguments prefix arg_names option_names)
  set(DEFAULT_ARGS)
  foreach(arg_name ${arg_names})    
    set(${prefix}_${arg_name})
  endforeach()
  foreach(option ${option_names})
    set(${prefix}_${option} FALSE)
  endforeach()

  set(current_arg_name DEFAULT_ARGS)
  set(current_arg_list)
  foreach(arg ${ARGN})            
    set(larg_names ${arg_names})    
    list(FIND larg_names "${arg}" is_arg_name)                   
    if (is_arg_name GREATER -1)
      set(${prefix}_${current_arg_name} ${current_arg_list})
      set(current_arg_name ${arg})
      set(current_arg_list)
    else()
      set(loption_names ${option_names})    
      list(FIND loption_names "${arg}" is_option)            
      if (is_option GREATER -1)
       set(${prefix}_${arg} TRUE)
      else()
       set(current_arg_list ${current_arg_list} ${arg})
      endif()
    endif()
  endforeach()
  set(${prefix}_${current_arg_name} ${current_arg_list})
endmacro()

# MACRO get_directory_name
#
# usage:
# directory_name(FullPathDirectory VariableName)
#
# set the variable VariableName to the name of the last directory of FullPathDirectory
# set the variable VariableName_CMAKE to be the same but in uppercase
125

126
127
128
129
130
131
132
macro(get_directory_name FullPathDirectory VariableName)
  string (REGEX REPLACE ".*/([^/]*)$" "\\1" ${VariableName} ${FullPathDirectory})

  # set the variable name to uppercase
  string(TOUPPER ${${VariableName}} ${VariableName}_CMAKE)  
endmacro()

133
# MACRO export_headers
134
#
135
136
137
138
139
# Duplicate headers installation:
# - one is used at compiled time and puts everything in 
#   ${CAMITK_BUILD_DIR}/include/${GroupName}/${ComponentName}/${SubdirName} 
# - the other one is used at installation time and puts everything in 
#   ${CAMITK_INSTALL_ROOT}/include/${GroupName}/${ComponentName}/${SubdirName}
140
#
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# usage:
# export_headers(HeaderFile1.h HeaderFile2.h ...
#                COMPONENT ComponentName
#                [GROUP GroupName]
#                [SUBDIRECTORY SubdirName]
# )
# 
# FILES        = list of files to install
# COMPONENT    = name of the component to use. This is also the include subdirectory name
#                used for copying the file
# GROUP        = the name of the group this install should be using group will be
#                prepend to the component name.
# SUBDIRECTORY = optional subdirectory to use in ${CAMITK_INCLUDE_DIR}/include/${ComponentName}
macro(export_headers)
155

156
157
158
  parse_arguments(EXPORT_HEADER 
    "COMPONENT;SUBDIRECTORY;GROUP"  # possible lists
    "" # possible options
159
160
161
    ${ARGN}
  )

162
163
164
165
166
167
168
169
170
171
172
173
174
  # special case for components: remove prefix for the destination directory
  string(REGEX REPLACE "^component-|^action-" "" EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_COMPONENT})
  
  # Check group
  if(EXPORT_HEADER_GROUP)
    # check directory
    if (NOT EXISTS ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_GROUP})
      add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                        POST_BUILD
                        COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}
                        COMMENT "Creating build-time group include dir ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}"
                        VERBATIM
      )
175
    endif()
176
177
    set(EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_GROUP}/${EXPORT_HEADER_DESTINATION})
  endif()
178

179
180
181
182
183
184
185
  # check that the directory exists otherwise create it
  if (NOT EXISTS ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION})
    add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                      POST_BUILD
                      COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}
                      COMMENT "Creating build-time include dir ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}"
                      VERBATIM
186
    )
187
188
189
190
191
192
193
194
  endif()
  
  # check the SUBDIRECTORY parameter
  if(EXPORT_HEADER_SUBDIRECTORY)
    set(EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_DESTINATION}/${EXPORT_HEADER_SUBDIRECTORY})
    # create subdirectory if it does not exists
    if (NOT EXISTS ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION})
      add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
195
                        POST_BUILD
196
197
                        COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}
                        COMMENT "Creating build-time include subdir ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}"
198
199
200
201
                        VERBATIM
      )
    endif()
  endif()
202
  
203

204
205
206
207
208
209
210
211
212
213
214
215
216
217
  # at build time, copy the files to build directory include files when the target is built
  foreach(HEADER ${EXPORT_HEADER_DEFAULT_ARGS})
    # check if file name is relative or not
    set(FILE_TO_COPY ${HEADER})
   
	# copy after build, only if there was a change
    add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                       POST_BUILD
                       COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE_TO_COPY} ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}/
                       COMMENT "Installing build-time header ${HEADER}"
                       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                       VERBATIM
    )
  endforeach()
218

219
220
221
222
223
  # during installation, copy the files to install directory
  install(FILES ${EXPORT_HEADER_DEFAULT_ARGS} 
          DESTINATION ${CAMITK_INSTALL_ROOT}/include/${CAMITK_SHORT_VERSION_STRING}/${EXPORT_HEADER_DESTINATION}/	
	      COMPONENT ${EXPORT_HEADER_COMPONENT}
  )
224

225
endmacro()
226

227

228
# MACRO camitk_extension
229
#
230
# Simplify writing a camitk extension (component, action) 
231
232
# 
# usage:
233
234
# 			extension(<type> 
#					  [DEFAULT]
235
236
#                     [NEEDS_ITK]
#                     [NEEDS_LIBXML2]
237
238
#                     [NEEDS_OPENCV]
#                     [NEEDS_IGSTK]
239
#                     [NEEDS_XSD]
240
#                     [NEEDS_QTXML]
241
242
243
244
245
246
247
248
249
250
#                     [NEEDS_TOOL tool1 tool2 ...]
#                     [NEEDS_COMPONENT_EXTENSION component1 component2 ...]
#                     [INCLUDE_DIRECTORIES dir1 dir2 ...]
#                     [DEFINES flag1 flag2 ...]
#                     [EXTERNAL_SOURCES file1 file2 ...]
#                     [LIBRARIES lib1 lib2 ...]
#                     [HEADERS_TO_INSTALL header1.h header2.h ...]
#                     [INSTALL_ALL_HEADERS]
#                    )
#
251
# The name of the extension is automatically the name of the directory from where this macro
252
253
# is called.
#
254
# <type>					= The selected type of extension you wish to build.
255
256
257
#							  possible values : ACTION_EXTENSION or COMPONENT_EXTENSION.
# DEFAULT                   = means this is a default component to be compiled automatically
# NEEDS_ITK                 = add this if your component needs itk. 
258
#                             Do not forget to add the needed list of itk libraries in the LIBRARIES parameter
259
# NEEDS_LIBXML2             = add this if your component needs libxml2 
260
# NEEDS_XSD                 = add this if your action needs Codesynthesis xsd cxx (xml schema compiler)
261
262
# NEEDS_OPENCV              = add this if your component needs OpenCV
# NEEDS_IGSTK               = add this if your component needs IgsTK
263
# NEEDS_XERCESC	 			= add this if your action / component needs XercesC library
264
# NEEDS_QTXML               = this application needs QtXML
265
266
# NEEDS_TOOL                = list of needed camitk tools
# NEEDS_COMPONENT_EXTENSION = list of needed component extensions
267
# NEEDS_ACTION_EXTENSION 	= list of needed component extensions
268
269
270
271
272
273
274
275
276
277
278
279
280
# INCLUDE_DIRECTORIES       = additional include directories
# DEFINES                   = list of define flags to add at compilation time
# EXTERNAL_SOURCES          = list of extra source/headers files (external to the current directory)
#                             that needed to be added to the SOURCES variable. 
#                             Note: EXTERNAL_SOURCES are not installed
# LIBRARIES                 = libraries to add to the link command
# HEADERS_TO_INSTALL        = list of headers to install, if present this will automatically
#                             create an "install-COMPONENT_NAMEcomponent" target, that can be used
#                             anywhere else to manage dependencies to this component.
#                             The headers are installed ${CAMITK_INCLUDE_DIR}
#                             when the target "install-COMPONENT_NAMEcomponent" is called.
# INSTALL_ALL_HEADERS       = install all of the headers (this is the lazy solution, please consider
#                             making a list and using HEADERS_TO_INSTALL parameter instead!   
281
282
283
macro(camitk_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} EXTENSION_NAME)
284
  
285
  parse_arguments(${EXTENSION_NAME_CMAKE} #prefix
286
    "NEEDS_TOOL;NEEDS_COMPONENT_EXTENSION;NEEDS_ACTION_EXTENSION;INCLUDE_DIRECTORIES;LIBRARIES;HEADERS_TO_INSTALL;DEFINES;EXTERNAL_SOURCES"  # possible lists
287
    "ACTION_EXTENSION;COMPONENT_EXTENSION;DEFAULT;NEEDS_XERCESC;NEEDS_ITK;NEEDS_LIBXML2;NEEDS_XSD;NEEDS_QTXML;NEEDS_OPENCV;NEEDS_IGSTK;INSTALL_ALL_HEADERS" # possible options
288
289
290
    ${ARGN}
  )

291
292
293
294
295
296
297
  # Get the type of extension
  if (${EXTENSION_NAME_CMAKE}_ACTION_EXTENSION)
	set(TYPE_EXTENSION "action")	
	string(TOUPPER ${TYPE_EXTENSION} TYPE_EXTENSION_CMAKE)
  elseif(${EXTENSION_NAME_CMAKE}_COMPONENT_EXTENSION)
	set(TYPE_EXTENSION "component")	
	string(TOUPPER ${TYPE_EXTENSION} TYPE_EXTENSION_CMAKE)
298
299
  endif()

300
301
  # if it is the first cmake run, create the extension variable with a correct initial value
  if(NOT CAMITK_${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL)
302
303
304
305
306
307
308
309
310
311
312
313
    # add option to enable/disable this extension and set it to true if either
    # it was marked as default or a -D???_${EXTENSION_NAME_CMAKE}:BOOL=TRUE was given on the command line
    set(${EXTENSION_NAME_CMAKE}_DEFAULT_IS_SET "FALSE")
    if(DEFINED ${EXTENSION_NAME_CMAKE}_DEFAULT)
        set(${EXTENSION_NAME_CMAKE}_DEFAULT_IS_SET ${${EXTENSION_NAME_CMAKE}_DEFAULT})
    endif()
    if(DEFINED ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE})
        set(${EXTENSION_NAME_CMAKE}_DEFAULT_IS_SET ${${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}})
    endif()
    set(${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE} ${${EXTENSION_NAME_CMAKE}_DEFAULT} CACHE BOOL "Build extension ${EXTENSION_NAME}")
    set(CAMITK_${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL TRUE CACHE BOOL "Is variable ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME} already created?")
    mark_as_advanced(CAMITK_${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL)
314
315
  endif()
  
316
317
  # if this extension is enabled, do everything needed
  # otherwise... do nothing
318
319
  if (${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE})   

320
321
322
323
    # check for target name
    set(${TYPE_EXTENSION_CMAKE}_TARGET_NAME ${TYPE_EXTENSION}-${EXTENSION_NAME})
    message(STATUS "Building extension ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}")
    
324
    # actions are compiled as shared object 
325
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${TYPE_EXTENSION}s) 
326

327
328
    # extension are compiled as shared object (for dll plateform put it in BIN)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TYPE_EXTENSION}s) 
329
330
331
332
333

    # include directories
    include_directories(${CAMITK_INCLUDE_DIRECTORIES})
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
334
    include_directories(${${EXTENSION_NAME_CMAKE}_INCLUDE_DIRECTORIES})
335
336

    # check definitions
337
338
    if(${EXTENSION_NAME_CMAKE}_DEFINES)
      foreach (FLAG ${${EXTENSION_NAME_CMAKE}_DEFINES})
339
340
341
342
        add_definitions(-D${FLAG})
      endforeach()
    endif()

promayon's avatar
promayon committed
343
344
    # check for needed tool
    set(TOOL_LIBRARIES)
345
346
    if(${EXTENSION_NAME_CMAKE}_NEEDS_TOOL)
      foreach(TOOL_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_TOOL})
promayon's avatar
promayon committed
347
        string(TOUPPER ${TOOL_NEEDED} ${TOOL_NEEDED}_INTERNAL)
348
        set(TOOL_${${TOOL_NEEDED}_INTERNAL} ON CACHE BOOL "Required by action extension ${EXTENSION_NAME}" FORCE )
promayon's avatar
promayon committed
349
350
351
352
353
        set(TOOL_LIBRARIES ${TOOL_LIBRARIES} ${TOOL_NEEDED})
        include_directories(${CAMITK_INCLUDE_DIR}/${TOOL_NEEDED})
      endforeach()
    endif()

354
 	# Looking for ITK
355
    set(ITK_LIBRARIES "")
356
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ITK)
357
358
359
      # ITK is required
      find_package(ITK REQUIRED)
      include(${ITK_USE_FILE})
360
      set(ITK_LIBRARIES ITKBasicFilters ITKCommon ITKIO)
361
362
    else()
      set(ITK_LIBRARIES "")
363
364
    endif()

365
   # Looking for LibXML2.0
366
    set(LIBXML2_LIBRARIES)
367
    if(${EXTENSION_NAME_CMAKE}_NEEDS_LIBXML2) 
368
      # LibXml2 is required
369
      find_package(Xml2)
370
371
372
373
374
      if (LIBXML2_FOUND)
        add_definitions(${LIBXML2_DEFINITIONS})
        include_directories(${LIBXML2_INCLUDE_DIR})      
      else()
        # most probably win32 or crosscompiling
375
        message(STATUS "${EXTENSION_NAME}: libxml2 required")
376
377
378
      endif()
    endif()
	
379
    # looking for OpenCV
380
    set(OpenCV_LIBRARIES "")
381
    if(${EXTENSION_NAME_CMAKE}_NEEDS_OPENCV) 
382
383
		# OpenCV is required
		find_package( OpenCV REQUIRED )
384
385
	else ( )
		set(OpenCV_LIBRARIES "")
386
387
	endif()

388
    #looking for IGSTK libraries ?
389
    set(IGSTK_LIBRARIES "")
390
    if(${EXTENSION_NAME_CMAKE}_NEEDS_IGSTK)
391
392
		find_package(IGSTK REQUIRED)
		include(${IGSTK_USE_FILE})	
promayon's avatar
promayon committed
393
	else()
394
395
396
		set(IGSTK_LIBRARIES "")
	endif()

promayon's avatar
promayon committed
397
398
    # Looking for XercesC
    set(XERCESC_LIBRARIES)
399
    if(${EXTENSION_NAME_CMAKE}_NEEDS_XERCESC)
promayon's avatar
promayon committed
400
401
402
403
404
405
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
      else()
        # most probably win32 or crosscompiling
406
        message(STATUS "${EXTENSION_NAME}: xerces-c required")
promayon's avatar
promayon committed
407
408
409
410
      endif()
    endif()

    # Looking for codesynthesis XSD CXX
411
    if(${EXTENSION_NAME_CMAKE}_NEEDS_XSD)
promayon's avatar
promayon committed
412
413
414
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
415
416
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
417
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
418
419
      else()
        # most probably win32 or crosscompiling
420
        message(STATUS "${EXTENSION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
421
422
423
      endif()
    endif()

424
    set(QT_LIBRARIES_WITH_QTXML)
saubatn's avatar
saubatn committed
425
426
427
    if(${EXTENSION_NAME_CMAKE}_NEEDS_QTXML)
	
	
428
429
430
431
432
433
434
435
436
437
        set (QT_USE_QTXML ON)
        find_package(Qt4 REQUIRED)
        if(QT_USE_FILE)
            include(${QT_USE_FILE})
            else(QT_USE_FILE)
                set(QT_LIBRARIES ${QT_QT_LIBRARY})
            endif(QT_USE_FILE)
            set(QT_LIBRARIES_WITH_QTXML ${QT_LIBRARIES})        
    endif()
                
438
    set(COMPONENT_EXTENSION_LIBRARIES)
439
    # check for intra-component extension
440
441
    if(${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
442
        string(TOUPPER ${COMPONENT_NEEDED} ${COMPONENT_NEEDED}_INTERNAL)
443
        set(COMPONENT_${${COMPONENT_NEEDED}_INTERNAL} ON CACHE BOOL "Required by extension ${EXTENSION_NAME}" FORCE )
444
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} component-${COMPONENT_NEEDED})
445
        include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
446
447
      endforeach()
    endif()
448

449
450
    set(ACTION_EXTENSION_LIBRARIES)
    # check for intra-action extension
451
452
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
453
        string(TOUPPER ${ACTION_NEEDED} ${ACTION_NEEDED}_INTERNAL)
454
        set(ACTION_${${ACTION_NEEDED}_INTERNAL} ON CACHE BOOL "Required by extension ${EXTENSION_NAME}" FORCE )
455
        set(ACTION_EXTENSION_LIBRARIES ${ACTION_EXTENSION_LIBRARIES} action-${ACTION_NEEDED})
456
        include_directories(${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED})
457
458
459
      endforeach()
    endif()

460
461
    # check for libs in all known camitk dir + actions subdir (beware of the plateform bin or lib?)
    link_directories( ${CAMITK_LIB_DIRECTORIES}
462
                      ${CAMITK_BIN_DIR}
463
                      ${CAMITK_BIN_DIR}/components
464
                      ${CAMITK_BIN_DIR}/actions
465
466
467
468
469
470
471
472
473
474
475
                      ${CAMITK_INSTALL_ROOT}/lib/${CAMITK_SHORT_VERSION_STRING}/actions
                      ${CAMITK_INSTALL_ROOT}/lib/${CAMITK_SHORT_VERSION_STRING}/components
                      ${CAMITK_INSTALL_ROOT}/bin/components
                      ${CAMITK_INSTALL_ROOT}/bin/actions
                      ${CMAKE_CURRENT_BINARY_DIR}/../../bin/components
                      ${CMAKE_CURRENT_BINARY_DIR}/../../bin/actions
    )

    # get all headers, sources and do what is needed for Qt 
    # one need to do this just before the add_library so that all defines, include directories and link directories
    # are set properly (gather_headers_and_sources include the call to Qt moc and uic)
476
    gather_headers_and_sources(${EXTENSION_NAME_CMAKE})
477
	
478
    # check for external sources
479
480
    if(${EXTENSION_NAME_CMAKE}_EXTERNAL_SOURCES)
            set(${EXTENSION_NAME_CMAKE}_SOURCES ${${EXTENSION_NAME_CMAKE}_SOURCES} ${${EXTENSION_NAME_CMAKE}_EXTERNAL_SOURCES})
481
    endif()
482
483

    # build the action extension module (library)
484
    add_library(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} SHARED ${${EXTENSION_NAME_CMAKE}_SOURCES})
485
    
486
487
488
    # Update XML Project description adding this target as a subproject of the main CamiTK project with
    # its dependencies (in the CMake target point of view)
    addSubProject(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${CAMITK_CORE_LIB} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${TOOL_LIBRARIES})
489

490
    # Set the libraries required to link the target
491
492
    # An action has to be linked with ${CAMITK_CORE_LIB}. As CAMITK_CORE_LIB is always a DLL/shared lib, there should
    # be no symbols loaded multiple times
493
    target_link_libraries(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${CAMITK_LIBRARIES} ${QT_LIBRARIES_WITH_QTXML} ${CAMITK_CORE_LIB} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${ITK_LIBRARIES} ${LIBXML2_LIBRARIES} ${OpenCV_LIBRARIES} ${IGSTK_LIBRARIES} ${XERCESC_LIBRARY} ${TOOL_LIBRARIES}  ${${EXTENSION_NAME_CMAKE}_LIBRARIES})
494

495
    # dependencies to core (only set for internal build)
496
    if (CAMITK_INTERNAL_BUILD)
497
      add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${CAMITK_CORE_LIB})
498
499
    endif()

500
    # see http://www.cmake.org/pipermail/cmake/2012-April/049889.html
501
    # target properties (outputname and remove soname)
502
503
504
505
506
507
508
    #  set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTY NO_SONAME 1)
    set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                           PROPERTIES OUTPUT_NAME ${EXTENSION_NAME}
    )
    set(${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES ${${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES}
        VERSION   "${CAMITK_VER_MAJ}.${CAMITK_VER_MIN}.${CAMITK_VER_PAT}"
        SOVERSION "${CAMITK_VER_MAJ}"
509
    )
510
511
    # set the library specific info (SONAME...)
    set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES ${${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES} LINK_INTERFACE_LIBRARIES "")
512

513
514
515
516
    # tools dependencies
    if(${EXTENSION_NAME_CMAKE}_NEEDS_TOOL) 
      foreach(TOOL_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_TOOL})
        add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${TOOL_NEEDED})
517
518
519
      endforeach()
    endif()

520
    # Set the Component(s) dependency
521
522
    if(${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
523
        string(TOUPPER ${COMPONENT_NEEDED} COMPONENT_NEEDED_CMAKE)
524
        # if this is not true, then the dependencies is from an external build, do not use add_dependencies
525
        if (CAMITK_COMPONENT_${COMPONENT_NEEDED_CMAKE}_INTERNAL)
526
527
528
529
530
            add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} component-${COMPONENT_NEEDED})
#                 message(STATUS "............................................................ ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} depends on component-${COMPONENT_NEEDED}")
#                 if(NOT TARGET "component-${COMPONENT_NEEDED}")
#                   message(STATUS "............................................................ component-${COMPONENT_NEEDED} not existing (yet)")
#                 endif()
531
532
533
534
        endif()
      endforeach()
    endif()

535
	# Set the Action(s) dependency
536
537
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
538
        string(TOUPPER ${ACTION_NEEDED} ACTION_NEEDED_CMAKE)
539
	# if this is not true, then the dependencies is from an external build, do not use add_dependencies
540
        if (CAMITK_ACTION_${ACTION_NEEDED_CMAKE}_INTERNAL)
541
542
543
544
545
		add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} action-${ACTION_NEEDED})
#                 message(STATUS "............................................................ ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} depends on action-${ACTION_NEEDED}")
#                 if(NOT TARGET "action-${ACTION_NEEDED}")
#                   message(STATUS "............................................................ action-${ACTION_NEEDED} not existing")
#                 endif() 
546
547
548
549
        endif()
      endforeach()
    endif()

550
    # generate an install target for headers
551
552
    if(${EXTENSION_NAME_CMAKE}_HEADERS_TO_INSTALL)
		export_headers(${${EXTENSION_NAME_CMAKE}_HEADERS_TO_INSTALL} COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} GROUP ${TYPE_EXTENSION}s)
553
554
555
    endif()

    # lazy you!
556
557
    if(${EXTENSION_NAME_CMAKE}_INSTALL_ALL_HEADERS)
      export_headers(${${EXTENSION_NAME_CMAKE}_HEADERS} COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} GROUP ${TYPE_EXTENSION}s)
558
559
560
    endif()

    # lib installation
561
    install(TARGETS ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
562
            RUNTIME DESTINATION bin/${TYPE_EXTENSION}s
saubatn's avatar
saubatn committed
563
564
            LIBRARY DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
            ARCHIVE DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
565
            COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
566
567
    )

568
569
570
571
572
573
574
575
576
577
578
	 # testdata files installation
    if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/testdata)
      # Check test data dir directory
      if (NOT EXISTS ${CAMITK_TESTDATA_DIR})
        add_custom_command(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                          POST_BUILD
                          COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_TESTDATA_DIR}
                          COMMENT "Creating build-time share directory for test data ${CAMITK_TESTDATA_DIR}"
                          VERBATIM
        )
      endif()
579

580
581
582
583
584
585
586
587
588
      # At build time, copy the files to test data directory
      add_custom_command(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                        POST_BUILD
                        COMMAND ${CMAKE_COMMAND} -E copy_directory testdata ${CAMITK_TESTDATA_DIR}
                        COMMENT "Installing build-time test data for ${EXTENSION_NAME}"
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        VERBATIM
      )
      
589

590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
      # during installation, copy the files to install directory
	  set (TESTDATA_DEST_DIR)
	  if ( MSVC )
		# Do NOT add ${CAMITK_SHORT_VERSION_STRING} to the testdata path for Win32 MSVC !
		set (TESTDATA_DEST_DIR share/testdata)
	  else ()
		set (TESTDATA_DEST_DIR share/${CAMITK_SHORT_VERSION_STRING}/testdata)
	  endif ()
      install(DIRECTORY testdata/
			  #DESTINATION share/testdata
              #DESTINATION share/${CAMITK_SHORT_VERSION_STRING}/testdata
			  DESTINATION ${TESTDATA_DEST_DIR}
              COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
              PATTERN ".svn" EXCLUDE
              PATTERN "*~" EXCLUDE
      )
    endif()
607

608
  endif()
609

610
endmacro()
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
# Old macro to configure a new action to the framework
# Use camitk_extension macro instead
macro(action_extension)
        message(WARNING "Deprecated macro action_extension detected : please use camitk_extension(ACTION_EXTENSION ...) instead.")
        camitk_extension(ACTION_EXTENSION ${ARGN})
endmacro()

# Old macro to configure a new component to the framework
# Use camitk_extension macro instead
macro(component_extension)
        message(WARNING "Deprecated macro component_extension detected : please use camitk_extension(COMPONENT_EXTENSION ...) instead.")
        camitk_extension(COMPONENT_EXTENSION ${ARGN})
endmacro()

# TODO write a viewer_extension macro in CamiTK


# MACRO camitk_tool
#
# This macro simplifies the declaration of a library inside CamiTK
# and is to be used for all inner project tools
#
promayon's avatar
promayon committed
634
# The name of the tool/library is deduced from the name of the directory, unless LIBNAME is provided
635
636
637
638
639
640
641
#
# If the library is compiled as shared, it adds the needed library properties
# If it needs relocation flag fPIC (on some plateforms), this macro should determine
# if this is the case and specify this flag
#
# usage:
# camitk_tool(
promayon's avatar
promayon committed
642
#     SHARED|STATIC
643
644
#     SOURCES source1.cpp source1.h...
#     TARGET_LINK_LIBRARIES lib1 lib2...
promayon's avatar
promayon committed
645
#     [INCLUDE_DIRECTORIES dir1 dir2...]
646
#     [NEEDS_LIBXML2]
promayon's avatar
promayon committed
647
648
649
650
651
#     [NEEDS_XERCESC]
#     [NEEDS_XSD]
#     [LINK_DIRECTORIES dir1 dir2...]
#     [LIBNAME libname]
# )
652
653
654
655
656
# where:
# SHARED                        optional, if the tool should be compiled as shared
# SOURCES                       all sources to be included in the library
# INCLUDE_DIRECTORIES           all needed include directories (${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} are automatically added)
# TARGET_LINK_LIBRARIES         all the libraries to be used during the link
657
# NEEDS_LIBXML2                 add this if the tool needs libxml2
promayon's avatar
promayon committed
658
659
660
661
# NEEDS_XERCESC                 add this if your action / component needs XercesC library
# NEEDS_XSD                     add this if your action needs Codesynthesis xsd cxx (xml schema compiler)
# LIBNAME                       force the library/tool name to be different from the directory it is in
# LINK_DIRECTORIES              additional directories to use in link_directories(...)
662
macro(camitk_tool)
promayon's avatar
promayon committed
663
  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} DEFAULT_LIBRARY_NAME)
664

promayon's avatar
promayon committed
665
666
667
  parse_arguments(${DEFAULT_LIBRARY_NAME_CMAKE}
    "SOURCES;TARGET_LINK_LIBRARIES;INCLUDE_DIRECTORIES;LIBNAME;LINK_DIRECTORIES"  # possible lists
    "SHARED;STATIC;NEEDS_LIBXML2;NEEDS_XERCESC;NEEDS_XSD" # possible options
668
669
670
    ${ARGN}
  )

promayon's avatar
promayon committed
671
672
673
674
675
676
677
678
  # if the libname is forced to be different (for string comparison problem, and
  # why there is a double quote here, see http://www.cmake.org/pipermail/cmake/2011-October/046939.html)
  if ("${${DEFAULT_LIBRARY_NAME_CMAKE}_LIBNAME}" STREQUAL "")
    set(LIBRARY_NAME ${DEFAULT_LIBRARY_NAME})
  else()
    set(LIBRARY_NAME ${${DEFAULT_LIBRARY_NAME_CMAKE}_LIBNAME})
  endif()
  
679
  # includes
promayon's avatar
promayon committed
680
  include_directories ( ${${DEFAULT_LIBRARY_NAME_CMAKE}_INCLUDE_DIRECTORIES}
681
682
683
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
  )
684

promayon's avatar
promayon committed
685
686
687
688
689
690
691
692
693
694
695
  # Looking for LibXML2.0
  set(LIBXML2_LIBRARIES)
  if(${DEFAULT_LIBRARY_NAME_CMAKE}_NEEDS_LIBXML2)
    # LibXml2 is required
    find_package(Xml2)
    if (LIBXML2_FOUND)
      add_definitions(${LIBXML2_DEFINITIONS})
      include_directories(${LIBXML2_INCLUDE_DIR})
    else()
      # most probably win32 or crosscompiling
      message(WARNING "${LIBRARY_NAME}: libxml2 required")
696
    endif()
promayon's avatar
promayon committed
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  endif()
  
  # Looking for XercesC
  set(XERCESC_LIBRARIES)
  if(${DEFAULT_LIBRARY_NAME_CMAKE}_NEEDS_XERCESC)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
      else()
      # most probably win32 or crosscompiling
        message(STATUS "${LIBRARY_NAME}: xerces-c required")
      endif()
  endif()
711

promayon's avatar
promayon committed
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  # Looking for codesynthesis XSD CXX
  if(${DEFAULT_LIBRARY_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
        include_directories(${XSD_INCLUDE_DIR})
      else()
        # most probably win32 or crosscompiling
        message(STATUS "${LIBRARY_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
      endif()
  endif()

  # some additional link directories are needed
  if (NOT "${${DEFAULT_LIBRARY_NAME_CMAKE}_LINK_DIRECTORIES}" STREQUAL "")
    link_directories(${${DEFAULT_LIBRARY_NAME_CMAKE}_LINK_DIRECTORIES})
  endif()
  
731
  # Add shared or static library
promayon's avatar
promayon committed
732
  if (${DEFAULT_LIBRARY_NAME_CMAKE}_SHARED)
733
    message(STATUS "Adding shared library: ${LIBRARY_NAME}")
promayon's avatar
promayon committed
734
    add_library(${LIBRARY_NAME} SHARED ${${DEFAULT_LIBRARY_NAME_CMAKE}_SOURCES})
735
736
737
    # prepare the library specific info (SONAME...)
    set(${LIBRARY_NAME}_LIBRARY_PROPERTIES ${${LIBRARY_NAME}_LIBRARY_PROPERTIES}
        VERSION   "${CAMITK_VER_MAJ}.${CAMITK_VER_MIN}.${CAMITK_VER_PAT}"
738
        SOVERSION "${CAMITK_VER_MAJ}"
739
740
741
742
    )
    # set the library specific info (SONAME...)
    set_target_properties(${LIBRARY_NAME} PROPERTIES ${${LIBRARY_NAME}_LIBRARY_PROPERTIES} LINK_INTERFACE_LIBRARIES "")
  else()
promayon's avatar
promayon committed
743
    if (${DEFAULT_LIBRARY_NAME_CMAKE}_STATIC)
744
        message(STATUS "Adding static library: ${LIBRARY_NAME}")
promayon's avatar
promayon committed
745
        add_library(${LIBRARY_NAME} STATIC ${${DEFAULT_LIBRARY_NAME_CMAKE}_SOURCES})
746
747
748
749
750
    else()
        message(FATAL_ERROR "In adding static library ${LIBRARY_NAME}.\n   Please specify the library/tool type: SHARED or STATIC")
    endif()
  endif()
  
751
752
  # Update XML Project description adding this target as a subproject of the main CamiTK project with
  # its dependencies (in the CMake target point of view)
saubatn's avatar
saubatn committed
753
  addSubProject(${LIBRARY_NAME})
754
  
755
756
757
  # 64bits and other platform with relocation needs -fPIC
  include(TestCXXAcceptsFlag)
  check_cxx_accepts_flag(-fPIC FPIC_FLAG_ACCEPTED)
promayon's avatar
promayon committed
758
759
  # no need to add -fPIC on mingw, otherwise it generates a warning: -fPIC ignored for target (all code is position independent) [enabled by default]
  if(FPIC_FLAG_ACCEPTED AND NOT MINGW)
760
761
762
763
    set_property(TARGET ${LIBRARY_NAME} APPEND PROPERTY COMPILE_FLAGS -fPIC)
  endif()

  #add libraries needed during the link
promayon's avatar
promayon committed
764
  target_link_libraries(${LIBRARY_NAME} ${${DEFAULT_LIBRARY_NAME_CMAKE}_TARGET_LINK_LIBRARIES} ${LIBXML2_LIBRARIES} ${XERCESC_LIBRARY})  
765
endmacro()
766
767
768
769
770
771

# MACRO application_extension
#
# Simplify writing application extension CMakeLists.txt
#
# usage:
772
773
774
# application_extension(
#        [DEFAULT]
#        [NEEDS_ITK]
775
#        [NEEDS_QTXML]
776
777
778
779
#        [NEEDS_TOOL tool1 tool2 ...]
#        [NEEDS_COMPONENT_EXTENSION component1 component2 ...]
#        [NEEDS_ACTION_EXTENSION ation1 action2 ...]
#     )
780
781
#
# where :
782
783
784
#     DEFAULT                     = means this is a default application to be compiled automatically
#     NEEDS_ITK                   = means this application requires ITK to be compiled / run.
#     NEEDS_TOOL                  = list of needed camitk tools
785
#     NEEDS_QTXML                 = this application needs QtXML
786
787
#     NEEDS_COMPONENT_EXTENSION   = list of needed component extensions
#     NEEDS_ACTION_EXTENSION      = list of needed component extensions
788
789
#
# The name of the application is automatically the name of the directory from where this macro
790
# is called prefixed with "camitk-"
791
#
792
# 
793
794
795
macro(application_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} APPLICATION_NAME)
796
  
797
  parse_arguments(${APPLICATION_NAME_CMAKE} 
798
    "NEEDS_TOOL;NEEDS_COMPONENT_EXTENSION;NEEDS_ACTION_EXTENSION"  # possible lists
799
    "DEFAULT;NEEDS_ITK;NEEDS_QTXML;ACTION_EXTENSION;COMPONENT_EXTENSION;NEEDS_XSD;NEEDS_XERCESC" # possible options
800
801
    ${ARGN}
  )
802
  
803
804
805
  # if it is the first cmake run, create the application variable with a correct initial value
  if(NOT CAMITK_APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL)
    message(STATUS "Checking ${APPLICATION_NAME}")
806
807
808
809
810
811
812
813
814
815
    # add option to enable/disable this application extension and set it to true if either
    # it was marked as default or a -DAPPLICATION_${APPLICATION_NAME_CMAKE}:BOOL=TRUE was given on the command line
    set(APPLICATION_${APPLICATION_NAME_CMAKE}_IS_SET "FALSE")
    if(DEFINED ${APPLICATION_NAME_CMAKE}_DEFAULT)
        set(APPLICATION_${APPLICATION_NAME_CMAKE}_IS_SET ${${APPLICATION_NAME_CMAKE}_DEFAULT})
    endif()
    if(DEFINED APPLICATION_${APPLICATION_NAME_CMAKE})
        set(APPLICATION_${APPLICATION_NAME_CMAKE}_IS_SET ${APPLICATION_${APPLICATION_NAME_CMAKE}})
    endif()
    set(APPLICATION_${APPLICATION_NAME_CMAKE} ${APPLICATION_${APPLICATION_NAME_CMAKE}_IS_SET} CACHE BOOL "Build application ${APPLICATION_NAME}")
816
817
818
819
820
821
822
823
824
    set(CAMITK_APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL TRUE CACHE BOOL "Is variable APPLICATION_${APPLICATION_NAME} already created?")
    mark_as_advanced(CAMITK_APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL)
  endif()

  message(STATUS "Building application ${APPLICATION_NAME}: ${APPLICATION_${APPLICATION_NAME_CMAKE}}") 

  # if this extension is enabled, do everything needed
  # otherwise... do nothing
  if (APPLICATION_${APPLICATION_NAME_CMAKE})
promayon's avatar
promayon committed
825
826
827
828
829
830
831
832
833
834
835
    # check for needed tool
    set(TOOL_LIBRARIES)
    if(${APPLICATION_NAME_CMAKE}_NEEDS_TOOL)
      foreach(TOOL_NEEDED ${${APPLICATION_NAME_CMAKE}_NEEDS_TOOL})
        message(STATUS "${TOOL_NEEDED} required by application ${APPLICATION_NAME}")
        string(TOUPPER ${TOOL_NEEDED} ${TOOL_NEEDED}_INTERNAL)
        set(TOOL_${${TOOL_NEEDED}_INTERNAL} ON CACHE BOOL "Required by application ${APPLICATION_NAME}" FORCE )
        set(TOOL_LIBRARIES ${TOOL_LIBRARIES} ${TOOL_NEEDED})
        include_directories(${CAMITK_INCLUDE_DIR}/${TOOL_NEEDED})
      endforeach()
    endif()
836
837
838
839
840
841
842
843
844
845
	
	# Looking for ITK
    set(ITK_LIBRARIES "")
    if(${APPLICATION_NAME_CMAKE}_NEEDS_ITK)
      # ITK is required
      find_package(ITK REQUIRED)
      include(${ITK_USE_FILE})
    else()
      set(ITK_LIBRARIES "")
    endif()
promayon's avatar
promayon committed
846
847
848
849
850
851
852
853
854
855
856
857
858

    # Looking for XercesC
    set(XERCESC_LIBRARIES)
    if(${APPLICATION_NAME_CMAKE}_NEEDS_XERCESC)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
      else()
        # most probably win32 or crosscompiling
        message(STATUS "${APPLICATION_NAME}: xerces-c required")
      endif()
    endif()
859
860
861
862
863
864
865
866
867
868
869
870
    
    set(QT_LIBRARIES_WITH_QTXML)
    if(${APPLICATION_NAME_CMAKE}_NEEDS_QTXML)
        set (QT_USE_QTXML ON)
        find_package(Qt4 REQUIRED)
        if(QT_USE_FILE)
            include(${QT_USE_FILE})
        else(QT_USE_FILE)
            set(QT_LIBRARIES ${QT_QT_LIBRARY})
        endif(QT_USE_FILE)
        set(QT_LIBRARIES_WITH_QTXML ${QT_LIBRARIES})        
    endif()
promayon's avatar
promayon committed
871
872
873
874
875
876

    # Looking for codesynthesis XSD CXX
    if(${APPLICATION_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
877
878
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
879
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
880
881
      else()
        # most probably win32 or crosscompiling
882
        message(STATUS "${APPLICATION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
883
884
      endif()
    endif()
885
886
887
888
889
890
891
892
893
894
895
896
	
	# Looking for required component that this application needs
	set(COMPONENT_EXTENSION_LIBRARIES)
    # check for intra-component extension
    if(${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
		string(TOUPPER ${COMPONENT_NEEDED} ${COMPONENT_NEEDED}_INTERNAL)
		set(COMPONENT_${${COMPONENT_NEEDED}_INTERNAL} ON CACHE BOOL "Required by application ${APPLICATION_NAME}" FORCE )
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} component-${COMPONENT_NEEDED})
		include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
      endforeach()
    endif()
897

898
    # set the directories where to seek for .h files at compilation time.
899
900
    include_directories(${CAMITK_INCLUDE_DIRECTORIES} ${CAMITK_INCLUDE_DIR}/${CAMITK_CORE_LIB} ${CAMITK_INCLUDE_DIR}/component ${CMAKE_CURRENT_BINARY_DIR})

901
902
    # set the directories where to seek for static and dynamic libraries at linking time.
    link_directories(${CAMITK_LIB_DIRECTORIES} ${CAMITK_BIN_DIR}/components)
903
904
905
906
907
908
909
910
911
912
913
914

    # check for target name
    set(APPLICATION_TARGET_NAME application-${APPLICATION_NAME})

    # get all headers, sources and do what is needed for Qt 
    # one need to do this just before the add_library so that all defines, include directories and link directories
    # are set properly (gather_headers_and_sources include the call to Qt moc and uic)
    gather_headers_and_sources(${APPLICATION_NAME})

    # add the executable target
    add_executable(${APPLICATION_TARGET_NAME} ${${APPLICATION_NAME}_SOURCES})

915
916
	# Update XML Project description adding this target as a subproject of the main CamiTK project with
	# its dependencies (in the CMake target point of view)
917
	addSubProject(${APPLICATION_TARGET_NAME} ${COMPONENT_EXTENSION_LIBRARIES} ${CAMITK_CORE_LIB} ${TOOL_LIBRARIES})
918

919
920
    # target properties
    set_target_properties(${APPLICATION_TARGET_NAME} 
921
                          PROPERTIES OUTPUT_NAME camitk-${APPLICATION_NAME}
922
923
    )

promayon's avatar
promayon committed
924
925
926
927
928
929
    # tool dependencies
    if(${APPLICATION_TARGET_NAME}_NEEDS_TOOL)
      foreach(TOOL_NEEDED ${${APPLICATION_TARGET_NAME}_NEEDS_TOOL})
        add_dependencies(${APPLICATION_TARGET_NAME} ${TOOL_NEEDED})
      endforeach()
    endif()
930
931
	
	# Set the Component(s) dependency
932
933
    if(${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
934
935
936
        string(TOUPPER ${COMPONENT_NEEDED} COMPONENT_NEEDED_CMAKE)
		# if this is not true, then the dependencies is from an external build, do not use add_dependencies
        if (CAMITK_COMPONENT_${COMPONENT_NEEDED_CMAKE}_INTERNAL)
937
			add_dependencies(${APPLICATION_TARGET_NAME} component-${COMPONENT_NEEDED})
938
939
940
        endif()
      endforeach()
    endif()
941
942
943
944
945
946
947
948
949
950
951
952
	
	# Set the Action(s) dependency
	set(ACTION_EXTENSION_LIBRARIES)
    if(${APPLICATION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${APPLICATION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
		string(TOUPPER ${ACTION_NEEDED} ${ACTION_NEEDED}_INTERNAL)
		set(ACTION_${${ACTION_NEEDED}_INTERNAL} ON CACHE BOOL "Required by application ${APPLICATION_NAME}" FORCE )
        set(ACTION_EXTENSION_LIBRARIES ${ACTION_EXTENSION_LIBRARIES} action-${ACTION_NEEDED})
		include_directories(${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED})
		# if this is not true, then the dependencies is from an external build, do not use add_dependencies
	  endforeach()
    endif()
promayon's avatar
promayon committed
953

954
955
    # dependences to core (only set for internal build)
    if (CAMITK_INTERNAL_BUILD)
956
		add_dependencies(${APPLICATION_TARGET_NAME} ${CAMITK_CORE_LIB})
promayon's avatar
promayon committed
957
    endif()
958
	
959
	# Set the libraries needed to build the application target
960
    target_link_libraries(${APPLICATION_TARGET_NAME} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${CAMITK_LIBRARIES} ${QT_LIBRARIES_WITH_QTXML} ${CAMITK_CORE_LIB} ${TOOL_LIBRARIES} ${XERCESC_LIBRARY} ${ITK_LIBRARIES})
961
	
962
963
964
965
966
    # installation
    install(TARGETS ${APPLICATION_TARGET_NAME}
            RUNTIME DESTINATION bin
            COMPONENT ${APPLICATION_TARGET_NAME}
    )
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
	
	# For Microsoft Visual C++, sets the default application to the corresponding project
	# (i.e. launches this application when we you click on "Debug" or "Start Without Debugging" button on Visual)
	# In addition, but not the least, sets the environment to the debug dll directory for VTK (and ITK)
	#     to solve the dll incompatibility between debug and relase version of QVTK.dll and ITKCommon.dll
	# Edit, don't know why, but macro does not work correctly inside application_extension()
	if ( MSVC )
		include(CreateLaunchers)
		create_target_launcher(
			${APPLICATION_TARGET_NAME}
			RUNTIME_LIBRARY_DIRS "%VTK_DIR%/bin/$(OutDir)" "%ITK_DIR%/bin/$(OutDir)"
		)
	endif( MSVC )

endif() #APPLICATION_${APPLICATION_NAME_CMAKE}
982
  
983
984
985
986
endmacro()



987
988
989
990
991
992
993
994
995
996

# MACRO initXmlSubProject
#
# Initialize the xml_subprojects variable to gather CamiTK subprojects
#
# usage:
# initXmlSubProject()
macro(initXmlSubProject)

	set(CAMITK_XML_PROJECT_DESCRIPTION "<Project name=\"CamiTK\">" CACHE INTERNAL "")
997
	set(CAMITK_SUBPROJECTS "" CACHE INTERNAL "")
998
999
1000
1001
1002
1003
1004
1005
1006
1007
	
endmacro()

# MACRO addSubProject
#
# Add a subproject definition from targets and its dependencies (if any) to the variable
# Typically recursively call this function accross all targets to generate Project.xml file.
#
# usage:
# addSubProject(TARGET
1008
#		DEPENDENCIES)
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
# TARGET : the library / exe program targeted for CMake compilation
# DEPENDENCIES : (optional) the library dependencies to build the target
macro(addSubProject target)

	# Create the xml node for this current subproject
	set(xml_subproject "\n  <SubProject name=\"${target}\">")
	foreach(dependency ${ARGN})
		set(xml_subproject ${xml_subproject} "\n    <Dependency name=\"${dependency}\"/>")
	endforeach()
	set(xml_subproject ${xml_subproject} "  </SubProject>")
	# Please note that no "\n" character is used, avoiding cmake cache to throw an "Offending entry"
	# At the moment I did not find a way to solve this one.
	
	# Add it to the list of different nodes
	set(CAMITK_XML_PROJECT_DESCRIPTION ${CAMITK_XML_PROJECT_DESCRIPTION} ${xml_subproject} CACHE INTERNAL "")
1024
	set(CAMITK_SUBPROJECTS ${CAMITK_SUBPROJECTS} ${target} CACHE INTERNAL "")
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
	
endmacro()
 
# MACRO validateXmlSubProjects
#
# Validate the xml_subprojects variable by ending its xml tag
# i.e. By adding the closing </Project> xml node, this will close the xml data
# Then create the 'dir'/Project.xml file 
# Use this file to send to the DashBoard to get the CamiTK project and subprojects definition
#
# usage:
# validateXmlSubProjects(DIR)
# DIR: The path to the directory where to store the xml data file
macro(validateXmlSubProjects dir)

1040
1041
	# Add apidoc subproject at the end
	set(CAMITK_XML_PROJECT_DESCRIPTION ${CAMITK_XML_PROJECT_DESCRIPTION} "\n  <SubProject name=\"apidoc\">\n  </SubProject>")
1042
1043
1044
	
	# Add packaging subproject at the end
	set(CAMITK_XML_PROJECT_DESCRIPTION ${CAMITK_XML_PROJECT_DESCRIPTION} "\n  <SubProject name=\"package\">\n  </SubProject>")
1045

1046
	# Write down the Project.xml file 
1047
1048
1049
	set(CAMITK_XML_PROJECT_DESCRIPTION ${CAMITK_XML_PROJECT_DESCRIPTION} "\n</Project>")
	set(filename "${dir}/Project.xml")
	file(WRITE ${filename} ${CAMITK_XML_PROJECT_DESCRIPTION})
1050
1051
1052
1053
1054
1055
	message(STATUS "Generated ${filename} for project description")

	#Write down subprojects.cmake filename 
	set(filename "${dir}/Subprojects.cmake")
	file(WRITE ${filename} "set(CAMITK_SUBPROJECTS ${CAMITK_SUBPROJECTS})")
	message(STATUS "Generated ${filename} for subprojects listing")
1056
1057

endmacro()