cmake_minimum_required(VERSION 3.20)
project(crengine-ng VERSION 0.9.14 DESCRIPTION "Cross-platform library for implementing e-book readers" LANGUAGES C CXX)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")

include(CheckIncludeFile)
include(CheckSymbolExists)

#  MY_VERSION_DEV_A/CODE description:
# alphaX - 0X; beta X - 1X; rcX - 2X; releaseX - 3X (or empty)
set(MY_VERSION_DEV_A "")
set(MY_VERSION_DEV_CODE 30)
set(MY_PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
if (MY_VERSION_DEV_A)
    set(MY_PROJECT_VERSION "${MY_PROJECT_VERSION}-${MY_VERSION_DEV_A}")
endif()
# Set shared library API version
# Increase if API is changed
set(LIB_API_VERSION 7)
# for windows rc file
set(PRODUCTVERSION_V "${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},${MY_VERSION_DEV_CODE}")
set(FILEVERSION_V ${PRODUCTVERSION_V})

option(ADD_DEBUG_EXTRA_OPTS "Add extra debug flags and technique" OFF)
set(DOC_DATA_COMPRESSION_LEVEL 1 CACHE STRING "Document buffer cache compression")
set_property(CACHE DOC_DATA_COMPRESSION_LEVEL PROPERTY STRINGS 0 1 2 3 4 5)
set(DOC_BUFFER_SIZE 0x400000 CACHE STRING "Total RAM buffers size for document")
set_property(CACHE DOC_BUFFER_SIZE PROPERTY STRINGS 0x10000 0x40000 0x100000 0x400000 0x800000 0x1000000)
set(MAX_IMAGE_SCALE_MUL 0 CACHE STRING "Maximum image scale multiplier")
set_property(CACHE MAX_IMAGE_SCALE_MUL PROPERTY STRINGS 0 1 2)
set(GRAY_BACKBUFFER_BITS 4 CACHE STRING "Gray depth for gray backbuffer")
set_property(CACHE GRAY_BACKBUFFER_BITS PROPERTY STRINGS 1 2 3 4 8)
option(ENABLE_LARGEFILE_SUPPORT "Enable large files support" ON)
option(USE_COLOR_BACKBUFFER "Use color backbuffer" ON)
option(USE_LOCALE_DATA "Use built-in locale data" ON)
option(LDOM_USE_OWN_MEM_MAN "Use own ldom memory manager" ON)

# Libraries support
set(WITH_LIBPNG AUTO CACHE STRING "Use libpng library for png image support")
set_property(CACHE WITH_LIBPNG PROPERTY STRINGS AUTO ON OFF)
set(WITH_LIBJPEG AUTO CACHE STRING "Use libjpeg library for jpeg image support")
set_property(CACHE WITH_LIBJPEG PROPERTY STRINGS AUTO ON OFF)
set(WITH_LIBWEBP AUTO CACHE STRING "Use libwebp library for webp image support")
set_property(CACHE WITH_LIBWEBP PROPERTY STRINGS AUTO ON OFF)
set(WITH_LIBJXL AUTO CACHE STRING "Use libjxl library for JPEG XL image support")
set_property(CACHE WITH_LIBJXL PROPERTY STRINGS AUTO ON OFF)
set(WITH_FREETYPE AUTO CACHE STRING "Use FreeType library for font rendering")
set_property(CACHE WITH_FREETYPE PROPERTY STRINGS AUTO ON OFF)
set(WITH_HARFBUZZ AUTO CACHE STRING "Use HarfBuzz library for text shaping")
set_property(CACHE WITH_HARFBUZZ PROPERTY STRINGS AUTO ON OFF)
set(WITH_LIBUNIBREAK AUTO CACHE STRING "Use libunibreak library")
set_property(CACHE WITH_LIBUNIBREAK PROPERTY STRINGS AUTO ON OFF)
set(WITH_FRIBIDI AUTO CACHE STRING "Use FriBiDi library for RTL text")
set_property(CACHE WITH_FRIBIDI PROPERTY STRINGS AUTO ON OFF)
set(WITH_ZSTD AUTO CACHE STRING "Use zstd for cache compression")
set_property(CACHE WITH_ZSTD PROPERTY STRINGS AUTO ON OFF)
set(WITH_UTF8PROC AUTO CACHE STRING "Use utf8proc for string comparison, etc")
set_property(CACHE WITH_UTF8PROC PROPERTY STRINGS AUTO ON OFF)
set(WITH_XXHASH AUTO CACHE STRING "Use xxHash to calculate cache hashes")
set_property(CACHE WITH_XXHASH PROPERTY STRINGS AUTO ON OFF)
set(WITH_FONTCONFIG AUTO CACHE STRING "Use FontConfig to enumerate available fonts")
set_property(CACHE WITH_FONTCONFIG PROPERTY STRINGS AUTO ON OFF)
option(USE_GIF "Allow GIF support via embedded decoder" ON)
option(USE_NANOSVG "Use nanosvg for svg image support" ON)
option(USE_CHM "Enable chm support via built-in chmlib" ON)
option(USE_ANTIWORD "Enable doc support via built-in antiword" ON)
option(USE_SHASUM "Use sources from RFC6234 to calculate SHA sums" OFF)
option(USE_CMARK_GFM "Enable Markdown support via built-in cmark-gfm" OFF)
option(USE_MD4C "Enable Markdown support via built-in md4c" ON)

# other
option(BUILD_TOOLS "Build some debug tools & utils" OFF)
option(OFFLINE_BUILD_MODE "Do not download anything during project build" OFF)
option(ENABLE_UNITTESTING "Enable unit testing using googletest" OFF)
option(ENABLE_LTO "Enable Link Time Optimization" OFF)

if(ENABLE_UNITTESTING)
    enable_testing()
endif()

# check option consistency
if (NOT WITH_FREETYPE)
    set(WITH_HARFBUZZ OFF)
endif()

set(PUBLIC_COMPILE_DEFINITIONS)
set(PRIVATE_COMPILE_DEFINITIONS)
set(PRIVATE_INCLUDE_DIRECTORIES)
set(PUBLIC_LINK_LIBRARIES)
set(PRIVATE_LINK_LIBRARIES)

if (APPLE)
    if(${CMAKE_SYSTEM} MATCHES "^Darwin-.*$")
        set(MACOS 1)
    endif()
endif()

set(CMAKE_C_FLAGS_DEBUG     "${CMAKE_C_FLAGS_DEBUG}     -D_DEBUG=1 -DDEBUG=1")
set(CMAKE_CXX_FLAGS_DEBUG   "${CMAKE_CXX_FLAGS_DEBUG}   -D_DEBUG=1 -DDEBUG=1")
set(CMAKE_C_FLAGS_RELEASE   "${CMAKE_C_FLAGS_RELEASE}   -DNDEBUG=1")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG=1")
set(CMAKE_C_FLAGS_RELWITHDEBINFO   "${CMAKE_C_FLAGS_RELWITHDEBINFO}   -DNDEBUG=1 -UDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG=1 -UDEBUG")

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    # Force to always compile with W4
    if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
        string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
    else()
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
    endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    # Update if necessary
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -pedantic -Wno-comment -fomit-frame-pointer")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -pedantic -Wno-comment -Wno-reorder -fomit-frame-pointer")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    # Update if necessary
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -pedantic -Wno-comment -fomit-frame-pointer")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -pedantic -Wno-comment -Wno-reorder -fomit-frame-pointer")
endif()

