Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

CamiTKMacros.cmake 47.5 KB
Newer Older
1
#
2
# CamitK Macros
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
#

# 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
33

34
35
36
37
macro(gather_headers_and_sources Name)
  # gather all possible C++ and Qt sources
  if (${ARGC} EQUAL 1)
    file(GLOB_RECURSE HEADERS *.h)
38
    file(GLOB_RECURSE SRCS *.cpp *.c)
39
40
41
42
43
    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 )
44
    file(GLOB_RECURSE SRCS ${ARGV1}/*.cpp *.c)
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
    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}
  )
81
endmacro()
82
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

# 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
124

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

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

132
133
134
135
136
137
138
#!
#! \addtogroup CamiTKMacros
#!
#! export_headers is a macro that install header files at build and install time
#!
#! Duplicate headers installation:
#! - one is used at compiled time and puts everything in 
139
#!   ${CMAKE_BINARY_DIR}/include/${GroupName}/${ComponentName}/${SubdirName} 
140
#! - the other one is used at installation time and puts everything in 
141
142
#!   ${CMAKE_INSTALL_PREFIX}/include/${GroupName}/${ComponentName}/${SubdirName}
#! 
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#! Usage:
#! \code
#! export_headers(HeaderFile1.h HeaderFile2.h ...
#!                COMPONENT ComponentName
#!                [GROUP GroupName]
#!                [SUBDIRECTORY SubdirName]
#! )
#! \endcode
#!
#! \param HeaderFileX.h (required)   A list of header files to install
#! \param COMPONENT                  name of the component to use. This is also the include subdirectory name
#!                                   used for copying the file
#! \param GROUP (optional)           the name of the group this install should be using group will be
#!                                   prepend to the component name.
#! \param SUBDIRECTORY (optional)    subdirectory to use in ${CAMITK_INCLUDE_DIR}/include/${ComponentName}
#!
#! Example invocation:
#!
#! \code
#! 
#! #--------------
#! # installation
#! #--------------
#! export_headers(${MYPROJECT_HEADERS}
#!                COMPONENT ${MYPROJECT_NAME}
#! )
#!
#! \endcode
171
macro(export_headers)
172

173
  parse_arguments(EXPORT_HEADER 
174
    "COMPONENT;SUBDIRECTORY;GROUP;"  # possible lists
175
    "" # no possible options
176
177
178
    ${ARGN}
  )

179
180
181
  # special case for components: remove prefix for the destination directory
  string(REGEX REPLACE "^component-|^action-" "" EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_COMPONENT})
  
182
183
184
  # define where to install files
  set(EXPORT_HEADER_INCLUDE_DIR ${CMAKE_BINARY_DIR}/include)
  set(EXPORT_HEADER_INSTALL_ROOT ${CMAKE_INSTALL_PREFIX})
185
  
186
187
188
  # Check group
  if(EXPORT_HEADER_GROUP)
    # check directory
189
    if (NOT EXISTS ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_GROUP})
190
191
      add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                        POST_BUILD
192
193
                        COMMAND ${CMAKE_COMMAND} -E make_directory ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}
                        COMMENT "Creating build-time group include dir ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_GROUP}"
194
195
                        VERBATIM
      )
196
    endif()
197
198
    set(EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_GROUP}/${EXPORT_HEADER_DESTINATION})
  endif()
199

200
  # check that the directory exists otherwise create it
201
  if (NOT EXISTS ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION})
202
203
    add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                      POST_BUILD
204
205
                      COMMAND ${CMAKE_COMMAND} -E make_directory ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}
                      COMMENT "Creating build-time include dir ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}"
206
                      VERBATIM
207
    )
208
209
210
211
212
213
  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
214
    if (NOT EXISTS ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION})
215
      add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
216
                        POST_BUILD
217
218
                        COMMAND ${CMAKE_COMMAND} -E make_directory ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}
                        COMMENT "Creating build-time include subdir ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}"
219
220
221
222
                        VERBATIM
      )
    endif()
  endif()
223
  
224

225
226
227
228
229
  # 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})
   
230
    # copy after build, only if there was a change
231
232
    add_custom_command(TARGET ${EXPORT_HEADER_COMPONENT}
                       POST_BUILD
233
                       COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE_TO_COPY} ${EXPORT_HEADER_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}/
234
235
236
237
238
                       COMMENT "Installing build-time header ${HEADER}"
                       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                       VERBATIM
    )
  endforeach()
239

240
241
  # during installation, copy the files to install directory
  install(FILES ${EXPORT_HEADER_DEFAULT_ARGS} 
242
          DESTINATION ${EXPORT_HEADER_INSTALL_ROOT}/include/${CAMITK_SHORT_VERSION_STRING}/${EXPORT_HEADER_DESTINATION}/	
243
          COMPONENT ${EXPORT_HEADER_COMPONENT}
244
  )
245

246
endmacro()
247

248

249
# MACRO camitk_extension
250
#
251
# Simplify writing a camitk extension (component, action) 
252
253
# 
# usage:
254
255
#    extension(<type>
#                     [DEFAULT]
256
257
#                     [NEEDS_ITK]
#                     [NEEDS_LIBXML2]
258
259
#                     [NEEDS_OPENCV]
#                     [NEEDS_IGSTK]
260
#                     [NEEDS_XSD]
261
#                     [NEEDS_QTXML]
262
263
264
265
266
267
268
269
#                     [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]
270
271
#                     [TARGET_NAME non-default-targetname]
#     )
272
#
273
# The name of the extension is automatically the name of the directory from where this macro
274
275
# is called.
#
276
# <type>					= The selected type of extension you wish to build.
277
278
279
#							  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. 
280
#                             Do not forget to add the needed list of itk libraries in the LIBRARIES parameter
281
# NEEDS_LIBXML2             = add this if your component needs libxml2 
282
# NEEDS_XSD                 = add this if your action needs Codesynthesis xsd cxx (xml schema compiler)
283
284
# NEEDS_OPENCV              = add this if your component needs OpenCV
# NEEDS_IGSTK               = add this if your component needs IgsTK
285
# NEEDS_XERCESC             = add this if your action / component needs XercesC library
286
# NEEDS_QTXML               = this application needs QtXML
287
288
# NEEDS_TOOL                = list of needed camitk tools
# NEEDS_COMPONENT_EXTENSION = list of needed component extensions
289
# NEEDS_ACTION_EXTENSION 	= list of needed component extensions
290
291
292
293
294
295
296
297
298
299
300
301
# 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
302
303
304
305
#                             making a list and using HEADERS_TO_INSTALL parameter instead!
# TARGET_NAME               = specify a target name different than the default (default is the action/component directory name)
#                             this can be very useful for example when you have action/component directory in your CEP that has
#                             the same name as one in the camitk opensource
306
307
308
macro(camitk_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} EXTENSION_NAME)
309
  
310
  parse_arguments(${EXTENSION_NAME_CMAKE} #prefix
311
    "NEEDS_TOOL;NEEDS_CEP_TOOL;NEEDS_COMPONENT_EXTENSION;NEEDS_ACTION_EXTENSION;INCLUDE_DIRECTORIES;LIBRARIES;HEADERS_TO_INSTALL;DEFINES;EXTERNAL_SOURCES;TARGET_NAME"  # possible lists
312
    "ACTION_EXTENSION;COMPONENT_EXTENSION;DEFAULT;NEEDS_XERCESC;NEEDS_ITK;NEEDS_LIBXML2;NEEDS_XSD;NEEDS_QTXML;NEEDS_OPENCV;NEEDS_IGSTK;INSTALL_ALL_HEADERS" # possible options
313
314
315
    ${ARGN}
  )

316
317
318
319
320
321
322
  # 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)
323
324
  endif()

325
326
  # 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)
327
328
329
330
331
332
333
334
335
336
    # 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}")
337
    set(CAMITK_${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL TRUE CACHE INTERNAL "Is variable ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME} already created?")
338
    mark_as_advanced(CAMITK_${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL)
339
340
  endif()
  
341
342
  # if this extension is enabled, do everything needed
  # otherwise... do nothing
343
344
  if (${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE})   

345
    # check for target name
346
347
348
349
350
    if (${EXTENSION_NAME_CMAKE}_TARGET_NAME)
        set(${TYPE_EXTENSION_CMAKE}_TARGET_NAME ${${EXTENSION_NAME_CMAKE}_TARGET_NAME})
    else()
        set(${TYPE_EXTENSION_CMAKE}_TARGET_NAME ${TYPE_EXTENSION}-${EXTENSION_NAME})
    endif()
351
352
    message(STATUS "Building extension ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}")
    
353
    # actions are compiled as shared object 
354
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${TYPE_EXTENSION}s) 
355

356
357
    # 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) 
358
359
360
361
362

    # include directories
    include_directories(${CAMITK_INCLUDE_DIRECTORIES})
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
363
    include_directories(${${EXTENSION_NAME_CMAKE}_INCLUDE_DIRECTORIES})
364
365

    # check definitions
366
367
    if(${EXTENSION_NAME_CMAKE}_DEFINES)
      foreach (FLAG ${${EXTENSION_NAME_CMAKE}_DEFINES})
368
369
370
371
        add_definitions(-D${FLAG})
      endforeach()
    endif()

promayon's avatar
promayon committed
372
373
    # check for needed tool
    set(TOOL_LIBRARIES)
374
375
    if(${EXTENSION_NAME_CMAKE}_NEEDS_TOOL)
      foreach(TOOL_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_TOOL})
promayon's avatar
promayon committed
376
        string(TOUPPER ${TOOL_NEEDED} ${TOOL_NEEDED}_INTERNAL)
377
        set(TOOL_${${TOOL_NEEDED}_INTERNAL} ON CACHE BOOL "Required by action extension ${EXTENSION_NAME}" FORCE )
promayon's avatar
promayon committed
378
        set(TOOL_LIBRARIES ${TOOL_LIBRARIES} ${TOOL_NEEDED})
379
380
        include_directories(${CAMITK_INCLUDE_DIR}/${TOOL_NEEDED}) # TODO remove this
		include_directories(${CMAKE_BINARY_DIR}/include/${TOOL_NEEDED})
promayon's avatar
promayon committed
381
382
383
      endforeach()
    endif()

384
 	# Looking for ITK
385
    set(ITK_LIBRARIES "")
386
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ITK)
387
388
389
      # ITK is required
      find_package(ITK REQUIRED)
      include(${ITK_USE_FILE})
390
      set(ITK_LIBRARIES ITKBasicFilters ITKCommon ITKIO)
391
392
    else()
      set(ITK_LIBRARIES "")
393
394
    endif()

395
   # Looking for LibXML2.0
396
    set(LIBXML2_LIBRARIES)
397
    if(${EXTENSION_NAME_CMAKE}_NEEDS_LIBXML2) 
398
      # LibXml2 is required
399
      find_package(Xml2)
400
401
402
403
404
      if (LIBXML2_FOUND)
        add_definitions(${LIBXML2_DEFINITIONS})
        include_directories(${LIBXML2_INCLUDE_DIR})      
      else()
        # most probably win32 or crosscompiling
405
        message(STATUS "${EXTENSION_NAME}: libxml2 required")
406
407
408
      endif()
    endif()
	
409
    # looking for OpenCV
410
    set(OpenCV_LIBRARIES "")
411
    if(${EXTENSION_NAME_CMAKE}_NEEDS_OPENCV) 
412
413
		# OpenCV is required
		find_package( OpenCV REQUIRED )
414
415
	else ( )
		set(OpenCV_LIBRARIES "")
416
417
	endif()

418
    #looking for IGSTK libraries ?
419
    set(IGSTK_LIBRARIES "")
420
    if(${EXTENSION_NAME_CMAKE}_NEEDS_IGSTK)
421
422
		find_package(IGSTK REQUIRED)
		include(${IGSTK_USE_FILE})	
promayon's avatar
promayon committed
423
	else()
424
425
426
		set(IGSTK_LIBRARIES "")
	endif()

promayon's avatar
promayon committed
427
428
    # Looking for XercesC
    set(XERCESC_LIBRARIES)
429
    if(${EXTENSION_NAME_CMAKE}_NEEDS_XERCESC)
promayon's avatar
promayon committed
430
431
432
433
434
435
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
      else()
        # most probably win32 or crosscompiling
436
        message(STATUS "${EXTENSION_NAME}: xerces-c required")
promayon's avatar
promayon committed
437
438
439
440
      endif()
    endif()

    # Looking for codesynthesis XSD CXX
441
    if(${EXTENSION_NAME_CMAKE}_NEEDS_XSD)
promayon's avatar
promayon committed
442
443
444
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
445
446
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
447
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
448
449
      else()
        # most probably win32 or crosscompiling
450
        message(STATUS "${EXTENSION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
451
452
453
      endif()
    endif()

454
    set(QT_LIBRARIES_WITH_QTXML)
saubatn's avatar
saubatn committed
455
    if(${EXTENSION_NAME_CMAKE}_NEEDS_QTXML)
456
457
458
459
460
461
462
463
464
465
        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()
                
466
    set(COMPONENT_EXTENSION_LIBRARIES)
467
    # check for intra-component extension
468
469
    if(${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
470
        string(TOUPPER ${COMPONENT_NEEDED} ${COMPONENT_NEEDED}_INTERNAL)
471
        set(COMPONENT_${${COMPONENT_NEEDED}_INTERNAL} ON CACHE BOOL "Required by extension ${EXTENSION_NAME}" FORCE )
472
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} ${COMPONENT_NEEDED})
473
        include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
474
475
      endforeach()
    endif()
476

477
478
    set(ACTION_EXTENSION_LIBRARIES)
    # check for intra-action extension
479
480
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
481
        string(TOUPPER ${ACTION_NEEDED} ${ACTION_NEEDED}_INTERNAL)
482
        set(ACTION_${${ACTION_NEEDED}_INTERNAL} ON CACHE BOOL "Required by extension ${EXTENSION_NAME}" FORCE )
483
        set(ACTION_EXTENSION_LIBRARIES ${ACTION_EXTENSION_LIBRARIES} ${ACTION_NEEDED})
484
        include_directories(${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED})
485
486
487
      endforeach()
    endif()

488
489
    # check for libs in all known camitk dir + actions subdir (beware of the plateform bin or lib?)
    link_directories( ${CAMITK_LIB_DIRECTORIES}
490
                      ${CAMITK_BIN_DIR}
491
                      ${CAMITK_BIN_DIR}/components
492
                      ${CAMITK_BIN_DIR}/actions
493
494
495
496
497
498
                      ${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
499
500
501
502
503
					  # For CEP
					  ${CMAKE_BINARY_DIR}/bin/components
					  ${CMAKE_BINARY_DIR}/bin/actions
					  ${CMAKE_BINARY_DIR}/bin
					  ${CMAKE_BINARY_DIR}/lib
504
505
506
507
508
    )

    # 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)
509
    gather_headers_and_sources(${EXTENSION_NAME_CMAKE})
510
	
511
    # check for external sources
512
513
    if(${EXTENSION_NAME_CMAKE}_EXTERNAL_SOURCES)
            set(${EXTENSION_NAME_CMAKE}_SOURCES ${${EXTENSION_NAME_CMAKE}_SOURCES} ${${EXTENSION_NAME_CMAKE}_EXTERNAL_SOURCES})
514
    endif()
515
516

    # build the action extension module (library)
517
    add_library(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} SHARED ${${EXTENSION_NAME_CMAKE}_SOURCES})
518
    
519
520
    # 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)
521
    camitk_sub_project_add(${TYPE_EXTENSION_CMAKE} ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} DEPENDENCIES ${CAMITK_CORE_LIB} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${TOOL_LIBRARIES})
522

523
    # Set the libraries required to link the target
524
    # An component or action has to be linked with ${CAMITK_CORE_LIB} and with all its dependencies
525
    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})
526

527
    # dependencies to core (only set for internal build)
528
    if (CAMITK_INTERNAL_BUILD)
529
      add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${CAMITK_CORE_LIB})
530
531
    endif()

532
    # see http://www.cmake.org/pipermail/cmake/2012-April/049889.html
533
    # target properties (outputname and remove soname)
534
535
536
537
538
539
540
    #  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}"
541
    )
542
543
    # set the library specific info (SONAME...)
    set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES ${${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES} LINK_INTERFACE_LIBRARIES "")
544

545
546
547
548
    # 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})
549
550
551
      endforeach()
    endif()

552
    # Set the Component(s) dependency
553
554
    if(${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
555
        string(TOUPPER ${COMPONENT_NEEDED} COMPONENT_NEEDED_CMAKE)
556
        # if this is not true, then the dependencies is from an external build, do not use add_dependencies
557
        if (CAMITK_COMPONENT_${COMPONENT_NEEDED_CMAKE}_INTERNAL)
558
559
560
561
562
            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()
563
564
565
566
        endif()
      endforeach()
    endif()

567
	# Set the Action(s) dependency
568
569
    if(${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
570
        string(TOUPPER ${ACTION_NEEDED} ACTION_NEEDED_CMAKE)
571
	# if this is not true, then the dependencies is from an external build, do not use add_dependencies
572
        if (CAMITK_ACTION_${ACTION_NEEDED_CMAKE}_INTERNAL)
573
574
575
576
577
		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() 
578
579
580
581
        endif()
      endforeach()
    endif()

582
    # generate an install target for headers
583
584
    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)
585
586
587
    endif()

    # lazy you!
588
589
    if(${EXTENSION_NAME_CMAKE}_INSTALL_ALL_HEADERS)
      export_headers(${${EXTENSION_NAME_CMAKE}_HEADERS} COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} GROUP ${TYPE_EXTENSION}s)
590
591
592
    endif()

    # lib installation
593
    install(TARGETS ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
594
            RUNTIME DESTINATION bin/${TYPE_EXTENSION}s
saubatn's avatar
saubatn committed
595
596
            LIBRARY DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
            ARCHIVE DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
597
            COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
598
599
    )

600
    # testdata files installation
601
602
    if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/testdata)
      # Check test data dir directory
603
      if (NOT EXISTS ${CMAKE_BINARY_DIR}/share/testdata)
604
605
        add_custom_command(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                          POST_BUILD
606
607
                          COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/share/testdata
                          COMMENT "Creating build-time share directory for test data ${CMAKE_BINARY_DIR}/share/testdata"
608
609
610
                          VERBATIM
        )
      endif()
611

612
613
614
      # At build time, copy the files to test data directory
      add_custom_command(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                        POST_BUILD
615
                        COMMAND ${CMAKE_COMMAND} -E copy_directory testdata ${CMAKE_BINARY_DIR}/share/testdata
616
617
618
619
620
                        COMMENT "Installing build-time test data for ${EXTENSION_NAME}"
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        VERBATIM
      )
      
621

622
      # during installation, copy the files to install directory
623
624
625
626
627
628
629
      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 ()
630
      install(DIRECTORY testdata/
631
              #DESTINATION share/testdata
632
              #DESTINATION share/${CAMITK_SHORT_VERSION_STRING}/testdata
633
              DESTINATION ${TESTDATA_DEST_DIR}
634
635
636
637
638
              COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
              PATTERN ".svn" EXCLUDE
              PATTERN "*~" EXCLUDE
      )
    endif()
639

640
  endif()
641

642
endmacro()
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
# 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
666
# The name of the tool/library is deduced from the name of the directory, unless LIBNAME is provided
667
668
669
670
671
672
673
#
# 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
674
#     SHARED|STATIC
675
676
#     SOURCES source1.cpp source1.h...
#     TARGET_LINK_LIBRARIES lib1 lib2...
promayon's avatar
promayon committed
677
#     [INCLUDE_DIRECTORIES dir1 dir2...]
678
#     [NEEDS_LIBXML2]
promayon's avatar
promayon committed
679
680
681
682
683
#     [NEEDS_XERCESC]
#     [NEEDS_XSD]
#     [LINK_DIRECTORIES dir1 dir2...]
#     [LIBNAME libname]
# )
684
685
686
687
688
# 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
689
# NEEDS_LIBXML2                 add this if the tool needs libxml2
promayon's avatar
promayon committed
690
691
692
693
# 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(...)
694
macro(camitk_tool)
promayon's avatar
promayon committed
695
  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} DEFAULT_LIBRARY_NAME)
696

promayon's avatar
promayon committed
697
698
699
  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
700
701
702
    ${ARGN}
  )

promayon's avatar
promayon committed
703
704
705
706
707
708
709
710
  # 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()
  
711
  # includes
promayon's avatar
promayon committed
712
  include_directories ( ${${DEFAULT_LIBRARY_NAME_CMAKE}_INCLUDE_DIRECTORIES}
713
714
715
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
  )
716

promayon's avatar
promayon committed
717
718
719
720
721
722
723
724
725
726
727
  # 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")
728
    endif()
promayon's avatar
promayon committed
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  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()
743

promayon's avatar
promayon committed
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  # 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()
  
763
  # Add shared or static library
promayon's avatar
promayon committed
764
  if (${DEFAULT_LIBRARY_NAME_CMAKE}_SHARED)
765
    message(STATUS "Adding shared library: ${LIBRARY_NAME}")
promayon's avatar
promayon committed
766
    add_library(${LIBRARY_NAME} SHARED ${${DEFAULT_LIBRARY_NAME_CMAKE}_SOURCES})
767
768
769
    # 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}"
770
        SOVERSION "${CAMITK_VER_MAJ}"
771
772
773
774
    )
    # 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
775
    if (${DEFAULT_LIBRARY_NAME_CMAKE}_STATIC)
776
        message(STATUS "Adding static library: ${LIBRARY_NAME}")
promayon's avatar
promayon committed
777
        add_library(${LIBRARY_NAME} STATIC ${${DEFAULT_LIBRARY_NAME_CMAKE}_SOURCES})
778
779
780
781
782
    else()
        message(FATAL_ERROR "In adding static library ${LIBRARY_NAME}.\n   Please specify the library/tool type: SHARED or STATIC")
    endif()
  endif()
  
783
784
  # 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)
785
  camitk_sub_project_add(TOOL ${LIBRARY_NAME})
786
  
787
788
789
  # 64bits and other platform with relocation needs -fPIC
  include(TestCXXAcceptsFlag)
  check_cxx_accepts_flag(-fPIC FPIC_FLAG_ACCEPTED)
promayon's avatar
promayon committed
790
  # no need to add -fPIC on mingw, otherwise it generates a warning: -fPIC ignored for target (all code is position independent) [enabled by default]
cfouard's avatar
cfouard committed
791
792
  # msvc is also accepting the flag, but then produce warning D9002 : ignoring unknown option '-fPIC'	cl
  if(FPIC_FLAG_ACCEPTED AND NOT WIN32)
793
794
795
796
    set_property(TARGET ${LIBRARY_NAME} APPEND PROPERTY COMPILE_FLAGS -fPIC)
  endif()

  #add libraries needed during the link
promayon's avatar
promayon committed
797
  target_link_libraries(${LIBRARY_NAME} ${${DEFAULT_LIBRARY_NAME_CMAKE}_TARGET_LINK_LIBRARIES} ${LIBXML2_LIBRARIES} ${XERCESC_LIBRARY})  
798
endmacro()
799
800
801
802
803
804

# MACRO application_extension
#
# Simplify writing application extension CMakeLists.txt
#
# usage:
805
806
807
# application_extension(
#        [DEFAULT]
#        [NEEDS_ITK]
808
#        [NEEDS_QTXML]
809
810
811
812
#        [NEEDS_TOOL tool1 tool2 ...]
#        [NEEDS_COMPONENT_EXTENSION component1 component2 ...]
#        [NEEDS_ACTION_EXTENSION ation1 action2 ...]
#     )
813
814
#
# where :
815
816
817
#     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
818
#     NEEDS_QTXML                 = this application needs QtXML
819
820
#     NEEDS_COMPONENT_EXTENSION   = list of needed component extensions
#     NEEDS_ACTION_EXTENSION      = list of needed component extensions
821
822
#
# The name of the application is automatically the name of the directory from where this macro
823
# is called prefixed with "camitk-"
824
#
825
# 
826
827
828
macro(application_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} APPLICATION_NAME)
829
  
830
  parse_arguments(${APPLICATION_NAME_CMAKE} 
831
    "NEEDS_TOOL;NEEDS_COMPONENT_EXTENSION;NEEDS_ACTION_EXTENSION"  # possible lists
832
    "DEFAULT;NEEDS_ITK;NEEDS_QTXML;ACTION_EXTENSION;COMPONENT_EXTENSION;NEEDS_XSD;NEEDS_XERCESC" # possible options
833
834
    ${ARGN}
  )
835
  
836
837
838
  # 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}")
839
840
841
842
843
844
845
846
847
848
    # 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}")
849
    set(CAMITK_APPLICATION_${APPLICATION_NAME_CMAKE}_INTERNAL TRUE CACHE INTERNAL "Is variable APPLICATION_${APPLICATION_NAME} already created?")
850
851
852
853
854
855
856
857
    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
858
859
860
861
862
863
864
865
866
867
868
    # 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()
869
870
871
872
873
874
875
876
877
878
	
	# 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
879
880
881
882
883
884
885
886
887
888
889
890
891

    # 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()
892
893
894
895
896
897
898
899
900
901
902
903
    
    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
904
905
906
907
908
909

    # Looking for codesynthesis XSD CXX
    if(${APPLICATION_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
910
911
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
912
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
913
914
      else()
        # most probably win32 or crosscompiling
915
        message(STATUS "${APPLICATION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
916
917
      endif()
    endif()
918
919
920
    
    # Looking for required component that this application needs
    set(COMPONENT_EXTENSION_LIBRARIES)
921
    # check for intra-component extension
922
923
924
925
    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 )
926
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} component-${COMPONENT_NEEDED})
927
928
            include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
        endforeach()
929
    endif()
930

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

934
935
    # set the directories where to seek for static and dynamic libraries at linking time.
    link_directories(${CAMITK_LIB_DIRECTORIES} ${CAMITK_BIN_DIR}/components)
936
937
938
939
940
941
942
943
944
945
946
947

    # 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})

948
949
950
    # 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)
    camitk_sub_project_add(APPLICATION ${APPLICATION_TARGET_NAME} DEPENDENCIES ${COMPONENT_EXTENSION_LIBRARIES} ${CAMITK_CORE_LIB} ${TOOL_LIBRARIES})
951

952
953
    # target properties
    set_target_properties(${APPLICATION_TARGET_NAME} 
954
                          PROPERTIES OUTPUT_NAME camitk-${APPLICATION_NAME}
955
956
    )

promayon's avatar
promayon committed
957
958
959
960
961
962
    # 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()
963
964
965
966
            
    # Set the Component(s) dependency
    if(${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION)
        foreach(COMPONENT_NEEDED ${${APPLICATION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
967
        string(TOUPPER ${COMPONENT_NEEDED} COMPONENT_NEEDED_CMAKE)
968
        # if this is not true, then the dependencies is from an external build, do not use add_dependencies
969
        if (CAMITK_COMPONENT_${COMPONENT_NEEDED_CMAKE}_INTERNAL)
970
            add_dependencies(${APPLICATION_TARGET_NAME} component-${COMPONENT_NEEDED})
971
        endif()
972
        endforeach()
973
    endif()
974
975
976
977
978
979
980
        
    # 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 )
981
        set(ACTION_EXTENSION_LIBRARIES ${ACTION_EXTENSION_LIBRARIES} action-${ACTION_NEEDED})
982
983
984
                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()
985
    endif()
promayon's avatar
promayon committed
986

987
988
    # dependences to core (only set for internal build)
    if (CAMITK_INTERNAL_BUILD)
989
        add_dependencies(${APPLICATION_TARGET_NAME} ${CAMITK_CORE_LIB})
promayon's avatar
promayon committed
990
    endif()
991
992
    
    # Set the libraries needed to build the application target
993
    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})
994
            
995
996
997
998
999
    # installation
    install(TARGETS ${APPLICATION_TARGET_NAME}
            RUNTIME DESTINATION bin
            COMPONENT ${APPLICATION_TARGET_NAME}
    )
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012

    # 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 )
1013
1014

endif() #APPLICATION_${APPLICATION_NAME_CMAKE}
1015
  
1016
1017
1018
1019
endmacro()



1020

1021
# MACRO camitk_sub_project_init
1022
1023
1024
1025
#
# Initialize the xml_subprojects variable to gather CamiTK subprojects
#
# usage:
1026
1027
1028
1029
1030
1031
1032
1033
# camitk_sub_project_init()
macro(camitk_sub_project_init)
    set(CAMITK_XML_PROJECT_DESCRIPTION "<Project name=\"CamiTK\">" CACHE INTERNAL "")
    set(CAMITK_SUBPROJECTS "" CACHE INTERNAL "")
    set(CAMITK_ACTION_TARGETS "" CACHE STRING "List of CamiTK action targets" FORCE)
    set(CAMITK_COMPONENT_TARGETS "" CACHE STRING "List of CamiTK component targets" FORCE)
    set(CAMITK_TOOL_TARGETS "" CACHE STRING "List of CamiTK tool targets" FORCE)
    set(CAMITK_APPLICATION_TARGETS "" CACHE STRING "List of CamiTK application targets" FORCE)
1034
1035
endmacro()

1036
# MACRO camitk_sub_project_add
1037
1038
1039
1040
1041
#
# 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:
1042
1043
1044
1045
1046
# camitk_sub_project_add(ACTION|COMPONENT|TOOL|APPLICATION target name
#               [DEPENDENCIES dep1 dep2 dep3]
#               
# )
# TARGET_TYPE name : the library / exe program targeted for CMake compilation
1047
# DEPENDENCIES : (optional) the library dependencies to build the target
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
# 
macro(camitk_sub_project_add)
    parse_arguments(ADD_SUB_PROJECT
        "ACTION;COMPONENT;TOOL;APPLICATION;CORELIB;DEPENDENCIES"  # possible lists 
        "" #possible options
        ${ARGN}
    )

    # check types
    if(ADD_SUB_PROJECT_ACTION)
        set(SUB_PROJECT_NAME ${ADD_SUB_PROJECT_ACTION})
        set(CAMITK_ACTION_TARGETS ${CAMITK_ACTION_TARGETS} ${SUB_PROJECT_NAME} CACHE STRING "List of CamiTK action targets" FORCE)
    endif()
    if(ADD_SUB_PROJECT_COMPONENT)
        set(SUB_PROJECT_NAME ${ADD_SUB_PROJECT_COMPONENT})
        set(CAMITK_COMPONENT_TARGETS ${CAMITK_COMPONENT_TARGETS} ${SUB_PROJECT_NAME} CACHE STRING "List of CamiTK component targets" FORCE)
    endif()
    if(ADD_SUB_PROJECT_TOOL)
        set(SUB_PROJECT_NAME ${ADD_SUB_PROJECT_TOOL})
        set(CAMITK_TOOL_TARGETS ${CAMITK_TOOL_TARGETS} ${SUB_PROJECT_NAME} CACHE STRING "List of CamiTK tool targets" FORCE)
    endif()
    if(ADD_SUB_PROJECT_APPLICATION)
        set(SUB_PROJECT_NAME ${ADD_SUB_PROJECT_APPLICATION})
        set(CAMITK_APPLICATION_TARGETS ${CAMITK_APPLICATION_TARGETS} ${SUB_PROJECT_NAME} CACHE STRING "List of CamiTK applications targets" FORCE)
    endif()
    if(ADD_SUB_PROJECT_CORELIB)
        set(SUB_PROJECT_NAME ${ADD_SUB_PROJECT_CORELIB})
    endif()
    
    # Create the xml node for this current subproject
    set(xml_subproject "\n