]> Creatis software - cpPlugins.git/blob - cmake/Functions.cmake
287e69344f0f7a5ddc2b33ddcea4a020fe63f0dc
[cpPlugins.git] / cmake / Functions.cmake
1 ## -------------------------------------------------------------------------
2 FUNCTION(NormPaths output_files)
3 SET(_out)
4 FOREACH(_f ${ARGN})
5   SET(_d)
6   FILE(TO_CMAKE_PATH ${_f} _d)
7   LIST(APPEND _out ${_d})
8 ENDFOREACH(_f)
9 SET(${output_files} "${_out}" PARENT_SCOPE)
10 ENDFUNCTION()
11
12 ## -------------------------------------------------------------------------
13 FUNCTION(Wrap_Qt_CPP output_files)
14 SET(_out)
15 FOREACH(_f ${ARGN})
16   IF(EXISTS ${_f})
17     FILE(READ ${_f} _txt)
18     STRING(FIND "${_txt}" "Q_OBJECT" _pos)
19     IF(NOT ${_pos} EQUAL -1)
20       SET(_s)
21       QT4_WRAP_CPP(_s ${_f})
22       SET(_out ${_out} ${_s})
23     ENDIF(NOT ${_pos} EQUAL -1)
24   ENDIF(EXISTS ${_f})
25 ENDFOREACH(_f)
26 SET(${output_files} "${_out}" PARENT_SCOPE)
27 ENDFUNCTION()
28
29 ## -------------------------------------------------------------------------
30 FUNCTION(Wrap_Qt_UI output_files)
31 NormPaths(_source_dir ${PROJECT_SOURCE_DIR})
32 NormPaths(_binary_dir ${PROJECT_BINARY_DIR})
33 SET(_out)
34 FOREACH(_f ${ARGN})
35   IF(EXISTS ${_f})
36     GET_FILENAME_COMPONENT(_name ${_f} NAME_WE)
37     GET_FILENAME_COMPONENT(_dir ${_f} DIRECTORY)
38     SET(_base_dir ${_source_dir})
39     STRING(FIND "${_dir}" "${_base_dir}" _pos)
40     IF(${_pos} EQUAL -1)
41       SET(_base_dir ${_binary_dir})
42       STRING(FIND "${_dir}" "${_base_dir}" _pos)
43     ENDIF(${_pos} EQUAL -1)
44     IF(NOT ${_pos} EQUAL -1)
45       STRING(REPLACE "${_base_dir}/" "" _dir ${_dir})
46       SET(_out_f ${_binary_dir}/${_dir}/ui_${_name}.h)
47       LIST(APPEND _out ${_out_f})
48       ADD_CUSTOM_COMMAND(
49         OUTPUT ${_out_f}
50         COMMAND Qt4::uic
51         ARGS -o ${_out_f} ${_f}
52         MAIN_DEPENDENCY ${_f} VERBATIM
53         )
54     ENDIF(NOT ${_pos} EQUAL -1)
55   ENDIF(EXISTS ${_f})
56 ENDFOREACH(_f)
57 SET(${output_files} "${_out}" PARENT_SCOPE)
58 ENDFUNCTION()
59
60 ## -------------------------------------------------------------------------
61 FUNCTION(
62   CreateLib
63   lib_name
64   lib_dir
65   lib_type
66   lib_source_files
67   lib_header_files
68   lib_qt_ui_files
69   lib_version
70   lib_short_version
71   )
72 ## -- Configure inputs to be cmake-path compatible
73 NormPaths(_sources ${lib_source_files})
74 NormPaths(_headers ${lib_header_files})
75 NormPaths(_qt_uis ${lib_qt_ui_files})
76
77 # -- Prepare Qt4-based code
78 IF(Qt4_FOUND)
79   ## -- Guess what headers sould be qt-moc'ed
80   Wrap_Qt_CPP(_qt_moc_sources ${_headers})
81   IF(_qt_moc_sources)
82     SET(_sources ${_sources} ${_qt_moc_sources})
83   ENDIF(_qt_moc_sources)
84
85   ## -- Guess what qt-ui's sould be qt-uic'ed
86   ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to change
87   ## -- the output file
88   Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
89   IF(_qt_ui_headers)
90     SET(_headers ${_headers} ${_qt_ui_headers})
91     SET(_sources ${_sources} ${_qt_ui_headers})
92   ENDIF(_qt_ui_headers)
93 ENDIF(Qt4_FOUND)
94
95 ## -- Ok, compile library
96 IF(_sources)
97   NormPaths(_cur_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
98   ADD_LIBRARY(${lib_name} ${lib_type} ${_sources} ${_headers})
99   #SET_TARGET_PROPERTIES(
100   #  ${lib_name}
101   #  PROPERTIES
102   #  VERSION "${lib_version}"
103   #  SOVERSION "${lib_short_version}"
104   #  )
105   GENERATE_EXPORT_HEADER(
106     ${lib_name}
107     BASE_NAME ${lib_name}
108     EXPORT_MACRO_NAME ${lib_name}_EXPORT
109     EXPORT_FILE_NAME ${lib_name}_Export.h
110     STATIC_DEFINE ${lib_name}_BUILT_AS_STATIC
111     )
112   SET(${lib_name}_LIB ${lib_name} CACHE INTERNAL "Library ${lib_name}")
113 ENDIF(_sources)
114
115 ENDFUNCTION()
116
117 ## -------------------------------------------------------------------------
118 FUNCTION(
119   LibFromDir
120   lib_name
121   lib_dir
122   lib_type
123   lib_source_dir
124   lib_version
125   lib_short_version
126   )
127
128 ## -- Configure inputs to be cmake-path compatible
129 NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
130 NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
131 NormPaths(_source_dir ${lib_source_dir})
132 STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
133 SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
134
135 ## -- Some useful variables
136 SET(_sources_extensions .c .cpp .cxx)
137 SET(_headers_extensions .h .hpp .hxx)
138 SET(_qt_ui_extensions .ui)
139 SET(_dirs ${_source_dir} ${_binary_dir})
140 SET(_sources)
141 SET(_headers)
142 SET(_qt_uis)
143
144 ## -- Glob source code
145 FOREACH(_d ${_dirs})
146   FOREACH(_e ${_sources_extensions})
147     FILE(GLOB_RECURSE _f "${_d}/*${_e}")
148     SET(_sources ${_sources} ${_f})
149   ENDFOREACH(_e)
150   FOREACH(_e ${_headers_extensions})
151     FILE(GLOB_RECURSE _f "${_d}/*${_e}")
152     SET(_headers ${_headers} ${_f})
153   ENDFOREACH(_e)
154   FOREACH(_e ${_qt_ui_extensions})
155     FILE(GLOB_RECURSE _f "${_d}/*${_e}")
156     SET(_qt_uis ${_qt_uis} ${_f})
157   ENDFOREACH(_e)
158 ENDFOREACH(_d)
159
160 ## -- Configure some files
161 FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
162 FOREACH(_c ${_configs})
163
164   ## -- Build input and output names
165   NormPaths(_input_file ${_c})
166   GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
167   GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
168   STRING(REPLACE ".in" "" _output_name ${_input_name})
169   STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
170   SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
171
172   ## -- Configure file
173   CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
174
175   ## -- Add it to the correct list
176   GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
177   IF(
178       "${_output_ext}" STREQUAL ".h"
179       OR
180       "${_output_ext}" STREQUAL ".hpp"
181       OR
182       "${_output_ext}" STREQUAL ".hxx"
183       )
184     SET(_headers ${_headers})
185   ENDIF()
186   IF(
187       "${_output_ext}" STREQUAL ".c"
188       OR
189       "${_output_ext}" STREQUAL ".cpp"
190       OR
191       "${_output_ext}" STREQUAL ".cxx"
192       )
193     SET(_sources ${_sources})
194   ENDIF()
195   IF("${_output_ext}" STREQUAL ".ui")
196     SET(_qt_uis ${_qt_uis})
197   ENDIF()
198 ENDFOREACH(_c)
199 IF(ARGN)
200   LIST(APPEND _sources ${ARGN})
201 ENDIF(ARGN)
202
203 ## -- Create library
204 CreateLib(
205   ${lib_name} ${lib_dir} ${lib_type}
206   "${_sources}" "${_headers}" "${_qt_uis}"
207   "${lib_version}" "${lib_short_version}"
208   )
209
210 ENDFUNCTION()
211
212 ## -------------------------------------------------------------------------
213 FUNCTION(
214   CompileInstances
215   out_lib_name
216   lib_dir
217   def_file
218   number_of_files
219   prefix
220   version
221   short_version
222   )
223 ## -- Configure inputs to be cmake-path compatible
224 NormPaths(_def_file ${def_file})
225 GET_FILENAME_COMPONENT(_def_name ${_def_file} NAME_WE)
226 GET_FILENAME_COMPONENT(_def_dir ${_def_file} DIRECTORY)
227 NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
228 NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
229 STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_def_dir})
230 SET(_out_base "${_global_binary_dir}${_out_dir}")
231 SET(_out_header "${_out_base}/${_def_name}.h")
232 SET(_lib_name "${prefix}${_def_name}")
233 SET(_input_extra_code "${_global_source_dir}${_out_dir}/${_def_name}_extra.cxx")
234
235 ## -- Infere source code filenames
236 MATH(EXPR _last_range "${number_of_files}-1")
237 SET(_out_code)
238 FOREACH(_n RANGE 0 ${_last_range})
239   LIST(APPEND _out_code ${_out_base}/${_def_name}_${_n}.cxx)
240 ENDFOREACH(_n)
241
242 ## -- Add extra code, if any
243 SET(_all_out_code ${_out_code})
244 IF(EXISTS ${_input_extra_code})
245   LIST(APPEND _all_out_code ${_input_extra_code})
246 ENDIF(EXISTS ${_input_extra_code})
247
248 ## -- Command to write source code
249 ADD_CUSTOM_COMMAND(
250   OUTPUT ${_out_header} ${_out_code}
251   DEPENDS ${cpPlugins_bash_BuildInstances_APP} ${_def_file}
252   COMMAND ${cpPlugins_bash_BuildInstances_APP} ${_def_file} ${_lib_name} ${_out_base}/${_def_name} ${number_of_files}
253   )
254
255 ## -- Create library
256 CreateLib(
257   "${_lib_name}" ${lib_dir} SHARED
258   "${_all_out_code}" "${_out_header}" ""
259   "${version}" "${short_version}"
260   )
261
262 ## -- Return value
263 SET(${out_lib_name} ${_lib_name} PARENT_SCOPE)
264
265 ENDFUNCTION()
266
267 ## -------------------------------------------------------------------------
268 FUNCTION(Wrap_cpPlugins output_lib source_dir version short_version prefix)
269
270 ## -- Configure inputs to be cmake-path compatible
271 NormPaths(_source_dir ${source_dir})
272 NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
273 NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
274 STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_source_dir})
275 SET(_out_dir "${_global_binary_dir}${_out_dir}")
276 FILE(MAKE_DIRECTORY ${_out_dir})
277 GET_FILENAME_COMPONENT(_lib_name ${_source_dir} NAME_WE)
278 SET(_lib_name ${prefix}${_lib_name})
279
280 ## -- Get source code
281 FILE(GLOB_RECURSE _hdr_h   "${_source_dir}/*.h")
282 FILE(GLOB_RECURSE _hdr_hxx "${_source_dir}/*.hxx")
283 FILE(GLOB_RECURSE _hdr_hpp "${_source_dir}/*.hpp")
284 FILE(GLOB_RECURSE _src_c   "${_source_dir}/*.c")
285 FILE(GLOB_RECURSE _src_cxx "${_source_dir}/*.cxx")
286 FILE(GLOB_RECURSE _src_cpp "${_source_dir}/*.cpp")
287 FILE(GLOB_RECURSE _qt_ui   "${_source_dir}/*.ui")
288
289 ## -- Identify sources to wrap
290 SET(_hdr_to_wrap)
291 FOREACH(_h ${_hdr_h})
292   FILE(READ ${_h} _txt)
293   STRING(FIND "${_txt}" "cpPluginsObject" _res)
294   IF(NOT ${_res} EQUAL -1)
295     LIST(APPEND _hdr_to_wrap ${_h})
296   ENDIF(NOT ${_res} EQUAL -1)
297 ENDFOREACH(_h)
298
299 ## -- Integrate all source files
300 SET(_all_src ${_src_c} ${_src_cpp} ${_src_cxx})
301 SET(_all_hdr ${_hdr_h} ${_hdr_hpp} ${_hdr_hxx})
302
303 ## -- Wrap plugins
304 IF(_hdr_to_wrap)
305   SET(_host ${_out_dir}/${_lib_name}_host.cxx)
306   ADD_CUSTOM_COMMAND(
307     OUTPUT ${_host}
308     DEPENDS ${cpPlugins_bash_HostCreator_APP} ${_hdr_to_wrap}
309     COMMAND ${cpPlugins_bash_HostCreator_APP} ${_lib_name} ${_host} ${_hdr_to_wrap}
310     )
311   SET(_all_src ${_all_src} ${_host})
312 ENDIF(_hdr_to_wrap)
313
314 ## -- Ok, build library
315 IF(_all_src)
316   CreateLib(
317     ${_lib_name} leo SHARED
318     "${_all_src}" "${_all_hdr}" "${_qt_ui}"
319     "${version}" "${short_version}"
320     ${ARGN}
321     )
322   SET(${output_lib} ${_lib_name} PARENT_SCOPE)
323 ELSE(_all_src)
324   MESSAGE(FATAL_ERROR "No source code found to build \"${_lib_name}\"")
325 ENDIF(_all_src)
326 ENDFUNCTION()
327
328 ## -------------------------------------------------------------------------
329 FUNCTION(AppFromDir output_app source_dir)
330
331 ## -- Configure inputs to be cmake-path compatible
332 NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
333 NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
334 NormPaths(_source_dir ${source_dir})
335 STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
336 SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
337 IF(${output_app})
338   SET(_app_name ${${output_app}})
339 ELSE(${output_app})
340   GET_FILENAME_COMPONENT(_app_name ${_source_dir} NAME_WE)
341 ENDIF(${output_app})
342 SET(_app_name_option OFF)
343 IF(ARGN)
344   LIST(GET ARGN 0 _app_name_option)
345 ENDIF(ARGN)
346 OPTION(
347   BUILD_${_app_name}
348   "Build \"${_app_name}\" application"
349   ${_app_name_option}
350   )
351
352 ## -- Real build commands
353 IF(BUILD_${_app_name})
354   ## -- Some useful variables
355   SET(_sources_extensions .c .cpp .cxx)
356   SET(_headers_extensions .h .hpp .hxx)
357   SET(_qt_ui_extensions .ui)
358   SET(_dirs ${_source_dir} ${_binary_dir})
359   SET(_sources)
360   SET(_headers)
361   SET(_qt_uis)
362
363   ## -- Glob source code
364   FOREACH(_d ${_dirs})
365     FOREACH(_e ${_sources_extensions})
366       FILE(GLOB_RECURSE _f "${_d}/*${_e}")
367       SET(_sources ${_sources} ${_f})
368     ENDFOREACH(_e)
369     FOREACH(_e ${_headers_extensions})
370       FILE(GLOB_RECURSE _f "${_d}/*${_e}")
371       SET(_headers ${_headers} ${_f})
372     ENDFOREACH(_e)
373     FOREACH(_e ${_qt_ui_extensions})
374       FILE(GLOB_RECURSE _f "${_d}/*${_e}")
375       SET(_qt_uis ${_qt_uis} ${_f})
376     ENDFOREACH(_e)
377   ENDFOREACH(_d)
378
379   ## -- Configure some files
380   FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
381   FOREACH(_c ${_configs})
382
383     ## -- Build input and output names
384     NormPaths(_input_file ${_c})
385     GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
386     GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
387     STRING(REPLACE ".in" "" _output_name ${_input_name})
388     STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
389     SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
390
391     ## -- Configure file
392     CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
393
394     ## -- Add it to the correct list
395     GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
396     IF(
397         "${_output_ext}" STREQUAL ".h"
398         OR
399         "${_output_ext}" STREQUAL ".hpp"
400         OR
401         "${_output_ext}" STREQUAL ".hxx"
402         )
403       SET(_headers ${_headers})
404     ENDIF()
405     IF(
406         "${_output_ext}" STREQUAL ".c"
407         OR
408         "${_output_ext}" STREQUAL ".cpp"
409         OR
410         "${_output_ext}" STREQUAL ".cxx"
411         )
412       SET(_sources ${_sources})
413     ENDIF()
414     IF("${_output_ext}" STREQUAL ".ui")
415       SET(_qt_uis ${_qt_uis})
416     ENDIF()
417   ENDFOREACH(_c)
418
419   # -- Prepare Qt4-based code
420   IF(Qt4_FOUND)
421
422     ## -- Guess what headers sould be qt-moc'ed
423     Wrap_Qt_CPP(_qt_moc_sources ${_headers})
424     IF(_qt_moc_sources)
425       SET(_sources ${_sources} ${_qt_moc_sources})
426     ENDIF(_qt_moc_sources)
427     ## -- Guess what qt-ui's sould be qt-uic'ed
428     ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to
429     ## -- change the output file
430     Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
431     IF(_qt_ui_headers)
432       SET(_headers ${_headers} ${_qt_ui_headers})
433       SET(_sources ${_sources} ${_qt_ui_headers})
434     ENDIF(_qt_ui_headers)
435   ENDIF(Qt4_FOUND)
436
437   ## -- Ok, compile application
438   IF(_sources)
439     SET(_gui_type "")
440     IF(WIN32)
441       SET(_gui_type WIN32)
442     ENDIF(WIN32)
443     IF(APPLE)
444       SET(_gui_type MACOSX_BUNDLE)
445     ENDIF(APPLE)
446     ADD_EXECUTABLE(${_app_name} ${_gui_type} ${_sources})
447     SET(${output_app} ${_app_name} PARENT_SCOPE)
448   ELSE(_sources)
449     SET(${output_app} "" PARENT_SCOPE)
450     MESSAGE(FATAL_ERROR "No source code found to build \"${_app_name}\"")
451   ENDIF(_sources)
452 ENDIF(BUILD_${_app_name})
453
454 ENDFUNCTION()
455
456 ## eof - $RCSfile$