include(project_checks)

if(MACOS)
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DMACOS=1 -DLINUX=1 -D_LINUX=1)
elseif ( WIN32 )
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DWIN32=1 -D_WIN32=1 -DNOMINMAX=1 -D_CRT_SECURE_NO_WARNINGS)
elseif ( ANDROID )
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DLINUX=1 -D_LINUX=1)
else()
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DLINUX=1 -D_LINUX=1)
endif()

if(ADD_DEBUG_EXTRA_OPTS)
    if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        add_definitions(-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC)
        set(DEBUG_EXTRA_FLAGS "-fstack-protector -fstack-clash-protection -fno-omit-frame-pointer -Wshift-overflow=2")
    elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        set(DEBUG_EXTRA_FLAGS "-fstack-check -fstack-protector -fno-omit-frame-pointer -Wshift-overflow")
    endif()
    if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR BSD OR MACOS OR ANDROID)
        if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
            set (DEBUG_EXTRA_FLAGS "${DEBUG_EXTRA_FLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover")
            set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-sanitize-recover -fstack-protector -fstack-clash-protection")
            set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-sanitize-recover -fstack-protector -fstack-clash-protection")
        elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
            set (DEBUG_EXTRA_FLAGS "${DEBUG_EXTRA_FLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all")
            set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fstack-check -fstack-protector")
            set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fstack-check -fstack-protector")
        endif()
    endif ()
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_EXTRA_FLAGS}")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_EXTRA_FLAGS}")
endif(ADD_DEBUG_EXTRA_OPTS)

