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