PROJECT(bfilter)

ENABLE_TESTING()

INCLUDE(CheckIncludeFile)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckLibraryExists)
INCLUDE(cmake/FindACE.cmake)
INCLUDE(cmake/FindSigC.cmake)
INCLUDE(cmake/FindZLIB.cmake)
INCLUDE(cmake/FindWx.cmake)
INCLUDE(cmake/SetDefaultGccFlags.cmake)
INCLUDE(cmake/SetDefaultMsvcFlags.cmake)
INCLUDE(cmake/SetDefaultBuildType.cmake)

SET(ACE_LIB ACE)
IF(APPLE)
	# This conflicts with CMAKE_OSX_SYSROOT
	SET(CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES)
	
	SET(
		CMAKE_OSX_ARCHITECTURES "i386;ppc"
		CACHE INTERNAL "OSX Architectures" FORCE
	)
ELSEIF(WIN32)
	CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR)
	# Earlier versions can't parse compiler flags like /Gy-
	
	OPTION(WIN9x_COMPATIBILITY "Support Win9x" OFF)
	IF(WIN9x_COMPATIBILITY)
		ADD_DEFINITIONS("-DWIN9x_COMPATIBILITY=1")
		SET(ACE_LIB ACE_win9x)
	ELSE(WIN9x_COMPATIBILITY)
		ADD_DEFINITIONS(-"DWIN9x_COMPATIBILITY=0")
		SET(ACE_LIB ACE_nt)
	ENDIF(WIN9x_COMPATIBILITY)
ELSE(APPLE)
	MESSAGE(FATAL_ERROR "CMake build system is not yet ready for UNIX builds. Use autoconf-based system instead.")
ENDIF(APPLE)

FILE(READ ${PROJECT_SOURCE_DIR}/VERSION BFILTER_VERSION)
STRING(REGEX MATCH "[-.0-9A-Za-z]*" BFILTER_VERSION "${BFILTER_VERSION}")
STRING(REGEX REPLACE "([0-9]+).*" "\\1" BFILTER_VERSION_MAJOR "${BFILTER_VERSION}")
STRING(REGEX REPLACE "[^.]*\\.([0-9]+).*" "\\1" BFILTER_VERSION_MINOR "${BFILTER_VERSION}")
STRING(REGEX REPLACE "[^.]*\\.[^.]*\\.?([0-9]*).*" "\\1" BFILTER_VERSION_MICRO "${BFILTER_VERSION}")
IF("${BFILTER_VERSION_MICRO}" STREQUAL "")
	SET(BFILTER_VERSION_MICRO 0)
ENDIF("${BFILTER_VERSION_MICRO}" STREQUAL "")

BF_FIND_ACE("${ACE_LIB}")
INCLUDE_DIRECTORIES(${ACE_INCLUDE_DIR})

BF_FIND_SIGC()
ADD_DEFINITIONS(${SIGC_CFLAGS})
INCLUDE_DIRECTORIES(${SIGC_INCLUDE_DIR} ${SIGC_CONFIG_DIR})

BF_FIND_ZLIB()
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})

IF(MSVC)
	BF_FIND_WX()
	INCLUDE_DIRECTORIES(${WX_INCLUDE_DIR} ${WX_LIB_DIR}/msw)
	LINK_DIRECTORIES(${WX_LIB_DIR})
ENDIF(MSVC)

BF_SET_DEFAULT_GCC_FLAGS()
BF_SET_DEFAULT_MSVC_FLAGS()
BF_SET_DEFAULT_BUILD_TYPE(MinSizeRel)

ADD_DEFINITIONS(
	-DHAVE_CONFIG_H -DJS_THREADSAFE
	-DBOOST_REGEX_NO_LIB -DBOOST_REGEX_NON_RECURSIVE
	-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION
)
# FIXME: BOOST defines will go away when WITH_EXTERNAL_BOOST option is implemented

IF(WIN32)
	ADD_DEFINITIONS(-DXP_WIN -D_X86_)