if(ENABLE_LTO)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
    list(APPEND PRIVATE_LINK_LIBRARIES "-flto")
endif()

# Document buffer cache / compression settings
if (NOT DEFINED DOC_DATA_COMPRESSION_LEVEL)
    message("-D DOC_DATA_COMPRESSION_LEVEL=0|1|2|3|4|5 parameter is not defined: will use default value (1)")
    set(DOC_DATA_COMPRESSION_LEVEL 1)
endif (NOT DEFINED DOC_DATA_COMPRESSION_LEVEL)
list(APPEND PRIVATE_COMPILE_DEFINITIONS -DDOC_DATA_COMPRESSION_LEVEL=${DOC_DATA_COMPRESSION_LEVEL})

# Total RAM buffers size for document
if (NOT DEFINED DOC_BUFFER_SIZE)
    message("-D DOC_BUFFER_SIZE=N parameter is not defined: will use default value (0x400000)")
    set(DOC_BUFFER_SIZE 0x400000)
endif (NOT DEFINED DOC_BUFFER_SIZE)
list(APPEND PRIVATE_COMPILE_DEFINITIONS -DDOC_BUFFER_SIZE=${DOC_BUFFER_SIZE})

# maximum image scale multiplier
if (NOT DEFINED MAX_IMAGE_SCALE_MUL)
    message("-D MAX_IMAGE_SCALE_MUL=N parameter is not defined: will use default value (0)")
    set(MAX_IMAGE_SCALE_MUL 0)
endif (NOT DEFINED MAX_IMAGE_SCALE_MUL)
list(APPEND PRIVATE_COMPILE_DEFINITIONS -DMAX_IMAGE_SCALE_MUL=${MAX_IMAGE_SCALE_MUL})

# Large file support
if (ENABLE_LARGEFILE_SUPPORT)
    list(APPEND PRIVATE_COMPILE_DEFINITIONS -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64)
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DLVLONG_FILE_SUPPORT=1)
endif(ENABLE_LARGEFILE_SUPPORT)

if (HAVE_LSEEK64)
    list(APPEND PRIVATE_COMPILE_DEFINITIONS -DHAVE_LSEEK64=1)
endif(HAVE_LSEEK64)

if (NOT USE_COLOR_BACKBUFFER)
    if (NOT DEFINED GRAY_BACKBUFFER_BITS)
        set(GRAY_BACKBUFFER_BITS 4)
    endif (NOT DEFINED GRAY_BACKBUFFER_BITS)
endif (NOT USE_COLOR_BACKBUFFER)
set(COLOR_BACKBUFFER ${USE_COLOR_BACKBUFFER})

