with_warnings()

include( ../wibble/test.cmake )
include( ../cmake/stringify.cmake )

file( GLOB SRC *.cpp )
file( GLOB H *.h )

foreach( D utility toolkit generator algorithm instances explicit )
    file( GLOB SRC_${D} ${D}/*.cpp )
    file( GLOB H_${D} ${D}/*.h )
    install( FILES ${H_${D}} DESTINATION include/divine/${D} COMPONENT divine_dev )
    if ( NOT ${D} STREQUAL instances )
       list( APPEND SRC ${SRC_${D}} )
    endif()
endforeach()

# generated instantiate files
set( H_INSTANCES_EXTERN "${CMAKE_CURRENT_BINARY_DIR}/instances/auto/extern.h" )
install( FILES "${H_INSTANCES_EXTERN}" DESTINATION include/divine/instances/auto COMPONENT divine_dev )
list( APPEND SRC_auto_instances "${CMAKE_CURRENT_BINARY_DIR}/instances/auto/select.cpp" )
foreach( I RANGE 1 ${MAX_INSTANCE_FILES_COUNT} )
    set( F "${CMAKE_CURRENT_BINARY_DIR}/instances/auto/instances-${I}.cpp" )
    list( APPEND SRC_auto_instances ${F} )
endforeach()
set_source_files_properties( ${SRC_auto_instances} PROPERTIES GENERATED ON )

if ( LEGACY )
   file( GLOB SRC_LEGACY legacy/*/*.cc legacy/*/*/*.cc legacy/*/*/*/*.cc
                         legacy/*/*.c legacy/*/*/*.c legacy/*/*/*/*.c )
   file( GLOB H_LEGACY legacy/*/*.hh legacy/*/*/*.hh )
endif()

