From 32c179e97c722372a5774034d22dded4cd9b82dd Mon Sep 17 00:00:00 2001
From: thomasl <thomasl@eurecom.fr>
Date: Mon, 23 Mar 2015 18:00:52 +0000
Subject: [PATCH] merge back cmake modifs from branch 0.3

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6882 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 cmake_targets/hss_build/CMakeLists.txt        |    2 +-
 .../tools/MODULES/CMakeParseArguments.cmake   |   66 +
 .../tools/MODULES/CMakeUserFindMySQL.cmake    |   48 +
 .../tools/MODULES/CMakeUserUseBison.cmake     |   71 ++
 .../tools/MODULES/CMakeUserUseFlex.cmake      |   46 +
 .../tools/MODULES/FindFreeDiameter.cmake      |   88 ++
 cmake_targets/tools/MODULES/FindGCCXML.cmake  |    8 +
 cmake_targets/tools/MODULES/FindGcrypt.cmake  |   36 +
 cmake_targets/tools/MODULES/FindGnuTLS.cmake  |   64 +
 cmake_targets/tools/MODULES/FindKbuild.cmake  |  105 ++
 cmake_targets/tools/MODULES/FindLibXml2.cmake |   53 +
 cmake_targets/tools/MODULES/FindMySQL.cmake   |   55 +
 cmake_targets/tools/MODULES/FindNettle.cmake  |   22 +
 .../tools/MODULES/FindPostgreSQL.cmake        |   36 +
 cmake_targets/tools/MODULES/FindSCTP.cmake    |   46 +
 cmake_targets/tools/MODULES/Kbuild.cmake      |    4 +
 .../tools/MODULES/cmake_useful.cmake          |  229 ++++
 .../tools/MODULES/kbuild_system.cmake         | 1131 +++++++++++++++++
 cmake_targets/tools/MODULES/kmodule.cmake     |  539 ++++++++
 .../tools/MODULES/path_prefixes.cmake         |  264 ++++
 20 files changed, 2912 insertions(+), 1 deletion(-)
 create mode 100644 cmake_targets/tools/MODULES/CMakeParseArguments.cmake
 create mode 100644 cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake
 create mode 100644 cmake_targets/tools/MODULES/CMakeUserUseBison.cmake
 create mode 100644 cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindFreeDiameter.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindGCCXML.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindGcrypt.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindGnuTLS.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindKbuild.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindLibXml2.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindMySQL.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindNettle.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindPostgreSQL.cmake
 create mode 100644 cmake_targets/tools/MODULES/FindSCTP.cmake
 create mode 100644 cmake_targets/tools/MODULES/Kbuild.cmake
 create mode 100644 cmake_targets/tools/MODULES/cmake_useful.cmake
 create mode 100644 cmake_targets/tools/MODULES/kbuild_system.cmake
 create mode 100644 cmake_targets/tools/MODULES/kmodule.cmake
 create mode 100644 cmake_targets/tools/MODULES/path_prefixes.cmake

diff --git a/cmake_targets/hss_build/CMakeLists.txt b/cmake_targets/hss_build/CMakeLists.txt
index e3bdf92821..afbc672027 100755
--- a/cmake_targets/hss_build/CMakeLists.txt
+++ b/cmake_targets/hss_build/CMakeLists.txt
@@ -49,7 +49,7 @@ set(OPENAIRHSS_DIR        ${OPENAIRCN_DIR}/OPENAIRHSS)
 set(OPENAIR_BIN_DIR       ${OPENAIR_TARGETS}/bin)
 
 
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENAIR_TARGETS}/CMAKE/MODULES/")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENAIR_CMAKE_SCRIPTS}/MODULES")
 include(cmake_useful)
 
 macro(add_option name val helpstr)
