cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(PIP)
set(PIP_MAJOR    3)
set(PIP_MINOR    7)
set(PIP_REVISION 0)
set(PIP_SUFFIX   )
set(PIP_COMPANY  SHS)
set(PIP_DOMAIN   org.SHS)

set(GIT_CMAKE_DIR)
if (NOT DEFINED SHSTKPROJECT)
	set(ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
	file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmake-download/CMakeLists.txt"
"# This file was generated by PIP CMake, don`t edit it!
cmake_minimum_required(VERSION 2.8.2)
project(cmake-download NONE)
include(ExternalProject)
ExternalProject_Add(cmake
	GIT_REPOSITORY    https://git.shs.tools/SHS/cmake.git
	GIT_TAG           \"origin/master\"
	GIT_CONFIG        \"advice.detachedHead=false\"
	SOURCE_DIR        \"${CMAKE_CURRENT_BINARY_DIR}/cmake-src\"
	BINARY_DIR        \"${CMAKE_CURRENT_BINARY_DIR}/cmake-build\"
	INSTALL_COMMAND   \"\"
	TEST_COMMAND      \"\"
)
")
	execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
		RESULT_VARIABLE result
		WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cmake-download)
	if(result)
		message(FATAL_ERROR "CMake step for cmake failed: ${result}")
	endif()
	execute_process(COMMAND "${CMAKE_COMMAND}" --build .
		RESULT_VARIABLE result
		WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cmake-download)
	if(result)
		message(FATAL_ERROR "Build step for cmake failed: ${result}")
	endif()
	install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}/cmake-build\" --target install)")
	set(GIT_CMAKE_DIR "${CMAKE_CURRENT_BINARY_DIR}/cmake-src")
endif()

if ("x${CMAKE_MODULE_PATH}" STREQUAL "x")
	set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
endif()
if (NOT "x${GIT_CMAKE_DIR}" STREQUAL "x")
	list(APPEND CMAKE_MODULE_PATH "${GIT_CMAKE_DIR}")
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
include(CheckFunctionExists)
include(PIPMacros)
include(SHSTKMacros)

shstk_begin_project(PIP)

set(_ICU_DEFAULT OFF)
if((NOT DEFINED WIN32) AND (NOT DEFINED ANDROID_PLATFORM) AND (NOT DEFINED APPLE))
	set(_ICU_DEFAULT ON)
endif()
set(PIP_DLL_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE STRING "")


# Options
option(ICU "ICU support for convert codepages" ${_ICU_DEFAULT})
option(STD_IOSTREAM "Building with std iostream operators support" OFF)
option(INTROSPECTION "Build with introspection" OFF)
option(TESTS "Build tests and perform their before install step" OFF)
option(COVERAGE "Build project with coverage info" OFF)
set(PIP_UTILS 1)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_STANDARD 11)


# Basic
set(PIP_MODULES)
set(LIBS_MAIN)
set(LIBS_STATUS)
set(HDRS)
set(PHDRS)
set(HDR_DIRS)
set(PIP_UTILS_LIST)
set(PIP_TESTS_LIST)
set(PIP_EXPORTS)

set(PIP_SRC_MODULES "console;crypt;compress;usb;fftw;opencl;io_utils;cloud;lua")
foreach(_m ${PIP_SRC_MODULES})
	set(PIP_MSG_${_m} "no")
endforeach()

