]> Creatis software - FrontAlgorithms.git/blobdiff - cmake/Functions.cmake
...
[FrontAlgorithms.git] / cmake / Functions.cmake
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
new file mode 100644 (file)
index 0000000..f5a90f3
--- /dev/null
@@ -0,0 +1,453 @@
+## -------------------------------------------------------------------------
+FUNCTION(NormPaths output_files)
+SET(_out)
+FOREACH(_f ${ARGN})
+  SET(_d)
+  FILE(TO_CMAKE_PATH ${_f} _d)
+  LIST(APPEND _out ${_d})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_Qt_CPP output_files)
+SET(_out)
+FOREACH(_f ${ARGN})
+  IF(EXISTS ${_f})
+    FILE(READ ${_f} _txt)
+    STRING(FIND "${_txt}" "Q_OBJECT" _pos)
+    IF(NOT ${_pos} EQUAL -1)
+      SET(_s)
+      QT4_WRAP_CPP(_s ${_f})
+      SET(_out ${_out} ${_s})
+    ENDIF(NOT ${_pos} EQUAL -1)
+  ENDIF(EXISTS ${_f})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_Qt_UI output_files)
+NormPaths(_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_binary_dir ${PROJECT_BINARY_DIR})
+SET(_out)
+FOREACH(_f ${ARGN})
+  IF(EXISTS ${_f})
+    GET_FILENAME_COMPONENT(_name ${_f} NAME_WE)
+    GET_FILENAME_COMPONENT(_dir ${_f} DIRECTORY)
+    SET(_base_dir ${_source_dir})
+    STRING(FIND "${_dir}" "${_base_dir}" _pos)
+    IF(${_pos} EQUAL -1)
+      SET(_base_dir ${_binary_dir})
+      STRING(FIND "${_dir}" "${_base_dir}" _pos)
+    ENDIF(${_pos} EQUAL -1)
+    IF(NOT ${_pos} EQUAL -1)
+      STRING(REPLACE "${_base_dir}/" "" _dir ${_dir})
+      SET(_out_f ${_binary_dir}/${_dir}/ui_${_name}.h)
+      LIST(APPEND _out ${_out_f})
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${_out_f}
+        COMMAND Qt4::uic
+        ARGS -o ${_out_f} ${_f}
+        MAIN_DEPENDENCY ${_f} VERBATIM
+        )
+    ENDIF(NOT ${_pos} EQUAL -1)
+  ENDIF(EXISTS ${_f})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+  CreateLib
+  lib_name
+  lib_type
+  lib_source_files
+  lib_header_files
+  lib_qt_ui_files
+  lib_version
+  lib_short_version
+  )
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_sources ${lib_source_files})
+NormPaths(_headers ${lib_header_files})
+NormPaths(_qt_uis ${lib_qt_ui_files})
+
+# -- Prepare Qt4-based code
+IF(Qt4_FOUND)
+  ## -- Guess what headers sould be qt-moc'ed
+  Wrap_Qt_CPP(_qt_moc_sources ${_headers})
+  IF(_qt_moc_sources)
+    SET(_sources ${_sources} ${_qt_moc_sources})
+  ENDIF(_qt_moc_sources)
+
+  ## -- Guess what qt-ui's sould be qt-uic'ed
+  ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to change
+  ## -- the output file
+  Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
+  IF(_qt_ui_headers)
+    SET(_headers ${_headers} ${_qt_ui_headers})
+    SET(_sources ${_sources} ${_qt_ui_headers})
+  ENDIF(_qt_ui_headers)
+ENDIF(Qt4_FOUND)
+
+## -- Ok, compile library
+IF(_sources)
+  NormPaths(_cur_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+  ADD_LIBRARY(${lib_name} SHARED ${_sources} ${_headers})
+  SET_TARGET_PROPERTIES(
+    ${lib_name}
+    PROPERTIES
+    VERSION "${lib_version}"
+    SOVERSION "${lib_short_version}"
+    )
+  GENERATE_EXPORT_HEADER(
+    ${lib_name}
+    BASE_NAME ${lib_name}
+    EXPORT_MACRO_NAME ${lib_name}_EXPORT
+    EXPORT_FILE_NAME ${lib_name}_Export.h
+    STATIC_DEFINE ${lib_name}_BUILT_AS_STATIC
+    )
+  SET(${lib_name}_LIB ${lib_name} CACHE INTERNAL "Library ${lib_name}")
+ENDIF(_sources)
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+  LibFromDir
+  lib_name
+  lib_type
+  lib_source_dir
+  lib_version
+  lib_short_version
+  )
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+NormPaths(_source_dir ${lib_source_dir})
+STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
+SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
+
+## -- Some useful variables
+SET(_sources_extensions .c .cpp .cxx)
+SET(_headers_extensions .h .hpp .hxx)
+SET(_qt_ui_extensions .ui)
+SET(_dirs ${_source_dir} ${_binary_dir})
+SET(_sources)
+SET(_headers)
+SET(_qt_uis)
+
+## -- Glob source code
+FOREACH(_d ${_dirs})
+  FOREACH(_e ${_sources_extensions})
+    FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+    SET(_sources ${_sources} ${_f})
+  ENDFOREACH(_e)
+  FOREACH(_e ${_headers_extensions})
+    FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+    SET(_headers ${_headers} ${_f})
+  ENDFOREACH(_e)
+  FOREACH(_e ${_qt_ui_extensions})
+    FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+    SET(_qt_uis ${_qt_uis} ${_f})
+  ENDFOREACH(_e)
+ENDFOREACH(_d)
+
+## -- Configure some files
+FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
+FOREACH(_c ${_configs})
+
+  ## -- Build input and output names
+  NormPaths(_input_file ${_c})
+  GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
+  GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
+  STRING(REPLACE ".in" "" _output_name ${_input_name})
+  STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
+  SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
+
+  ## -- Configure file
+  CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
+
+  ## -- Add it to the correct list
+  GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
+  IF(
+      "${_output_ext}" STREQUAL ".h"
+      OR
+      "${_output_ext}" STREQUAL ".hpp"
+      OR
+      "${_output_ext}" STREQUAL ".hxx"
+      )
+    SET(_headers ${_headers})
+  ENDIF()
+  IF(
+      "${_output_ext}" STREQUAL ".c"
+      OR
+      "${_output_ext}" STREQUAL ".cpp"
+      OR
+      "${_output_ext}" STREQUAL ".cxx"
+      )
+    SET(_sources ${_sources})
+  ENDIF()
+  IF("${_output_ext}" STREQUAL ".ui")
+    SET(_qt_uis ${_qt_uis})
+  ENDIF()
+ENDFOREACH(_c)
+IF(ARGN)
+  LIST(APPEND _sources ${ARGN})
+ENDIF(ARGN)
+
+## -- Create library
+CreateLib(
+  ${lib_name} ${lib_type}
+  "${_sources}" "${_headers}" "${_qt_uis}"
+  "${lib_version}" "${lib_short_version}"
+  )
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+  CompileInstances
+  out_lib_name
+  def_file
+  number_of_files
+  prefix
+  version
+  short_version
+  )
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_def_file ${def_file})
+GET_FILENAME_COMPONENT(_def_name ${_def_file} NAME_WE)
+GET_FILENAME_COMPONENT(_def_dir ${_def_file} DIRECTORY)
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_def_dir})
+SET(_out_base "${_global_binary_dir}${_out_dir}")
+SET(_out_header "${_out_base}/${_def_name}.h")
+SET(_lib_name "${prefix}${_def_name}")
+SET(_input_extra_code "${_global_source_dir}${_out_dir}/${_def_name}_extra.cxx")
+
+## -- Infere source code filenames
+MATH(EXPR _last_range "${number_of_files}-1")
+SET(_out_code)
+FOREACH(_n RANGE 0 ${_last_range})
+  LIST(APPEND _out_code ${_out_base}/${_def_name}_${_n}.cxx)
+ENDFOREACH(_n)
+
+## -- Add extra code, if any
+SET(_all_out_code ${_out_code})
+IF(EXISTS ${_input_extra_code})
+  LIST(APPEND _all_out_code ${_input_extra_code})
+ENDIF(EXISTS ${_input_extra_code})
+
+## -- Command to write source code
+ADD_CUSTOM_COMMAND(
+  OUTPUT ${_out_header} ${_out_code}
+  DEPENDS ${cpPlugins_bash_BuildInstances_APP} ${_def_file}
+  COMMAND ${cpPlugins_bash_BuildInstances_APP} ${_def_file} ${_lib_name} ${_out_base}/${_def_name} ${number_of_files}
+  )
+
+## -- Create library
+CreateLib(
+  "${_lib_name}" SHARED
+  "${_all_out_code}" "${_out_header}" ""
+  "${version}" "${short_version}"
+  )
+
+## -- Return value
+SET(${out_lib_name} ${_lib_name} PARENT_SCOPE)
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_cpPlugins output_lib source_dir version short_version prefix)
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_source_dir ${source_dir})
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_source_dir})
+SET(_out_dir "${_global_binary_dir}${_out_dir}")
+FILE(MAKE_DIRECTORY ${_out_dir})
+GET_FILENAME_COMPONENT(_lib_name ${_source_dir} NAME_WE)
+SET(_lib_name ${prefix}${_lib_name})
+
+## -- Get source code
+FILE(GLOB_RECURSE _hdr_h   "${_source_dir}/*.h")
+FILE(GLOB_RECURSE _hdr_hxx "${_source_dir}/*.hxx")
+FILE(GLOB_RECURSE _hdr_hpp "${_source_dir}/*.hpp")
+FILE(GLOB_RECURSE _src_c   "${_source_dir}/*.c")
+FILE(GLOB_RECURSE _src_cxx "${_source_dir}/*.cxx")
+FILE(GLOB_RECURSE _src_cpp "${_source_dir}/*.cpp")
+FILE(GLOB_RECURSE _qt_ui   "${_source_dir}/*.ui")
+
+## -- Identify sources to wrap
+SET(_hdr_to_wrap)
+FOREACH(_h ${_hdr_h})
+  FILE(READ ${_h} _txt)
+  STRING(FIND "${_txt}" "cpPluginsObject" _res)
+  IF(NOT ${_res} EQUAL -1)
+    LIST(APPEND _hdr_to_wrap ${_h})
+  ENDIF(NOT ${_res} EQUAL -1)
+ENDFOREACH(_h)
+
+## -- Integrate all source files
+SET(_all_src ${_src_c} ${_src_cpp} ${_src_cxx})
+SET(_all_hdr ${_hdr_h} ${_hdr_hpp} ${_hdr_hxx})
+
+## -- Wrap plugins
+IF(_hdr_to_wrap)
+  SET(_host ${_out_dir}/${_lib_name}_host.cxx)
+  ADD_CUSTOM_COMMAND(
+    OUTPUT ${_host}
+    DEPENDS ${cpPlugins_bash_HostCreator_APP} ${_hdr_to_wrap}
+    COMMAND ${cpPlugins_bash_HostCreator_APP} ${_lib_name} ${_host} ${_hdr_to_wrap}
+    )
+  SET(_all_src ${_all_src} ${_host})
+ENDIF(_hdr_to_wrap)
+
+## -- Ok, build library
+IF(_all_src)
+  CreateLib(
+    ${_lib_name} SHARED
+    "${_all_src}" "${_all_hdr}" "${_qt_ui}"
+    "${version}" "${short_version}"
+    ${ARGN}
+    )
+  SET(${output_lib} ${_lib_name} PARENT_SCOPE)
+ELSE(_all_src)
+  MESSAGE(FATAL_ERROR "No source code found to build \"${_lib_name}\"")
+ENDIF(_all_src)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(AppFromDir output_app source_dir)
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+NormPaths(_source_dir ${source_dir})
+STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
+SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
+IF(${output_app})
+  SET(_app_name ${${output_app}})
+ELSE(${output_app})
+  GET_FILENAME_COMPONENT(_app_name ${_source_dir} NAME_WE)
+ENDIF(${output_app})
+SET(_app_name_option OFF)
+IF(ARGN)
+  LIST(GET ARGN 0 _app_name_option)
+ENDIF(ARGN)
+OPTION(
+  BUILD_${_app_name}
+  "Build \"${_app_name}\" application"
+  ${_app_name_option}
+  )
+
+## -- Real build commands
+IF(BUILD_${_app_name})
+  ## -- Some useful variables
+  SET(_sources_extensions .c .cpp .cxx)
+  SET(_headers_extensions .h .hpp .hxx)
+  SET(_qt_ui_extensions .ui)
+  SET(_dirs ${_source_dir} ${_binary_dir})
+  SET(_sources)
+  SET(_headers)
+  SET(_qt_uis)
+
+  ## -- Glob source code
+  FOREACH(_d ${_dirs})
+    FOREACH(_e ${_sources_extensions})
+      FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+      SET(_sources ${_sources} ${_f})
+    ENDFOREACH(_e)
+    FOREACH(_e ${_headers_extensions})
+      FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+      SET(_headers ${_headers} ${_f})
+    ENDFOREACH(_e)
+    FOREACH(_e ${_qt_ui_extensions})
+      FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+      SET(_qt_uis ${_qt_uis} ${_f})
+    ENDFOREACH(_e)
+  ENDFOREACH(_d)
+
+  ## -- Configure some files
+  FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
+  FOREACH(_c ${_configs})
+
+    ## -- Build input and output names
+    NormPaths(_input_file ${_c})
+    GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
+    GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
+    STRING(REPLACE ".in" "" _output_name ${_input_name})
+    STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
+    SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
+
+    ## -- Configure file
+    CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
+
+    ## -- Add it to the correct list
+    GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
+    IF(
+        "${_output_ext}" STREQUAL ".h"
+        OR
+        "${_output_ext}" STREQUAL ".hpp"
+        OR
+        "${_output_ext}" STREQUAL ".hxx"
+        )
+      SET(_headers ${_headers})
+    ENDIF()
+    IF(
+        "${_output_ext}" STREQUAL ".c"
+        OR
+        "${_output_ext}" STREQUAL ".cpp"
+        OR
+        "${_output_ext}" STREQUAL ".cxx"
+        )
+      SET(_sources ${_sources})
+    ENDIF()
+    IF("${_output_ext}" STREQUAL ".ui")
+      SET(_qt_uis ${_qt_uis})
+    ENDIF()
+  ENDFOREACH(_c)
+
+  # -- Prepare Qt4-based code
+  IF(Qt4_FOUND)
+
+    ## -- Guess what headers sould be qt-moc'ed
+    Wrap_Qt_CPP(_qt_moc_sources ${_headers})
+    IF(_qt_moc_sources)
+      SET(_sources ${_sources} ${_qt_moc_sources})
+    ENDIF(_qt_moc_sources)
+    ## -- Guess what qt-ui's sould be qt-uic'ed
+    ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to
+    ## -- change the output file
+    Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
+    IF(_qt_ui_headers)
+      SET(_headers ${_headers} ${_qt_ui_headers})
+      SET(_sources ${_sources} ${_qt_ui_headers})
+    ENDIF(_qt_ui_headers)
+  ENDIF(Qt4_FOUND)
+
+  ## -- Ok, compile application
+  IF(_sources)
+    SET(_gui_type "")
+    IF(WIN32)
+      SET(_gui_type WIN32)
+    ENDIF(WIN32)
+    IF(APPLE)
+      SET(_gui_type MACOSX_BUNDLE)
+    ENDIF(APPLE)
+    ADD_EXECUTABLE(${_app_name} ${_gui_type} ${_sources})
+    SET(${output_app} ${_app_name} PARENT_SCOPE)
+  ELSE(_sources)
+    SET(${output_app} "" PARENT_SCOPE)
+    MESSAGE(FATAL_ERROR "No source code found to build \"${_app_name}\"")
+  ENDIF(_sources)
+ENDIF(BUILD_${_app_name})
+
+ENDFUNCTION()
+
+## eof - $RCSfile$