project(daqd-trunk)
cmake_minimum_required(VERSION 3.12)

enable_testing()

# DEFINE BUILD_ON_BOOT from commandline when building on a typical puppet configured boot server
# This will cut out sections that depend on packages not usually installed on such bootservers.

FIND_PROGRAM(BISON_PROG bison)
FIND_PROGRAM(FLEX_PROG flex)

SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/config/cmake" )
message("cmake modules" ${CMAKE_MODULE_PATH})

INCLUDE(CheckCXXCompilerFlag)
INCLUDE(CheckIncludeFile)
INCLUDE(CheckIncludeFileCXX)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(FindThreads)
INCLUDE(Sanitizers)
INCLUDE(Cpp11)
INCLUDE(Integration)
FIND_PACKAGE(PkgConfig)
FIND_PACKAGE(ClockGetTime)
FIND_PACKAGE(EPICSBase REQUIRED)


if( NOT BUILD_ON_BOOT ) #Exclude some packages/build when building on boot server
    FIND_PACKAGE(FrameCPP REQUIRED)
    FIND_PACKAGE(RapidJSON)
    FIND_PACKAGE(yaml-cpp)
    find_package(pybind11)
    FIND_PACKAGE(Python3)
    FIND_PROGRAM(GOLANG go
            HINTS /usr/bin)
    find_program(CARGO cargo)

    if( NOT DEFINED Python3_SITEARCH)
        MESSAGE(FATAL_ERROR "Python 3 library installation directory was not found.")
    endif()


    # check python3 SITEARCH is found
    # the Python3_SITEARCH variable tells us where to install architecture dependent
    # python packages.
    # This is converted to a relative install path called Python3_ARCH_INSTALL_DIR,
    # needed for pybind11 packages.
    #
    # Python3_SITELIB gives the install path for architecture independent packages
    # if those are needed, then Python3_SITELIB should get the same treatment as Python3_SITEARCH.
    # Python3_LIB_INSTALL_DIR should be created and used for those packages.
    if( NOT DEFINED Python3_SITEARCH)
        MESSAGE(FATAL_ERROR "Python 3 library installation directory was not found.")
    endif()

    # generate relative python install directories
    get_filename_component(Python3_PKG_ARCH_DIR ${Python3_SITEARCH} NAME)
    get_filename_component(Python3_ARCH_BASE_DIR ${Python3_SITEARCH} DIRECTORY)
    get_filename_component(Python3_PYTHON_ARCH_DIR ${Python3_ARCH_BASE_DIR} NAME)
    SET(Python3_ARCH_INSTALL_DIR lib/${Python3_PYTHON_ARCH_DIR}/${Python3_PKG_ARCH_DIR})

    MESSAGE(STATUS "Python3 version: ${Python3_VERSION}")
    MESSAGE(STATUS "Python3 site arch: ${Python3_SITEARCH}")
    MESSAGE(STATUS "Python3 arch install dir: ${Python3_ARCH_INSTALL_DIR}")
    MESSAGE(STATUS "Python3 include dirs: ${Python3_INCLUDE_DIRS}")
    MESSAGE(STATUS "Python3 libraries: ${Python3_LIBRARIES}")
    MESSAGE(STATUS "Python3 library dirs: ${Python3_LIBRARY_DIRS}")
    MESSAGE(STATUS "Python3 sitelib: ${Python3_SITELIB}")
    MESSAGE(STATUS "Python3 development found: ${Python3_Development_FOUND}")

endif()

FIND_PACKAGE(NDS2Client)
FIND_PACKAGE(Boost COMPONENTS filesystem system)
FIND_PACKAGE(RPC)


if (PUB_SUB_LOCAL)
    message("Using a local source copy of cds-pubsub")
    add_subdirectory("${PUB_SUB_LOCAL}" cds-pubsub)
    add_library(cds::pub_sub ALIAS pub_sub)
    add_library(cds::pub_sub_asan ALIAS pub_sub_asan)
    set(libcds-pubsub_FOUND "true")
else (PUB_SUB_LOCAL)
    FIND_PACKAGE(libcds-pubsub)
endif (PUB_SUB_LOCAL)


CHECK_CXX_SOURCE_COMPILES("#include <iostream>
#include <FlexLexer.h>
struct TestLexer: public yyFlexLexer {
	TestLexer(std::ifstream* arg_yyin = 0, std::ofstream* arg_yyout = 0)
	{ std::ostream& tmp = yyout; }
};
int main(int argc, char **argv)
{ return 1; }" FLEX_USES_IOSTREAM_REF)

CHECK_CXX_COMPILER_FLAG(-Wno-deprecated-declarations CAN_AVOID_DEPR_DECL)
if(CAN_AVOID_DEPR_DECL)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
endif(CAN_AVOID_DEPR_DECL)

CHECK_INCLUDE_FILE(FlexLexer.h HAVE_FLEXLEXER_H)
CHECK_INCLUDE_FILE(arpa/inet.h HAVE_ARPA_INET_H)
CHECK_INCLUDE_FILE(assert.h HAVE_ASSERT_H)
CHECK_INCLUDE_FILE(ctype.h HAVE_CTYPE_H)
CHECK_INCLUDE_FILE(errno.h HAVE_ERRNO_H)
CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H)
CHECK_INCLUDE_FILE(fstream.h HAVE_FSTREAM_H)
CHECK_INCLUDE_FILE(iostream.h HAVE_IOSTREAM_H)
CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H)
CHECK_INCLUDE_FILE(math.h HAVE_MATH_H)
CHECK_INCLUDE_FILE(netinet/in.h HAVE_NETINET_IN_H)
CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H)
CHECK_INCLUDE_FILE(signal.h HAVE_SIGNAL_H)
CHECK_INCLUDE_FILE(stdio.h HAVE_STDIO_H)
CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H)
CHECK_INCLUDE_FILE(stream.h HAVE_STREAM_H)
CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
CHECK_INCLUDE_FILE(sys/socket.h HAVE_SYS_SOCKET_H)
CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
CHECK_INCLUDE_FILE(time.h HAVE_TIME_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(regexp.h HAVE_REGEXP_H)
CHECK_INCLUDE_FILE(regex.h HAVE_REGEX_H)



CHECK_FUNCTION_EXISTS(strchr HAVE_STRCHR)
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
CHECK_FUNCTION_EXISTS(fchdir HAVE_FCHDIR)

add_compile_options(-g3)

add_subdirectory(src)

if( NOT DEFINED BUILD_ON_ROOT )
    add_subdirectory(test)
endif()
