CamiTKMacros.cmake 40.8 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
34
#
# 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
#
35

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

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

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
macro(get_directory_name FullPathDirectory VariableName)
  string (REGEX REPLACE ".*/([^/]*)$" "\\1" ${VariableName} ${FullPathDirectory})

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

# MACRO component_extension
#
# Simplify writing component extension CMakeLists.txt
# 
# usage:
# component_extension([DEFAULT]
#                     [NEEDS_ITK]
#                     [NEEDS_LIBXML2]
142
143
#                     [NEEDS_OPENCV]
#                     [NEEDS_IGSTK]
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#                     [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]
#                    )
#
# The name of the component is automatically the name of the directory from where this macro
# is called.
#
# DEFAULT                   = means this is a default component to be compiled automatically
# NEEDS_ITK                 = add this if your component needs itk. 
#                             Do not forget to add the needed list of itk libraries in the LIBRARIES parameter
# NEEDS_LIBXML2             = add this if your component needs libxml2 
161
# NEEDS_XSD                 = add this if your action needs Codesynthesis xsd cxx (xml schema compiler)
162
# NEEDS_OPENCV              = add this if your component needs OpenCV
163
# NEEDS_IGSTK               = add this if your component needs IgsTK
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# NEEDS_TOOL                = list of needed camitk tools
# NEEDS_COMPONENT_EXTENSION = list of needed component extensions
# 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!   
macro(component_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} COMPONENT_NAME)

  parse_arguments(${COMPONENT_NAME_CMAKE} 
    "NEEDS_TOOL;NEEDS_COMPONENT_EXTENSION;INCLUDE_DIRECTORIES;LIBRARIES;HEADERS_TO_INSTALL;DEFINES;EXTERNAL_SOURCES"  # possible lists
185
    "DEFAULT;NEEDS_ITK;NEEDS_LIBXML2;NEEDS_XSD;NEEDS_OPENCV;NEEDS_IGSTK;INSTALL_ALL_HEADERS" # possible options
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    ${ARGN}
  )

  # if it is the first cmake run, create the component variable with a correct initial value
  if(NOT CAMITK_COMPONENT_${COMPONENT_NAME_CMAKE}_INTERNAL)
    message(STATUS "Checking ${COMPONENT_NAME}")
    # add option to enable/disable this component extension
    set(COMPONENT_${COMPONENT_NAME_CMAKE} ${${COMPONENT_NAME_CMAKE}_DEFAULT} CACHE BOOL "Build component extension ${COMPONENT_NAME}")
    set(CAMITK_COMPONENT_${COMPONENT_NAME_CMAKE}_INTERNAL TRUE CACHE BOOL "Is variable COMPONENT_${COMPONENT_NAME} already created?")
    mark_as_advanced(CAMITK_COMPONENT_${COMPONENT_NAME_CMAKE}_INTERNAL)
  endif()

  message(STATUS "Building component extension ${COMPONENT_NAME}: ${COMPONENT_${COMPONENT_NAME_CMAKE}}") 

  # if this extension is enabled, do everything needed
  # otherwise... do nothing
  if (COMPONENT_${COMPONENT_NAME_CMAKE})   
    # components are compiled as shared object 
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/components) 

    # components are compiled as shared object (for dll plateform put it in BIN)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/components) 

    # include directories
    include_directories(${CAMITK_INCLUDE_DIRECTORIES})
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    include_directories(${${COMPONENT_NAME_CMAKE}_INCLUDE_DIRECTORIES})

    # check definitions
    if(${COMPONENT_NAME_CMAKE}_DEFINES)
      foreach (FLAG ${${COMPONENT_NAME_CMAKE}_DEFINES})
        add_definitions(-D${FLAG})
      endforeach()
    endif()

222
223
	# Looking for ITK
	set(ITK_LIBRARIES "")