diff --git a/cmake_targets/tools/MODULES/CMakeParseArguments.cmake b/cmake_targets/tools/MODULES/CMakeParseArguments.cmake
new file mode 100644
index 0000000000..ab53b112fa
--- /dev/null
+++ b/cmake_targets/tools/MODULES/CMakeParseArguments.cmake
@@ -0,0 +1,66 @@
+# Analogue for standard CMake module with same name, appeared in CMake 2.8.3.
+#
+# Used for compatibility with older versions of cmake.
+
+function(cmake_parse_arguments prefix options one_value_keywords multi_value_keywords)
+    set(all_keywords ${options} ${one_value_keywords} ${multi_value_keywords})
+    # Clear variables before parsing.
+    foreach(arg ${one_value_keywords} ${multie_value_keywords})
+        set(cpa_${arg})
+    endforeach()
+
+    foreach(arg ${options})
+        set(cpa_${arg} FALSE)
+    endforeach()
+
+    set(cpa_UNPARSED_ARGUMENTS)
+
+    set(current_keyword)
+    # Classification for current_keyword:
+    # 'ONE' or 'MULTY'.
+    set(current_keyword_type)
+
+    # now iterate over all arguments and fill the result variables
+    foreach(arg ${ARGN})
+        list(FIND all_keywords ${arg} keyword_index)
+
+        if(keyword_index EQUAL -1)
+            if(current_keyword)
+                if(current_keyword_type STREQUAL "ONE")
+                    set(cpa_${current_keyword} ${arg})
+                    set(current_keyword)
+                else(current_keyword_type STREQUAL "ONE")
+                    list(APPEND cpa_${current_keyword} ${arg})
+                endif(current_keyword_type STREQUAL "ONE")
+            else(current_keyword)
+                list(APPEND cpa_UNPARSED_ARGUMENTS ${arg})
+            endif(current_keyword)
+        else(keyword_index EQUAL -1)
+            if(current_keyword AND current_keyword_type STREQUAL "ONE")
+                message(SEND_ERROR "Value is expected for one-value-keyword ${current_keyword}")
+            endif(current_keyword AND current_keyword_type STREQUAL "ONE")
+            list(FIND options ${arg} option_index)
+            if(option_index EQUAL -1)
+                set(current_keyword ${arg})
+                list(FIND one_value_keywords ${arg} one_value_index)
+                if(one_value_index EQUAL -1)
+                    set(current_keyword_type "MULTI")
+                else(one_value_index EQUAL -1)
+                    set(current_keyword_type "ONE")
+                endif(one_value_index EQUAL -1)
+            else(option_index EQUAL -1)
+                set(current_keyword)
+                set(cpa_${arg} TRUE)
+            endif(option_index EQUAL -1)
+        endif(keyword_index EQUAL -1)
+    endforeach(arg ${ARGN})
+
+    if(current_keyword AND current_keyword_type STREQUAL "ONE")
+        message(SEND_ERROR "Value is expected for one-value-keyword ${current_keyword}")
+    endif(current_keyword AND current_keyword_type STREQUAL "ONE")
+
+    # propagate the result variables to the caller:
+    foreach(keyword ${all_keywords} UNPARSED_ARGUMENTS)
+        set(${prefix}_${keyword}  ${cpa_${keyword}} PARENT_SCOPE)
+    endforeach(keyword ${all_keywords})
+endfunction(cmake_parse_arguments prefix options one_value_keywords multi_value_keywords)
diff --git a/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake b/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake
new file mode 100644
index 0000000000..1b5de7e3ac
--- /dev/null
+++ b/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake
@@ -0,0 +1,48 @@
+# - Find mysqlclient
+# Find the native MySQL includes and library
+#
+#  MYSQL_INCLUDE_DIR - where to find mysql.h, etc.
+#  MYSQL_LIBRARIES   - List of libraries when using MySQL.
+#  MYSQL_FOUND       - True if MySQL found.
+
+IF (MYSQL_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(MYSQL_FIND_QUIETLY TRUE)
+ENDIF (MYSQL_INCLUDE_DIR)
+
+FIND_PATH(MYSQL_INCLUDE_DIR mysql.h
+  /usr/local/include/mysql
+  /usr/include/mysql
+)
+
+SET(MYSQL_NAMES mysqlclient mysqlclient_r)
+FIND_LIBRARY(MYSQL_LIBRARY
+  NAMES ${MYSQL_NAMES}
+  PATHS /usr/lib /usr/local/lib
+  PATH_SUFFIXES mysql
+)
+
+IF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY)
+  SET(MYSQL_FOUND TRUE)
+  SET( MYSQL_LIBRARIES ${MYSQL_LIBRARY} )
+ELSE (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY)
+  SET(MYSQL_FOUND FALSE)
+  SET( MYSQL_LIBRARIES )
+ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY)
+
+IF (MYSQL_FOUND)
+  IF (NOT MYSQL_FIND_QUIETLY)
+    MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARY}")
+  ENDIF (NOT MYSQL_FIND_QUIETLY)
+ELSE (MYSQL_FOUND)
+  IF (MYSQL_FIND_REQUIRED)
+    MESSAGE(STATUS "Looked for MySQL libraries named ${MYSQL_NAMES}.")
+    MESSAGE(FATAL_ERROR "Could NOT find MySQL library")
+  ENDIF (MYSQL_FIND_REQUIRED)
+ENDIF (MYSQL_FOUND)
+
+MARK_AS_ADVANCED(
+  MYSQL_LIBRARY
+  MYSQL_INCLUDE_DIR
+  )
+
diff --git a/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake b/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake
new file mode 100644
index 0000000000..5295a1ba39
--- /dev/null
+++ b/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake
@@ -0,0 +1,71 @@
+# - Look for GNU Bison, the parser generator
+# Based off a news post from Andy Cedilnik at Kitware
+# Defines the following:
+#  BISON_EXECUTABLE - path to the bison executable
+#  BISON_FILE - parse a file with bison
+#  BISON_PREFIX_OUTPUTS - Set to true to make BISON_FILE produce prefixed
+#                         symbols in the generated output based on filename.
+#                         So for ${filename}.y, you'll get ${filename}parse(), etc.
+#                         instead of yyparse().
+#  BISON_GENERATE_DEFINES - Set to true to make BISON_FILE output the matching
+#                           .h file for a .c file. You want this if you're using
+#                           flex.
+
+IF(NOT DEFINED BISON_PREFIX_OUTPUTS)
+ SET(BISON_PREFIX_OUTPUTS FALSE)
+ENDIF(NOT DEFINED BISON_PREFIX_OUTPUTS)
+
+IF(NOT DEFINED BISON_GENERATE_DEFINES)
+ SET(BISON_GENERATE_DEFINES FALSE)
+ENDIF(NOT DEFINED BISON_GENERATE_DEFINES)
+
+IF(NOT BISON_EXECUTABLE)
+ MESSAGE(STATUS "Looking for bison")
+ FIND_PROGRAM(BISON_EXECUTABLE bison)
+ IF(BISON_EXECUTABLE)
+   MESSAGE(STATUS "Looking for bison -- ${BISON_EXECUTABLE}")
+ ENDIF(BISON_EXECUTABLE)
+ENDIF(NOT BISON_EXECUTABLE)
+
+IF(BISON_EXECUTABLE)
+ MACRO(BISON_FILE FILENAME)
+   GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH)
+   IF("${PATH}" STREQUAL "")
+     SET(PATH_OPT "")
+   ELSE("${PATH}" STREQUAL "")
+     SET(PATH_OPT "/${PATH}")
+   ENDIF("${PATH}" STREQUAL "")
+   GET_FILENAME_COMPONENT(HEAD "${FILENAME}" NAME_WE)
+   IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+     FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+   ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+   IF(BISON_PREFIX_OUTPUTS)
+     SET(PREFIX "${HEAD}")
+   ELSE(BISON_PREFIX_OUTPUTS)
+     SET(PREFIX "yy")
+   ENDIF(BISON_PREFIX_OUTPUTS)
+   SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.c")
+   IF(BISON_GENERATE_DEFINES)
+     SET(HEADER "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.h")
+     ADD_CUSTOM_COMMAND(
+       OUTPUT "${OUTFILE}" "${HEADER}"
+       COMMAND "${BISON_EXECUTABLE}"
+       ARGS "--name-prefix=${PREFIX}"
+       "--defines"
+       "--output-file=${OUTFILE}"
+       "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
+       DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
+     SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" "${HEADER}" PROPERTIES GENERATED TRUE)
+     SET_SOURCE_FILES_PROPERTIES("${HEADER}" PROPERTIES HEADER_FILE_ONLY TRUE)
+   ELSE(BISON_GENERATE_DEFINES)
+     ADD_CUSTOM_COMMAND(
+       OUTPUT "${OUTFILE}"
+       COMMAND "${BISON_EXECUTABLE}"
+       ARGS "--name-prefix=${PREFIX}"
+       "--output-file=${OUTFILE}"
+       "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
+       DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
+     SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE)
+   ENDIF(BISON_GENERATE_DEFINES)
+ ENDMACRO(BISON_FILE) 
+ENDIF(BISON_EXECUTABLE)
diff --git a/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake b/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake
new file mode 100644
index 0000000000..09a3e71e6d
--- /dev/null
+++ b/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake
@@ -0,0 +1,46 @@
+# - Look for GNU flex, the lexer generator.
+# Defines the following:
+#  FLEX_EXECUTABLE - path to the flex executable
+#  FLEX_FILE - parse a file with flex
+#  FLEX_PREFIX_OUTPUTS - Set to true to make FLEX_FILE produce outputs of
+#                        lex.${filename}.c, not lex.yy.c . Passes -P to flex. 
+
+IF(NOT DEFINED FLEX_PREFIX_OUTPUTS)
+  SET(FLEX_PREFIX_OUTPUTS FALSE)
+ENDIF(NOT DEFINED FLEX_PREFIX_OUTPUTS) 
+
+IF(NOT FLEX_EXECUTABLE)
+  MESSAGE(STATUS "Looking for flex")
+  FIND_PROGRAM(FLEX_EXECUTABLE flex)
+  IF(FLEX_EXECUTABLE)
+    MESSAGE(STATUS "Looking for flex -- ${FLEX_EXECUTABLE}")
+  ENDIF(FLEX_EXECUTABLE)
+ENDIF(NOT FLEX_EXECUTABLE) 
+
+IF(FLEX_EXECUTABLE)
+  MACRO(FLEX_FILE FILENAME)
+    GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH)
+    IF("${PATH}" STREQUAL "")
+      SET(PATH_OPT "")
+    ELSE("${PATH}" STREQUAL "")
+      SET(PATH_OPT "/${PATH}")
+    ENDIF("${PATH}" STREQUAL "")
+    IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+      FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+    ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}")
+    IF(FLEX_PREFIX_OUTPUTS)
+      GET_FILENAME_COMPONENT(PREFIX "${FILENAME}" NAME_WE)
+    ELSE(FLEX_PREFIX_OUTPUTS)
+      SET(PREFIX "yy")
+    ENDIF(FLEX_PREFIX_OUTPUTS)
+    SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/lex.${PREFIX}.c")
+    ADD_CUSTOM_COMMAND(
+      OUTPUT "${OUTFILE}"
+      COMMAND "${FLEX_EXECUTABLE}"
+      ARGS "--prefix=${PREFIX}"
+      "--outfile=${OUTFILE}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}"
+      DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
+    SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE)
+  ENDMACRO(FLEX_FILE)
+ENDIF(FLEX_EXECUTABLE)
diff --git a/cmake_targets/tools/MODULES/FindFreeDiameter.cmake b/cmake_targets/tools/MODULES/FindFreeDiameter.cmake
new file mode 100644
index 0000000000..6351ff2ce3
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindFreeDiameter.cmake
@@ -0,0 +1,88 @@
+# - Find freediameter
+# Find the native FreeDiameter includes and libraries
+#
+#  FREEDIAMETER_FOUND - True if FreeDiameter found.
+#  FREEDIAMETER_INCLUDE_DIR - where to find gnutls.h, etc.
+#  FREEDIAMETER_LIBRARIES - List of libraries when using gnutls.
+#  FREEDIAMETER_HSS_S6A_ENABLED - true if FreeDiameter enabled for S6A interface 
+
+
+if (FREEDIAMETER_INCLUDE_DIR AND FREEDIAMETER_LIBRARIES)
+  set(FREEDIAMETER_FIND_QUIETLY TRUE)
+endif (FREEDIAMETER_INCLUDE_DIR AND FREEDIAMETER_LIBRARIES)
+
+# Include dir
+find_path(FREEDIAMETER_INCLUDE_DIR
+    NAMES
+    freeDiameter/freeDiameter-host.h
+    freeDiameter/libfdcore.h
+    freeDiameter/libfdproto.h
+)
+
+# Library
+find_library(FREEDIAMETER_LIBRARY 
+  NAMES fdcore
+)
+
+# handle the QUIETLY and REQUIRED arguments and set FREEDIAMETER_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEDIAMETER DEFAULT_MSG FREEDIAMETER_LIBRARY FREEDIAMETER_INCLUDE_DIR)
+
+IF(FREEDIAMETER_FOUND)
+  SET( FREEDIAMETER_LIBRARIES ${FREEDIAMETER_LIBRARY} )
+ELSE(FREEDIAMETER_FOUND)
+  SET( FREEDIAMETER_LIBRARIES )
+ENDIF(FREEDIAMETER_FOUND)
+
+find_library(FREEDIAMETER_LIBRARY2 
+  NAMES fdproto
+)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEDIAMETER2 DEFAULT_MSG FREEDIAMETER_LIBRARY2 FREEDIAMETER_INCLUDE_DIR)
+IF(FREEDIAMETER2_FOUND)
+  SET( FREEDIAMETER_LIBRARIES ${FREEDIAMETER_LIBRARIES} ${FREEDIAMETER_LIBRARY2} )
+ELSE(FREEDIAMETER2_FOUND)
+  SET( FREEDIAMETER_LIBRARIES )
+ENDIF(FREEDIAMETER2_FOUND)
+
+
+# Lastly make it so that the FREEDIAMETER_LIBRARY and FREEDIAMETER_INCLUDE_DIR variables
+# only show up under the advanced options in the gui cmake applications.
+MARK_AS_ADVANCED( FREEDIAMETER_LIBRARY FREEDIAMETER_INCLUDE_DIR )
+
+# Now check if the library is patched for OPENAIR HSS S6A.
+IF(FREEDIAMETER_FOUND)
+  IF( FREEDIAMETER_INCLUDE_DIR )
+    # Extract FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR from freeDiameter-host.h
+    # Read the whole file:
+    #
+    FILE(READ "${FREEDIAMETER_INCLUDE_DIR}/freeDiameter/freeDiameter-host.h" _freeDiameter_HOST_H_CONTENTS)
+
+    STRING(REGEX REPLACE ".*#define FD_PROJECT_VERSION_MAJOR ([0-9]+).*" "\\1" FD_PROJECT_VERSION_MAJOR "${_freeDiameter_HOST_H_CONTENTS}")
+    STRING(REGEX REPLACE ".*#define FD_PROJECT_VERSION_MINOR ([0-9]+).*" "\\1" FD_PROJECT_VERSION_MINOR "${_freeDiameter_HOST_H_CONTENTS}")
+
+    IF(FD_PROJECT_VERSION_MAJOR GREATER 0)
+      MATH(EXPR FREEDIAMETER_VERSION_VALUE "${FD_PROJECT_VERSION_MAJOR} * 100 + ${FD_PROJECT_VERSION_MINOR} * 10")
+      SET(FREEDIAMETER_VERSION "${FREEDIAMETER_VERSION_VALUE}" CACHE INTERNAL "Freediameter release version")
+      MESSAGE(STATUS "freeDiameter version found ${FREEDIAMETER_VERSION}")
+    ENDIF(FD_PROJECT_VERSION_MAJOR GREATER 0)
+  ENDIF( FREEDIAMETER_INCLUDE_DIR )
+  IF( NOT( "${FREEDIAMETER_VERSION_TEST_FOR}" STREQUAL "${FREEDIAMETER_LIBRARIES}" ))
+    INCLUDE (CheckLibraryExists) 
+    MESSAGE(STATUS "Checking freeDiameter patched for S6A")
+    UNSET(FREEDIAMETER_HSS_S6A_ENABLED)
+    UNSET(FREEDIAMETER_HSS_S6A_ENABLED CACHE)
+    UNSET(DICT_S6A_FOUND)
+    UNSET(DICT_S6A_FOUND CACHE)
+
+    GET_FILENAME_COMPONENT(FREEDIAMETER_PATH ${FREEDIAMETER_LIBRARY} PATH)
+    FIND_FILE(DICT_S6A_FOUND NAMES dict_s6a.fdx PATHS ${FREEDIAMETER_PATH} ${FREEDIAMETER_PATH}/freeDiameter)
+    IF(DICT_S6A_FOUND)
+        SET( FREEDIAMETER_HSS_S6A_ENABLED TRUE CACHE INTERNAL "dict_s6a.fdx Found")
+    ELSE(DICT_S6A_FOUND)
+        SET( FREEDIAMETER_HSS_S6A_ENABLED FALSE CACHE INTERNAL "dict_s6a.fdx not Found")
+    ENDIF(DICT_S6A_FOUND)
+    SET( FREEDIAMETER_VERSION_TEST_FOR ${FREEDIAMETER_LIBRARIES} CACHE INTERNAL "Version the test was made against" )
+  ENDIF (NOT( "${FREEDIAMETER_VERSION_TEST_FOR}" STREQUAL "${FREEDIAMETER_LIBRARIES}" ))
+ENDIF(FREEDIAMETER_FOUND)
+
diff --git a/cmake_targets/tools/MODULES/FindGCCXML.cmake b/cmake_targets/tools/MODULES/FindGCCXML.cmake
new file mode 100644
index 0000000000..6a4daa084d
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindGCCXML.cmake
@@ -0,0 +1,8 @@
+# FindGCCXML
+# ----------
+find_program(GCCXML
+NAMES gccxml
+PATHS "/usr/bin"
+"usr/local/bin"
+)
+mark_as_advanced(GCCXML)
diff --git a/cmake_targets/tools/MODULES/FindGcrypt.cmake b/cmake_targets/tools/MODULES/FindGcrypt.cmake
new file mode 100644
index 0000000000..fd4517dafb
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindGcrypt.cmake
@@ -0,0 +1,36 @@
+# - Find gnutls
+# Find the native GCRYPT includes and library
+#
+#  GCRYPT_FOUND - True if gnutls found.
+#  GCRYPT_INCLUDE_DIR - where to find gnutls.h, etc.
+#  GCRYPT_LIBRARIES - List of libraries when using gnutls.
+
+if (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARIES)
+  set(GCRYPT_FIND_QUIETLY TRUE)
+endif (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARIES)
+
+# Include dir
+find_path(GCRYPT_INCLUDE_DIR
+	NAMES
+	  gcrypt.h
+)
+
+# Library
+find_library(GCRYPT_LIBRARY 
+  NAMES gcrypt
+)
+
+# handle the QUIETLY and REQUIRED arguments and set GCRYPT_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GCRYPT DEFAULT_MSG GCRYPT_LIBRARY GCRYPT_INCLUDE_DIR)
+
+IF(GCRYPT_FOUND)
+  SET( GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} )
+ELSE(GCRYPT_FOUND)
+  SET( GCRYPT_LIBRARIES )
+ENDIF(GCRYPT_FOUND)
+
+# Lastly make it so that the GCRYPT_LIBRARY and GCRYPT_INCLUDE_DIR variables
+# only show up under the advanced options in the gui cmake applications.
+MARK_AS_ADVANCED( GCRYPT_LIBRARY GCRYPT_INCLUDE_DIR )
diff --git a/cmake_targets/tools/MODULES/FindGnuTLS.cmake b/cmake_targets/tools/MODULES/FindGnuTLS.cmake
new file mode 100644
index 0000000000..19c4fffae6
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindGnuTLS.cmake
@@ -0,0 +1,64 @@
+# - Find gnutls
+# Find the native GNUTLS includes and library
+#
+#  GNUTLS_FOUND - True if gnutls found.
+#  GNUTLS_INCLUDE_DIR - where to find gnutls.h, etc.
+#  GNUTLS_LIBRARIES - List of libraries when using gnutls.
+#  GNUTLS_VERSION_210 - true if GnuTLS version is >= 2.10.0 (does not require additional separate gcrypt initialization)
+#  GNUTLS_VERSION_212 - true if GnuTLS version is >= 2.12.0 (supports gnutls_transport_set_vec_push_function)
+#  GNUTLS_VERSION_300 - true if GnuTLS version is >= 3.00.0 (x509 verification functions changed)
+#  GNUTLS_VERSION_310 - true if GnuTLS version is >= 3.01.0 (stabilization branch with new APIs)
+
+if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARIES)
+  set(GNUTLS_FIND_QUIETLY TRUE)
+endif (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARIES)
+
+# Include dir
+find_path(GNUTLS_INCLUDE_DIR
+	NAMES
+	  gnutls.h
+	  gnutls/gnutls.h
+)
+
+# Library
+find_library(GNUTLS_LIBRARY 
+  NAMES gnutls
+)
+
+# handle the QUIETLY and REQUIRED arguments and set GNUTLS_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNUTLS DEFAULT_MSG GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR)
+
+IF(GNUTLS_FOUND)
+  SET( GNUTLS_LIBRARIES ${GNUTLS_LIBRARY} )
+ELSE(GNUTLS_FOUND)
+  SET( GNUTLS_LIBRARIES )
+ENDIF(GNUTLS_FOUND)
+
+# Lastly make it so that the GNUTLS_LIBRARY and GNUTLS_INCLUDE_DIR variables
+# only show up under the advanced options in the gui cmake applications.
+MARK_AS_ADVANCED( GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR )
+
+# Now check if the library is recent. gnutls_hash was added in 2.10.0.
+# Also test library is even more recent. gnutls_x509_trust_list_verify_crt was added in 3.00.0.
+IF(GNUTLS_FOUND)
+  IF( NOT( "${GNUTLS_VERSION_TEST_FOR}" STREQUAL "${GNUTLS_LIBRARY}" ))
+    INCLUDE (CheckLibraryExists) 
+    MESSAGE(STATUS "Checking GNUTLS version")
+    UNSET(GNUTLS_VERSION_210)
+    UNSET(GNUTLS_VERSION_210 CACHE)
+    UNSET(GNUTLS_VERSION_212)
+    UNSET(GNUTLS_VERSION_212 CACHE)
+    UNSET(GNUTLS_VERSION_300)
+    UNSET(GNUTLS_VERSION_300 CACHE)
+    UNSET(GNUTLS_VERSION_310)
+    UNSET(GNUTLS_VERSION_310 CACHE)
+    GET_FILENAME_COMPONENT(GNUTLS_PATH ${GNUTLS_LIBRARY} PATH)
+    CHECK_LIBRARY_EXISTS(gnutls gnutls_hash ${GNUTLS_PATH} GNUTLS_VERSION_210) 
+    CHECK_LIBRARY_EXISTS(gnutls gnutls_transport_set_vec_push_function ${GNUTLS_PATH} GNUTLS_VERSION_212) 
+    CHECK_LIBRARY_EXISTS(gnutls gnutls_x509_trust_list_verify_crt ${GNUTLS_PATH} GNUTLS_VERSION_300) 
+    CHECK_LIBRARY_EXISTS(gnutls gnutls_handshake_set_timeout ${GNUTLS_PATH} GNUTLS_VERSION_310) 
+    SET( GNUTLS_VERSION_TEST_FOR ${GNUTLS_LIBRARY} CACHE INTERNAL "Version the test was made against" )
+  ENDIF (NOT( "${GNUTLS_VERSION_TEST_FOR}" STREQUAL "${GNUTLS_LIBRARY}" ))
+ENDIF(GNUTLS_FOUND)
diff --git a/cmake_targets/tools/MODULES/FindKbuild.cmake b/cmake_targets/tools/MODULES/FindKbuild.cmake
new file mode 100644
index 0000000000..08accb8551
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindKbuild.cmake
@@ -0,0 +1,105 @@
+# - Support for building kernel modules
+
+# This module defines several variables which may be used when build
+# kernel modules.
+#
+# The following variables are set here:
+#  Kbuild_VERSION_STRING - kernel version.
+#  Kbuild_ARCH - architecture.
+#  Kbuild_BUILD_DIR - directory for build kernel and/or its components.
+#  Kbuild_VERSION_{MAJOR|MINOR|TWEAK} - kernel version components
+#  Kbuild_VERSION_STRING_CLASSIC - classic representation of version,
+# where parts are delimited by dots.
+#
+# Cache variables which affect on this package:
+#  CMAKE_SYSTEM_VERSION - change Kbuild_VERSION_STRING
+# Also, setting CMAKE_SYSTEM_VERSION will be interpreted by cmake as crosscompile.
+#
+# Cache variables(ADVANCED) which affect on this package:
+#  ARCH - if not empty, change Kbuild_ARCH
+#  KBUILD_DIR - change Kbuild_BUILD_DIR
+
+set(Kbuild_VERSION_STRING ${CMAKE_SYSTEM_VERSION})
+
+# Form classic version view.
+string(REGEX MATCH "([0-9]+)\\.([0-9]+)[.-]([0-9]+)"
+    _kernel_version_match
+    "${Kbuild_VERSION_STRING}"
+)
+
+if(NOT _kernel_version_match)
+    message(FATAL_ERROR "Kernel version has unexpected format: ${Kbuild_VERSION_STRING}")
+endif(NOT _kernel_version_match)
+
+set(Kbuild_VERSION_MAJOR ${CMAKE_MATCH_1})
+set(Kbuild_VERSION_MINOR ${CMAKE_MATCH_2})
+set(Kbuild_VERSION_TWEAK ${CMAKE_MATCH_3})
+# Version string for compare
+set(Kbuild_VERSION_STRING_CLASSIC "${Kbuild_VERSION_MAJOR}.${Kbuild_VERSION_MINOR}.${Kbuild_VERSION_TWEAK}")
+
+set(KBUILD_DIR "/lib/modules/${Kbuild_VERSION_STRING}/build" CACHE PATH
+    "Directory for build linux kernel and/or its components."
+)
+mark_as_advanced(KBUILD_DIR)
+
+set(Kbuild_BUILD_DIR "${KBUILD_DIR}")
+
+set(ARCH "" CACHE STRING
+    "Architecture for build linux kernel components for, empty string means autodetect."
+)
+mark_as_advanced(ARCH)
+
+if(NOT ARCH)
+    # Autodetect arch.
+    execute_process(COMMAND uname -m
+        RESULT_VARIABLE uname_m_result
+        OUTPUT_VARIABLE ARCH_DEFAULT
+    )
+    if(NOT uname_m_result EQUAL 0)
+        message("'uname -m' failed:")
+        message("${ARCH_DEFAULT}")
+        message(FATAL_ERROR "Failed to determine system architecture.")
+    endif(NOT uname_m_result EQUAL 0)
+
+    string(REGEX REPLACE "\n$" "" ARCH_DEFAULT "${ARCH_DEFAULT}")
+
+    # Pairs of pattern-replace for postprocess architecture string from
+    # 'uname -m'.
+    # Taken from ./Makefile of the kernel build.
+    set(_kbuild_arch_replacers
+        "i.86" "x86"
+        "x86_64" "x86"
+        "sun4u" "sparc64"
+        "arm.*" "arm"
+        "sa110" "arm"
+        "s390x" "s390"
+        "parisc64" "parisc"
+        "ppc.*" "powerpc"
+        "mips.*" "mips"
+        "sh[234].*" "sh"
+        "aarch64.*" "arm64"
+    )
+
+    set(_current_pattern)
+    foreach(p ${_kbuild_arch_replacers})
+        if(_current_pattern)
+            string(REGEX REPLACE "${_current_pattern}" "${p}" ARCH_DEFAULT "${ARCH_DEFAULT}")
+            set(_current_pattern)
+        else(_current_pattern)
+            set(_current_pattern "${p}")
+        endif(_current_pattern)
+    endforeach(p ${_kbuild_arch_replacers})
+
+    set(Kbuild_ARCH "${ARCH_DEFAULT}")
+else(NOT ARCH)
+    # User-provided value is used.
+    set(Kbuild_ARCH "${ARCH}")
+endif(NOT ARCH)
+
+
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Kbuild
+    REQUIRED_VARS Kbuild_BUILD_DIR
+    VERSION_VAR KBuild_VERSION_STRING_CLASSIC
+)
diff --git a/cmake_targets/tools/MODULES/FindLibXml2.cmake b/cmake_targets/tools/MODULES/FindLibXml2.cmake
new file mode 100644
index 0000000000..e18dc2e921
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindLibXml2.cmake
@@ -0,0 +1,53 @@
+# - Try to find the LibXml2 xml processing library
+# Once done this will define
+#
+#  LIBXML2_FOUND - System has LibXml2
+#  LIBXML2_INCLUDE_DIR - The LibXml2 include directory
+#  LIBXML2_LIBRARIES - The libraries needed to use LibXml2
+#  LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
+#  LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+FIND_PACKAGE(PkgConfig)
+PKG_CHECK_MODULES(PC_LIBXML libxml-2.0)
+SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
+
+FIND_PATH(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
+   HINTS
+   ${PC_LIBXML_INCLUDEDIR}
+   ${PC_LIBXML_INCLUDE_DIRS}
+   PATH_SUFFIXES libxml2
+   )
+
+FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2
+   HINTS
+   ${PC_LIBXML_LIBDIR}
+   ${PC_LIBXML_LIBRARY_DIRS}
+   )
+
+FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint)
+# for backwards compat. with KDE 4.0.x:
+SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
+
+# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
+
diff --git a/cmake_targets/tools/MODULES/FindMySQL.cmake b/cmake_targets/tools/MODULES/FindMySQL.cmake
new file mode 100644
index 0000000000..668f8a434d
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindMySQL.cmake
@@ -0,0 +1,55 @@
+# - Find mysqlclient
+#
+# -*- cmake -*-
+#
+# Find the native MySQL includes and library
+#
+#  MySQL_INCLUDE_DIR - where to find mysql.h, etc.
+#  MySQL_LIBRARIES   - List of libraries when using MySQL.
+#  MySQL_FOUND       - True if MySQL found.
+
+IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
+  # Already in cache, be silent
+  SET(MySQL_FIND_QUIETLY TRUE)
+ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
+
+# Include dir
+FIND_PATH(MySQL_INCLUDE_DIR 
+  NAMES mysql.h
+  PATH_SUFFIXES mysql
+)
+
+# Library
+#SET(MySQL_NAMES mysqlclient mysqlclient_r)
+SET(MySQL_NAMES mysqlclient)
+FIND_LIBRARY(MySQL_LIBRARY
+  NAMES ${MySQL_NAMES}
+  PATHS /usr/lib /usr/local/lib
+  PATH_SUFFIXES mysql
+)
+
+IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
+  SET(MySQL_FOUND TRUE)
+  SET( MySQL_LIBRARIES ${MySQL_LIBRARY} )
+ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
+  SET(MySQL_FOUND FALSE)
+  SET( MySQL_LIBRARIES )
+ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
+
+
+IF (MySQL_FOUND)
+  IF (NOT MySQL_FIND_QUIETLY)
+    MESSAGE(STATUS "Found MySQL: ${MySQL_LIBRARY}")
+  ENDIF (NOT MySQL_FIND_QUIETLY)
+ELSE (MySQL_FOUND)
+  IF (MySQL_FIND_REQUIRED)
+    MESSAGE(STATUS "Looked for MySQL libraries named ${MySQL_NAMES}.")
+    MESSAGE(FATAL_ERROR "Could NOT find MySQL library")
+  ENDIF (MySQL_FIND_REQUIRED)
+ENDIF (MySQL_FOUND)
+
+MARK_AS_ADVANCED(
+  MySQL_LIBRARY
+  MySQL_INCLUDE_DIR
+  )
+
diff --git a/cmake_targets/tools/MODULES/FindNettle.cmake b/cmake_targets/tools/MODULES/FindNettle.cmake
new file mode 100644
index 0000000000..4602e74997
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindNettle.cmake
@@ -0,0 +1,22 @@
+# Find the native Nettle includes, library, and flags
+#
+# NETTLE_INCLUDE_DIR - where to find nettle.h, etc.
+# NETTLE_LIBRARIES - List of libraries when using Nettle.
+# NETTLE_FOUND - True if Nettle found.
+IF (NETTLE_INCLUDE_DIR)
+# Already in cache, be silent
+    SET(NETTLE_FIND_QUIETLY TRUE)
+ENDIF (NETTLE_INCLUDE_DIR)
+FIND_PATH(NETTLE_INCLUDE_DIR nettle/nettle-meta.h)
+SET(NETTLE_NAMES nettle)
+FIND_LIBRARY(NETTLE_LIBRARY NAMES ${NETTLE_NAMES} )
+# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
+IF(NETTLE_FOUND)
+    SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
+ELSE(NETTLE_FOUND)
+    SET(NETTLE_LIBRARIES )
+ENDIF(NETTLE_FOUND)
+MARK_AS_ADVANCED(NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
diff --git a/cmake_targets/tools/MODULES/FindPostgreSQL.cmake b/cmake_targets/tools/MODULES/FindPostgreSQL.cmake
new file mode 100644
index 0000000000..a639a262b0
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindPostgreSQL.cmake
@@ -0,0 +1,36 @@
+# - Find PostgreSQL library
+#
+# This module defines:
+#  POSTGRESQL_FOUND - True if the package is found
+#  POSTGRESQL_INCLUDE_DIR - containing libpq-fe.h
+#  POSTGRESQL_LIBRARIES - Libraries to link to use PQ functions.
+
+if (POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+  set(POSTGRESQL_FIND_QUIETLY TRUE)
+endif (POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+# Include dir
+find_path(POSTGRESQL_INCLUDE_DIR 
+	NAMES libpq-fe.h
+	PATH_SUFFIXES pgsql postgresql
+)
+
+# Library
+find_library(POSTGRESQL_LIBRARY 
+  NAMES pq
+)
+
+# handle the QUIETLY and REQUIRED arguments and set POSTGRESQL_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(POSTGRESQL DEFAULT_MSG POSTGRESQL_LIBRARY POSTGRESQL_INCLUDE_DIR)
+
+IF(POSTGRESQL_FOUND)
+  SET( POSTGRESQL_LIBRARIES ${POSTGRESQL_LIBRARY} )
+ELSE(POSTGRESQL_FOUND)
+  SET( POSTGRESQL_LIBRARIES )
+ENDIF(POSTGRESQL_FOUND)
+
+# Lastly make it so that the POSTGRESQL_LIBRARY and POSTGRESQL_INCLUDE_DIR variables
+# only show up under the advanced options in the gui cmake applications.
+MARK_AS_ADVANCED( POSTGRESQL_LIBRARY POSTGRESQL_INCLUDE_DIR )
diff --git a/cmake_targets/tools/MODULES/FindSCTP.cmake b/cmake_targets/tools/MODULES/FindSCTP.cmake
new file mode 100644
index 0000000000..de8e878a99
--- /dev/null
+++ b/cmake_targets/tools/MODULES/FindSCTP.cmake
@@ -0,0 +1,46 @@
+# - Try to find SCTP library and headers
+# Once done, this will define
+#
+#  SCTP_FOUND - system has SCTP
+#  SCTP_INCLUDE_DIR - the SCTP include directories
+#  SCTP_LIBRARIES - link these to use SCTP
+
+if (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
+  set(SCTP_FIND_QUIETLY TRUE)
+endif (SCTP_INCLUDE_DIR AND SCTP_LIBRARIES)
+
+# Include dir
+find_path(SCTP_INCLUDE_DIR
+  NAMES netinet/sctp.h
+)
+
+# Library
+find_library(SCTP_LIBRARY
+  NAMES sctp
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+#set(SCTP_PROCESS_INCLUDES SCTP_INCLUDE_DIR)
+#set(SCTP_PROCESS_LIBS SCTP_LIBRARY)
+#libfind_process(SCTP)
+
+
+# handle the QUIETLY and REQUIRED arguments and set SCTP_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SCTP DEFAULT_MSG SCTP_LIBRARY SCTP_INCLUDE_DIR)
+
+# If we successfully found the sctp library then add the library to the
+# SCTP_LIBRARIES cmake variable otherwise set SCTP_LIBRARIES to nothing.
+IF(SCTP_FOUND)
+   SET( SCTP_LIBRARIES ${SCTP_LIBRARY} )
+ELSE(SCTP_FOUND)
+   SET( SCTP_LIBRARIES )
+ENDIF(SCTP_FOUND)
+
+
+# Lastly make it so that the SCTP_LIBRARY and SCTP_INCLUDE_DIR variables
+# only show up under the advanced options in the gui cmake applications.
+MARK_AS_ADVANCED( SCTP_LIBRARY SCTP_INCLUDE_DIR )
+
diff --git a/cmake_targets/tools/MODULES/Kbuild.cmake b/cmake_targets/tools/MODULES/Kbuild.cmake
new file mode 100644
index 0000000000..7403cd04df
--- /dev/null
+++ b/cmake_targets/tools/MODULES/Kbuild.cmake
@@ -0,0 +1,4 @@
+src=${dir}
+obj-m += ${name}.o
+${name}-y += ${objs}
+ccflags-y += ${module_cc_opt}
diff --git a/cmake_targets/tools/MODULES/cmake_useful.cmake b/cmake_targets/tools/MODULES/cmake_useful.cmake
new file mode 100644
index 0000000000..af6bbb56c7
--- /dev/null
+++ b/cmake_targets/tools/MODULES/cmake_useful.cmake
@@ -0,0 +1,229 @@
+# Create rule for obtain one file by copying another one
+function(rule_copy_file target_file source_file)
+    add_custom_command(OUTPUT ${target_file}
+        COMMAND cp -p ${source_file} ${target_file}
+        DEPENDS ${source_file}
+    )
+endfunction(rule_copy_file target_file source_file)
+
+#  rule_copy_source([source_dir] file ...)
+#
+# Create rule for obtain file(s) in binary tree by copiing it from source tree.
+#
+# Files are given relative to ${source_dir}, if it is set, or
+# relative to ${CMAKE_CURRENT_SOURCE_DIR}.
+#
+# Files will be copied into ${CMAKE_CURRENT_BINARY_DIR} with same
+# relative paths.
+#
+# ${source_dir} should be absolute path(that is, starts from '/').
+# Otherwise first argument is treated as first file to copy.
+function(rule_copy_source file)
+    string(REGEX MATCH "^/" is_abs_path ${file})
+    if(is_abs_path)
+        set(source_dir ${file})
+        set(files ${ARGN})
+    else(is_abs_path)
+        set(source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+        set(files ${file} ${ARGN})
+    endif(is_abs_path)
+    
+    foreach(file_real ${files})
+        rule_copy_file("${CMAKE_CURRENT_BINARY_DIR}/${file_real}"
+            ${source_dir}/${file_real})
+    endforeach(file_real ${files})
+endfunction(rule_copy_source file)
+
+#  to_abs_path(output_var path [...])
+#
+# Convert relative path of file to absolute path:
+# use path in source tree, if file already exist there.
+# otherwise use path in binary tree.
+# If initial path already absolute, return it.
+function(to_abs_path output_var)
+    set(result)
+    foreach(path ${ARGN})
+        string(REGEX MATCH "^/" _is_abs_path ${path})
+        if(_is_abs_path)
+            list(APPEND result ${path})
+        else(_is_abs_path)
+            file(GLOB to_abs_path_file 
+                "${CMAKE_CURRENT_SOURCE_DIR}/${path}"
+            )
+            if(NOT to_abs_path_file)
+                set (to_abs_path_file "${CMAKE_CURRENT_BINARY_DIR}/${path}")
+            endif(NOT to_abs_path_file)
+            list(APPEND result ${to_abs_path_file})
+        endif(_is_abs_path)
+    endforeach(path ${ARGN})
+    set("${output_var}" ${result} PARENT_SCOPE)
+endfunction(to_abs_path output_var path)
+
+#  is_path_inside_dir(output_var dir path)
+#
+# Set output_var to true if path is absolute path inside given directory.
+# NOTE: Path should be absolute.
+macro(is_path_inside_dir output_var dir path)
+    file(RELATIVE_PATH _rel_path ${dir} ${path})
+    string(REGEX MATCH "^\\.\\." _is_not_inside_dir ${_rel_path})
+    if(_is_not_inside_dir)
+        set(${output_var} "FALSE")
+    else(_is_not_inside_dir)
+        set(${output_var} "TRUE")
+    endif(_is_not_inside_dir)
+endmacro(is_path_inside_dir output_var dir path)
+
+
+# Write given content to the file.
+#
+# If file is already exists and its content is same as written one, file
+# is not rewritten, so its write timestamp remains unchanged.
+function(file_update filename content)
+    if(EXISTS "${filename}")
+        file(READ "${filename}" old_content)
+        if(old_content STREQUAL "${content}")
+            return()
+        endif(old_content STREQUAL "${content}")
+    endif(EXISTS "${filename}")
+    # File doesn't exists or its content differ.
+    file(WRITE "${filename}" "${content}")
+endfunction(file_update filename content)
+
+
+# Write given content to the file in APPEND mode.
+#
+# For append we use position variable <pos> which should be initialized
+# to 0 for every new build process and which is updated every time when
+# this function is called.
+# If file is already exists and its content at given <pos> is same as
+# written one, file is not rewritten, so its write timestamp remains unchanged.
+#
+# Note, that file will not be rewritten if new build process issues less
+# APPEND actions than one which create file.
+# But similar problem exists for file_update() and even for built-in
+# configure_file() command: file will not be removed if new build process
+# do not call configure_file() for it.
+function(file_update_append filename content POS)
+    set(pos "${${POS}}")
+    string(LENGTH "${content}" len)
+    # Update output variable first.
+    # This allows to use return() when need not to do anything
+    math(EXPR pos_new "${pos}+${len}")
+    set(${POS} "${pos_new}" PARENT_SCOPE)
+    if(EXISTS "${filename}")
+        file(READ "${filename}" old_content LIMIT "${len}" OFFSET "${pos}")
+        if(old_content STREQUAL "${content}")
+            return()
+        elseif(old_content STREQUAL "")
+            file(APPEND "${filename}" "${content}")
+            return()
+        endif(old_content STREQUAL "${content}")
+    else(EXISTS "${filename}")
+        if(NOT pos EQUAL 0)
+            message(FATAL_ERROR "Appending to non-zero position to non-existent file.")
+        endif(NOT pos EQUAL 0)
+    endif(EXISTS "${filename}")
+    # File doesn't exists or its content differ.
+    if(NOT pos EQUAL 0)
+        file(READ "${filename}" prefix LIMIT "${pos}")
+    else(NOT pos EQUAL 0)
+        set(prefix)
+    endif(NOT pos EQUAL 0)
+    file(WRITE "${filename}" "${prefix}${content}")
+endfunction(file_update_append filename content POS)
+
+
+# Common mechanism for output status message
+# when checking different aspects.
+#
+# Normal using:
+#
+#  check_begin("Checking <...>")
+#  if(NOT <check-already-has-been-done>)
+#     check_try() # Here message is printed
+#     # Perform check(try_compile(), etc.)
+#  endif(NOT <check-already-has-been-done>)
+#  check_end("<check-result>") # Here message is printed with result.
+
+# Should be called (unconditionally) when new cheking is issued.
+# Note, that given @status_msg is not printed at that step.
+function(check_begin status_msg)
+    set(_check_status_msg ${status_msg} PARENT_SCOPE)
+    set(_check_has_tries PARENT_SCOPE)
+endfunction(check_begin status_msg)
+
+# Should be called before every real checking, that is which is not come
+# from cache variables comparision.
+#
+# First call of that function is trigger printing of @status_msg,
+# passed to check_begin().
+function(check_try)
+    if(NOT _check_has_tries)
+        message(STATUS "${_check_status_msg}")
+        set(_check_has_tries "1" PARENT_SCOPE)
+    endif(NOT _check_has_tries)
+endfunction(check_try)
+
+# Should be called when cheking is end, and @result_msg should be short
+# description of check result.
+# If any check_try() has been issued before,
+#   "@status_msg - @result_msg"
+# will be printed.
+# Otherwise,
+#   "@status_msg - [cached] @result_msg"
+# will be printed, at it will be the only message for that check.
+function(check_end result_msg)
+    if(NOT _check_has_tries)
+        message(STATUS "${_check_status_msg} [cached] - ${result_msg}")
+    else(NOT _check_has_tries)
+        message(STATUS "${_check_status_msg} - ${result_msg}")
+    endif(NOT _check_has_tries)
+    set(_check_status_msg PARENT_SCOPE)
+    set(_check_has_tries PARENT_SCOPE)
+endfunction(check_end result_msg)
+
+#  set_bool_string(var true_string false_string value [CACHE ... | PARENT_SCOPE])
+#
+# Set variable to one of two string according to true property of some value.
+#
+# If 'value' is true-evaluated, 'var' will be set to 'true_string',
+# otherwise to 'var' will be set to 'false_string'.
+# Like standard set(), macro accept CACHE and PARENT_SCOPE modifiers.
+#
+# Useful for form meaningful value for cache variables, contained result
+# of some operation.
+# Also may be used for form message for check_end().
+macro(set_bool_string var true_string false_string value)
+    # Macro parameters are not a variables, so them cannot be tested
+    # using 'if(value)'.
+    # Usage 'if(${value})' leads to warnings since 2.6.4 when ${val}
+    # is boolean constant
+    # (because until 2.6.4 'if(value)' always dereference val).
+    # So copy 'value' to local variable for test it.
+    set(_set_bool_string_value ${value})
+    if(_set_bool_string_value)
+        set(${var} "${true_string}" ${ARGN})
+    else()
+        set(${var} "${false_string}" ${ARGN})
+    endif()
+endmacro(set_bool_string)
+
+#  set_zero_string(var true_string false_string value [CACHE ... | PARENT_SCOPE])
+#
+# Set variable to one of two string according to zero property of some value.
+#
+# If 'value' is '0' (presizely), 'var' will be set to 'zero_string',
+# otherwise to 'var' will be set to 'nonzero_string'.
+# Like standard set(), macro accept CACHE and PARENT_SCOPE modifiers.
+#
+# Useful for form meaningful value for cache variables, contained result
+# of execute_process().
+# Also may be used for form message for check_end().
+macro(set_zero_string var zero_string nonzero_string value)
+    set(_set_zero_string_value ${value})
+    if(_set_zero_string_value EQUAL "0")
+        set(${var} ${zero_string} ${ARGN})
+    else()
+        set(${var} ${nonzero_string} ${ARGN})
+    endif()
+endmacro(set_zero_string)
\ No newline at end of file
diff --git a/cmake_targets/tools/MODULES/kbuild_system.cmake b/cmake_targets/tools/MODULES/kbuild_system.cmake
new file mode 100644
index 0000000000..42a1a2d42b
--- /dev/null
+++ b/cmake_targets/tools/MODULES/kbuild_system.cmake
@@ -0,0 +1,1131 @@
+# Provide way for create kernel modules, and perform other actions on them
+# in a way similar to standard cmake executables and libraries processing.
+#
+# NB: At the end of the whole configuration stage
+#   kbuild_finalize_linking()
+# should be executed.
+#
+# Should be included after:
+#  find_package(Kbuild)
+#
+# Cached variables(ADVANCED), which affects on definitions below:
+#  CROSS_COMPILE - corresponded parameter for 'make' to build kernel objects.
+#  KBUILD_C_FLAGS - Additional kbuild flags for all builds
+#  KBUILD_C_FLAGS{DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL} - per-configuration flags.
+
+include(cmake_useful)
+
+# Compute path to the auxiliary files.
+get_filename_component(kbuild_this_module_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
+set(kbuild_aux_dir "${kbuild_this_module_dir}/kbuild_system_files")
+
+# _declare_per_build_vars(<variable> <doc-pattern>)
+#
+# [INTERNAL] Per-build type definitions for given <variable>.
+# 
+# Create CACHE STRING variables <variable>_{DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL}
+# with documentation string <doc-pattern> where %build% is replaced
+# with corresponded build type description.
+#
+# Default value for variable <variable>_<type> is taken from <variable>_<type>_INIT.
+macro(_declare_per_build_vars variable doc_pattern)
+    set(_build_type)
+    foreach(t
+        RELEASE "release"
+        DEBUG "debug"
+        RELWITHDEBINFO "Release With Debug Info"
+        MINSIZEREL "release minsize"
+    )
+        if(_build_type)
+            string(REPLACE "%build%" "${t}" _docstring ${doc_pattern})
+            set("${variable}_${_build_type}" "${${variable}_${_build_type}_INIT}"
+                CACHE STRING "${_docstring}")
+            set(_build_type)
+        else(_build_type)
+            set(_build_type "${t}")
+        endif(_build_type)
+    endforeach(t)
+endmacro(_declare_per_build_vars variable doc_pattern)
+
+
+# Default compiler flags.
+#
+# These flags are used directly when configuring 'Kbuild', so them should be
+# expressed as single-string, where different flags are joinged using ' '.
+set(KBUILD_C_FLAGS "" CACHE STRING
+    "Compiler flags used by Kbuild system during all builds."
+)
+
+# Additional default compiler flags per build type.
+set(KBUILD_C_FLAGS_DEBUG_INIT "-g")
+set(KBUILD_C_FLAGS_RELWITHDEBINFO_INIT "-g")
+
+_declare_per_build_vars(KBUILD_C_FLAGS
+    "Compiler flags used by Kbuild system during %build% builds."
+)
+mark_as_advanced(
+    KBUILD_C_FLAGS
+    KBUILD_C_FLAGS_DEBUG
+    KBUILD_C_FLAGS_RELEASE
+    KBUILD_C_FLAGS_RELWITHDEBINFO
+    KBUILD_C_FLAGS_MINSIZEREL
+)
+
+
+# Additional definitions which are passed directly to 'make' for
+# kbuild process.
+#
+# Unlike to compiler flags, these ones are expressed using cmake list.
+set(KBUILD_MAKE_FLAGS "" CACHE STRING
+    "Make flags used by Kbuild system during all builds."
+)
+
+_declare_per_build_vars(KBUILD_MAKE_FLAGS
+    "Make flags used by Kbuild system during %build% builds."
+)
+
+mark_as_advanced(
+    KBUILD_MAKE_FLAGS
+    KBUILD_MAKE_FLAGS_DEBUG
+    KBUILD_MAKE_FLAGS_RELEASE
+    KBUILD_MAKE_FLAGS_RELWITHDEBINFO
+    KBUILD_MAKE_FLAGS_MINSIZEREL
+)
+
+set(CROSS_COMPILE "" CACHE STRING "Cross compilation prefix for build linux kernel objects.")
+mark_as_advanced(CROSS_COMPILE)
+
+# Property prefixed with 'KMODULE_' is readonly for outer use,
+# unless explicitely noted in its description.
+
+# Property is set for every target described kernel module.
+# Concrete property's value currently has no special meaning.
+define_property(TARGET PROPERTY KMODULE_TYPE
+    BRIEF_DOCS "Whether given target describes kernel module."
+    FULL_DOCS "Whether given target describes kernel module."
+)
+
+# Absolute filename of .ko file which is built.
+# NOTE: Imported targets use
+#  KMODULE_IMPORTED_MODULE_LOCATION
+# property instead.
+define_property(TARGET PROPERTY KMODULE_MODULE_LOCATION
+    BRIEF_DOCS "Location of the built kernel module."
+    FULL_DOCS "Location of the built kernel module."
+)
+
+# Name of the given module, like "ext4" or "kedr".
+define_property(TARGET PROPERTY KMODULE_MODULE_NAME
+    BRIEF_DOCS "Name of the kernel module."
+    FULL_DOCS "Name of the kernel module."
+)
+
+
+# Absolute filename of Module.symvers file which is built.
+# NOTE: Imported targets use
+#  KMODULE_IMPORTED_SYMVERS_LOCATION
+# property instead.
+define_property(TARGET PROPERTY KMODULE_SYMVERS_LOCATION
+    BRIEF_DOCS "Location of the symvers file of the kernel module."
+    FULL_DOCS "Location of the symvers file of the kernel module."
+)
+
+# Property is "TRUE" for every target described imported kernel module,
+# "FALSE" for other targets described kernel module.
+define_property(TARGET PROPERTY KMODULE_IMPORTED
+    BRIEF_DOCS "Whether given target describes imported kernel module."
+    FULL_DOCS "Whether given target describes imported kernel module."
+)
+
+# Absolute filename of .ko file which is imported.
+# Property may be set after
+#  kbuild_add_module(... IMPORTED)
+# for allow loading of given module or perform other actions required
+# kernel module itself.
+#
+# Analogue for KMODULE_MODULE_LOCATION property of normal(non-exported)
+# kernel module target.
+define_property(TARGET PROPERTY KMODULE_IMPORTED_MODULE_LOCATION
+    BRIEF_DOCS "Location of the imported kernel module."
+    FULL_DOCS "Location of the imported kernel module."
+)
+
+# Absolute filename of Module.symvers file for imported kernel module.
+# Property may be set after
+#  kbuild_add_module(... IMPORTED)
+# for allow linking with given module or perform other actions required
+# its symbols.
+#
+# Analogue for KMODULE_MODULE_SYMVERS_LOCATION property of normal(non-exported)
+# kernel module target.
+define_property(TARGET PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION
+    BRIEF_DOCS "Location of the symvers file for imported kernel module."
+    FULL_DOCS "Location of the symvers file for imported kernel module."
+)
+
+# Helpers for simple extract some kernel module properties.
+
+#  kbuild_get_module_location(RESULT_VAR name)
+#
+# Return location of the module, determined by the property
+# KMODULE_MODULE_LOCATION or KMODULE_IMPORTED_MODULE_LOCATION for
+# imported target. In the last case the property is checked for being set.
+function(kbuild_get_module_location RESULT_VAR name)
+    if(NOT TARGET ${name})
+        message(FATAL_ERROR "\"${name}\" is not really a target.")
+    endif(NOT TARGET ${name})
+    get_property(kmodule_type TARGET ${name} PROPERTY KMODULE_TYPE)
+    if(NOT kmodule_type)
+        message(FATAL_ERROR "\"${name}\" is not really a target for kernel module.")
+    endif(NOT kmodule_type)
+    get_property(kmodule_imported TARGET ${name} PROPERTY KMODULE_IMPORTED)
+    if(kmodule_imported)
+        get_property(module_location TARGET ${name} PROPERTY KMODULE_IMPORTED_MODULE_LOCATION)
+        if(NOT module_location)
+            message(FATAL_ERROR "target \"${name}\" for imported module has no property KMODULE_IMPORTED_MODULE_LOCATION set.")
+        endif(NOT module_location)
+    else(kmodule_imported)
+        get_property(module_location TARGET ${name} PROPERTY KMODULE_MODULE_LOCATION)
+    endif(kmodule_imported)
+    set(${RESULT_VAR} ${module_location} PARENT_SCOPE)
+endfunction(kbuild_get_module_location RESULT_VAR module)
+
+#  kbuild_get_symvers_location(RESULT_VAR name)
+#
+# Return location of the symvers file for the module, determined by the
+# property KMODULE_SYMVERS_LOCATION or KMODULE_IMPORTED_SYMVERS_LOCATION
+# for imported target. In the last case the property is checked for being set.
+function(kbuild_get_symvers_location RESULT_VAR name)
+    if(NOT TARGET ${name})
+        message(FATAL_ERROR "\"${name}\" is not really a target.")
+    endif(NOT TARGET ${name})
+    get_property(kmodule_type TARGET ${name} PROPERTY KMODULE_TYPE)
+    if(NOT kmodule_type)
+        message(FATAL_ERROR "\"${name}\" is not really a target for kernel module.")
+    endif(NOT kmodule_type)
+    get_property(kmodule_imported TARGET ${name} PROPERTY KMODULE_IMPORTED)
+    if(kmodule_imported)
+        get_property(symvers_location TARGET ${name} PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION)
+        if(NOT symvers_location)
+            message(FATAL_ERROR "target \"${name}\" for imported module has no property KMODULE_IMPORTED_SYMVERS_LOCATION set.")
+        endif(NOT symvers_location)
+    else(kmodule_imported)
+        get_property(symvers_location TARGET ${name} PROPERTY KMODULE_SYMVERS_LOCATION)
+    endif(kmodule_imported)
+    set(${RESULT_VAR} ${symvers_location} PARENT_SCOPE)
+endfunction(kbuild_get_symvers_location RESULT_VAR module)
+
+#  kbuild_add_module(<name> [EXCLUDE_FROM_ALL] [MODULE_NAME <module_name>] [<sources> ...])
+#
+# Build kernel module from <sources>, analogue of add_library().
+#
+# Source files are divided into two categories:
+# -Object sources
+# -Other sourses
+#
+# Object sources are those sources, which may be used in building kernel
+# module externally.
+# Follow types of object sources are supported now:
+# .c: a file with the code in C language;
+# .S: a file with the code in assembly language;
+# .o_shipped: shipped file in binary format,
+#             does not require additional preprocessing.
+# 
+# Other sources are treated as only prerequisite of building process.
+#
+#
+# kbuild_add_module(<name> [MODULE_NAME <module_name>] IMPORTED)
+#
+# Create target, corresponded to the imported kernel module.
+# In that case KMODULE_IMPORTED_* properties should be set manually if needed.
+#
+# In either case, if MODULE_NAME option is given, it determine name
+# of the kernel module. Otherwise <name> itself is used.
+function(kbuild_add_module name)
+    cmake_parse_arguments(kbuild_add_module "IMPORTED;EXCLUDE_FROM_ALL" "MODULE_NAME" "" ${ARGN})
+    if(kbuild_add_module_MODULE_NAME)
+        set(module_name "${kbuild_add_module_MODULE_NAME}")
+    else(kbuild_add_module_MODULE_NAME)
+        set(module_name "${name}")
+    endif(kbuild_add_module_MODULE_NAME)
+    
+    string(LENGTH ${module_name} module_name_len)
+    if(module_name_len GREATER 55)
+        # Name of the kernel module should fit into array of size (64-sizeof(unsigned long)).
+        # On 64-bit systems(most restricted) this is 56.
+        # Even 56 length is not good, as it is not include null character.
+        # Without it, old versions of rmmod failed to unload module.
+        message(SEND_ERROR "Kernel module name exceeds 55 characters: '${module_name}'")
+    endif(module_name_len GREATER 55)
+    
+    if(kbuild_add_module_IMPORTED)
+        # Creation of IMPORTED target is simple.
+        add_custom_target(${name})
+        set_property(TARGET ${name} PROPERTY KMODULE_TYPE "kmodule")
+        set_property(TARGET ${name} PROPERTY KMODULE_IMPORTED "TRUE")
+        set_property(TARGET ${name} PROPERTY KMODULE_MODULE_NAME "${module_name}")
+        return()
+    endif(kbuild_add_module_IMPORTED)
+
+    if(kbuild_add_module_EXCLUDE_FROM_ALL)
+        set(all_arg)
+    else(kbuild_add_module_EXCLUDE_FROM_ALL)
+        set(all_arg "ALL")
+    endif(kbuild_add_module_EXCLUDE_FROM_ALL)
+    
+    # List of all source files, which are given.
+    set(sources ${kbuild_add_module_UNPARSED_ARGUMENTS})
+
+    # Sources with absolute paths
+    to_abs_path(sources_abs ${sources})
+    # list of files from which module building is depended
+    set(depend_files)
+    # Sources of "c" type, but without extension.
+    # Used for clean files, and for out-of-source builds do not create
+    # files in source tree.
+    set(c_sources_noext_abs)
+	# The sources with the code in assembly
+	set(asm_sources_noext_abs)
+	# Sources of "o_shipped" type, but without extension
+	set(shipped_sources_noext_abs)
+    # Categorize sources
+    foreach(source_abs ${sources_abs})
+        get_filename_component(ext ${source_abs} EXT)
+        if(ext STREQUAL ".c" OR ext STREQUAL ".S" OR ext STREQUAL ".o_shipped")
+			# Real sources
+			# Move source into binary tree, if needed
+			copy_source_to_binary_dir("${source_abs}" source_abs)
+            
+            get_filename_component(source_noext "${source_abs}" NAME_WE)
+            get_filename_component(source_dir "${source_abs}" PATH)
+            set(source_noext_abs "${source_dir}/${source_noext}")
+            if(ext STREQUAL ".c")
+				# c-source
+				list(APPEND c_sources_noext_abs ${source_noext_abs})
+			elseif(ext STREQUAL ".S")
+				# asm source
+				list(APPEND asm_sources_noext_abs ${source_noext_abs})
+			elseif(ext STREQUAL ".o_shipped")
+				# shipped-source
+				list(APPEND shipped_sources_noext_abs ${source_noext_abs})
+			endif(ext STREQUAL ".c")
+		endif(ext STREQUAL ".c" OR ext STREQUAL ".S" OR ext STREQUAL ".o_shipped")
+		# In any case, add file to depend list
+        list(APPEND depend_files ${source_abs})
+    endforeach(source_abs ${sources_abs})
+
+    # Object sources relative to current binary dir
+    # (for $(module)-y :=)
+    set(obj_sources_noext_rel)
+    foreach(obj_sources_noext_abs
+            ${c_sources_noext_abs} ${asm_sources_noext_abs} ${shipped_sources_noext_abs})
+        file(RELATIVE_PATH obj_source_noext_rel
+            ${CMAKE_CURRENT_BINARY_DIR} ${obj_sources_noext_abs})
+        list(APPEND obj_sources_noext_rel ${obj_source_noext_rel})
+    endforeach(obj_sources_noext_abs)
+
+    if(NOT obj_sources_noext_rel)
+        message(FATAL_ERROR "List of object files for building kernel module ${name} is empty.")
+    endif(NOT obj_sources_noext_rel)
+
+    set(obj_sources_rel)
+    # Detect, if build simple - source object name coincide with module name
+    
+    if(NOT obj_sources_noext_rel STREQUAL ${name})
+        # Check, whether only one of source object names coincide with module name.
+        # This situation is incorrect for kbuild system.
+        list(FIND obj_sources_noext_rel ${name} is_objects_contain_name)
+        if(is_objects_contain_name GREATER -1)
+            message(FATAL_ERROR "Module should be built "
+            "either from only one object with same name, "
+            "or from objects with names different from the name of the module")
+        endif(is_objects_contain_name GREATER -1)
+        
+        foreach(obj_source_noext_rel ${obj_sources_noext_rel})
+            list(APPEND obj_sources_rel "${obj_source_noext_rel}.o")
+        endforeach(obj_source_noext_rel ${obj_sources_noext_rel})
+    endif(NOT obj_sources_noext_rel STREQUAL ${name})
+
+    _get_directory_property_chained(ccflags KBUILD_COMPILE_DEFINITIONS " ")
+    _get_directory_property_chained(include_dirs KBUILD_INCLUDE_DIRECTORIES)
+
+    # Target for create module.
+    add_custom_target(${name} ALL
+        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko"
+                "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}"
+    )
+
+	# Create .cmd files for 'shipped' sources.
+    # Gcc does not create them automatically for some reason.
+	set(cmd_create_command)
+    if(shipped_sources_noext_abs)
+		foreach(shipped_source_noext_abs ${shipped_source_noext_abs})
+			get_filename_component(shipped_dir ${shipped_source_noext_abs} PATH)
+            get_filename_component(shipped_name ${shipped_source_noext_abs} NAME)
+			list(APPEND cmd_create_command
+				COMMAND printf "cmd_%s.o := cp -p %s.o_shipped %s.o\\n"
+					"${shipped_source_noext_abs}"
+					"${shipped_source_noext_abs}"
+					"${shipped_source_noext_abs}"
+					> "${shipped_dir}/.${shipped_name}.o.cmd")
+		endforeach(shipped_source_noext_abs ${shipped_source_noext_abs})
+	endif(shipped_sources_noext_abs)
+    
+    # User-defined parameters for 'make'
+    set(make_flags ${KBUILD_MAKE_FLAGS})
+    _get_per_build_var(make_flags_per_build KBUILD_MAKE_FLAGS)
+    list(APPEND make_flags ${make_flags_per_build})
+    
+    # Rule for create module(and symvers file).
+    add_custom_command(
+        OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko"
+            "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}"
+        ${cmd_create_command}
+        COMMAND $(MAKE) ${make_flags} ${kbuild_additional_make_flags} 
+            -C ${Kbuild_BUILD_DIR} M=${CMAKE_CURRENT_BINARY_DIR} modules
+# Update timestamps for targets.
+# In some cases Kbuild system may decide do not update resulted files
+# even in case when depencies newer.
+# Updating timestamps prevent command to be executed every make call. 
+        COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko"
+            "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}"
+        DEPENDS ${depend_files}
+            "${CMAKE_CURRENT_BINARY_DIR}/Kbuild"
+        COMMENT "Building kernel module ${name}"
+    )
+    
+    # Fill properties for the target.
+    set_property(TARGET ${name} PROPERTY KMODULE_TYPE "kmodule")
+    set_property(TARGET ${name} PROPERTY KMODULE_IMPORTED "FALSE")
+    set_property(TARGET ${name} PROPERTY KMODULE_MODULE_NAME "${module_name}")
+
+    set_property(TARGET ${name} PROPERTY KMODULE_MODULE_LOCATION
+        "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko"
+    )
+    set_property(TARGET ${name} PROPERTY KMODULE_SYMVERS_LOCATION
+        "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}"
+    )
+    
+    # Internal properties
+    set_property(TARGET ${name} PROPERTY KMODULE_BINARY_DIR
+        "${CMAKE_CURRENT_BINARY_DIR}"
+    )
+    set_property(TARGET ${name} PROPERTY KMODULE_OBJ_SOURCES ${obj_sources_rel})
+    set_property(TARGET ${name} PROPERTY KMODULE_COMPILE_FLAGS ${ccflags})
+    set_property(TARGET ${name} PROPERTY KMODULE_INCLUDE_DIRECTORIES ${include_dirs})
+
+
+    # Add target to the list of modules for built.
+    set_property(GLOBAL APPEND PROPERTY KMODULE_TARGETS "${name}")
+    
+    # The rule to clean files
+	_kbuild_module_clean_files(${name}
+		C_SOURCE ${c_sources_noext_abs}
+		ASM_SOURCE ${asm_sources_noext_abs}
+		SHIPPED_SOURCE ${shipped_sources_noext_abs})
+endfunction(kbuild_add_module name)
+
+#  kbuild_include_directories(dirs ...)
+#
+# Add include directories for Kbuild process.
+macro(kbuild_include_directories)
+    set_property(DIRECTORY APPEND PROPERTY KBUILD_INCLUDE_DIRECTORIES ${ARGN})
+endmacro(kbuild_include_directories)
+
+#  kbuild_add_definitions (flags)
+#
+# Specify additional flags for compile kernel module.
+#
+# Note that multiple flags should be specified as single string,
+# delimited with ' '.
+function(kbuild_add_definitions flags)
+    get_property(current_flags DIRECTORY PROPERTY KBUILD_COMPILE_DEFINITIONS)
+    _string_join(" " current_flags "${current_flags}" "${flags}")
+    set_property(DIRECTORY PROPERTY KBUILD_COMPILE_DEFINITIONS "${current_flags}")
+endfunction(kbuild_add_definitions flags)
+
+# There is no control for kbuild make flags except default values.
+# Support for kbuild_add_make_definitions may be added if needed.
+
+
+#  kbuild_link_module(<name> [<link> ...])
+#
+# Link kernel module with other modules, that allows to use symbols from
+# other modules.
+#
+# <link> may be:
+#  1) target name for other kernel module intended for build
+#  2) target name for imported kernel module with
+#     KMODULE_IMPORTED_SYMVERS_LOCATION property set
+#  3) absolute path to symvers file of other kernel module.
+#
+# In any case, file-level dependency will be created for symvers file to link with.
+# In the first case, also target-level dependency will be added
+#
+# Analogue for target_link_library().
+#
+# May be used only from the same directory, where module target is created.
+function(kbuild_link_module name)
+    # Check that @name corresponds to kernel module target for build.
+    get_property(is_module TARGET ${name} PROPERTY KMODULE_TYPE SET)
+    if(NOT is_module)
+        message(FATAL_ERROR "kbuild_module_link: passed <name>\n\t\"${name}\"\n which is not kernel module target.")
+    endif(NOT is_module)
+    get_property(module_imported TARGET ${name} PROPERTY KMODULE_IMPORTED)
+    if(kmodule_imported)
+        message(FATAL_ERROR "Imported kernel module target \"${name}\" may not be linked.")
+    endif(kmodule_imported)
+    
+    get_property(module_name TARGET ${name} PROPERTY KMODULE_MODULE_NAME)
+    
+    foreach(l ${ARGN})
+        string(REGEX MATCH "/" link_is_file ${l})
+        if(link_is_file)
+            string(REGEX MATCH "^/" file_is_absolute ${l})
+            if(NOT file_is_absolute)
+                message(FATAL_ERROR "kbuild_module_link: passed filename\n\t\"${link}\"\nwhich is not absolute as <link>.")
+            endif(NOT file_is_absolute)
+            set(symvers_location "${l}")
+            # Do not require symvers file to be already existed.
+        else(link_is_file)
+            if(NOT TARGET ${l})
+                message(FATAL_ERROR "kbuild_module_link: passed link\n\t\"${l}\"\n which is neither an absolute path to symvers file nor a target.")
+            endif(NOT TARGET ${l})
+            get_property(kmodule_type TARGET ${l} PROPERTY KMODULE_TYPE)
+            if(NOT kmodule_type)
+                message(FATAL_ERROR "kbuild_module_link: passed target\n\t\"${l}\"\n which is not a target for kernel module as link.")
+            endif(NOT kmodule_type)
+            get_property(kmodule_imported TARGET ${l} PROPERTY KMODULE_IMPORTED)
+            if(kmodule_imported)
+                get_property(symvers_location TARGET ${l} PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION)
+                if(NOT symvers_location)
+                    message(FATAL_ERROR "kbuild_module_link: passed imported target\n\t\"${l}\"\n without \"KMODULE_IMPORTED_SYMVERS_LOCATION\" property set as link.")
+                endif(NOT symvers_location)
+            else(kmodule_imported)
+                get_property(symvers_location TARGET ${l} PROPERTY KMODULE_SYMVERS_LOCATION)
+                # Target dependency is added only for non-imported target.
+                add_dependencies(${name} ${l})
+            endif(kmodule_imported)
+        endif(link_is_file)
+        add_custom_command(OUTPUT
+            "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko"
+            "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}"
+            DEPENDS ${symvers_location}
+            APPEND
+        )
+        set_property(TARGET ${name} APPEND PROPERTY KMODULE_DEPEND_SYMVERS ${symvers_location})
+    endforeach(l ${ARGN})
+endfunction(kbuild_link_module name)
+
+# kbuild_finalize_linking()
+#
+# Should be called after all kernel modules and their links defined.
+# Usually this is the end of main CMakeLists.txt file.
+function(kbuild_finalize_linking)
+    _get_per_build_var(ccflags_per_build KBUILD_C_FLAGS)
+    
+    get_property(kmodule_targets GLOBAL PROPERTY KMODULE_TARGETS)
+    foreach(m ${kmodule_targets})
+        get_property(module_binary_dir TARGET ${m} PROPERTY KMODULE_BINARY_DIR)
+        get_property(module_name TARGET ${m} PROPERTY KMODULE_MODULE_NAME)
+        get_property(module_symvers_cmake TARGET ${m} PROPERTY KMODULE_DEPEND_SYMVERS)
+        
+        get_property(obj_sources TARGET ${m} PROPERTY KMODULE_OBJ_SOURCES)
+        get_property(ccflags_local TARGET ${m} PROPERTY KMODULE_COMPILE_FLAGS)
+        get_property(include_dirs TARGET ${m} PROPERTY KMODULE_INCLUDE_DIRECTORIES)
+        
+        # Combine all compiler flags together
+        _string_join(" " ccflags "${KBUILD_C_FLAGS}" "${ccflags_local}")
+        foreach(dir ${include_dirs})
+            _string_join(" " ccflags "${ccflags}" "-I${dir}")
+        endforeach(dir ${include_dirs})
+        _string_join(" " ccflags "${ccflags}" "${ccflags_per_build}")
+        
+        string(REPLACE ";" " " module_symvers "${module_symvers_cmake}")
+        
+        if(obj_sources)
+            set(obj_src_string "${module_name}-y := ")
+            foreach(obj ${obj_sources})
+                set(obj_src_string "${obj_src_string} ${obj}")
+            endforeach(obj ${obj_sources})
+        else(obj_sources)
+            # Simple building process - module name is same as the name
+            # of the only source.
+            set(obj_src_string "")
+        endif(obj_sources)
+        # Configure kbuild file
+        configure_file(${kbuild_this_module_dir}/kbuild_system_files/Kbuild.in
+            ${module_binary_dir}/Kbuild
+        )
+    endforeach(m ${kmodule_targets})
+endfunction(kbuild_finalize_linking)
+
+# kbuild_install(TARGETS <module_name> ...
+#    [[MODULE|SYMVERS]
+#      DESTINATION <dir>
+#      [CONFIGURATIONS [...]]
+#      [COMPONENT <component>]
+#    ]+)
+#
+# Install kernel module(s) and/or symvers file(s) into given directory.
+#
+# Almost all options means same as for install() cmake command.
+# 'MODULE' refers to kernel module itself, SYMVERS refers symvers file.
+#
+# Unlike to standard install() command, there is no default destination
+# directory neither for modules nor for symvers files.
+# So, at least one rule should be defined, and 'DESTINATION' option
+# should be set for every rule.
+#
+# TODO: support for 'EXPORT' mode.
+function(kbuild_install type)
+    if(NOT type STREQUAL "TARGETS")
+        message(FATAL_ERROR "Only 'TARGETS' mode is currently supported")
+    endif(NOT type STREQUAL "TARGETS")
+    
+    parse_install_arguments(kbuild_install
+        "MODULE;SYMVERS" # Section types
+        "" "DESTINATION;COMPONENT" "CONFIGURATIONS" # Section keywords classification.
+        ${ARGN}
+    )
+    
+    set(kbuild_install_TARGETS ${kbuild_install_GLOBAL_ARGUMENTS})
+    if(NOT kbuild_install_TARGETS)
+        message(FATAL_ERROR "No targets given for kbuild_install() command")
+    endif(NOT kbuild_install_TARGETS)
+    
+    if(NOT kbuild_install_sections)
+        message(FATAL_ERROR "There is no default destination for install kernel module components, but no section described it is given.")
+    endif(NOT kbuild_install_sections)
+
+    foreach(section_type ${kbuild_install_sections})
+        if(NOT kbuild_install_${section_type}_DESTINATION)
+            message(FATAL_ERROR "DESTINATION is not defined for section ${section_type}")
+        endif(NOT kbuild_install_${section_type}_DESTINATION)
+        # All additional arguments for given section.
+        set(install_args_${section_type}
+            DESTINATION "${kbuild_install_${section_type}_DESTINATION}")
+        if(kbuild_install_${section_type}_CONFIGURATION)
+            list(APPEND install_args_${section_type}
+                CONFIGURATION "${kbuild_install_${section_type}_CONFIGURATION}"
+            )
+        endif(kbuild_install_${section_type}_CONFIGURATION)
+        if(kbuild_install_${section_type}_COMPONENT)
+            list(APPEND install_args_${section_type}
+                COMPONENT "${kbuild_install_${section_type}_COMPONENT}"
+            )
+        endif(kbuild_install_${section_type}_COMPONENT)
+        # Module installation.
+        if(section_type STREQUAL "MODULE" OR section_type STREQUAL "ALL")
+            # Combine locations for all modules in one list.
+            set(module_locations)
+            foreach(t ${kbuild_install_TARGETS})
+                kbuild_get_module_location(module_location ${t})
+                list(APPEND module_locations ${module_location})
+            endforeach(t ${kbuild_install_TARGETS})
+            # .. and install them at once.
+            install(FILES ${module_locations} ${install_args_${section_type}})
+        endif(section_type STREQUAL "MODULE" OR section_type STREQUAL "ALL")
+        # Symvers installation.
+        if(section_type STREQUAL "SYMVERS" OR section_type STREQUAL "ALL")
+            # Because of renaming, symvers files should be installed separately.
+            foreach(t ${kbuild_install_TARGETS})
+                kbuild_get_symvers_location(symvers_location ${t})
+                get_property(module_name TARGET ${t} PROPERTY KMODULE_MODULE_NAME)
+                install(FILES ${symvers_location}
+                    RENAME "${module_name}.symvers"
+                    ${install_args_${section_type}}
+                )
+            endforeach(t ${kbuild_install_TARGETS})
+        endif(section_type STREQUAL "SYMVERS" OR section_type STREQUAL "ALL")
+    endforeach(section_type ${kbuild_install_sections})
+endfunction(kbuild_install type)
+
+
+# kbuild_try_compile(RESULT_VAR bindir srcfile|SOURCES src ...
+#           [CMAKE_FLAGS <Flags>]
+#           [KBUILD_COMPILE_DEFINITIONS flags ...]
+#           [OUTPUT_VARIABLE var])
+#
+# Similar to try_module in simplified form, but compile srcfile as
+# kernel module, instead of user space program.
+#
+# KBUILD_COMPILE_DEFINITIONS contains compiler definition flags for
+# build kernel module.
+#
+# Possible CMAKE_FLAGS which has special semantic:
+#  KBUILD_INCLUDE_DIRECTORIES - include directories for build kernel module
+#  KBUILD_LINK_MODULE - symvers file(s) for link module with other modules.
+function(kbuild_try_compile RESULT_VAR bindir srcfile)
+    cmake_parse_arguments(kbuild_try_compile "" "OUTPUT_VARIABLE" "CMAKE_FLAGS;KBUILD_COMPILE_DEFINITIONS" ${ARGN})
+    if(srcfile STREQUAL "SOURCES")
+        set(srcfiles ${kbuild_try_compile_UNPARSED_ARGUMENTS})
+    else(srcfile STREQUAL "SOURCES")
+        set(srcfiles ${srcfile})
+    endif(srcfile STREQUAL "SOURCES")
+
+    # Inside try_compile project values of variables
+    # CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR
+    # differs from ones in current project.
+    #
+    # So make all paths absolute before pass them into try_compile project.
+    # Note, that copiing files into binary dir is nevertheless performed
+    # in the try_compile project, because it bases on real current binary dir.
+    to_abs_path(srcfiles_abs ${srcfiles})
+    
+    # Collect parameters to try_compile() function
+    set(cmake_flags
+        "-DSOURCES:STRING=${srcfiles_abs}" # Source file(s)
+        "-DCMAKE_MODULE_PATH:PATH=${CMAKE_MODULE_PATH}" # Path for search include files.
+        ${kbuild_try_compile_CMAKE_FLAGS}
+    )
+
+    # Parameters for compiler
+    if(kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS)
+        list(APPEND cmake_flags
+            "-DKBUILD_COMPILE_DEFINITIONS:STRING=${kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS}"
+        )
+    endif(kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS)
+
+    # Other user-defined cmake flags
+    if(kbuild_try_compile_CMAKE_FLAGS)
+        
+    endif(kbuild_try_compile_CMAKE_FLAGS)
+
+    # Possible definition of output variable.
+    if(kbuild_try_compile_OUTPUT_VARIABLE)
+        set(output_variable_def "OUTPUT_VARIABLE" "output_tmp")
+    else(build_try_compile_OUTPUT_VARIABLE)
+        set(output_variable_def)
+    endif(kbuild_try_compile_OUTPUT_VARIABLE)
+
+    
+    try_compile(result_tmp # Result variable(temporary)
+        "${bindir}" # Binary directory
+        "${kbuild_aux_dir}/try_compile_project" # Source directory
+        "kmodule" # Project name
+         CMAKE_FLAGS # Flags to CMake:
+            ${cmake_flags}
+            ${kbuild_try_compile_flags}
+        ${output_variable_def}
+    )
+    
+    if(kbuild_try_compile_OUTPUT_VARIABLE)
+        # Set output variable for the caller
+        set("${kbuild_try_compile_OUTPUT_VARIABLE}" "${output_tmp}" PARENT_SCOPE)
+    endif(kbuild_try_compile_OUTPUT_VARIABLE)
+    # Set result variable for the caller
+    set("${RESULT_VAR}" "${result_tmp}" PARENT_SCOPE)
+endfunction(kbuild_try_compile RESULT_VAR bindir srcfile)
+
+########### Auxiliary functions for internal use #######################
+# Per-directory tracking for kbuild compiler flags.
+#
+# Unlike to standard COMPILE_FLAGS, these flags do not include values
+# set for parent directories.
+# (There is no generic "fill-with-parent's values" mechanism exists
+# in cmake).
+#
+# So, this property has a little sence for the user.
+# It exists only for make effect of kbuild_add_definitions() to 
+# cross "function" scope.
+define_property(DIRECTORY PROPERTY KBUILD_COMPILE_FLAGS
+    BRIEF_DOCS "Compiler flags used by Kbuild system added in this directory."
+    FULL_DOCS "Compiler flags used by Kbuild system added in this directory."
+)
+
+# Per-directory tracking for kbuild include directories.
+#
+# Unlike to standard INCLUDE_DIRECTORIES, these ones do not include values
+# set for parent directories.
+# (There is no generic "fill-with-parent's values" mechanism exists
+# in cmake).
+#
+# So, this property has a little sence for the user.
+# It exists only for make effect of kbuild_include_directories() to 
+# cross "function" scope.
+define_property(DIRECTORY PROPERTY KBUILD_INCLUDE_DIRECTORIES
+    BRIEF_DOCS "Include directories used by Kbuild system; added in this directory."
+    FULL_DOCS "Include directories used by Kbuild system; added in this directory."
+)
+
+
+# Parameters below are set externally only in try_compile() for subproject,
+# which include this file.
+# No need to cache them as try_compile() project is not configured by the user.
+
+# Real top-level source directory.
+if(NOT KBUILD_REAL_SOURCE_DIR)
+    set(KBUILD_REAL_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+endif(NOT KBUILD_REAL_SOURCE_DIR)
+# Real top-level binary directory.
+if(NOT KBUILD_REAL_BINARY_DIR)
+    set(KBUILD_REAL_BINARY_DIR ${CMAKE_BINARY_DIR})
+endif(NOT KBUILD_REAL_BINARY_DIR)
+
+# These flags are passed to the 'make' when compile kernel module.
+set(kbuild_additional_make_flags)
+# These CMake flags will be passed to try_compile() subproject.
+set(kbuild_try_compile_flags
+    "-DKBUILD_REAL_SOURCE_DIR=${KBUILD_REAL_SOURCE_DIR}"
+    "-DKBUILD_REAL_BINARY_DIR=${KBUILD_REAL_BINARY_DIR}"
+)
+
+# ARCH and CROSS_COMPILE are passed to submake only when non-empty.
+if(ARCH)
+    list(APPEND kbuild_additional_make_flags "ARCH=${ARCH}")
+    list(APPEND kbuild_try_compile_flags "-DARCH=${ARCH}")
+endif(ARCH)
+if(CROSS_COMPILE)
+    list(APPEND kbuild_additional_make_flags "CROSS_COMPILE=${CROSS_COMPILE}")
+    list(APPEND kbuild_try_compile_flags "-DCROSS_COMPILE=${CROSS_COMPILE}")
+endif(CROSS_COMPILE)
+
+# List of targets created with kmodule_add_module() without
+# 'IMPORTED' option.
+#
+# This list is traversed in kmodule_finalize_linking() for
+# create 'Kbuild' files.
+#
+# Note, that this list does not contain all defined kernel modules,
+# so property normally shouldn't be used by outer code.
+define_property(GLOBAL PROPERTY KMODULE_TARGETS
+    BRIEF_DOCS "List of kernel module targets configured for build"
+    FULL_DOCS "List of kernel module targets configured for build"
+)
+
+# CMAKE_CURRENT_BINARY_DIR at the moment, when kbuild_add_module() is issued.
+define_property(TARGET PROPERTY KMODULE_BINARY_DIR
+    BRIEF_DOCS "CMAKE_CURRENT_BINARY_DIR where module is built."
+    FULL_DOCS "CMAKE_CURRENT_BINARY_DIR where module is built."
+)
+
+# List of object files, used for build kernel module.
+#
+# List may be empty in case of simple build, when target module has same
+# name as its only source.
+#
+# This is internal property for configure 'Kbuild' file.
+define_property(TARGET PROPERTY KMODULE_OBJ_SOURCES
+    BRIEF_DOCS "Object source files for build kernel module."
+    FULL_DOCS "Object source files for build kernel module."
+)
+
+# Compiler flags, added with kbuild_add_definitions()
+#
+# Note, that KBUILD_C_FLAGS* are not included here.
+#
+# This is internal property for configure 'Kbuild' file.
+define_property(TARGET PROPERTY KMODULE_COMPILE_FLAGS
+    BRIEF_DOCS "Additional compile flags for build kernel module."
+    FULL_DOCS "Additional compile flags for build kernel module."
+)
+
+# Include directories, added with kbuild_include_directories().
+#
+# This is internal property for configure 'Kbuild' file.
+define_property(TARGET PROPERTY KMODULE_COMPILE_FLAGS
+    BRIEF_DOCS "Additional compile flags for build kernel module."
+    FULL_DOCS "Additional compile flags for build kernel module."
+)
+
+
+# List of symvers files, added by kbuild_link_module().
+#
+# This is internal property for configure 'Kbuild' file.
+define_property(TARGET PROPERTY KMODULE_DEPEND_SYMVERS
+    BRIEF_DOCS "Symvers files this module depends on."
+    FULL_DOCS "Symvers files this module depends on."
+)
+
+# Constants for internal filenames.
+set(_kbuild_symvers "Module.symvers")
+
+#  copy_source_to_binary_dir(<source> <new_source_var>)
+#
+# Helper for the building kernel module.
+#
+# Make sure that given source file is inside current binary dir.
+# That place is writable and has some "uniqeness" garantee for generate
+# auxiliary files during build process.
+#
+# If <source> already inside current binary dir, do nothing and
+# set <new_source_var> variable to <source> itself.
+#
+# Otherwise create rule for copy source into "nice" place inside
+# current binary dir and set <new_source_var> pointed to that place.
+function(copy_source_to_binary_dir source new_source_var)
+    is_path_inside_dir(is_in_current_binary ${CMAKE_CURRENT_BINARY_DIR} "${source}")
+    if(is_in_current_binary)
+        # Source is already placed where we want.
+        set(${new_source_var} "${source}" PARENT_SCOPE)
+    else(is_in_current_binary)
+        # Base directory from which count relative source path.
+        # By default, it is root directory.
+        set(base_dir "/")
+        # Try "nicer" base directories.
+        foreach(d
+            ${KBUILD_REAL_BINARY_DIR}
+            ${CMAKE_CURRENT_SOURCE_DIR}
+            ${KBUILD_REAL_SOURCE_DIR}
+            )
+            is_path_inside_dir(is_in_d ${d} "${source}")
+            if(is_in_d)
+                set(base_dir ${d})
+                break()
+            endif(is_in_d)
+        endforeach(d)
+		# Copy source into same relativ dir, but inside current binary one.
+        file(RELATIVE_PATH source_rel "${base_dir}" "${source}")
+		set(new_source "${CMAKE_CURRENT_BINARY_DIR}/${source_rel}")
+        get_filename_component(new_source_dir ${new_source} PATH)
+        file(MAKE_DIRECTORY "${new_source_dir}")
+		rule_copy_file("${new_source}" "${source}")
+        # Return path to the new source.
+        set(${new_source_var} "${new_source}" PARENT_SCOPE)
+    endif(is_in_current_binary)
+endfunction(copy_source_to_binary_dir source new_source_var)
+
+#  _get_per_build_var(RESULT_VAR variable)
+#
+# Return value of per-build variable.
+macro(_get_per_build_var RESULT_VAR variable)
+    if(CMAKE_BUILD_TYPE)
+        string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_uppercase)
+        set(${RESULT_VAR} "${${variable}_${_build_type_uppercase}}")
+    else(CMAKE_BUILD_TYPE)
+        set(${RESULT_VAR})
+    endif(CMAKE_BUILD_TYPE)
+endmacro(_get_per_build_var RESULT_VAR variable)
+
+#  _string_join(sep RESULT_VAR str1 str2)
+#
+# Join strings <str1> and <str2> using <sep> as glue.
+#
+# Note, that precisely 2 string are joined, not a list of strings.
+# This prevents automatic replacing of ';' inside strings while parsing arguments.
+macro(_string_join sep RESULT_VAR str1 str2)
+    if("${str1}" STREQUAL "")
+        set("${RESULT_VAR}" "${str2}")
+    elseif("${str2}" STREQUAL "")
+        set("${RESULT_VAR}" "${str1}")
+    else("${str1}" STREQUAL "")
+        set("${RESULT_VAR}" "${str1}${sep}${str2}")
+    endif("${str1}" STREQUAL "")
+endmacro(_string_join sep RESULT_VAR str1 str2)
+#  _build_get_directory_property_chained(RESULT_VAR <propert_name> [<separator>])
+#
+# Return list of all values for given property in the current directory
+# and all parent directories.
+#
+# If <separator> is given, it is used as glue for join values.
+# By default, cmake list separator (';') is used.
+function(_get_directory_property_chained RESULT_VAR property_name)
+    set(sep ";")
+    foreach(arg ${ARGN})
+        set(sep "${arg}")
+    endforeach(arg ${ARGN})
+    set(result "")
+    set(d "${CMAKE_CURRENT_SOURCE_DIR}")
+    while(NOT "${d}" STREQUAL "")
+        get_property(p DIRECTORY "${d}" PROPERTY "${property_name}")
+        # debug
+        # message("Property ${property_name} for directory ${d}: '${p}'")
+        _string_join("${sep}" result "${p}" "${result}")
+        # message("Intermediate result: '${result}'")
+        get_property(d DIRECTORY "${d}" PROPERTY PARENT_DIRECTORY)
+    endwhile(NOT "${d}" STREQUAL "")
+    set("${RESULT_VAR}" "${result}" PARENT_SCOPE)
+endfunction(_get_directory_property_chained RESULT_VAR property_name)
+
+#  _kbuild_module_clean_files(module_name
+# 	[C_SOURCE c_source_noext_abs ...]
+# 	[ASM_SOURCE asm_source_noext_abs ...]
+#	[SHIPPED_SOURCE shipped_source_noext_abs ...])
+#
+# Tell CMake that intermediate files, created by kbuild system,
+# should be cleaned with 'make clean'.
+function(_kbuild_module_clean_files module_name)
+    cmake_parse_arguments(kbuild_module_clean "" "" "C_SOURCE;ASM_SOURCE;SHIPPED_SOURCE" ${ARGN})
+    if(kbuild_module_clean_UNPARSED_ARGUMENTS)
+        message(FATAL_ERROR "Unparsed arguments")
+    endif(kbuild_module_clean_UNPARSED_ARGUMENTS)
+
+	# List common files (names only) for cleaning
+	set(common_files_names
+        ".tmp_versions" # Directory
+        "modules.order"
+		"Module.markers"
+    )
+	# List module name-depending files (extensions only) for cleaning
+	set(name_files_ext
+		".o"
+		".mod.c"
+		".mod.o"
+    )
+	# Same but for the files with names starting with a dot ('.').
+	set(name_files_dot_ext
+		".ko.cmd"
+		".mod.o.cmd"
+		".o.cmd"
+    )
+	# List source name-depending files (extensions only) for cleaning
+	set(source_name_files_ext
+		".o"
+    )
+	# Same but for the files with names starting with a dot ('.')
+	set(source_name_files_dot_ext
+		".o.cmd"
+		".o.d" # This file is created in case of unsuccessfull build
+    )
+	
+	# Now collect all sort of files into list
+	set(files_list)
+
+	foreach(name ${common_files_names})
+		list(APPEND files_list "${CMAKE_CURRENT_BINARY_DIR}/${name}")
+	endforeach(name ${common_files_names})
+	
+	foreach(ext ${name_files_ext})
+		list(APPEND files_list
+			"${CMAKE_CURRENT_BINARY_DIR}/${module_name}${ext}")
+	endforeach(ext ${name_files_ext})
+	
+	foreach(ext ${name_files_dot_ext})
+		list(APPEND files_list
+			"${CMAKE_CURRENT_BINARY_DIR}/.${module_name}${ext}")
+	endforeach(ext ${name_files_ext})
+	
+    # All the types of sources are processed in a similar way
+    foreach(obj_source_noext_abs ${kbuild_module_clean_C_SOURCE}
+        ${kbuild_module_clean_ASM_SOURCE} ${kbuild_module_clean_SHIPPED_SOURCE})
+
+        get_filename_component(dir ${obj_source_noext_abs} PATH)
+        get_filename_component(name ${obj_source_noext_abs} NAME)
+        foreach(ext ${source_name_files_ext})
+            list(APPEND files_list "${dir}/${name}${ext}")
+        endforeach(ext ${source_name_files_ext})
+        foreach(ext ${source_name_files_dot_ext})
+            list(APPEND files_list "${dir}/.${name}${ext}")
+        endforeach(ext ${source_name_files_ext})
+    endforeach(obj_source_noext_abs)
+	# Tell CMake that given files should be cleaned.
+	set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${files_list}")
+endfunction(_kbuild_module_clean_files module_name)
+
+#  parse_install_arguments(prefix <section-type-keywords> <options> <one-value-keywords> <multiple-value-keywords> args..)
+#
+# Helper for parse arguments for install-like command.
+#
+# All arguments before the first keyword are classified as GLOBAL_ARGUMENTS
+# and stored into list ${prefix}_GLOBAL_ARGUMENTS.
+#
+# <section-type-keywords> describe possible keywords denoting section type.
+# At most one section may exist for every type.
+# Special type ALL means generic section. 
+#
+# <options>, <one-value-keywords> and <multiple-value-keywords> describe
+# all keywords inside section.
+# Values corresponded to these keywords are stored under
+# <prefix>_<section-type>_*.
+# Note, that unlike to cmake_parse_arguments(), all arguments inside
+# section definition should be either keyword or its value(s).
+# Additionally, <prefix>_<section-type> is set to TRUE for every
+# encountered section and <prefix>_sections contains list of such sections.
+#
+# If non section is currently active, the first section keyword starts
+# special generic section. Definitions for this section are stored as
+# for section of type ALL.
+# If such section exists, it should be the only section.
+#
+# Function is generic, but currently is used only there.
+function(parse_install_arguments prefix section_types options one_value_keywords multiple_value_keywords)
+    set(all_keywords ${section_types} ${options} ${one_value_keywords} ${multiple_value_keywords})
+    # Type of the currently parsed section('ALL' for ALL section).
+    set(current_section_type)
+    # Active section-related keyword for current section.
+    set(current_section_keyword)
+    # Classification for @_current_section_keyword:
+    # 'OPTION', 'ONE' or 'MULTY'.
+    set(current_section_keyword_type)
+    
+    # Clean all previous keyword values.
+    set("pia_GLOBAL_ARGUMENTS")
+    foreach(section_type "ALL" ${section_types})
+        set(pia_${section_type} "FALSE")
+        foreach(opt ${options})
+            set("pia_${section_type}_${opt}" "FALSE")
+        endforeach(opt ${options})
+        foreach(keyword ${one_value_keywords} ${multiple_value_keywords})
+            set("pia_${section_type}_${keyword}")
+        endforeach(keyword ${one_value_keywords} ${multiple_value_keywords})
+    endforeach(section_type "ALL" ${section_types})
+    set("pia_sections")
+
+    foreach(arg ${ARGN})
+        list(FIND all_keywords ${arg} keyword_index)
+        if(keyword_index EQUAL "-1")
+            if(current_section_type)
+                if(NOT current_section_keyword)
+                    message(FATAL_ERROR "In section ${current_section_type} argument ${arg} does not belong to any keyword.")
+                endif(NOT current_section_keyword)
+                if(current_section_keyword_type STREQUAL "ONE")
+                    set("pia_${current_section_type}_${current_section_keyword}" "${arg}")
+                    set(current_section_keyword "")
+                else(current_section_keyword_type STREQUAL "ONE")
+                    list(APPEND "pia_${current_section_type}_${current_section_keyword}" "${arg}")
+                endif(current_section_keyword_type STREQUAL "ONE")
+            else(current_section_type)
+                list(APPEND "pia_GLOBAL_ARGUMENTS" "${arg}")
+            endif(current_section_type)
+        else(keyword_index EQUAL "-1")
+            if(current_section_type AND current_section_keyword AND current_section_keyword_type STREQUAL "ONE")
+                message(FATAL_ERROR "Keyword ${arg} found while value for one-value-option ${current_section_keyword} expected.")
+            endif(current_section_type AND current_section_keyword AND current_section_keyword_type STREQUAL "ONE")
+            list(FIND section_types "${arg}" section_type_index)
+            if(section_type_index EQUAL "-1")
+                if(NOT current_section_type)
+                    set(current_section_type "ALL")
+                    set("pia_${current_section_type}" "TRUE")
+                    list(APPEND "pia_sections" "${current_section_type}")
+                endif(NOT current_section_type)
+                list(FIND options ${arg} option_index)
+                if(option_index EQUAL "-1")
+                    set(current_section_keyword ${arg})
+                    list(FIND one_value_keywords ${current_section_keyword} one_index)
+                    if(one_index EQUAL "-1")
+                        set(current_section_keyword_type "MULTY")
+                    else(one_index EQUAL "-1")
+                        set(current_section_keyword_type "ONE")
+                    endif(one_index EQUAL "-1")
+                    set("pia_${current_section_type}_${current_section_keyword}")
+                else(option_index EQUAL "-1")
+                    set("${prefix}_${current_section_type}_${current_section_keyword}" "TRUE")
+                    set(current_section_keyword_type)
+                endif(option_index EQUAL "-1")
+            else(section_type_index EQUAL "-1")
+                if("pia_ALL")
+                    message(FATAL_ERROR "Generic section should be the only section defined")
+                endif("pia_ALL")
+                set(current_section_type "${arg}")
+                if("pia_${current_section_type}")
+                    message(FATAL_ERROR "Section ${current_section_type} is defined twice.")
+                endif("pia_${current_section_type}")
+                set("pia_${current_section_type}" "TRUE")
+                list(APPEND "pia_sections" "${current_section_type}")
+                # Current keyword is initially undefined for such section.
+                set(current_section_keyword)
+            endif(section_type_index EQUAL "-1")
+        endif(keyword_index EQUAL "-1")
+    endforeach(arg ${ARGN})
+
+    # propagate the result variables to the caller
+    set("${prefix}_GLOBAL_ARGUMENTS" ${pia_GLOBAL_ARGUMENTS} PARENT_SCOPE)
+    foreach(section_type "ALL" ${section_types})
+        set(${prefix}_${section_type} ${pia_${section_type}} PARENT_SCOPE)
+        foreach(keyword ${options} ${one_value_keywords} ${multiple_value_keywords})
+            set("${prefix}_${section_type}_${keyword}" ${pia_${section_type}_${keyword}} PARENT_SCOPE)
+        endforeach(keyword ${options} ${one_value_keywords} ${multiple_value_keywords})
+    endforeach(section_type "ALL" ${section_types})
+    set("${prefix}_sections" ${pia_sections} PARENT_SCOPE)
+endfunction(parse_install_arguments prefix section_types options one_value_keywords multiple_value_keywords)
diff --git a/cmake_targets/tools/MODULES/kmodule.cmake b/cmake_targets/tools/MODULES/kmodule.cmake
new file mode 100644
index 0000000000..2912ac115a
--- /dev/null
+++ b/cmake_targets/tools/MODULES/kmodule.cmake
@@ -0,0 +1,539 @@
+set(kmodule_this_module_dir "${CMAKE_SOURCE_DIR}/cmake/modules/")
+set(kmodule_test_sources_dir "${CMAKE_SOURCE_DIR}/cmake/kmodule_sources")
+
+set(kmodule_function_map_file "")
+if (CMAKE_CROSSCOMPILING)
+	if (KEDR_SYSTEM_MAP_FILE)
+		set (kmodule_function_map_file "${KEDR_SYSTEM_MAP_FILE}")
+	else (KEDR_SYSTEM_MAP_FILE)
+# KEDR_SYSTEM_MAP_FILE is not specified, construct the default path 
+# to the symbol map file.
+		set (kmodule_function_map_file 
+	"${KEDR_ROOT_DIR}/boot/System.map-${KBUILD_VERSION_STRING}"
+		)
+	endif (KEDR_SYSTEM_MAP_FILE)
+endif (CMAKE_CROSSCOMPILING)
+
+# List of unreliable functions, that is, the functions that may be
+# be exported and mentioned in System.map but still cannot be used
+# because no header provides their declarations.
+set(unreliable_functions_list
+    "__kmalloc_node"
+	"kmem_cache_alloc_node"
+	"kmem_cache_alloc_node_notrace"
+	"kmem_cache_alloc_node_trace"
+)
+
+# kmodule_is_function_exist(function_name RESULT_VAR)
+# Verify, whether given function exist in the kernel space on the current system.
+# RESULT_VAR is TRUE, if function_name exist in the kernel space, FALSE otherwise.
+# RESULT_VAR is cached.
+
+function(kmodule_is_function_exist function_name RESULT_VAR)
+    check_begin("Looking for ${function_name} in the kernel")
+    if(NOT DEFINED ${RESULT_VAR})
+        check_try()
+        execute_process(
+            COMMAND sh "${kmodule_this_module_dir}/kmodule_files/scripts/lookup_kernel_function.sh"
+				${function_name} ${kmodule_function_map_file}
+			WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+            RESULT_VARIABLE kmodule_is_function_exist_result
+            OUTPUT_QUIET)
+
+		if (kmodule_is_function_exist_result EQUAL 0)
+            list(FIND unreliable_functions_list ${function_name} unreliable_function_index)
+            if(unreliable_function_index GREATER -1)
+                # Additional verification for unreliable function
+                kbuild_try_compile(kmodule_function_is_exist_reliable
+                    "${CMAKE_BINARY_DIR}/check_unreliable_functions/${function_name}"
+                    "${kmodule_test_sources_dir}/check_unreliable_functions/${function_name}.c"
+                )
+                if(NOT kmodule_function_is_exist_reliable)
+                    set(kmodule_is_function_exist_result 1)
+                endif(NOT kmodule_function_is_exist_reliable)
+            endif(unreliable_function_index GREATER -1)
+        endif(kmodule_is_function_exist_result EQUAL 0)
+
+        if (kmodule_is_function_exist_result EQUAL 0)
+            set(${RESULT_VAR} "TRUE" CACHE INTERNAL "Does ${function_name} exist in the kernel?")
+        elseif(kmodule_is_function_exist_result EQUAL 1)
+            set(${RESULT_VAR} "FALSE" CACHE INTERNAL "Does ${function_name} exist in the kernel?")
+        else(kmodule_is_function_exist_result EQUAL 0)
+            message(FATAL_ERROR 
+"Cannot determine whether function '${function_name}' exists in the kernel"
+			)
+        endif(kmodule_is_function_exist_result EQUAL 0)
+    endif(NOT DEFINED ${RESULT_VAR})
+    set_bool_string(check_result "found" "not found" ${${RESULT_VAR}})
+    check_end(${check_result})
+endfunction(kmodule_is_function_exist function_name RESULT_VAR)
+
+# Creates the list of functions that actually exist on the 
+# current system.
+#
+# kmodule_configure_kernel_functions(output_list 
+#	{[REQUIRED | OPTIONAL] {func | ONE_OF_LIST}} ...)
+#
+# ONE_OF_LIST := ONE_OF_BEGIN {func ...} ONE_OF_END
+#
+# There are 2 modes of function lookup: 
+# OPTIONAL - if the function doesn't exist, it is silently ignored.
+# REQUIRED - if the function doesn't exist, FATAL_ERROR message is printed.
+#
+# Initial mode is REQUIRED, and it can be changed at any time by REQUIRED 
+# and OPTIONAL keywords.
+#
+# ONE_OF_BEGIN/ONE_OF_END determine a section for which no more than one 
+# function among all listed there should exist. FATAL_ERROR message is 
+# printed otherwise. When mode is REQUIRED, precisely one function must 
+# exist.
+# Inside this section other keywords must not be used (even another 
+# ONE_OF_BEGIN).
+
+function(kmodule_configure_kernel_functions output_list)
+	set(kmodule_configure_kernel_functions_mode "REQUIRED")
+	set(kmodule_configure_kernel_functions_one_of_section "FALSE")
+	set(output_list_tmp)
+    set(${output_list})
+	foreach(arg ${ARGN})
+		if(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL")
+			if(kmodule_configure_kernel_functions_one_of_section)
+				message(FATAL_ERROR 
+"Inside ONE_OF_BEGIN/ONE_OF_END section, other keywords are not allowed."
+				)
+			endif(kmodule_configure_kernel_functions_one_of_section)
+			set(kmodule_configure_kernel_functions_mode ${arg})
+		elseif(arg STREQUAL "ONE_OF_BEGIN")
+			if(kmodule_configure_kernel_functions_one_of_section)
+				message(FATAL_ERROR "Nested ONE_OF_BEGIN/ONE_OF_END sections are not allowed.")
+			endif(kmodule_configure_kernel_functions_one_of_section)
+			set(kmodule_configure_kernel_functions_one_of_section "TRUE")
+			set(kmodule_configure_kernel_functions_one_of_section_function)
+		elseif(arg STREQUAL "ONE_OF_END")
+			if(NOT kmodule_configure_kernel_functions_one_of_section)
+				message(FATAL_ERROR "ONE_OF_END without ONE_OF_BEGIN is not allowed.")
+			endif(NOT kmodule_configure_kernel_functions_one_of_section)
+			if(kmodule_configure_kernel_functions_one_of_section_function)
+				list(APPEND output_list_tmp ${kmodule_configure_kernel_functions_one_of_section_function})				
+			else(kmodule_configure_kernel_functions_one_of_section_function)
+				if(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED")
+					message(FATAL_ERROR 
+"None of the functions listed in ONE_OF section exist in the kernel but it is required."
+					)
+				endif(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED")
+			endif(kmodule_configure_kernel_functions_one_of_section_function)
+			set(kmodule_configure_kernel_functions_one_of_section "FALSE")
+		else(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL")
+			set(kmodule_func_varname _KMODULE_IS_${arg}_EXIST)
+			kedr_find_function(${arg} ${kmodule_func_varname})
+			if(kmodule_configure_kernel_functions_one_of_section)
+				if(${kmodule_func_varname})
+					if(kmodule_configure_kernel_functions_one_of_section_function)
+						message(FATAL_ERROR "Two functions from ONE_OF sections exist in the kernel.")
+					else(kmodule_configure_kernel_functions_one_of_section_function)
+						set(kmodule_configure_kernel_functions_one_of_section_function ${arg})	
+					endif(kmodule_configure_kernel_functions_one_of_section_function)
+				endif(${kmodule_func_varname})
+			else(kmodule_configure_kernel_functions_one_of_section)
+				if(${kmodule_func_varname})
+					list(APPEND output_list_tmp ${arg})
+				else(${kmodule_func_varname})
+					if(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED")
+						message(FATAL_ERROR "Function ${arg} is not found in the kernel but it is required.")
+					endif(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED")
+				endif(${kmodule_func_varname})
+			endif(kmodule_configure_kernel_functions_one_of_section)
+		endif(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL")
+	endforeach(arg ${ARGN})
+	if(kmodule_configure_kernel_functions_one_of_section)
+		message(FATAL_ERROR "Found ONE_OF_BEGIN without ONE_OF_END")
+	endif(kmodule_configure_kernel_functions_one_of_section)
+    set(${output_list} ${output_list_tmp} PARENT_SCOPE)
+endfunction(kmodule_configure_kernel_functions output_list)
+
+############################################################################
+# Utility macros to check for particular features. If the particular feature
+# is supported, the macros will set the corresponding variable to TRUE, 
+# otherwise - to FALSE (the name of variable is mentioned in the comments 
+# for the macro). 
+############################################################################
+
+# Check if the system has everything necessary to build at least simple
+# kernel modules. 
+# The macro sets variable 'MODULE_BUILD_SUPPORTED'.
+macro(check_module_build)
+	check_begin("Checking if kernel modules can be built on this system")
+	if (NOT MODULE_BUILD_SUPPORTED)
+		check_try()
+		kbuild_try_compile(module_build_supported_impl 
+			"${CMAKE_BINARY_DIR}/check_module_build"
+			"${kmodule_test_sources_dir}/check_module_build/module.c"
+		)
+		set_bool_string(MODULE_BUILD_SUPPORTED "yes" "no" ${module_build_supported_impl}
+			CACHE INTERNAL "Can kernel modules be built on this system?"
+		)
+	endif (NOT MODULE_BUILD_SUPPORTED)
+	
+	check_end("${MODULE_BUILD_SUPPORTED}")
+	
+	if (NOT MODULE_BUILD_SUPPORTED)
+		message(FATAL_ERROR 
+"There are problems with building kernel modules on this system. "
+"Please check that the appropriate kernel headers and build tools "
+"are installed."
+			)
+	endif (NOT MODULE_BUILD_SUPPORTED)
+endmacro(check_module_build)
+
+# Check if reliable stack trace information can be obtained. 
+# This is the case, for example, if the kernel is compiled with support
+# for frame pointers and/or stack unwind on.
+# The macro sets variable 'STACK_TRACE_RELIABLE'.
+macro(check_stack_trace)
+	check_begin("Checking if stack trace information is reliable")
+	if (NOT DEFINED STACK_TRACE_RELIABLE)
+		check_try()
+		kbuild_try_compile(stack_trace_reliable_impl 
+			"${CMAKE_BINARY_DIR}/check_stack_trace"
+			"${kmodule_test_sources_dir}/check_stack_trace/module.c"
+		)
+		set_bool_string(STACK_TRACE_RELIABLE "yes" "no" ${stack_trace_reliable_impl}
+			CACHE INTERNAL "Are stack traces reliable on this system?")
+	endif (NOT DEFINED STACK_TRACE_RELIABLE)
+	check_end("${STACK_TRACE_RELIABLE}")
+
+	if (NOT STACK_TRACE_RELIABLE)
+		message ("\n[WARNING]\n"
+		"It looks like reliable stack traces cannot be obtained on this system.\n"
+		"The output of KEDR-based tools like LeakCheck will be less detailed\n"
+		"(each stack trace shown will contain only one frame).\n"
+		"If this is not acceptable, you could rebuild the kernel with\n"
+		"CONFIG_FRAME_POINTER or CONFIG_STACK_UNWIND (if available) set to \"y\"\n"
+		"and then reconfigure and rebuild KEDR.\n")
+	endif (NOT STACK_TRACE_RELIABLE)
+endmacro(check_stack_trace)
+
+# Check whether ring buffer is implemented by the kernel.
+# Set cache variable RING_BUFFER_IMPLEMENTED according to this checking.
+function(check_ring_buffer)
+	check_begin("Checking if ring buffer is implemented in the kernel")
+
+	if (NOT DEFINED RING_BUFFER_IMPLEMENTED)
+		check_try()
+		kbuild_try_compile(ring_buffer_implemented_impl 
+			"${CMAKE_BINARY_DIR}/check_ring_buffer"
+			"${kmodule_test_sources_dir}/check_ring_buffer/module.c"
+		)
+		
+		set_bool_string(RING_BUFFER_IMPLEMENTED "yes" "no" "${ring_buffer_implemented_impl}"
+			CACHE INTERNAL "Whether ring buffer is implemented in the kernel"
+		)
+	endif (NOT DEFINED RING_BUFFER_IMPLEMENTED)
+	check_end(${RING_BUFFER_IMPLEMENTED})
+	
+	if (NOT RING_BUFFER_IMPLEMENTED)
+		message("\n[WARNING]\nRing buffer is not supported by the system.\n"
+			"The tracing facilities as well as call monitoring plugins will not be built.\n"
+			"If this is not acceptable, you could rebuild the kernel with\n"
+			"CONFIG_RING_BUFFER set to \"y\" and then reconfigure and rebuild KEDR.\n")
+	endif (NOT RING_BUFFER_IMPLEMENTED)
+endfunction(check_ring_buffer)
+
+# Check which memory allocator is used by the kernel.
+# Set KERNEL_MEMORY_ALLOCATOR to 'slab', 'slub', 'slob' or 'other'.
+#
+# Some functions in that allocators may have same names, but different signatures.
+function(check_allocator)
+	check_begin("Checking which memory allocator is used by the kernel")
+	if(NOT DEFINED KERNEL_MEMORY_ALLOCATOR)
+		check_try()
+		# Use local variable for detect allocator,
+		# Cache one will be set at the end
+		set(allocator "")
+		if(allocator STREQUAL "")
+			kbuild_try_compile(is_allocator_slab 
+				"${CMAKE_BINARY_DIR}/check_allocator_slab"
+				"${kmodule_test_sources_dir}/check_allocator/module.c"
+				KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLAB"
+			)
+			if (is_allocator_slab)
+				set(allocator "slab")
+			endif (is_allocator_slab)
+		endif(allocator STREQUAL "")
+
+		if(allocator STREQUAL "")
+			kbuild_try_compile(is_allocator_slub 
+				"${CMAKE_BINARY_DIR}/check_allocator_slub"
+				"${kmodule_test_sources_dir}/check_allocator/module.c"
+				KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLUB"
+			)
+			if (is_allocator_slub)
+				set(allocator "slub")
+			endif (is_allocator_slub)
+		endif(allocator STREQUAL "")
+		
+		if(allocator STREQUAL "")
+			kbuild_try_compile(is_allocator_slob 
+				"${CMAKE_BINARY_DIR}/check_allocator_slob"
+				"${kmodule_test_sources_dir}/check_allocator/module.c"
+				KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLOB"
+			)
+			if (is_allocator_slob)
+				set(allocator "slob")
+			endif (is_allocator_slub)
+		endif(allocator STREQUAL "")
+		
+		if(allocator STREQUAL "")
+			set(allocator "other")
+		endif(allocator STREQUAL "")
+
+		set(KERNEL_MEMORY_ALLOCATOR "${allocator}" CACHE INTERNAL
+			"Memory allocator which is used by the kernel"
+		)
+	endif (NOT DEFINED KERNEL_MEMORY_ALLOCATOR)
+	check_end("${KERNEL_MEMORY_ALLOCATOR}")
+endfunction(check_allocator)
+
+# Check if 'kfree_rcu' is available in the kernel (it is likely to be 
+# a macro or an inline). If it is available, we should handle it as 
+# 'free' in LeakCheck. As KEDR cannot normally intercept kfree_rcu()
+# itself, it needs to intercept call_rcu/call_rcu_sched and check their
+# arguments.
+# The macro sets variable 'HAVE_KFREE_RCU'.
+macro(check_kfree_rcu)
+	check_begin("Checking if kfree_rcu() is available")
+
+	if (NOT DEFINED HAVE_KFREE_RCU)
+		check_try()
+		kbuild_try_compile(have_kfree_rcu_impl 
+			"${CMAKE_BINARY_DIR}/check_kfree_rcu"
+			"${kmodule_test_sources_dir}/check_kfree_rcu/module.c"
+		)
+		
+		set_bool_string(HAVE_KFREE_RCU "yes" "no" ${have_kfree_rcu_impl}
+			CACHE INTERNAL "Is kfree_rcu() available?"
+		)
+	endif ()
+	check_end("${HAVE_KFREE_RCU}")
+endmacro(check_kfree_rcu)
+############################################################################
+
+# Check if posix_acl_from_xattr() accepts struct user_namespace as the
+# first argument.
+# The macro sets variable 'POSIX_ACL_XATTR_HAS_USER_NS'.
+macro(check_xattr_user_ns)
+	check_begin("Checking if posix_acl_from_xattr() has struct user_namespace * argument")
+	if (NOT DEFINED POSIX_ACL_XATTR_HAS_USER_NS)
+		check_try()
+		kbuild_try_compile(have_xattr_user_ns_impl
+			"${CMAKE_BINARY_DIR}/check_xattr_user_ns"
+			"${kmodule_test_sources_dir}/check_xattr_user_ns/module.c"
+		)
+
+		set_bool_string(POSIX_ACL_XATTR_HAS_USER_NS "yes" "no" ${have_xattr_user_ns_impl}
+			CACHE INTERNAL "Does posix_acl_from_xattr() have struct user_namespace argument?"
+			)
+	endif ()
+	check_end("${POSIX_ACL_XATTR_HAS_USER_NS}")
+endmacro(check_xattr_user_ns)
+############################################################################
+
+# Check if hlist_for_each_entry*() macros accept only 'type *pos' argument
+# rather than both 'type *tpos' and 'hlist_node *pos' as the loop cursors.
+# The macro sets variable 'HLIST_FOR_EACH_ENTRY_POS_ONLY'.
+macro(check_hlist_for_each_entry)
+	check_begin("Checking the signatures of hlist_for_each_entry*() macros")
+	if (NOT DEFINED HLIST_FOR_EACH_ENTRY_POS_ONLY)
+		check_try()
+		kbuild_try_compile(pos_only_impl
+			"${CMAKE_BINARY_DIR}/check_hlist_for_each_entry"
+			"${kmodule_test_sources_dir}/check_hlist_for_each_entry/module.c"
+		)
+		set_bool_string(HLIST_FOR_EACH_ENTRY_POS_ONLY "yes" "no" ${pos_only_impl}
+			CACHE INTERNAL 
+	"Do hlist_for_each_entry*() macros have only 'type *pos' to use as a loop cursor?"
+		)
+	endif ()
+	set_bool_string(check_result "do not use additional loop cursor" "use additional loop cursor"
+		${HLIST_FOR_EACH_ENTRY_POS_ONLY})
+	check_end(${check_result})
+endmacro(check_hlist_for_each_entry)
+############################################################################
+
+# Check if 'random32' is available in the kernel.
+# The macro sets variable 'KEDR_HAVE_RANDOM32'.
+macro(check_random32)
+	check_begin("Checking if random32() is available")
+	if (NOT DEFINED KEDR_HAVE_RANDOM32)
+		check_try()
+		kbuild_try_compile(have_random32_impl
+			"${CMAKE_BINARY_DIR}/check_random32"
+			"${kmodule_test_sources_dir}/check_random32/module.c"
+		)
+		set_bool_string(KEDR_HAVE_RANDOM32 "yes" "no" "${have_random32_impl}"
+			CACHE INTERNAL "Is random32() available?"
+		)
+	endif ()
+	check_end("${KEDR_HAVE_RANDOM32}")
+endmacro(check_random32)
+############################################################################
+
+# The payload modules should call kedr_find_function() for each kernel 
+# function they would like to process. If the function is not known
+# to KEDR (absent from the "function database", see "functions/" directory), 
+# kedr_find_function() issues a fatal error.
+# 
+# 'func_name' is the name of the function,
+# 'found_var' is the name of the output variable (the variable will evaluate
+# as "true" if found, as "false" otherwise). 
+function (kedr_find_function func_name found_var)
+	if (NOT DEFINED KEDR_DATA_FILE_${func_name})
+		message(FATAL_ERROR "Unsupported function: ${func_name}")
+	endif (NOT DEFINED KEDR_DATA_FILE_${func_name})
+	
+	# OK, known function. 
+	kmodule_is_function_exist(${func_name} ${found_var})
+	if (${found_var})
+		# Mark the function as used by at least one payload module.
+		# This can be used when preparing the tests for call interception.
+		# The actual value does not matter, it only matters that this 
+		# variable is defined.
+		set(KEDR_FUNC_USED_${func_name} "yes" CACHE INTERNAL
+			"Is kernel function ${func_name} used by any payload module?")
+		set(${found_var} "${${found_var}}" PARENT_SCOPE)
+	else ()
+		set(${found_var} "NO" PARENT_SCOPE)
+	endif (${found_var})
+endfunction (kedr_find_function func_name found_var)
+
+# Returns (in ${path_var}) the path to the .data file for the function 
+# ${func_name}. The function must be present in the system and 
+# kedr_find_function() must be called for it before kedr_get_data_for_func().
+function (kedr_get_data_for_func func_name path_var)
+	if (NOT DEFINED KEDR_FUNC_USED_${func_name})
+		message(FATAL_ERROR 
+"Attempt to lookup data for a function that is not marked as used: "
+		"${func_name}")
+	endif (NOT DEFINED KEDR_FUNC_USED_${func_name})
+	
+	set(${path_var} "${KEDR_DATA_FILE_${func_name}}" PARENT_SCOPE)
+endfunction (kedr_get_data_for_func func_name path_var)
+
+# kedr_get_header_data_list(list_var func1 [func2 func3 ...])
+# Get the list of paths to the 'header.data' files for the given functions.
+# The functions must be present in the system and # kedr_find_function() 
+# must be called for each of them before kedr_get_header_data_list() is 
+# called.
+# The resulting list is returned in ${list_var}. It will contain at least 
+# one item. It will not contain duplicates.
+function (kedr_get_header_data_list list_var)
+	set(hdata_list)
+	foreach (func ${ARGN})
+		if (NOT DEFINED KEDR_FUNC_USED_${func})
+			message(FATAL_ERROR 
+"Attempt to lookup header data for a function that is not marked as used: "
+			"${func}")
+		endif (NOT DEFINED KEDR_FUNC_USED_${func})
+		list(APPEND hdata_list "${KEDR_HEADER_DATA_FILE_${func}}")
+	endforeach ()
+	list(REMOVE_DUPLICATES hdata_list)
+	
+	list(LENGTH hdata_list hdata_list_len)
+	if (NOT hdata_list_len)
+		message(FATAL_ERROR 
+		"kedr_get_header_data_list(): BUG: the output list is empty.")
+	endif (NOT hdata_list_len)
+	
+	set(${list_var} ${hdata_list} PARENT_SCOPE)
+endfunction (kedr_get_header_data_list list_var)
+
+# kedr_create_header_rules(
+#	header_impl_file header_data_file func1 [func2 ...])
+# Create the rules to generate ${header_impl_file} from
+# ${header_data_file} and the specific header files for the given
+# functions.
+function(kedr_create_header_rules header_impl_file header_data_file 
+	functions)
+	set(hlist_data)
+	kedr_get_header_data_list(hlist_data ${functions} ${ARGN})
+	to_abs_path(hdata_files_abs ${header_data_file} ${hlist_data})
+	add_custom_command(OUTPUT ${header_impl_file}
+		COMMAND cat ${hdata_files_abs} > ${header_impl_file}
+		DEPENDS ${hdata_files_abs}
+	)
+endfunction(kedr_create_header_rules header_impl_file header_data_file 
+	functions)
+
+# kedr_create_data_rules(func)
+# Create the rules to generate ${func}_impl.data from
+# ${func}.data (contains processing instructions specific to the current 
+# payload) and the .data file from "func_db" (contains function signature).
+function(kedr_create_data_rules func)
+	set(func_db_data_file)
+	kedr_get_data_for_func(${func} func_db_data_file)
+	
+	set(func_proc_data_file)
+	to_abs_path(func_proc_data_file ${func}.data)
+	
+	add_custom_command(OUTPUT "${func}_impl.data"
+		COMMAND printf "\"[group]\\n\"" > "${func}_impl.data"
+		COMMAND grep -E -v '\\[group\\]' 
+			"${func_db_data_file}" >> "${func}_impl.data"
+		COMMAND printf "\"\\n\"" >> "${func}_impl.data"
+		COMMAND grep -E -v '\\[group\\]' 
+			"${func_proc_data_file}" >> "${func}_impl.data"
+		DEPENDS
+			"${func_proc_data_file}"
+			"${func_db_data_file}"
+	)
+endfunction(kedr_create_data_rules func)
+
+# kedr_create_payload_module(module_name payload_data_file template_dir)
+# Create the rules to build a payload module with the given name.
+# 'payload_data_file' defines how the kernel functions are to be processed
+# by this payload module.
+# 'template_dir' - path to the direcotry containing the templates to be used
+# to prepare the source code of the module from 'payload_data_file'.
+function(kedr_create_payload_module module_name payload_data_file 
+	template_dir)
+	
+	# Rules to build the module
+	kbuild_add_module(${module_name}
+		"payload.c"
+		"functions_support.c"
+	)
+	kbuild_link_module(${module_name} kedr)
+		
+	# Rules to obtain the source files of the module
+	kedr_generate("payload.c" ${payload_data_file} "${template_dir}")
+	kedr_generate("functions_support.c" ${payload_data_file} "${KEDR_GEN_TEMPLATES_DIR}/functions_support.c")
+endfunction(kedr_create_payload_module module_name payload_data_file 
+	template_dir)
+
+# kedr_create_payload_data(payload_data_file func1 [func2 ...])
+# Create .data files and the header data files for the functions and prepare
+# the main .data file (${payload_data_file}) for the payload module.
+function(kedr_create_payload_data header_data_file payload_data_file 
+	functions)
+	set(header_impl_file "header_impl.data")
+	set(functions_data)
+
+	foreach(func ${functions} ${ARGN})
+		list(APPEND functions_data "${func}_impl.data")
+		kedr_create_data_rules(${func})
+	endforeach(func ${functions} ${ARGN})
+	
+	kedr_create_header_rules(${header_impl_file} ${header_data_file} 
+		${functions} ${ARGN})
+	
+	to_abs_path(payload_data_file_abs ${payload_data_file})
+	to_abs_path(source_files_abs ${header_impl_file} ${functions_data})
+	
+	set(payload_data_file_abs "${CMAKE_CURRENT_BINARY_DIR}/${payload_data_file}")
+	add_custom_command(OUTPUT ${payload_data_file_abs}
+		COMMAND cat ${source_files_abs} > ${payload_data_file_abs}
+		DEPENDS ${source_files_abs}
+	)
+endfunction(kedr_create_payload_data header_data_file payload_data_file 
+	functions)
+############################################################################
diff --git a/cmake_targets/tools/MODULES/path_prefixes.cmake b/cmake_targets/tools/MODULES/path_prefixes.cmake
new file mode 100644
index 0000000000..7deaec0fed
--- /dev/null
+++ b/cmake_targets/tools/MODULES/path_prefixes.cmake
@@ -0,0 +1,264 @@
+# Declare variables for path prefixes for different types of files.
+# NB: depends on 'multi_kernel' and 'uninstall_target'.
+
+# fill_install_prefixes(<project_name> <project_prefix>
+#     [BASE_INSTALL_PREFIX <base_install_prefix>]
+#     [KERNEL]
+# )
+#
+# Setup variables <project_prefix>_* to the install prefixes for
+# different project components.
+# Precisely, variables with next sufficies are set:
+#  INSTALL_PREFIX_EXEC - executables
+#  INSTALL_PREFIX_READONLY - readonly files
+#  INSTALL_PREFIX_GLOBAL_CONF - global configuration files
+#  INSTALL_PREFIX_PREFIX_LIB - libraries
+#  INSTALL_INCLUDE_DIR - include directory(for flags to compiler)
+#  INSTALL_PREFIX_INCLUDE - include files
+#  INSTALL_PREFIX_TEMP_SESSION - temporary files(exists until system restarts)
+#  INSTALL_PREFIX_TEMP - temporary files(preserved even when system restats)
+#  INSTALL_PREFIX_STATE - files which describe current state of the project.
+#  INSTALL_PREFIX_CACHE - cache files
+#  INSTALL_PREFIX_VAR - other modifiable files
+#  INSTALL_PREFIX_DOC - documentation files
+#  INSTALL_PREFIX_EXAMPLES - documentation files
+#
+# With 'KERNEL' option enabled paths for kernel-related files also set:
+#  INSTALL_KINCLUDE_DIR - directory for include when build kernel components
+#  INSTALL_PREFIX_KINCLUDE - include files for the kernel.
+#
+# Additionally, with 'KERNEL' option enabled, several variables are set to
+# paths, which contains "%kernel%" pattern.
+# These paths are intended for kernel-dependent files; for make paths
+# complete one should replace "%kernel%" substring with version of the
+# kernel.
+# Next kernel-dependend paths are set(sufficies only):
+#  KERNEL_INSTALL_PREFIX_KMODULE - directory for install kernel modules
+#  KERNEL_INSTALL_PREFIX_KSYMVERS - directory for install kernel modules' symvers files.
+#  KERNEL_INSTALL_INCLUDE_KERNEL_DIR - include directory with kernel-dependent headers.
+#  KERNEL_INSTALL_PREFIX_INCLUDE_KERNEL - include files, which depends from kernel.
+#
+# Iff option 'COMMON_INSTALL_PREFIX' is given, all paths above are
+# calculated using <base_install_prefix> as base prefix.
+# Otherwise, CMAKE_INSTALL_PREFIX is used for that purpose.
+#
+# Additionally,
+#  INSTALL_TYPE
+# variable(suffix) is set to one of:
+#  - "GLOBAL_OPT" - install into "/opt",
+#  - "GLOBAL" - global installation except one into "/opt",
+#  - "LOCAL" - local installation.
+function(fill_install_prefixes project_name project_prefix)
+    cmake_parse_arguments(fip "KERNEL" "BASE_INSTALL_PREFIX" "" ${ARGN})
+    if(fip_UNPARSED_ARGUMENTS)
+    list(GET fip_UNPARSED_ARGUMENTS 0 exceeded_arg)
+    message(SEND_ERROR "Exceeded argument: ${exceeded_arg}")
+    endif(fip_UNPARSED_ARGUMENTS)
+    if(NOT fip_BASE_INSTALL_PREFIX)
+    set(fip_BASE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+    endif(NOT fip_BASE_INSTALL_PREFIX)
+
+    # Follow conventions about paths listed in
+    #   devel-docs/general/path_conventions.txt
+    # in kedr-devel package.
+
+    # Determine type of installation
+    if(fip_BASE_INSTALL_PREFIX MATCHES "^/opt")
+	set(fip_INSTALL_TYPE "GLOBAL_OPT")
+    elseif(fip_BASE_INSTALL_PREFIX MATCHES "^/usr"
+	OR fip_BASE_INSTALL_PREFIX STREQUAL "/"
+    )
+	set(fip_INSTALL_TYPE "GLOBAL")
+    else()
+	set(fip_INSTALL_TYPE "LOCAL")
+    endif()
+
+    # 1
+    if(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+	set(fip_INSTALL_PREFIX_EXEC "/opt/${project_name}/bin")
+    else(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+	set(fip_INSTALL_PREFIX_EXEC "${fip_BASE_INSTALL_PREFIX}/bin")
+    endif(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+    # 2
+    set(fip_INSTALL_PREFIX_EXEC_AUX
+	"${fip_BASE_INSTALL_PREFIX}/lib/${project_name}"
+    )
+    # 3
+    set(fip_INSTALL_PREFIX_READONLY
+        "${fip_BASE_INSTALL_PREFIX}/share/${project_name}"
+    )
+    # 4
+    set(fip_INSTALL_PREFIX_MANPAGE
+        "${fip_BASE_INSTALL_PREFIX}/share/man"
+    )
+    # 5
+    if(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+	set(fip_INSTALL_PREFIX_GLOBAL_CONF "/etc/opt/${project_name}")
+    elseif(fip_INSTALL_TYPE STREQUAL "GLOBAL")
+	set(fip_INSTALL_PREFIX_GLOBAL_CONF "/etc/${project_name}")
+    else(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+	set(fip_INSTALL_PREFIX_GLOBAL_CONF
+	    "${fip_BASE_INSTALL_PREFIX}/etc/${project_name}"
+	)
+    endif(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+    # 6
+    set(fip_INSTALL_PREFIX_LIB "${fip_BASE_INSTALL_PREFIX}/lib")
+    # 7
+    set(fip_INSTALL_PREFIX_LIB_AUX
+        "${fip_BASE_INSTALL_PREFIX}/lib/${project_name}"
+    )
+    # 8
+    set(fip_INSTALL_INCLUDE_DIR "${fip_BASE_INSTALL_PREFIX}/include")
+
+    set(fip_INSTALL_PREFIX_INCLUDE
+        "${fip_INSTALL_INCLUDE_DIR}/${project_name}"
+    )
+    # 9
+    set(fip_INSTALL_PREFIX_TEMP_SESSION "/tmp/${project_name}")
+    # 10
+    if(fip_INSTALL_TYPE MATCHES "GLOBAL")
+	set(fip_INSTALL_PREFIX_TEMP "/var/tmp/${project_name}")
+    else(fip_INSTALL_TYPE MATCHES "GLOBAL")
+	set(fip_INSTALL_PREFIX_TEMP
+            "${fip_BASE_INSTALL_PREFIX}/var/tmp/${project_name}"
+	)
+    endif(fip_INSTALL_TYPE MATCHES "GLOBAL")
+    # 11
+    if(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+        set(fip_INSTALL_PREFIX_STATE
+	    "/var/opt/${project_name}/lib/${project_name}"
+	)
+    elseif(fip_INSTALL_TYPE STREQUAL "GLOBAL")
+        set(fip_INSTALL_PREFIX_STATE "/var/lib/${project_name}")
+    else(fip_INSTALL_TYPE STREQUAL "GLOBAL")
+	set(fip_INSTALL_PREFIX_STATE
+	    "${fip_BASE_INSTALL_PREFIX}/var/lib/${project_name}"
+	)
+    endif(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+    # 12
+    if(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+        set(fip_INSTALL_PREFIX_CACHE
+	    "/var/opt/${project_name}/cache/${project_name}"
+	)
+    elseif(fip_INSTALL_TYPE STREQUAL "GLOBAL")
+	set(fip_INSTALL_PREFIX_CACHE "/var/cache/${project_name}")
+    else(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+	set(fip_INSTALL_PREFIX_CACHE
+	    "${fip_BASE_INSTALL_PREFIX}/var/cache/${project_name}"
+	)
+    endif(fip_INSTALL_TYPE STREQUAL "GLOBAL_OPT")
+    # 13
+    if(fip_INSTALL_TYPE MATCHES "GLOBAL")
+        set(fip_INSTALL_PREFIX_VAR "/var/opt/${project_name}")
+    else(fip_INSTALL_TYPE MATCHES "GLOBAL")
+	set(fip_INSTALL_PREFIX_VAR
+	    "${fip_BASE_INSTALL_PREFIX}/var/${project_name}"
+	)
+    endif(fip_INSTALL_TYPE MATCHES "GLOBAL")
+    # 14
+    set(fip_INSTALL_PREFIX_DOC
+	"${fip_BASE_INSTALL_PREFIX}/share/doc/${project_name}"
+    )
+
+    # Set derivative install path and prefixes
+
+    # additional, 4
+    set(fip_INSTALL_PREFIX_EXAMPLES
+    "${fip_INSTALL_PREFIX_READONLY}/examples")
+
+    # Export symbols to the outer scope
+    foreach(suffix
+	INSTALL_TYPE
+	INSTALL_PREFIX_EXEC
+	INSTALL_PREFIX_EXEC_AUX
+	INSTALL_PREFIX_READONLY
+	INSTALL_PREFIX_MANPAGE
+	INSTALL_PREFIX_GLOBAL_CONF
+	INSTALL_PREFIX_LIB
+	INSTALL_PREFIX_LIB_AUX
+	INSTALL_INCLUDE_DIR
+	INSTALL_PREFIX_INCLUDE
+	INSTALL_PREFIX_TEMP_SESSION
+	INSTALL_PREFIX_TEMP
+	INSTALL_PREFIX_STATE
+	INSTALL_PREFIX_CACHE
+	INSTALL_PREFIX_VAR
+	INSTALL_PREFIX_DOC
+	INSTALL_PREFIX_EXAMPLES
+    )
+	set(${project_prefix}_${suffix} "${fip_${suffix}}" PARENT_SCOPE)
+    endforeach(suffix)
+    
+    if(fip_KERNEL)
+	# Set derivative install path and prefixes
+	# additional, 1
+	if(fip_INSTALL_TYPE MATCHES GLOBAL)
+	    set(fip_KERNEL_INSTALL_PREFIX_KMODULE
+		"/lib/modules/%kernel%/extra"
+	    )
+	else(fip_INSTALL_TYPE MATCHES GLOBAL)
+	    set(fip_KERNEL_INSTALL_PREFIX_KMODULE
+		"${fip_INSTALL_PREFIX_LIB}/modules/%kernel%/extra"
+	    )
+	endif(fip_INSTALL_TYPE MATCHES GLOBAL)
+
+	# additional, 2
+	set(fip_KERNEL_INSTALL_PREFIX_KSYMVERS
+	    "${fip_INSTALL_PREFIX_LIB}/modules/%kernel%/symvers"
+	)
+	# additional, 3
+	set(fip_INSTALL_KINCLUDE_DIR "${fip_INSTALL_INCLUDE_DIR}")
+	set(fip_INSTALL_PREFIX_KINCLUDE "${fip_INSTALL_PREFIX_INCLUDE}")
+
+	# Kernel include files, which depends from kernel version.
+	# This prefix is not listed in path conventions.
+	set(fip_KERNEL_INSTALL_INCLUDE_KERNEL_DIR
+	    "${fip_BASE_INSTALL_PREFIX}/include-kernel/%kernel%"
+	)
+
+	set(fip_KERNEL_INSTALL_PREFIX_INCLUDE_KERNEL
+	    "${fip_KERNEL_INSTALL_INCLUDE_KERNEL_DIR}/${project_name}-kernel"
+	)
+
+	# Export symbols to the outer scope
+	foreach(suffix
+	    KERNEL_INSTALL_PREFIX_KMODULE
+	    KERNEL_INSTALL_PREFIX_KSYMVERS
+	    INSTALL_KINCLUDE_DIR
+	    INSTALL_PREFIX_KINCLUDE
+	    KERNEL_INSTALL_INCLUDE_KERNEL_DIR
+	    KERNEL_INSTALL_PREFIX_INCLUDE_KERNEL
+	)
+	    set(${project_prefix}_${suffix} "${fip_${suffix}}" PARENT_SCOPE)
+	endforeach(suffix)
+    endif(fip_KERNEL)
+endfunction(fill_install_prefixes project_name project_prefix)
+
+
+########################################################################
+# Kernel-dependent paths.
+#
+# Some deliverables may depends on linux kernel.
+#
+# For make "one user installation for several kernels" paradigm works,
+# installation directory for that deliverables should include
+# kernel-version part(like "3.10.2-generic").
+#
+# So, components installed by user installation can determine at runtime,
+# which kernel-dependent deliverable should be used on currently loaded system.
+# They do selection using 'uname -r' request.
+#
+# For define variables represented kernel-dependent directories,
+# we use strings containing "%kernel%" stem.
+
+#  kernel_path(kernel_version RESULT_VARIABLE pattern ...)
+#
+# Form concrete path representation from kernel-dependent pattern(s).
+# Replace occurence of %kernel% in pattern(s) with given @kernel_version string.
+# Result is stored in the RESULT_VARIABLE.
+#
+# @kernel_version may be concrete version of the kernel,
+# or variable reference in some language.
+macro(kernel_path kernel_version RESULT_VARIABLE pattern)
+    string(REPLACE "%kernel%" "${kernel_version}" ${RESULT_VARIABLE} ${pattern} ${ARGN})
+endmacro(kernel_path kernel_version RESULT_VARIABLE pattern)
-- 
GitLab