# Libraries

# zlib library (cmake module)
find_package(ZLIB REQUIRED)
if (ZLIB_FOUND)
    set(USE_ZLIB ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "ZLIB::ZLIB")
else()
    set(USE_ZLIB OFF)
endif()

# libpng library (cmake module)
if(WITH_LIBPNG STREQUAL "AUTO")
    find_package(PNG)
elseif(WITH_LIBPNG)
    find_package(PNG REQUIRED)
endif()
if (PNG_FOUND)
    set(USE_LIBPNG ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "PNG::PNG")
else()
    set(USE_LIBPNG OFF)
endif()

# jpeg library (cmake module)
if(WITH_LIBJPEG STREQUAL "AUTO")
    find_package(JPEG)
elseif(WITH_LIBJPEG)
    find_package(JPEG REQUIRED)
endif()
if (JPEG_FOUND)
    set(USE_LIBJPEG ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "JPEG::JPEG")
else()
    set(USE_LIBJPEG OFF)
endif()

# libwebp library (package config; local find module)
if(WITH_LIBWEBP STREQUAL "AUTO" OR ${WITH_LIBWEBP})
    find_package(WebP CONFIG)
    if (NOT WebP_FOUND)
        message(STATUS "WebP cmake config not found, alternative find module will be used")
        find_package(WebP MODULE COMPONENTS webp webpdemux)
    endif()
endif()
if (WebP_FOUND)
    set(USE_LIBWEBP ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "WebP::webp")
    list(APPEND PRIVATE_LINK_LIBRARIES "WebP::webpdemux")
else()
    if(WITH_LIBWEBP STREQUAL "ON")
        message(FATAL_ERROR "libwebp NOT found!")
    endif()
    set(USE_LIBWEBP OFF)
endif()

# libjxl library (local find module)
if(WITH_LIBJXL STREQUAL "AUTO")
    find_package(JXL MODULE)
elseif(WITH_LIBJXL)
    find_package(JXL MODULE REQUIRED)
endif()
if (JXL_FOUND)
    set(USE_LIBJXL ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "JXL::jxl")
    list(APPEND PRIVATE_LINK_LIBRARIES "JXL::jxl_cms")
    list(APPEND PRIVATE_LINK_LIBRARIES "JXL::jxl_threads")
else()
    set(USE_LIBJXL OFF)
endif()

if (MACOS)
    list(APPEND PUBLIC_COMPILE_DEFINITIONS -DCR_EMULATE_GETTEXT=1)
else()
    # libintl (gettext) (cmake module)
    find_package(Intl)
    if (Intl_FOUND)
        set(USE_LIBINTL ON)
        list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${Intl_INCLUDE_DIRS})
        list(APPEND PRIVATE_LINK_LIBRARIES "Intl::Intl")
    else()
        list(APPEND PUBLIC_COMPILE_DEFINITIONS -DCR_EMULATE_GETTEXT=1)
    endif()
endif()

# FreeType library (cmake module)
set(FREETYPE_MIN_VERSION "2.10.0")
if(WITH_FREETYPE STREQUAL "AUTO")
    find_package(Freetype ${FREETYPE_MIN_VERSION})
elseif(WITH_FREETYPE)
    find_package(Freetype ${FREETYPE_MIN_VERSION} REQUIRED)
endif()
if (FREETYPE_FOUND)
    set(USE_FREETYPE ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "Freetype::Freetype")
else()
    set(USE_FREETYPE OFF)
endif()

# HarfBuzz library (local find module)
# When building HarfBuzz using CMake, a config file is generated; however,
#  since CMake is not officially supported, the file is unfortunately non-functional
#  (though this may not apply to all versions).
set(HARFBUZZ_MIN_VERSION "2.6.0")
if(WITH_HARFBUZZ STREQUAL "AUTO")
    find_package(harfbuzz ${HARFBUZZ_MIN_VERSION} MODULE)
