macro(global_set Name Value)
#    message("set ${Name} to ${Value}" ${ARGN})
    set(${Name} "${Value}" CACHE STRING "NoDesc" FORCE)
endmacro()

macro(condition_set Name Value)
    if (NOT ${Name})
        global_set(${Name} ${Value})
    else ()
#        message("exists ${Name} is ${Value}" ${ARGN})
    endif ()
endmacro()


set(SOURCE_FILES "" CACHE STRING "Source Files" FORCE)
macro(add_source_files)
    #    message(" + add_source_files ${ARGN}")
    file(GLOB_RECURSE newlist ${ARGN})

    foreach (filepath ${newlist})
        string(TOLOWER ${filepath} F)
        string(TOLOWER ${CMAKE_BINARY_DIR} M)
        string(FIND ${F} ${M} found)
        if (NOT found EQUAL 0)
            set(SOURCE_FILES ${SOURCE_FILES} ${filepath} CACHE STRING "Source Files" FORCE)
        endif ()
    endforeach ()
endmacro()

function(JOIN VALUES GLUE OUTPUT)
    string(REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
    string(REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
    set(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()

global_set(LDFLAGS "")
global_set(CMAKE_EXE_LINKER_FLAGS "")
global_set(CMAKE_SHARED_LINKER_FLAGS "")
global_set(CMAKE_MODULE_LINKER_FLAGS "")

function(removeDuplicateSubstring stringIn stringOut)
    separate_arguments(stringIn)
    list(REMOVE_DUPLICATES stringIn)
    string(REPLACE ";" " " stringIn "${stringIn}")
    set(${stringOut} "${stringIn}" PARENT_SCOPE)
endfunction()

macro(add_compile_flags WHERE)
    JOIN("${ARGN}" " " STRING_ARGS)
    if (${WHERE} STREQUAL C)
        global_set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${STRING_ARGS}")

    elseif (${WHERE} STREQUAL CXX)
        global_set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STRING_ARGS}")

    elseif (${WHERE} STREQUAL LD)
        global_set(LDFLAGS "${LDFLAGS} ${STRING_ARGS}")
        global_set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${STRING_ARGS}")
        global_set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${STRING_ARGS}")
        global_set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${STRING_ARGS}")

    elseif (${WHERE} STREQUAL BOTH)
        add_compile_flags(C ${ARGN})
        add_compile_flags(CXX ${ARGN})

    elseif (${WHERE} STREQUAL ALL)
        add_compile_flags(C ${ARGN})
        add_compile_flags(CXX ${ARGN})
        add_compile_flags(LD ${ARGN})

    else ()
        message(FATAL_ERROR "add_compile_flags - only support: C, CXX, BOTH, LD, ALL")
    endif ()
endmacro()