macro(pip_module NAME LIBS LABEL INCLUDES SOURCES MSG)
	set(CPPS)
	set(HS)
	set(PHS)
	set(CRES)
	file(GLOB_RECURSE CPPS "libs/${NAME}/*.cpp" "libs/${NAME}/*.c")
	file(GLOB_RECURSE HS   "libs/${NAME}/*.h")
	file(GLOB_RECURSE PHS  "libs/${NAME}/*_p.h" "libs/${NAME}/3rd/*.h")
	file(GLOB_RECURSE RES  "libs/${NAME}/*.conf")
	if (NOT "x${PHS}" STREQUAL "x")
		list(REMOVE_ITEM HS ${PHS})
	endif()
	if (NOT "x${SOURCES}" STREQUAL "x")
		file(GLOB_RECURSE ASRC "${SOURCES}/*.cpp" "${SOURCES}/*.c")
		list(APPEND CPPS ${ASRC})
	endif()
	#message("${NAME} HS = ${HS}")
	list(APPEND HDRS ${HS})
	list(APPEND PHDRS ${PHS})

	if(${CMAKE_VERSION} VERSION_LESS "3.8.0")
	else()
		source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${CPPS} ${HS} ${PHS})
	endif()
	set(_target "pip_${NAME}")
	set(_libs "${LIBS}")
	if ("${NAME}" STREQUAL "main")
		set(_target "pip")
	else()
		list(APPEND _libs "pip")
	endif()
	string(TOUPPER "${_target}" DEF_NAME)

	set(PIP_MSG_${NAME} "yes${MSG}")
	import_version(${_target} PIP)
	set_deploy_property(${_target} ${PIP_LIB_TYPE}
		LABEL "${LABEL}"
		FULLNAME "${PIP_DOMAIN}.${_target}"
		COMPANY  "${PIP_COMPANY}"
		INFO "Platform-Independent Primitives")
	make_rc(${_target} _RC)

	set(LINK_LIBS)
	foreach (_l ${_libs})
		if (${${_l}_FOUND})
			list(APPEND LINK_LIBS ${${_l}_LIBRARIES})
		else()
			list(APPEND LINK_LIBS ${_l})
		endif()
	endforeach()

	if (NOT "x${RES}" STREQUAL "x")
		pip_resources(CRES "${RES}")
	endif()
	add_definitions(-D${DEF_NAME})
	add_library(${_target} ${PIP_LIB_TYPE} ${CPPS} ${CRES} ${_RC} ${HS} ${PHS})
	target_include_directories(${_target} PUBLIC ${PIP_INCLUDES})
	if (NOT "x${RES}" STREQUAL "x")
		add_dependencies(${_target} pip_rc)
	endif()
	if (NOT "x${INCLUDES}" STREQUAL "x")
		target_include_directories(${_target} PRIVATE ${INCLUDES})
	endif()
	list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT")
	target_link_libraries(${_target} ${LINK_LIBS})
	list(APPEND PIP_MODULES ${_target})
	if (NOT "x${LIBS}" STREQUAL "x")
		list(APPEND LIBS_STATUS ${LIBS})
	endif()
endmacro()

macro(pip_find_lib NAME)
	find_library(${NAME}_LIBRARIES ${NAME} ${ARGN})
	set(${NAME}_FOUND FALSE)
	if(${NAME}_LIBRARIES)
		set(${NAME}_FOUND TRUE)
	endif()
endmacro()

# Version
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_version.h")


if (NOT DEFINED PIP_CMG)
	if (CMAKE_CROSSCOMPILING OR (DEFINED ANDROID_PLATFORM))
		set(PIP_CMG "pip_cmg")
		set(PIP_RC "pip_rc")
		set(PIP_DEPLOY_TOOL "deploy_tool")
	else()
		set(PIP_CMG "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator/pip_cmg")
		set(PIP_RC "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler/pip_rc")
		set(PIP_DEPLOY_TOOL "${CMAKE_CURRENT_BINARY_DIR}/utils/deploy_tool/deploy_tool")
	endif()
endif()


# Compiler
get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME)