if( COIN )
    file( GLOB SRC_COIN coin/*.cpp coin/parse/*.cpp)
    set_source_files_properties( coin/parse/lex.coin.cpp PROPERTIES COMPILE_DEFINITIONS YY_NO_INPUT=1 )
endif( COIN )

if( LLVM )
    file( GLOB SRC_LLVM llvm/*.cpp )
    STRING( REPLACE "llvm/usr-pthread.cpp" "" SRC_LLVM "${SRC_LLVM}" )
    STRING( REPLACE "llvm/usr-glue.cpp" "" SRC_LLVM "${SRC_LLVM}" )
    STRING( REPLACE "llvm/usr-cxa_exception.cpp" "" SRC_LLVM "${SRC_LLVM}" )
    file( GLOB llvmtesth llvm/*.test.h )
endif( LLVM )

if( DVE )
    file( GLOB SRC_DVE dve/*.cpp )
endif( DVE )

if ( TIMED )
    file( GLOB SRC_TIMED timed/*.cpp )
    include_directories( ${Boost_INCLUDE_DIR} )
endif( TIMED )

file( GLOB SRC_BA ltl2ba/*.cpp )
file( GLOB H_BA ltl2ba/*.hh )

file( GLOB testh *.test.h toolkit/*.test.h graph/*.test.h explicit/*.test.h )

set( SRC_DLFCN "" )
if( WIN32 )
    set( SRC_DLFCN ../external/dlfcn-win32/dlfcn.c )
endif( WIN32 )

set( SHA1 ${divine_BINARY_DIR}/divine/sha1 )
set( UPDATE_SHA1 ${divine_SOURCE_DIR}/divine/update-sha1.sh )

add_custom_command(
  COMMAND sh ${UPDATE_SHA1} "${SHA1SUM}" "${divine_SOURCE_DIR}" "${SHA1}"
  OUTPUT "${SHA1}.cpp.fake"
)
set_source_files_properties( "${SHA1}.cpp.fake" PROPERTIES SYMBOLIC ON )
set_source_files_properties( "${SHA1}.cpp" PROPERTIES GENERATED ON )

add_custom_command(
  OUTPUT divinecompileflags.cpp
  VERBATIM
  COMMAND sh -c "echo -n \"const char* divineCompileFlags = \\\"${BUILDOPTS}\\\";\">divinecompileflags.cpp"
)

stringify( "" toolkit/pool.h )
stringify( "" toolkit/blob.h )
stringify( "" cesmi/usr-cesmi.h )
stringify( "" cesmi/usr-cesmi.cpp )
stringify( "" cesmi/usr-ltl.h )
stringify( "" cesmi/usr-ltl.cpp )
stringify( "" llvm/usr.h )
stringify( "" llvm/usr-pthread.h )
stringify( "" llvm/usr-pthread.cpp )
stringify( "" llvm/usr-glue.cpp )
stringify( "" llvm/usr-atomic.h )
stringify( "" llvm/usr-cxa_exception.cpp )
stringify( "" llvm/usr-unwind.h )

set( GENERATED_INSTANCES_DIR "${CMAKE_CURRENT_BINARY_DIR}/instances/auto" )
add_executable( instances-generator instances/generator/generator.cpp )
file( MAKE_DIRECTORY ${GENERATED_INSTANCES_DIR} )
add_custom_command( TARGET instances-generator POST_BUILD
    COMMAND "${CMAKE_CURRENT_BINARY_DIR}/instances-generator" ${MAX_INSTANCE_FILES_COUNT} ${MIN_INSTANCES_PER_FILE}
    WORKING_DIRECTORY ${GENERATED_INSTANCES_DIR}
    COMMENT "Generating instance files"
    VERBATIM )
target_link_libraries( instances-generator wibble )
target_link_libraries( instances-generator libdivine )

include_directories( ${DIVINE_INCLUDES} )
add_definitions( ${MPI_COMPILE_FLAGS} ${LLVM_COMPILE_FLAGS} )
set_source_files_properties( ${SRC_LLVM} PROPERTIES COMPILE_FLAGS "-fno-rtti" )
set_source_files_properties( llvm/execution.cpp llvm/constants.cpp PROPERTIES COMPILE_FLAGS "-fno-rtti -fno-exceptions" )

add_library( libdivine STATIC
    ${SRC_DLFCN} ${SRC} ${SRC_LEGACY} ${SRC_TIMED}
    ${SRC_COIN} ${SRC_BA} ${SRC_LLVM} ${SRC_DVE}
    "${SHA1}.cpp" "${SHA1}.cpp.fake" "divinecompileflags.cpp"
    ${STRINGIFIED} )

add_library( libdivine-instances OBJECT ${SRC_instances} ${SRC_auto_instances} )
add_dependencies( libdivine-instances instances-generator )

set_target_properties( libdivine PROPERTIES OUTPUT_NAME "divine" )

wibble_add_test( divine-test ${testh} ${llvmtesth} )

if( NOT WIN32 )
  set_target_properties( libdivine PROPERTIES COMPILE_FLAGS -fPIC )
endif( NOT WIN32 )

if( LLVM )
  target_link_libraries( libdivine ${LLVM_LIBRARIES} )
  target_link_libraries( libdivine ${LLVM_SYSLIBS} )
  target_link_libraries( libdivine pdclib_str )
  target_link_libraries( libdivine m_str )
  target_link_libraries( libdivine cxxabi_str )
  target_link_libraries( libdivine cxx_str )
endif()

if( CURSES )
  target_link_libraries( libdivine ${CURSES_LIBRARIES} )
endif()

target_link_libraries( libdivine ${MPI_LIBRARIES} )

if( LTL3BA )
  target_link_libraries( libdivine ltl3ba )
endif( LTL3BA )

if( TIMED )
  target_link_libraries( libdivine dbm )
  target_link_libraries( libdivine utap )
endif()

if ( SQL_REPORT )
    target_link_libraries( libdivine nanodbc )
endif()

target_link_libraries( libdivine wibble )
target_link_libraries( divine-test libdivine )

if( NOT WIN32 )
  target_link_libraries( libdivine dl )
  wibble_check_target( divine-test )
else()
    target_link_libraries( libdivine psapi )
endif( NOT WIN32 )

install( TARGETS libdivine DESTINATION lib COMPONENT divine_dev )

install( FILES ${H} DESTINATION include/divine COMPONENT divine_dev )
install( FILES ${H_LEGACY} DESTINATION include/divine/legacy COMPONENT divine_dev )
install( FILES ${H_BA} DESTINATION include/divine/ltl2ba COMPONENT divine_dev )

