function(get_project_list _project_list _srcs)
	set(new_list ${${_project_list}})
	file(GLOB srcs ${_srcs}/*)
	foreach(item ${srcs})
		if((IS_DIRECTORY ${item}) 
			OR (${item} MATCHES "\.cpp$") 
			OR (${item} MATCHES "\.c$")
			OR (${item} MATCHES "\.cc$"))
			set(m)
			string(REGEX MATCH "/([^/\.]+)[^/]*$" m ${item})
			set(m1 ${CMAKE_MATCH_1})
			list(APPEND new_list ${m1})
		endif()
	endforeach()
	set(${_project_list} ${new_list} PARENT_SCOPE)
endfunction()

function(get_source_list _source_list _path)
	set(new_list ${${_source_list}})
	set(postfix h hpp c cpp)
	if(EXISTS ${_path})
		foreach(item ${postfix})
			set(srcs)
			file(GLOB_RECURSE srcs ${_path}/*.${item})
			list(APPEND new_list ${srcs})
		endforeach()
	else()
		foreach(item ${postfix})
            set(file ${_path}.${item})
			if(EXISTS ${file})
				list(APPEND new_list ${file})
			endif()
		endforeach()
	endif()
	set(${_source_list} ${new_list} PARENT_SCOPE)
endfunction()

function(get_filename_component_list _var _FileNameList _mode)
	set(out)
	foreach(item ${_FileNameList})
		get_filename_component(result ${item} ${_mode})
		list(APPEND out ${result})
	endforeach()
	set(${_var} ${out} PARENT_SCOPE)
endfunction()

function(string_regex_replace_all _regular _replace _output _input)
	set(r TRUE)
	while(${r})
		string(REGEX REPLACE ${_regular} ${_replace} out ${_input})
		string(COMPARE NOTEQUAL ${_input} ${out} r)
		set(_input ${out})
	endwhile()
	set(${_output} ${out} PARENT_SCOPE)
endfunction()

function(update_folder _folder _var)
	if(${MSVC_VERSION} GREATER_EQUAL 1920)
		set(${_var} ${_folder} PARENT_SCOPE)
	else()
		string(REGEX REPLACE "^([a-z]+)/" "\\1_/" _folder ${_folder})
		string(REGEX REPLACE "/([a-z]+)$" "/\\1_" _folder ${_folder})
		string_regex_replace_all("/([a-z]+)/" "/\\1_/" out ${_folder})
		set(_folder ${out})
		set(${_var} ${_folder} PARENT_SCOPE)
	endif()
endfunction()

function(get_target_list _var _src _main)
	set(project_list)
	file(GLOB_RECURSE project_list ${_src}/*)
	get_filename_component_list(dir_list "${project_list}" DIRECTORY)
	list(REMOVE_DUPLICATES dir_list)

	foreach(item ${dir_list})
		file(GLOB current ${item}/* ${item}/*.cpp)
		set(name)
		get_filename_component(name ${item} NAME)
		set(lib)
		get_filename_component_list(lib " ${current}" NAME_WE)
		list(REMOVE_DUPLICATES lib)
		set(proj)
		set(src)
		list(FIND lib ${_main} out)
		if(NOT (${out} EQUAL -1))
			set(proj ${_main})
			add_executable(${proj} "")
		else()
			set(proj ${name})
			add_library(${proj} "")

			string(REGEX MATCH "(${_src}/.*)${proj}.*$" _ ${item})
			set(folder ${CMAKE_MATCH_1})
			update_folder(${folder} folder)
			set_property(TARGET ${proj} PROPERTY FOLDER ${folder})
		endif()

		list(APPEND target_list ${proj})

		list(REMOVE_ITEM lib ${proj})
		file(GLOB src ${item}/${proj}.*)
		list(REMOVE_ITEM lib ${proj})

		set_property(TARGET ${proj} PROPERTY LIB ${lib} ${Boost_LIBRARIES})
		set_property(TARGET ${proj} PROPERTY SRC ${src})

		foreach(i ${lib})
			if(NOT (IS_DIRECTORY ${item}/${i}))
				set(proj ${i})
				list(APPEND target_list ${proj})

				add_library(${proj} "")
				file(GLOB src ${item}/${proj}.*)

				set_property(TARGET ${proj} PROPERTY SRC ${src})

				set(folder)
				if(${name} STREQUAL ${_src})
					if(${MSVC_VERSION} GREATER_EQUAL 1920)
						set(folder ${name})
					else()
						set(folder ${name}_)
					endif()
				else()
					string(REGEX MATCH "(${_src}/.*)$" _ ${item})
					set(folder ${CMAKE_MATCH_1})
					update_folder(${folder} folder)
				endif()

				set_property(TARGET ${proj} PROPERTY FOLDER ${folder})
			endif()
		endforeach()
	endforeach()

	set(${_var} ${target_list} PARENT_SCOPE)
endfunction()