elseif(WITH_HARFBUZZ)
    find_package(harfbuzz ${HARFBUZZ_MIN_VERSION} MODULE REQUIRED)
endif()
if (harfbuzz_FOUND)
    set(CMAKE_REQUIRED_LIBRARIES "harfbuzz::harfbuzz;Freetype::Freetype")
    CHECK_INCLUDE_FILE("hb-ft.h" HAVE_HARFBUZZ_HB_FT_H)
    unset(CMAKE_REQUIRED_LIBRARIES)
    if(NOT HAVE_HARFBUZZ_HB_FT_H)
        message(FATAL_ERROR "The HarfBuzz library must be compiled with FreeType support!")
    endif(NOT HAVE_HARFBUZZ_HB_FT_H)
    list(APPEND PRIVATE_LINK_LIBRARIES "harfbuzz::harfbuzz")
    set(USE_HARFBUZZ ON)
    if (MACOS)
        # workaround for static HarfBuzz compiled with option "--with-coretext=yes"
        list(APPEND PUBLIC_LINK_LIBRARIES "-framework Cocoa")
    endif (MACOS)
else()
    if(WITH_HARFBUZZ STREQUAL "ON")
        message(FATAL_ERROR "harfbuzz NOT found!")
    endif()
    set(USE_HARFBUZZ OFF)
endif()

# FriBiDi library (local find module)
set(FRIBIDI_MIN_VERSION "1.0.0")
if(WITH_FRIBIDI STREQUAL "AUTO")
    find_package(FriBidi ${FRIBIDI_MIN_VERSION} MODULE)
elseif(WITH_FRIBIDI)
    find_package(FriBidi ${FRIBIDI_MIN_VERSION} MODULE REQUIRED)
endif()
if (FRIBIDI_FOUND)
    set(USE_FRIBIDI ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "FriBidi::FriBidi")
else()
    set(USE_FRIBIDI OFF)
endif()

# libunibreak library (local find module)
set(LIBUNIBREAK_MIN_VERSION "4.0")
if(WITH_LIBUNIBREAK STREQUAL "AUTO")
    find_package(libunibreak ${LIBUNIBREAK_MIN_VERSION} MODULE)
elseif(WITH_LIBUNIBREAK)
    find_package(libunibreak ${LIBUNIBREAK_MIN_VERSION} MODULE REQUIRED)
endif()
if (LIBUNIBREAK_FOUND)
    set(USE_LIBUNIBREAK ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "libunibreak::libunibreak")
else()
    set(USE_LIBUNIBREAK OFF)
endif()

# zstd library (package config; local find module)
set(ZSTD_MIN_VERSION "1.4.0")
if(WITH_ZSTD STREQUAL "AUTO" OR ${WITH_ZSTD})
    find_package(zstd ${ZSTD_MIN_VERSION} CONFIG)
    if (NOT zstd_FOUND)
        message(STATUS "zstd cmake config not found, alternative find module will be used")
        find_package(zstd ${ZSTD_MIN_VERSION} MODULE)
    endif()
endif()
if (zstd_FOUND)
    set(USE_ZSTD ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "zstd::libzstd")
else()
    if(WITH_ZSTD STREQUAL "ON")
        message(FATAL_ERROR "zstd NOT found!")
    endif()
    set(USE_ZSTD OFF)
endif()

# utf8proc library (package config; local find module)
if(WITH_UTF8PROC STREQUAL "AUTO" OR ${WITH_UTF8PROC})
    find_package(utf8proc CONFIG)
    if (NOT utf8proc_FOUND)
        message(STATUS "utf8proc cmake config not found, alternative find module will be used")
        find_package(utf8proc MODULE)
    endif()
endif()
if (utf8proc_FOUND)
    set(USE_UTF8PROC ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "utf8proc::utf8proc")