224
225
226
227
    if(${COMPONENT_NAME_CMAKE}_NEEDS_ITK)
      # ITK is required
      find_package(ITK REQUIRED)
      include(${ITK_USE_FILE})
228
229
	else()
		set(ITK_LIBRARIES "")
230
231
    endif()

promayon's avatar
promayon committed
232
   # Looking for LibXML2.0
233
234
235
    set(LIBXML2_LIBRARIES)
    if(${COMPONENT_NAME_CMAKE}_NEEDS_LIBXML2) 
      # LibXml2 is required
236
      find_package(Xml2)
237
238
239
240
241
242
243
244
245
      if (LIBXML2_FOUND)
        add_definitions(${LIBXML2_DEFINITIONS})
        include_directories(${LIBXML2_INCLUDE_DIR})      
      else()
        # most probably win32 or crosscompiling
        message(STATUS "${COMPONENT_NAME}: libxml2 required")
      endif()
    endif()
	
promayon's avatar
promayon committed
246
247
248
249
250
251
252
253
254
255
256
257
258
    # Looking for XercesC
    set(XERCESC_LIBRARIES)
    if(${EXTENSION_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 "${EXTENSION_NAME}: xerces-c required")
      endif()
    endif()

259
260
261
262
263
264
265
    # Looking for codesynthesis XSD CXX
    if(${EXTENSION_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
266
267
        include_directories(${XSD_INCLUDE_DIR})
	  else()
268
269
270
271
272
        # most probably win32 or crosscompiling
        message(STATUS "${EXTENSION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
      endif()
    endif()

273
    set(OpenCV_LIBRARIES "")
274
275
    if(${COMPONENT_NAME_CMAKE}_NEEDS_OPENCV) 
		# OpenCV is required
276
277
278
279
		find_package(OpenCV 2 REQUIRED )
#		include( ${OpenCV_USE_FILE} )
	else(${COMPONENT_NAME_CMAKE}_NEEDS_OPENCV)
		set(OpenCV_LIBRARIES "")
280
281
	endif()

282
283
284
285
286
287
288
289
    set(IGSTK_LIBRARIES "")
    if(${COMPONENT_NAME_CMAKE}_NEEDS_IGSTK)
		find_package(IGSTK REQUIRED)
		include(${IGSTK_USE_FILE})	
	else(${COMPONENT_NAME_CMAKE}_NEEDS_IGSTK)
		set(IGSTK_LIBRARIES "")
	endif()

290
291
292
293
294
    # check for intra-component extension
    if(${COMPONENT_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${COMPONENT_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
        string(TOUPPER ${COMPONENT_NEEDED} ${COMPONENT_NEEDED}_INTERNAL)
        set(COMPONENT_${${COMPONENT_NEEDED}_INTERNAL} ON CACHE BOOL "Required by component extension ${COMPONENT_NAME}" FORCE )
295
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} component-${COMPONENT_NEEDED})
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
        include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
      endforeach()
    endif()

    # check for needed tool 
    set(TOOL_LIBRARIES)
    if(${COMPONENT_NAME_CMAKE}_NEEDS_TOOL) 
      foreach(TOOL_NEEDED ${${COMPONENT_NAME_CMAKE}_NEEDS_TOOL})
        string(TOUPPER ${TOOL_NEEDED} ${TOOL_NEEDED}_INTERNAL)
        set(TOOL_${${TOOL_NEEDED}_INTERNAL} ON CACHE BOOL "Required by component extension ${COMPONENT_NAME}" FORCE )
        set(TOOL_LIBRARIES ${TOOL_LIBRARIES} ${TOOL_NEEDED})
        include_directories(${CAMITK_INCLUDE_DIR}/${TOOL_NEEDED})
      endforeach()
    endif()

    # check for target name
    set(COMPONENT_TARGET_NAME component-${COMPONENT_NAME})

    # check for libs in all known camitk dir + components subdir (beware of the plateform bin or lib?)
    link_directories( ${CAMITK_LIB_DIRECTORIES}
                      ${CAMITK_BIN_DIR} 
                      ${CAMITK_BIN_DIR}/components 
                      ${CAMITK_INSTALL_ROOT}/lib/${CAMITK_SHORT_VERSION_STRING}/components
                      ${CAMITK_INSTALL_ROOT}/bin/components
                      ${CMAKE_CURRENT_BINARY_DIR}/../../bin/components
    )

    # 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(${COMPONENT_NAME_CMAKE})
327
328
329
330
331
    
    # check for external sources
    if(${COMPONENT_NAME_CMAKE}_EXTERNAL_SOURCES)
            set(${COMPONENT_NAME_CMAKE}_SOURCES ${${COMPONENT_NAME_CMAKE}_SOURCES} ${${COMPONENT_NAME_CMAKE}_EXTERNAL_SOURCES})
    endif()
332
333
334
335

    # build the component extension module (library)
    add_library(${COMPONENT_TARGET_NAME} SHARED ${${COMPONENT_NAME_CMAKE}_SOURCES})

336
337
338
339
	# 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(${COMPONENT_TARGET_NAME} ${CAMITK_CORE_LIB} ${${COMPONENT_EXTENSION_LIBRARIES}} ${TOOL_LIBRARIES})

340
341
342
    # dependences to component and specific libraries
    # A component has to be linked with ${CAMITK_CORE_LIB}. As CAMTIK_CORE_LIB is always a DLL/shared lib, there should
    # be no symbol loaded multiple times
343
    target_link_libraries(${COMPONENT_TARGET_NAME} ${CAMITK_LIBRARIES} ${CAMITK_CORE_LIB} ${ITK_LIBRARIES} ${LIBXML2_LIBRARIES} ${OpenCV_LIBRARIES} ${IGSTK_LIBRARIES} ${TOOL_LIBRARIES} ${COMPONENT_EXTENSION_LIBRARIES} ${${COMPONENT_NAME_CMAKE}_LIBRARIES})
344
345
346
347
348
349

    # dependences to core (only set for internal build)
    if (CAMITK_INTERNAL_BUILD)
      add_dependencies(${COMPONENT_TARGET_NAME} ${CAMITK_CORE_LIB})
    endif()

350
351
    # target properties (outputname and remove soname)
    set_property(TARGET ${COMPONENT_TARGET_NAME} PROPERTY NO_SONAME 1) 
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    set_target_properties(${COMPONENT_TARGET_NAME} 
                          PROPERTIES OUTPUT_NAME ${COMPONENT_NAME}
    )

    # tool dependencies
    if(${COMPONENT_NAME_CMAKE}_NEEDS_TOOL) 
      foreach(TOOL_NEEDED ${${COMPONENT_NAME_CMAKE}_NEEDS_TOOL})
        add_dependencies(${COMPONENT_TARGET_NAME} ${TOOL_NEEDED})
      endforeach()
    endif()

    # other component extension dependencies
    if(${COMPONENT_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${COMPONENT_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
        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)
          add_dependencies(${COMPONENT_TARGET_NAME} component-${COMPONENT_NEEDED})
        endif()
      endforeach()
    endif()

    # generate an install target for headers
    if(${COMPONENT_NAME_CMAKE}_HEADERS_TO_INSTALL)
      export_headers(${${COMPONENT_NAME_CMAKE}_HEADERS_TO_INSTALL} COMPONENT ${COMPONENT_TARGET_NAME} GROUP components)      
    endif()

    # lazy you!
    if(${COMPONENT_NAME_CMAKE}_INSTALL_ALL_HEADERS)
      export_headers(${${COMPONENT_NAME_CMAKE}_HEADERS} COMPONENT ${COMPONENT_TARGET_NAME} GROUP components)   
    endif()

    # lib installation
    install(TARGETS ${COMPONENT_TARGET_NAME}
            RUNTIME DESTINATION bin/components
            LIBRARY DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/components
            ARCHIVE DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/components
            COMPONENT ${COMPONENT_TARGET_NAME}
    )

    # 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 ${COMPONENT_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()

      # At build time, copy the files to test data directory
      add_custom_command(TARGET ${COMPONENT_TARGET_NAME}
                        POST_BUILD
                        COMMAND ${CMAKE_COMMAND} -E copy_directory testdata ${CAMITK_TESTDATA_DIR}
                        COMMENT "Installing build-time test data for ${COMPONENT_NAME}"
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        VERBATIM
      )
      

      # during installation, copy the files to install directory
415
416
417
418
419
420
421
	  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 ()
422
423
      install(DIRECTORY testdata/
			  #DESTINATION share/testdata
424
425
              #DESTINATION share/${CAMITK_SHORT_VERSION_STRING}/testdata
			  DESTINATION ${TESTDATA_DEST_DIR}
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
              COMPONENT ${COMPONENT_TARGET_NAME}
              PATTERN ".svn" EXCLUDE
              PATTERN "*~" EXCLUDE
      )
    endif()

  endif()

endmacro()







# MACRO action_extension
#
# Simplify writing action extension CMakeLists.txt
# 
# usage:
# action_extension([DEFAULT]
#                     [NEEDS_ITK]
#                     [NEEDS_LIBXML2]
450
451
#					  [NEEDS_OPENCV]
#					  [NEEDS_IGSTK]
452
453
#                     [NEEDS_TOOL tool1 tool2 ...]
#                     [NEEDS_COMPONENT_EXTENSION component1 component2 ...]
454
#                     [NEEDS_ACTION_EXTENSION action1 action2 ...]
455
456
457
458
459
460
461
462
463
464
465
466
467
468
#                     [INCLUDE_DIRECTORIES dir1 dir2 ...]
#                     [DEFINES flag1 flag2 ...]
#                     [EXTERNAL_SOURCES file1 file2 ...]
#                     [LIBRARIES lib1 lib2 ...]
#                     [HEADERS_TO_INSTALL header1.h header2.h ...]
#                     [INSTALL_ALL_HEADERS]
#                    )
#
# The name of the action is automatically the name of the directory from where this macro
# is called.
#
# DEFAULT                   = means this is a default action to be compiled automatically
# NEEDS_ITK                 = add this if your action needs itk. 
#                             Do not forget to add the needed list of itk libraries in the LIBRARIES parameter
469
470
# NEEDS_LIBXML2             = add this if your action needs libxml2
# NEEDS_XSD                 = add this if your action needs Codesynthesis xsd cxx (xml schema compiler)
471
# NEEDS_OPENCV              = add this if your action needs OpenCV
472
# NEEDS_IGSTK               = add this if your action needs IgsTK
473
474
# NEEDS_TOOL                = list of needed camitk tools
# NEEDS_COMPONENT_EXTENSION = list of needed component extensions
475
# NEEDS_ACTION_EXTENSION    = list of needed action extensions
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
# 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!   
macro(action_extension)
  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} ACTION_NAME)
  
  parse_arguments(${ACTION_NAME_CMAKE} 
493
    "NEEDS_TOOL;NEEDS_COMPONENT_EXTENSION;NEEDS_ACTION_EXTENSION;INCLUDE_DIRECTORIES;LIBRARIES;HEADERS_TO_INSTALL;DEFINES;EXTERNAL_SOURCES"  # possible lists
494
    "DEFAULT;NEEDS_ITK;NEEDS_LIBXML2;NEEDS_XSD;NEEDS_OPENCV;NEEDS_IGSTK;INSTALL_ALL_HEADERS" # possible options
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
    ${ARGN}
  )

  # if it is the first cmake run, create the action variable with a correct initial value
  if(NOT CAMITK_ACTION_${ACTION_NAME_CMAKE}_INTERNAL)
    message(STATUS "Checking ${ACTION_NAME}")
    # add option to enable/disable this action extension
    set(ACTION_${ACTION_NAME_CMAKE} ${${ACTION_NAME_CMAKE}_DEFAULT} CACHE BOOL "Build action extension ${ACTION_NAME}")
    set(CAMITK_ACTION_${ACTION_NAME_CMAKE}_INTERNAL TRUE CACHE BOOL "Is variable ACTION_${ACTION_NAME} already created?")
    mark_as_advanced(CAMITK_ACTION_${ACTION_NAME_CMAKE}_INTERNAL)
  endif()

  message(STATUS "Building action extension ${ACTION_NAME}: ${ACTION_${ACTION_NAME_CMAKE}}") 

  # if this extension is enabled, do everything needed
  # otherwise... do nothing
  if (ACTION_${ACTION_NAME_CMAKE})   
    # actions are compiled as shared object 
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/actions) 

    # actions are compiled as shared object (for dll plateform put it in BIN)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/actions) 

    # include directories
    include_directories(${CAMITK_INCLUDE_DIRECTORIES})
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    include_directories(${${ACTION_NAME_CMAKE}_INCLUDE_DIRECTORIES})

    # check definitions
    if(${ACTION_NAME_CMAKE}_DEFINES)
      foreach (FLAG ${${ACTION_NAME_CMAKE}_DEFINES})
        add_definitions(-D${FLAG})
      endforeach()
    endif()

promayon's avatar
promayon committed
531
532
533
534
535
536
537
538
539
540
541
    # check for needed tool
    set(TOOL_LIBRARIES)
    if(${ACTION_NAME_CMAKE}_NEEDS_TOOL)
      foreach(TOOL_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_TOOL})
        string(TOUPPER ${TOOL_NEEDED} ${TOOL_NEEDED}_INTERNAL)
        set(TOOL_${${TOOL_NEEDED}_INTERNAL} ON CACHE BOOL "Required by action extension ${ACTION_NAME}" FORCE )
        set(TOOL_LIBRARIES ${TOOL_LIBRARIES} ${TOOL_NEEDED})
        include_directories(${CAMITK_INCLUDE_DIR}/${TOOL_NEEDED})
      endforeach()
    endif()

542
 	# Looking for ITK
543
544
    set(ITK_LIBRARIES "")
    if(${ACTION_NAME_CMAKE}_NEEDS_ITK)
545
546
547
      # ITK is required
      find_package(ITK REQUIRED)
      include(${ITK_USE_FILE})
548
549
    else()
      set(ITK_LIBRARIES "")
550
551
    endif()

552
   # Looking for LibXML2.0
553
554
555
    set(LIBXML2_LIBRARIES)
    if(${ACTION_NAME_CMAKE}_NEEDS_LIBXML2) 
      # LibXml2 is required
556
      find_package(Xml2)
557
558
559
560
561
562
563
564
565
      if (LIBXML2_FOUND)
        add_definitions(${LIBXML2_DEFINITIONS})
        include_directories(${LIBXML2_INCLUDE_DIR})      
      else()
        # most probably win32 or crosscompiling
        message(STATUS "${ACTION_NAME}: libxml2 required")
      endif()
    endif()
	
566
    # looking for OpenCV
567
    set(OpenCV_LIBRARIES "")
568
569
570
    if(${ACTION_NAME_CMAKE}_NEEDS_OPENCV) 
		# OpenCV is required
		find_package( OpenCV REQUIRED )
571
572
	else ( )
		set(OpenCV_LIBRARIES "")
573
574
	endif()

575
    #looking for IGSTK libraries => what is that ?
576
    set(IGSTK_LIBRARIES "")
promayon's avatar
promayon committed
577
    if(${ACTION_NAME_CMAKE}_NEEDS_IGSTK)
578
579
		find_package(IGSTK REQUIRED)
		include(${IGSTK_USE_FILE})	
promayon's avatar
promayon committed
580
	else()
581
582
583
		set(IGSTK_LIBRARIES "")
	endif()

promayon's avatar
promayon committed
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    # Looking for XercesC
    set(XERCESC_LIBRARIES)
    if(${ACTION_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 "${ACTION_NAME}: xerces-c required")
      endif()
    endif()

    # Looking for codesynthesis XSD CXX
    if(${ACTION_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
602
603
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
604
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
605
606
      else()
        # most probably win32 or crosscompiling
607
        message(STATUS "${ACTION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
608
609
610
      endif()
    endif()

611
    set(COMPONENT_EXTENSION_LIBRARIES)
612
    # check for intra-component extension
613
614
615
616
    if(${ACTION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
        string(TOUPPER ${COMPONENT_NEEDED} ${COMPONENT_NEEDED}_INTERNAL)
	set(COMPONENT_${${COMPONENT_NEEDED}_INTERNAL} ON CACHE BOOL "Required by action ${ACTION_NAME}" FORCE )
617
        set(COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_EXTENSION_LIBRARIES} component-${COMPONENT_NEEDED})
618
619
620
 	include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
      endforeach()
    endif()
621

622

623
624
625
626
627
628
    set(ACTION_EXTENSION_LIBRARIES)
    # check for intra-action extension
    if(${ACTION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
        string(TOUPPER ${ACTION_NEEDED} ${ACTION_NEEDED}_INTERNAL)
	set(ACTION_${${ACTION_NEEDED}_INTERNAL} ON CACHE BOOL "Required by action ${ACTION_NAME}" FORCE )
629
        set(ACTION_EXTENSION_LIBRARIES ${ACTION_EXTENSION_LIBRARIES} action-${ACTION_NEEDED})
630
631
632
633
 	include_directories(${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED})
      endforeach()
    endif()

634

635

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
    # check for target name
    set(ACTION_TARGET_NAME action-${ACTION_NAME})

    # check for libs in all known camitk dir + actions subdir (beware of the plateform bin or lib?)
    link_directories( ${CAMITK_LIB_DIRECTORIES}
                      ${CAMITK_BIN_DIR} 
                      ${CAMITK_BIN_DIR}/components
                      ${CAMITK_BIN_DIR}/actions 
                      ${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)
    gather_headers_and_sources(${ACTION_NAME_CMAKE})
	
657
658
659
660
    # check for external sources
    if(${ACTION_NAME_CMAKE}_EXTERNAL_SOURCES)
            set(${ACTION_NAME_CMAKE}_SOURCES ${${ACTION_NAME_CMAKE}_SOURCES} ${${ACTION_NAME_CMAKE}_EXTERNAL_SOURCES})
    endif()
661
662
663
664

    # build the action extension module (library)
    add_library(${ACTION_TARGET_NAME} SHARED ${${ACTION_NAME_CMAKE}_SOURCES})

665
666
667
668
	# 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(${ACTION_TARGET_NAME} ${CAMITK_CORE_LIB} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${TOOL_LIBRARIES})

669
670
671
    # dependences to action and specific libraries
    # An action has to be linked with ${CAMITK_CORE_LIB}. As CAMTIK_CORE_LIB is always a DLL/shared lib, there should
    # be no symbol loaded multiple times
promayon's avatar
promayon committed
672
    target_link_libraries(${ACTION_TARGET_NAME} ${CAMITK_LIBRARIES} ${CAMITK_CORE_LIB} ${COMPONENT_EXTENSION_LIBRARIES} ${ITK_LIBRARIES} ${LIBXML2_LIBRARIES} ${OpenCV_LIBRARIES} ${IGSTK_LIBRARIES} ${XERCESC_LIBRARY} ${TOOL_LIBRARIES}  ${${ACTION_NAME_CMAKE}_LIBRARIES})
673
674
675
676
677
678

    # dependences to core (only set for internal build)
    if (CAMITK_INTERNAL_BUILD)
      add_dependencies(${ACTION_TARGET_NAME} ${CAMITK_CORE_LIB})
    endif()

679
680
    # target properties (outputname and remove soname)
    set_property(TARGET ${ACTION_TARGET_NAME} PROPERTY NO_SONAME 1)    
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
    set_target_properties(${ACTION_TARGET_NAME} 
                          PROPERTIES OUTPUT_NAME ${ACTION_NAME}
    )

    # tool dependencies
    if(${ACTION_NAME_CMAKE}_NEEDS_TOOL) 
      foreach(TOOL_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_TOOL})
        add_dependencies(${ACTION_TARGET_NAME} ${TOOL_NEEDED})
      endforeach()
    endif()

    # other action extension dependencies
    if(${ACTION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION) 
      foreach(COMPONENT_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
        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)
	  add_dependencies(${ACTION_TARGET_NAME} component-${COMPONENT_NEEDED})
        endif()
      endforeach()
    endif()

703
704
705
706
707
708
709
710
711
712
    if(${ACTION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION) 
      foreach(ACTION_NEEDED ${${ACTION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
        string(TOUPPER ${ACTION_NEEDED} ACTION_NEEDED_CMAKE)
	# if this is not true, then the dependencies is from an external build, do not use add_dependencies
        if (CAMITK_ACTION_${ACTION_NEEDED_CMAKE}_INTERNAL)
	  add_dependencies(${ACTION_TARGET_NAME} action-${ACTION_NEEDED})
        endif()
      endforeach()
    endif()

713
714
    # generate an install target for headers
    if(${ACTION_NAME_CMAKE}_HEADERS_TO_INSTALL)
715
      export_headers(${${ACTION_NAME_CMAKE}_HEADERS_TO_INSTALL} COMPONENT ${ACTION_TARGET_NAME} GROUP actions)
716
717
718
719
    endif()

    # lazy you!
    if(${ACTION_NAME_CMAKE}_INSTALL_ALL_HEADERS)
720
      export_headers(${${ACTION_NAME_CMAKE}_HEADERS} COMPONENT ${ACTION_TARGET_NAME} GROUP actions)
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
    endif()

    # lib installation
    install(TARGETS ${ACTION_TARGET_NAME}
            RUNTIME DESTINATION bin/actions
            LIBRARY DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/actions
            ARCHIVE DESTINATION lib/${CAMITK_SHORT_VERSION_STRING}/actions
            COMPONENT ${ACTION_TARGET_NAME}
    )
  endif()

endmacro()








# MACRO application_extension
#
# Simplify writing application extension CMakeLists.txt
#
# usage:
# application_extension([DEFAULT])
#
# The name of the application is automatically the name of the directory from where this macro
749
# is called prefixed with "camitk-"
750
751
752
753
754
755
756
#
# DEFAULT = means this is a default application to be compiled automatically
macro(application_extension)

  get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} APPLICATION_NAME)

  parse_arguments(${APPLICATION_NAME_CMAKE} 
promayon's avatar
promayon committed
757
758
    "NEEDS_TOOL"  # possible lists
    "DEFAULT;NEEDS_XSD;NEEDS_XERCESC" # possible options
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
    ${ARGN}
  )

  # 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}")
    # add option to enable/disable this application extension
    set(APPLICATION_${APPLICATION_NAME_CMAKE} ${${APPLICATION_NAME_CMAKE}_DEFAULT} CACHE BOOL "Build application ${APPLICATION_NAME}")
    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
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
    # 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()

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

    # Looking for codesynthesis XSD CXX
    if(${APPLICATION_NAME_CMAKE}_NEEDS_XSD)
      # XercesC is required
      find_package(XercesC REQUIRED)
      if (XERCESC_FOUND)
806
807
        include_directories(${XERCESC_INCLUDE_DIR})
        find_package(XSD REQUIRED)
808
        include_directories(${XSD_INCLUDE_DIR})
promayon's avatar
promayon committed
809
810
      else()
        # most probably win32 or crosscompiling
811
        message(STATUS "${APPLICATION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
promayon's avatar
promayon committed
812
813
      endif()
    endif()
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831

    # configure compiler
    include_directories(${CAMITK_INCLUDE_DIRECTORIES} ${CAMITK_INCLUDE_DIR}/${CAMITK_CORE_LIB} ${CAMITK_INCLUDE_DIR}/component ${CMAKE_CURRENT_BINARY_DIR})

    # configure linker
    link_directories(${CAMITK_LIB_DIRECTORIES})

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

832
833
834
835
	# 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(${APPLICATION_TARGET_NAME} ${CAMITK_CORE_LIB} ${TOOL_LIBRARIES})

saubatn's avatar
saubatn committed
836
    target_link_libraries(${APPLICATION_TARGET_NAME} ${CAMITK_LIBRARIES} ${CAMITK_CORE_LIB} ${TOOL_LIBRARIES} ${XERCESC_LIBRARY} )
837
838
839

    # target properties
    set_target_properties(${APPLICATION_TARGET_NAME} 
840
                          PROPERTIES OUTPUT_NAME camitk-${APPLICATION_NAME}
841
842
    )

promayon's avatar
promayon committed
843
844
845
846
847
848
849
    # 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()

850
851
    # dependences to core (only set for internal build)
    if (CAMITK_INTERNAL_BUILD)
promayon's avatar
promayon committed
852
853
	add_dependencies(${APPLICATION_TARGET_NAME} ${CAMITK_CORE_LIB})
    endif()
854
855
856
857
858
859
860
861
	
    # installation
    install(TARGETS ${APPLICATION_TARGET_NAME}
            RUNTIME DESTINATION bin
            COMPONENT ${APPLICATION_TARGET_NAME}
    )
  endif()

862
863
864
865
# For Microsoft Visual C++, sets the default application to the corresponding project
# (i.e. launches imp 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
866
867
868
869
870
871
#if ( MSVC )
#	create_target_launcher(
#		${APPLICATION_TARGET_NAME}
#		RUNTIME_LIBRARY_DIRS "%VTK_DIR%/bin/$(OutDir)" "%ITK_DIR%/bin/$(OutDir)"
#	)		
#endif( MSVC )
872
  
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
endmacro()

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

  parse_arguments(EXPORT_HEADER 
    "COMPONENT;SUBDIRECTORY;GROUP"  # possible lists
    "" # possible options
    ${ARGN}
  )

  # special case for components: remove prefix for the destination directory
905
906
  string(REGEX REPLACE "^component-|^action-" "" EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_COMPONENT})
  
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
  # 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
      )
    endif()
    set(EXPORT_HEADER_DESTINATION ${EXPORT_HEADER_GROUP}/${EXPORT_HEADER_DESTINATION})
  endif()

  # 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
    )
  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}
                        POST_BUILD
                        COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}
                        COMMENT "Creating build-time include subdir ${CAMITK_INCLUDE_DIR}/${EXPORT_HEADER_DESTINATION}"
                        VERBATIM
      )
    endif()
  endif()
  

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

  # during installation, copy the files to install directory
  install(FILES ${EXPORT_HEADER_DEFAULT_ARGS} 
          DESTINATION include/${CAMITK_SHORT_VERSION_STRING}/${EXPORT_HEADER_DESTINATION}/
          COMPONENT ${EXPORT_HEADER_COMPONENT}
  )

endmacro()

969
970
971
972
973
974
975
976
977
978

# 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 "")
979
	set(CAMITK_SUBPROJECTS "" CACHE INTERNAL "")
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
	
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
#				DEPENDENCIES)
# 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>")