ELSE(WIN32)
	ADD_DEFINITIONS(-DXP_UNIX)
ENDIF(WIN32)
IF(APPLE)
	ADD_DEFINITIONS(-DJS_HAVE_LONG_LONG -DENABLE_PROXYWATCHER -DENABLE_RECONFIGURE)
ENDIF(APPLE)

INCLUDE_DIRECTORIES(
	"${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}"
	foundation boost reactor libjs/environment main main/confio
)


# Prepare and write config.h, also prepare the EXTRA_LIBS variable.

CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
CHECK_INCLUDE_FILE(poll.h HAVE_POLL_H)
CHECK_INCLUDE_FILE(sys/poll.h HAVE_SYS_POLL_H)

# Is poll() native or emulated?
IF(HAVE_POLL_H OR HAVE_SYS_POLL_H)
	CHECK_SYMBOL_EXISTS(_POLL_EMUL_H_ poll.h sys/poll.h POLL_EMULATED)
	STRING(COMPARE EQUAL "${POLL_EMULATED}" "" HAVE_NATIVE_POLL)
ENDIF(HAVE_POLL_H OR HAVE_SYS_POLL_H)

# Find the library containing clock_gettime()
CHECK_FUNCTION_EXISTS(clock_gettime CLOCK_GETTIME_IN_LIBC)
CHECK_LIBRARY_EXISTS(rt clock_gettime "" CLOCK_GETTIME_IN_LIBRT)
CHECK_LIBRARY_EXISTS(posix4 clock_gettime "" CLOCK_GETTIME_IN_LIBPOSIX4)
IF(CLOCK_GETTIME_IN_LIBC)
	SET(HAVE_CLOCK_GETTIME 1)
ELSEIF(CLOCK_GETTIME_IN_LIBRT)
	SET(HAVE_CLOCK_GETTIME 1)
	LIST(APPEND EXTRA_LIBS rt)
ELSEIF(CLOCK_GETTIME_IN_LIBPOSIX4)
	SET(HAVE_CLOCK_GETTIME 1)
	LIST(APPEND EXTRA_LIBS posix4)
ENDIF(CLOCK_GETTIME_IN_LIBC)

# Find the library containing dlopen()
# We don't need it, but ACE does. If ACE is compiled statically, it's
# our responsibility to link with libraries it needs.
CHECK_LIBRARY_EXISTS(dl dlopen "" DLOPEN_IN_LIBDL)
IF(DLOPEN_IN_LIBDL)
	LIST(APPEND EXTRA_LIBS dl)
ENDIF(DLOPEN_IN_LIBDL)

# Check if atomic operations are optimized on this platform.
CHECK_SYMBOL_EXISTS(
	ATOMIC_OPS_OPTIMIZED
	${PROJECT_SOURCE_DIR}/foundation/AtomicOpsConfig.h
	ATOMIC_OPS_OPTIMIZED
)
IF(NOT ATOMIC_OPS_OPTIMIZED)
	MESSAGE(STATUS "WARNING: Atomic operations are not optimized for you platform!")
	MESSAGE(STATUS "WARNING: Expect poor performance.")
ENDIF(NOT ATOMIC_OPS_OPTIMIZED)

# TODO: enable binreloc on Linux

# TODO: switch options for gui, debug gui, external boost and libs

CONFIGURE_FILE(
	${PROJECT_SOURCE_DIR}/config.h.cm
	${CMAKE_CURRENT_BINARY_DIR}/config.h
)

# Process CMakeLists.txt's in subdirectories
ADD_SUBDIRECTORY(mkskel)
ADD_SUBDIRECTORY(lexgen)
ADD_SUBDIRECTORY(boost)
ADD_SUBDIRECTORY(foundation)
ADD_SUBDIRECTORY(libjs)
ADD_SUBDIRECTORY(reactor)
ADD_SUBDIRECTORY(main)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(conf)
IF(WIN32)
	ADD_SUBDIRECTORY(packaging/windows)
ENDIF(WIN32)