else()
    if(WITH_UTF8PROC STREQUAL "ON")
        message(FATAL_ERROR "utf8proc NOT found!")
    endif()
    set(WITH_UTF8PROC OFF)
endif()

# xxHash library (package config; local find module)
if(WITH_XXHASH STREQUAL "AUTO" OR ${WITH_XXHASH})
    find_package(xxHash CONFIG)
    if (NOT xxHash_FOUND)
        message(STATUS "xxHash cmake configuration not found, alternative find module will be used")
        find_package(xxHash MODULE)
    endif()
endif()
if (xxHash_FOUND)
    set(USE_XXHASH ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "xxHash::xxhash")
else()
    if(WITH_XXHASH STREQUAL "ON")
        message(FATAL_ERROR "xxHash NOT found!")
    endif()
    set(USE_XXHASH OFF)
endif()

# FontConfig library (cmake module)
set(FONTCONFIG_MIN_VERSION "2.11.0")
if(WITH_FONTCONFIG STREQUAL "AUTO")
    find_package(Fontconfig ${FONTCONFIG_MIN_VERSION})
elseif(WITH_FONTCONFIG)
    find_package(Fontconfig ${FONTCONFIG_MIN_VERSION} REQUIRED)
endif()
if (Fontconfig_FOUND)
    set(USE_FONTCONFIG ON)
    list(APPEND PRIVATE_LINK_LIBRARIES "Fontconfig::Fontconfig")
else()
    set(USE_FONTCONFIG OFF)
endif()

# nanosvg library
if(USE_NANOSVG)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/nanosvg/src)
endif()

# patched built-in libchm
if (USE_CHM)
    message("Will build patched LIBCHM library")
    add_subdirectory(thirdparty/chmlib)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/chmlib/src)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_chmlib)
endif(USE_CHM)

# patched built-in antiword
if (USE_ANTIWORD)
    message("Will build patched ANTIWORD library")
    add_subdirectory(thirdparty/antiword)
    target_compile_definitions(cre_antiword PRIVATE -DCR3_ANTIWORD_PATCH=1)
    list(APPEND PRIVATE_COMPILE_DEFINITIONS -DCR3_ANTIWORD_PATCH=1)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/antiword)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_antiword)
endif()

# qimagescale library
add_subdirectory(thirdparty/qimagescale)
list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/qimagescale)
list(APPEND PRIVATE_LINK_LIBRARIES cre_qimagescale)

# built-in rfc6234-shas
if (USE_SHASUM)
    message("Will build RFC6234 SHAs library")
    add_subdirectory(thirdparty/rfc6234-shas)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/rfc6234-shas)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_rfc6234-shas)
endif()

if (USE_CMARK_GFM AND USE_MD4C)
    message(FATAL_ERROR "You can only choose one of cmark-gfm or md4c!")
endif()

# built-in cmark-gfm
if (USE_CMARK_GFM)
    message("Will build cmark-gfm library")
    add_subdirectory(thirdparty/cmark-gfm)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/cmark-gfm/src)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/thirdparty/cmark-gfm/src)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/cmark-gfm/extensions)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/thirdparty/cmark-gfm/extensions)
    list(APPEND PRIVATE_COMPILE_DEFINITIONS -DCMARK_GFM_STATIC_DEFINE -DCMARK_GFM_EXTENSIONS_STATIC_DEFINE)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_cmark-gfm)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_cmark-gfm-extensions)
endif(USE_CMARK_GFM)

# built-in md4c
if (USE_MD4C)
    message("Will build md4c library")
    add_subdirectory(thirdparty/md4c)
    list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/md4c/src)
    list(APPEND PRIVATE_LINK_LIBRARIES cre_md4c-html)
endif(USE_MD4C)

# check usage consistency
if (NOT USE_FREETYPE)
    set(USE_HARFBUZZ OFF)
endif()

include_directories(crengine/include)
include_directories(${CMAKE_BINARY_DIR}/crengine)

add_subdirectory(crengine)
