cmake_minimum_required(VERSION 2.6)

set(PROJECT lboot)

project(${PROJECT} C)
set(LBOOT_VERSION  1.0.2)
add_definitions(-DLBOOT_VERSION="${LBOOT_VERSION}")




option(ENABLE_USB   "enable usb interface" OFF)
option(ENABLE_MBRTU "enable Modbus-RTU interface" OFF)
option(ENABLE_TFTP  "enable tftp" OFF)
option(ENABLE_CAN   "enable CAN interface over L Card CAN-USB adapter" OFF)
option(ENABLE_USB_LIBUSB "enable libusb backend for usb interface" ON)
if(WIN32)
    option(ENABLE_USB_LCOMP  "enable lcomp backend for usb interface" ON)
else(WIN32)
    set(ENABLE_USB_LCOMP OFF)
endif(WIN32)
option(ENABLE_PACKAGES "enable create linux package files" OFF)





message(STATUS "")
message(STATUS "Start configure lboot. Options:")
message(STATUS "    usb:      ${ENABLE_USB}")
message(STATUS "    mbrtu:    ${ENABLE_MBRTU}")
message(STATUS "    tftp:     ${ENABLE_TFTP}")
message(STATUS "    can-usb:  ${ENABLE_CAN}")

if(NOT ENABLE_USB AND NOT ENABLE_MBRTU AND NOT ENABLE_TFTP AND NOT ENABLE_CAN)
    message(FATAL_ERROR "minimum one interface must be enabled!!!")
endif()



#добавляем нужную реализацию таймера
set(LTIMER_DIR lib/ltimer)
set(LCSPEC_DIR lib/lcspec)
include(${LTIMER_DIR}/ltimer.cmake)

#устанавливаем файлы исходных текстов и заголовков, общие для всех вариантов проекта
set(SOURCES
    src/main.c
    src/sha.c
    ${LTIMER_SOURCES}
    )

set(HEADERS
    inc/lboot.h
    inc/lboot_prt.h
    inc/sha.h
    inc/sha-private.h
    ${LTIMER_HEADERS}
    )

set(LIBS
    ${LTIMER_LIBS})


#если есть системная реализация getopt - используем ее, иначе используем свою
find_file(GETOPT_PATH getopt.h PATH_SUFFIXES getopt)
if(NOT GETOPT_PATH)
    message(STATUS "getopt.h - not found. use internal realization of getopt")
    set (SOURCES ${SOURCES} src/getopt.c src/getopt1.c)
    set (HEADERS ${HEADERS} inc/getopt/getopt.h)
    include_directories(inc/getopt)
else(NOT GETOPT_PATH)
    message(STATUS "getopt.h - found : ${GETOPT_PATH}")
endif(NOT GETOPT_PATH)


find_file(HAVE_STDINT stdint.h PATH_SUFFIXES )
if (HAVE_STDINT)
    message(STATUS "stdint.h - found : ${HAVE_STDINT}")
else(HAVE_STDINT)
    message(STATUS "stdint.h - not found. use pstdint.h")
    set (HEADERS ${HEADERS} inc/stdint/stdint.h)
    include_directories(inc/stdint)
endif(HAVE_STDINT)





if(ENABLE_MBRTU)
    #добавляем путь к модулям cmake в path для cmake
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
    #ищем libmodbus
    find_package(MODBUS REQUIRED)
    #включаем найденный путь к заголовкам limodbus и саму библиотеку
    include_directories(${MODBUS_INCLUDE_DIRS})
    set(LIBS ${LIBS} ${MODBUS_LIBRARIES})

    #добавляем исходник с реализацией протокола загрузки по Modbus-RTU
    set(SOURCES ${SOURCES} src/lboot_mbrtu.c)
    set(HEADERS ${HEADERS} inc/lboot_mbrtu.h)
endif(ENABLE_MBRTU)



if(ENABLE_USB)

    #для linux используем libusb-1.0
    if(ENABLE_USB_LIBUSB)
        if(WIN32)
            set(LIBUSB_DIR lib/libusb-1.0)
            include(${LIBUSB_DIR}/libusb.cmake)
            set(SOURCES ${SOURCES} ${LIBUSB_SOURCES})
            set(HEADERS ${HEADERS} ${LIBUSB_HEADERS})
            set(LIBS    ${LIBS}    ${LIBUSB_LIBS})
        else(WIN32)
            set(LIBS ${LIBS} usb-1.0)
        endif(WIN32)
    endif(ENABLE_USB_LIBUSB)

    #добавляем исходник с реализацией протокола загрузки по USB
    set(SOURCES ${SOURCES} src/lboot_usb.c)
    #в windows добавляем заголовочный файл с кодами IOCTL драйвера
    if(WIN32)
        set(HEADERS ${HEADERS} inc/ioctl.h)
    endif(WIN32)
endif(ENABLE_USB)

if(ENABLE_TFTP)
    set(SOURCES ${SOURCES} src/lboot_tftp.c)
    if(WIN32)
        set(LIBS ${LIBS} Ws2_32)
    endif(WIN32)
endif(ENABLE_TFTP)


if(ENABLE_CAN)
    #добавляем исходник с реализацией протокола загрузки по CAN
    set(SOURCES ${SOURCES} src/lboot_can.c)
    #добавляем библиотеку
    if(WIN32)
        set(HEADERS ${HEADERS} lib/can/can.h lib/can/can_lss.h lib/serial/serial.h)
        set(SOURCES ${SOURCES} lib/can/can.c lib/serial/serial.c)
        include_directories(lib/can lib/serial)
    else(WIN32)
        message(FATAL_ERROR "can supported yet only on Windows!!!")
    endif(WIN32)
endif(ENABLE_CAN)


#создаем конфигурационный файл на основе установленных опций
configure_file ("inc/lboot_config.h.in" "lboot_config.h")
set(HEADERS ${HEADERS} ${PROJECT_BINARY_DIR}/lboot_config.h)


#для MSVC меняем /MD на /MT для статической компиляции msvc_distr
if(MSVC)
    foreach(flag_var
            CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
            CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
            CMAKE_CXX_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
            )
       if(${flag_var} MATCHES "/MD")
          string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
       endif(${flag_var} MATCHES "/MD")
    endforeach(flag_var)

    add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NON_CONFORMING_SWPRINTFS)
endif(MSVC)


include_directories(${PROJECT_SOURCE_DIR}/inc ${PROJECT_BINARY_DIR})

add_executable(${PROJECT} ${HEADERS} ${SOURCES})

target_link_libraries(${PROJECT} ${LIBS})


if(UNIX)
    install(TARGETS ${PROJECT} RUNTIME  DESTINATION bin)
    if(ENABLE_USB)
        if(NOT UDEV_RULES_DIR)
            set(UDEV_RULES_DIR lib/udev/rules.d)
        endif(NOT UDEV_RULES_DIR)
        install(FILES lboot.rules DESTINATION ${UDEV_RULES_DIR})
    endif(ENABLE_USB)


    #цели для сборки пакетов
    if(ENABLE_PACKAGES)
        if (NOT OSC_PROJECT)
            set(OSC_PROJECT      home:l-card)
        endif(NOT OSC_PROJECT)
        set(PACKAGE_NAME     ${PROJECT})
        set(PACKAGE_VERSION  ${LBOOT_VERSION})
        set(PACKAGE_ARCH_INSTALL_FILE ${PACKAGE_NAME}.install)
        include(cmake/packages/packages.cmake)
    endif(ENABLE_PACKAGES)
endif(UNIX)