# Main lib
file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/libs/main/*")
list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/libs/main")
set(PIP_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}")
foreach(F ${PIP_FOLDERS})
	if (IS_DIRECTORY "${F}")
		list(APPEND PIP_INCLUDES "${F}")
		#include_directories("${F}")
	endif()
endforeach(F)

if (TESTS)
	set(PIP_ROOT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
	add_subdirectory(tests)
endif()

if(PIP_FREERTOS)
	add_definitions(-DPIP_FREERTOS)
	set(ICU OFF)
	set(LOCAL ON)
endif()

# Check Bessel functions
set(CMAKE_REQUIRED_INCLUDES math.h)
set(CMAKE_REQUIRED_LIBRARIES m)
CHECK_FUNCTION_EXISTS(j0 PIP_MATH_J0)
CHECK_FUNCTION_EXISTS(j1 PIP_MATH_J1)
CHECK_FUNCTION_EXISTS(jn PIP_MATH_JN)
CHECK_FUNCTION_EXISTS(y0 PIP_MATH_Y0)
CHECK_FUNCTION_EXISTS(y1 PIP_MATH_Y1)
CHECK_FUNCTION_EXISTS(yn PIP_MATH_YN)
if(PIP_MATH_J0)
	add_definitions(-DPIP_MATH_J0)
endif()
if(PIP_MATH_J1)
	add_definitions(-DPIP_MATH_J1)
endif()
if(PIP_MATH_JN)
	add_definitions(-DPIP_MATH_JN)
endif()
if(PIP_MATH_Y0)
	add_definitions(-DPIP_MATH_Y0)
endif()
if(PIP_MATH_Y1)
	add_definitions(-DPIP_MATH_Y1)
endif()
if(PIP_MATH_YN)
	add_definitions(-DPIP_MATH_YN)
endif()


# Check if RT timers exists
set(CMAKE_REQUIRED_INCLUDES time.h)
set(CMAKE_REQUIRED_LIBRARIES )
if((NOT DEFINED ENV{QNX_HOST}) AND (NOT APPLE) AND (NOT WIN32) AND (NOT DEFINED ANDROID_PLATFORM) AND (NOT PIP_FREERTOS))
	list(APPEND LIBS_MAIN rt)
	set(CMAKE_REQUIRED_LIBRARIES rt)
endif()
CHECK_FUNCTION_EXISTS(timer_create  PIP_TIMER_RT_0)
CHECK_FUNCTION_EXISTS(timer_settime PIP_TIMER_RT_1)
CHECK_FUNCTION_EXISTS(timer_delete  PIP_TIMER_RT_2)


# Check if build debug version
if (CMAKE_BUILD_TYPE MATCHES Debug)
	set(PIP_BUILD_TYPE "Debug")
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -Wall")
	add_definitions(-DPIP_DEBUG)
else()
	set(PIP_BUILD_TYPE "Release")
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall")
endif()

set(PIP_COVERAGE "no")
if (COVERAGE)
	find_program(GCOV_EXECUTABLE gcov)
	if (GCOV_EXECUTABLE)
		set(PIP_COVERAGE "yes")
		set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} --coverage")
		set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} --coverage")
	else()
		message(STATUS "GCOV_EXECUTABLE: not found")
	endif()
endif()


# Check if std::iostream operators support
set(PIP_STD_IOSTREAM "no")
if(STD_IOSTREAM)
	set(PIP_STD_IOSTREAM "yes")
	add_definitions(-DPIP_STD_IOSTREAM)
endif()


# Check if ICU used for PIString and PIChar
set(PIP_ICU "no")
if(ICU)
	set(PIP_ICU "yes")
	add_definitions(-DPIP_ICU)
	list(APPEND LIBS_MAIN icuuc)
endif()


# Check if PIP should be built with introspection
set(_PIP_DEFS "")
set(_PIP_DEFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/pip_defs.h")
set(PIP_INTROSPECTION "no")
if(INTROSPECTION)
	set(PIP_INTROSPECTION "yes")
	add_definitions(-DPIP_INTROSPECTION)
	set(_PIP_DEFS "PIP_INTROSPECTION")
endif()
if ((NOT DEFINED _PIP_SAVED_DEFS) OR (NOT "x${_PIP_SAVED_DEFS}" STREQUAL "x${_PIP_DEFS}"))
	set(_PIP_SAVED_DEFS "${_PIP_DEFS}" CACHE STRING "pip_defs" FORCE)
	file(WRITE ${_PIP_DEFS_FILE} "// This file was generated by PIP CMake, don`t edit it!\n")
	if (NOT "x${_PIP_DEFS}" STREQUAL "x")
		file(APPEND ${_PIP_DEFS_FILE} "#ifndef ${_PIP_DEFS}\n#  define ${_PIP_DEFS}\n#endif\n")
	endif()
endif()
list(APPEND HDRS ${_PIP_DEFS_FILE})
#message("${_PIP_DEFS_CHANGED}")


# Check if RT timers exists
if(PIP_TIMER_RT_0 AND PIP_TIMER_RT_1 AND PIP_TIMER_RT_2)
	set(PIP_TIMERS "Thread, ThreadRT, Pool")
	add_definitions(-DPIP_TIMER_RT)
else()
	set(PIP_TIMERS "Thread, Pool")
endif()



# Add main library
if(APPLE)
	add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
endif()
if ((NOT DEFINED SHSTKPROJECT) AND (DEFINED ANDROID_PLATFORM))
	include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
	#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
	#message("${ANDROID_NDK}/sysroot/usr/include")
endif()
if(NOT PIP_FREERTOS)
if(WIN32)
	if(${C_COMPILER} STREQUAL "cl.exe")
	else()
		list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi)
	endif()
else()
	list(APPEND LIBS_MAIN dl)
	if(DEFINED ENV{QNX_HOST})
		list(APPEND LIBS_MAIN socket)
	else()
		if (NOT DEFINED ANDROID_PLATFORM)
			list(APPEND LIBS_MAIN pthread util)
		endif()
	endif()
endif()
endif()
set(PIP_LIBS)
if(PIP_FREERTOS)
	set(PIP_LIBS ${LIBS_MAIN})
else()
	foreach(LIB_ ${LIBS_MAIN})
		pip_find_lib(${LIB_})
	endforeach()
endif()
if(WIN32)
	add_definitions(-DPSAPI_VERSION=1)
	if(${C_COMPILER} STREQUAL "cl.exe")
		set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0")
	endif()
else()
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
	if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
	endif()
endif()
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")


pip_module(main "${LIBS_MAIN}" "PIP main library" "" "" "")

generate_export_header(pip)
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h")
foreach(_m ${PIP_SRC_MODULES})
	set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_${_m}_EXPORTS)
	generate_export_header(pip BASE_NAME "pip_${_m}")
	list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_${_m}_export.h")
endforeach()
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS)


if (NOT CROSSTOOLS)
	if (NOT PIP_FREERTOS)


		pip_module(console "" "PIP console support" "" "" "")


		pip_find_lib(usb)
		if(usb_FOUND)
			pip_module(usb "usb" "PIP usb support" "" "" "")
		endif()


		pip_find_lib(zlib NAMES z zlib)
		if(zlib_FOUND)
			pip_module(compress "zlib" "PIP compression support" "" "" "")
		endif()


		pip_find_lib(sodium)
		if(sodium_FOUND)
			pip_module(crypt "sodium" "PIP crypt support" "" "" "")
			pip_module(cloud "pip_io_utils" "PIP cloud support" "" "" "")
		endif()


		# Check if PIP support fftw3 for PIFFT using in math module
		set(FFTW_LIB_NAME fftw3)
		set(FFTW_LIB_SUFFIXES "" "f" "l" "q")
		set(FFTW_LIB_SUFFIXES2 "" "-3")
		set(FFTW_LIBS)
		set(FFTW_ABS_LIBS)
		set(CMAKE_REQUIRED_INCLUDES fftw3.h)
		foreach(FFTW_S_ IN LISTS FFTW_LIB_SUFFIXES)
			set(FFTW_BREAK false)
			foreach(FFTW_S2_ IN LISTS FFTW_LIB_SUFFIXES2)
				if(NOT FFTW_BREAK)
					set(FFTW_CLN  "${FFTW_LIB_NAME}${FFTW_S_}${FFTW_S2_}")
					set(FFTW_CLNT "${FFTW_LIB_NAME}${FFTW_S_}_threads${FFTW_S2_}")
					find_library(${FFTW_CLN}_LIBRARIES ${FFTW_CLN})
					find_library(${FFTW_CLNT}_LIBRARIES ${FFTW_CLNT})
					set(${FFTW_CLN}_FOUND FALSE)
					set(${FFTW_CLNT}_FOUND FALSE)
					if(${FFTW_CLN}_LIBRARIES)
						set(${FFTW_CLN}_FOUND TRUE)
						list(APPEND FFTW_LIBS "${FFTW_CLN}")
						list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_LIBRARIES}")
						set(${FFTW_CLN}_CTS "${FFTW_CLN}")
						if(${FFTW_CLNT}_FLIBRARIES)
							set(${FFTW_CLNT}_FOUND TRUE)
							list(APPEND FFTW_LIBS "${FFTW_CLNT}")
							list(APPEND FFTW_ABS_LIBS "${${FFTW_CLNT}_LIBRARIES}")
							list(APPEND ${FFTW_CLN}_CTS "${FFTW_CLNT}")
						endif()
						set(CMAKE_REQUIRED_LIBRARIES ${${FFTW_CLN}_CTS})
						CHECK_FUNCTION_EXISTS(fftw${FFTW_S_}_make_planner_thread_safe ${FFTW_CLN}_TSFE)
						add_definitions(-DPIP_FFTW${FFTW_S_})
						if(${FFTW_CLN}_TSFE)
							add_definitions(-DPIP_FFTW${FFTW_S_}_THREADSAFE)
						else()
							message(STATUS "Warning: PIFFTW${FFTW_S_}::preparePlan was not threadsafe")
						endif()
					endif()
				endif()
			endforeach()
		endforeach()
		if(FFTW_LIBS)
			pip_module(fftw "${FFTW_LIBS}" "PIP FFTW support" "" "" "")
		endif()


		find_package(OpenCL QUIET) #OpenCL_VERSION_STRING
		if(OpenCL_FOUND)
			set(_opencl_lib OpenCL::OpenCL)
			if(${CMAKE_VERSION} VERSION_LESS "3.7.0")
				target_link_libraries(_opencl_lib OpenCL)
			endif()
			set(_opencl_inc "${OpenCL_INCLUDE_DIRS}")
			if(APPLE)
				set(_opencl_inc "${OpenCL_INCLUDE_DIRS}/Headers")
			endif()
			pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "${_opencl_inc}" "" " (${OpenCL_VERSION_STRING})")
		endif()


		if(sodium_FOUND)
			pip_module(io_utils "pip_crypt" "PIP I/O support" "" "" " (+crypt)")
		else()
			pip_module(io_utils "" "PIP I/O support" "" "" "")
		endif()


		# Lua module
		set(_lua_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/3rd/lua")
		set(_lua_bri_dir "${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd")
		set(_lua_src_hdr "${_lua_src_dir}/lua.hpp" "${_lua_src_dir}/lua.h" "${_lua_src_dir}/luaconf.h" "${_lua_src_dir}/lualib.h")
		pip_module(lua "" "PIP Lua support" "${_lua_src_dir};${_lua_bri_dir}" "${_lua_src_dir}" " (internal)")
		target_include_directories(pip_lua PUBLIC "${_lua_src_dir}" "${_lua_bri_dir}")
		if (WIN32)
			target_compile_definitions(pip_lua PRIVATE LUA_BUILD_AS_DLL LUA_CORE)
		endif()
		list(APPEND HDR_DIRS "${_lua_bri_dir}/LuaBridge")
		list(APPEND HDRS ${_lua_src_hdr})

		# Test program
		if(PIP_UTILS)
			#add_library(pip_plugin SHARED "test_plugin.h" "test_plugin.cpp")
			#target_link_libraries(pip_plugin pip)
			add_executable(pip_test "main.cpp")
			target_link_libraries(pip_test pip)
			if(sodium_FOUND)
				add_executable(pip_cloud_test "main_picloud_test.cpp")
				target_link_libraries(pip_cloud_test pip_cloud)
			endif()
		endif()

	else()
		pip_module(crypt "" "PIP crypt support" "" "" "")
		pip_module(compress "" "PIP compression support" "" "" "")
		pip_module(io_utils "pip_crypt" "PIP I/O support" "" "" " (+crypt)")
	endif()
endif()

string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}")
target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"")

# Install
# Check if system or local install will be used (to system install use "-DLIB=" argument of cmake)
if(NOT LOCAL)
	if(WIN32)
		if(MINGW)
			if (NOT CROSSTOOLS)
				install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
				if(HDR_DIRS)
					install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip)
				endif()
				install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION ${MINGW_LIB})
			endif()
			install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION ${MINGW_BIN})
			find_library(STDLIB "stdc++-6" PATHS ${MINGW_BIN} NO_DEFAULT_PATH)
			find_library(STDLIB "stdc++-6")
			#message("${STDLIB}")
			if (STDLIB)
				file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator")
				file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler")
				file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/deploy_tool")
			endif()
		else()
			install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pip_export.h DESTINATION include)
		endif()
	else()
		if (NOT CROSSTOOLS)
			install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
			if(HDR_DIRS)
				install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
			endif()
		endif()
		install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
	endif()
else()
	if(NOT PIP_FREERTOS)
		if(WIN32)
			install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin)
			install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib)
		else()
			install(TARGETS ${PIP_MODULES} DESTINATION lib)
		endif()
		install(FILES ${HDRS} DESTINATION include/pip)
		if(HDR_DIRS)
			install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
		endif()
	endif()
endif()
file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in")
install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules)

if(NOT PIP_FREERTOS)

# Auxiliary
	if (NOT CROSSTOOLS)
		add_subdirectory("utils/piterminal")
	endif()

# Utils
	add_subdirectory("utils/code_model_generator")
	add_subdirectory("utils/resources_compiler")
	add_subdirectory("utils/deploy_tool")
	if(PIP_UTILS AND (NOT CROSSTOOLS))
		add_subdirectory("utils/system_test")
		add_subdirectory("utils/udp_file_transfer")
		if(sodium_FOUND)
			add_subdirectory("utils/system_daemon")
			add_subdirectory("utils/crypt_tool")
			add_subdirectory("utils/cloud_dispatcher")
		endif()
	endif()
	
endif()


shstk_is_parent_exists(_pe)
if (_pe)
	set(PIP_MODULES ${PIP_MODULES} PARENT_SCOPE)
endif()

#
# Build Documentation
#
if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
	include(PIPDocumentation)
	find_package(Doxygen)
	if(DOXYGEN_FOUND)
		set(DOXY_DEFINES "${PIP_EXPORTS}")
		foreach (_m "console" "usb" "compress" "crypt" "cloud" "fftw" "opencl" "io_utils" "lua")
			string(TOUPPER "${_m}" _mdef)
			list(APPEND DOXY_DEFINES "PIP_${_mdef}_EXPORT")
		endforeach()
		set(DOXY_PROJECT_NUMBER "${PIP_VERSION}")
		set(DOXY_QHP_CUST_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
		set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
		set(DOXY_EXAMPLE_PATH    "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"")
		set(DOXY_IMAGE_PATH      "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"")
		set(DOXY_LOGO_PATH       "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/pip.png\"")
		set(DOXY_EXCLUDE         "\"${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd\"")
		set(DOXY_DOMAIN "${PIP_DOMAIN}.${PROJECT_NAME}.doc")
		if ("x${DOC_LANG}" STREQUAL "x")
			set(DOXY_OUTPUT_LANGUAGE English)
			set(DOXY_OUTPUT_DIR      en)
		else()
			set(DOXY_OUTPUT_LANGUAGE ${DOC_LANG})
			set(DOXY_OUTPUT_DIR      ${DOC_DIR})
		endif()
		if(DOXYGEN_DOT_EXECUTABLE)
			string(REPLACE "\\" "/" _DOT_PATH "${DOXYGEN_DOT_PATH}")
			set(DOXY_DOT_PATH    "\"${_DOT_PATH}\"")
			set(DOXY_DIA_PATH    "\"${_DOT_PATH}\"")
		endif()
		set(DOXY_INPUT)
		foreach(F ${PIP_MAIN_FOLDERS})
			list(APPEND DOXY_INPUT "\"${F}\"")
		endforeach(F)
		string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\";\"${CMAKE_CURRENT_SOURCE_DIR}/doc/pages\"")
		string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_INCLUDES}")
		string(REPLACE ";" " " DOXY_DEFINES "${DOXY_DEFINES}")
		add_documentation(doc doc/Doxyfile.in)
		install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
	endif()
endif()


set(_max_len 0)
foreach(_m ${PIP_SRC_MODULES})
	string(LENGTH "${_m}" _clen)
	if (_clen GREATER _max_len)
		set(_max_len ${_clen})
	endif()
endforeach()
macro(expand_to_length _out _str _len)
	set(${_out} "${_str}")
	while(TRUE)
		string(LENGTH "${${_out}}" _clen)
		if (_clen GREATER_EQUAL ${_len})
			break()
		endif()
		string(APPEND ${_out} " ")
	endwhile()
endmacro()

list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
message("----------PIP----------")
message(" Version: ${PIP_VERSION} ")
message(" Linkage: ${PIP_LIB_TYPE_MSG}")
message(" Type   : ${PIP_BUILD_TYPE}")
if (NOT LOCAL)
	message(" Install: \"${CMAKE_INSTALL_PREFIX}\"")
else()
	if(NOT PIP_FREERTOS)
		message(" Install: local \"bin\", \"lib\" and \"include\"")
	endif()
endif()
message("")
message(" Options:")
message("  std::iostream: ${PIP_STD_IOSTREAM}")
message("  ICU strings  : ${PIP_ICU}")
message("  Timer types  : ${PIP_TIMERS}")
message("  Introspection: ${PIP_INTROSPECTION}")
message("  Coverage     : ${PIP_COVERAGE}")
if(INTROSPECTION)
	message(STATUS "  Warning: Introspection reduces the performance!")
endif()
message("")
message(" Modules:")
foreach(_m ${PIP_SRC_MODULES})
	expand_to_length(_m_e "${_m}" ${_max_len})
	message("  ${_m_e}: ${PIP_MSG_${_m}}")
endforeach()
message("")
if (PIP_TESTS_LIST)
	message(" Tests:")
	foreach(_test ${PIP_TESTS_LIST})
		message("  * ${_test}")
	endforeach()
else()
	message(" Tests: skip (tests off)")
endif()
message("")
message(" Utilites:")
foreach(_util ${PIP_UTILS_LIST})
	message("  * ${_util}")
endforeach()
if(NOT PIP_FREERTOS)
	message("")
	message(" Using libraries:")
	foreach(LIB_ ${LIBS_STATUS})
		if (NOT TARGET ${LIB_})
			if(${LIB_}_FOUND)
				message("  ${LIB_} -> ${${LIB_}_LIBRARIES}")
			else()
				message("  ${LIB_} not found, may fail")
			endif()
		endif()
	endforeach()
endif()
message("-----------------------")
