# Available CMake versions:
#  - Ubuntu  20.04 LTS   : 3.16.3
#  - Solaris 11.4 SRU 15 : 3.15
cmake_minimum_required(VERSION 3.15)

# Since this project's version is loaded from other files, this policy
# will help suppress the warning generated by cmake.
# This policy is set because we can't provide "VERSION" in "project" command.
# Use `cmake --help-policy CMP0048` for more information.
cmake_policy(SET CMP0048 NEW)
project(brotli C)

if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "Setting build type to Release as none was specified")
  set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
else()
  message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
endif()

# Detect Emscripten compiler.
# The EMSCRIPTEN variable is set by Emscripten's CMake toolchain file and is
# the recommended way to detect Emscripten builds.
#
# Note: Previously this used check_c_source_compiles() to test for the
# __EMSCRIPTEN__ macro, but that approach is unreliable in cross-compilation
# scenarios where CMake links a static library instead of an executable,
# causing false positives for non-Emscripten WASM toolchains (e.g., WASI SDK).
if (EMSCRIPTEN)
  set(BROTLI_EMSCRIPTEN TRUE)
else()
  set(BROTLI_EMSCRIPTEN FALSE)
endif()
if (BROTLI_EMSCRIPTEN)
  message(STATUS "Compiler is EMSCRIPTEN")
else()
  message(STATUS "Compiler is not EMSCRIPTEN")
endif()

if (BROTLI_EMSCRIPTEN)
  message(STATUS "Switching to static build for EMSCRIPTEN")
  set(BUILD_SHARED_LIBS OFF)
endif()

# Reflect CMake variable as a build option.
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(BROTLI_BUILD_TOOLS ON CACHE BOOL "Build/install CLI tools")
set(BROTLI_BUILD_FOR_PACKAGE OFF CACHE BOOL "Build/install both shared and static libraries")

if (BROTLI_BUILD_FOR_PACKAGE AND NOT BUILD_SHARED_LIBS)
  message(FATAL_ERROR "Both BROTLI_BUILD_FOR_PACKAGE and BUILD_SHARED_LIBS are set")
endif()

# If Brotli is being bundled in another project, we don't want to
# install anything.  However, we want to let people override this, so
# we'll use the BROTLI_BUNDLED_MODE variable to let them do that; just
# set it to OFF in your project before you add_subdirectory(brotli).
get_directory_property(BROTLI_PARENT_DIRECTORY PARENT_DIRECTORY)
if (NOT DEFINED BROTLI_BUNDLED_MODE)
  # Bundled mode hasn't been set one way or the other, set the default
  # depending on whether or not we are the top-level project.
  if (BROTLI_PARENT_DIRECTORY)
    set(BROTLI_BUNDLED_MODE ON)
  else()
    set(BROTLI_BUNDLED_MODE OFF)
  endif()
endif()  # BROTLI_BUNDLED_MODE
mark_as_advanced(BROTLI_BUNDLED_MODE)

include(GNUInstallDirs)

# Reads macro from .h file; it is expected to be a single-line define.
function(read_macro PATH MACRO OUTPUT)
  file(STRINGS ${PATH} _line REGEX "^#define +${MACRO} +(.+)$")
  string(REGEX REPLACE "^#define +${MACRO} +(.+)$" "\\1" _val "${_line}")
  set(${OUTPUT} ${_val} PARENT_SCOPE)
endfunction(read_macro)

# Version information
read_macro("c/common/version.h" "BROTLI_VERSION_MAJOR" BROTLI_VERSION_MAJOR)
read_macro("c/common/version.h" "BROTLI_VERSION_MINOR" BROTLI_VERSION_MINOR)
read_macro("c/common/version.h" "BROTLI_VERSION_PATCH" BROTLI_VERSION_PATCH)
set(BROTLI_VERSION "${BROTLI_VERSION_MAJOR}.${BROTLI_VERSION_MINOR}.${BROTLI_VERSION_PATCH}")
mark_as_advanced(BROTLI_VERSION BROTLI_VERSION_MAJOR BROTLI_VERSION_MINOR BROTLI_VERSION_PATCH)

# ABI Version information
read_macro("c/common/version.h" "BROTLI_ABI_CURRENT" BROTLI_ABI_CURRENT)
read_macro("c/common/version.h" "BROTLI_ABI_REVISION" BROTLI_ABI_REVISION)
read_macro("c/common/version.h" "BROTLI_ABI_AGE" BROTLI_ABI_AGE)
math(EXPR BROTLI_ABI_COMPATIBILITY "${BROTLI_ABI_CURRENT} - ${BROTLI_ABI_AGE}")
mark_as_advanced(BROTLI_ABI_CURRENT BROTLI_ABI_REVISION BROTLI_ABI_AGE BROTLI_ABI_COMPATIBILITY)

if (ENABLE_SANITIZER)
  set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
  set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
endif ()

include(CheckLibraryExists)
set(LIBM_LIBRARY)
set(LIBM_DEP)
CHECK_LIBRARY_EXISTS(m log2 "" HAVE_LIB_M)
if (HAVE_LIB_M)
  set(LIBM_LIBRARY "m")
  if (NOT BUILD_SHARED_LIBS)
    set(LIBM_DEP "-lm")
  endif()
endif()

set(BROTLI_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/c/include")
mark_as_advanced(BROTLI_INCLUDE_DIRS)

if (BROTLI_BUILD_FOR_PACKAGE)
  set(BROTLI_SHARED_LIBRARIES brotlienc brotlidec brotlicommon)
  set(BROTLI_STATIC_LIBRARIES brotlienc-static brotlidec-static brotlicommon-static)
  set(BROTLI_LIBRARIES ${BROTLI_SHARED_LIBRARIES} ${LIBM_LIBRARY})
else()  # NOT BROTLI_BUILD_FOR_PACKAGE
  if (BUILD_SHARED_LIBS)
    set(BROTLI_SHARED_LIBRARIES brotlienc brotlidec brotlicommon)
    set(BROTLI_STATIC_LIBRARIES)
  else()  # NOT BUILD_SHARED_LIBS
    set(BROTLI_SHARED_LIBRARIES)
    set(BROTLI_STATIC_LIBRARIES brotlienc brotlidec brotlicommon)
  endif()
  set(BROTLI_LIBRARIES ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES} ${LIBM_LIBRARY})
endif()  # BROTLI_BUILD_FOR_PACKAGE
mark_as_advanced(BROTLI_LIBRARIES)

if (MSVC)
  message(STATUS "Defining _CRT_SECURE_NO_WARNINGS to avoid warnings about security")

  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

file(GLOB_RECURSE BROTLI_COMMON_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/common/*.c)
file(GLOB_RECURSE BROTLI_DEC_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/dec/*.c)
file(GLOB_RECURSE BROTLI_ENC_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} c/enc/*.c)

add_library(brotlicommon ${BROTLI_COMMON_SOURCES})
add_library(brotlidec ${BROTLI_DEC_SOURCES})
add_library(brotlienc ${BROTLI_ENC_SOURCES})

if (BROTLI_BUILD_FOR_PACKAGE)
  add_library(brotlicommon-static STATIC ${BROTLI_COMMON_SOURCES})
  add_library(brotlidec-static STATIC ${BROTLI_DEC_SOURCES})
  add_library(brotlienc-static STATIC ${BROTLI_ENC_SOURCES})
endif()

# Older CMake versions does not understand INCLUDE_DIRECTORIES property.
include_directories(${BROTLI_INCLUDE_DIRS})

if (BUILD_SHARED_LIBS)
  foreach(lib ${BROTLI_SHARED_LIBRARIES})
    target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" )
    string(TOUPPER "${lib}" LIB)
    set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION")
  endforeach()
endif()  # BUILD_SHARED_LIBS

foreach(lib ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES})
  target_link_libraries(${lib} ${LIBM_LIBRARY})
  set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS})
  set_target_properties(${lib} PROPERTIES
    VERSION "${BROTLI_ABI_COMPATIBILITY}.${BROTLI_ABI_AGE}.${BROTLI_ABI_REVISION}"
    SOVERSION "${BROTLI_ABI_COMPATIBILITY}")
  if (NOT BROTLI_EMSCRIPTEN)
    set_target_properties(${lib} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
  endif()
  set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${BROTLI_INCLUDE_DIRS}>")
endforeach()  # BROTLI_xxx_LIBRARIES

target_link_libraries(brotlidec brotlicommon)
target_link_libraries(brotlienc brotlicommon)

# For projects stuck on older versions of CMake, this will set the
# BROTLI_INCLUDE_DIRS and BROTLI_LIBRARIES variables so they still
# have a relatively easy way to use Brotli:
#
#   include_directories(${BROTLI_INCLUDE_DIRS})
#   target_link_libraries(foo ${BROTLI_LIBRARIES})
if (BROTLI_PARENT_DIRECTORY)
  set(BROTLI_INCLUDE_DIRS "${BROTLI_INCLUDE_DIRS}" PARENT_SCOPE)
  set(BROTLI_LIBRARIES "${BROTLI_LIBRARIES}" PARENT_SCOPE)
endif()

# Build the brotli executable
if (BROTLI_BUILD_TOOLS)
  add_executable(brotli c/tools/brotli.c)
  target_link_libraries(brotli ${BROTLI_LIBRARIES})
  # brotli is a CLI tool
  set_target_properties(brotli PROPERTIES MACOSX_BUNDLE OFF)
endif()

# Installation
if (NOT BROTLI_BUNDLED_MODE)
  if (BROTLI_BUILD_TOOLS)
    install(
      TARGETS brotli
      RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
    )
  endif()

  install(
    TARGETS ${BROTLI_SHARED_LIBRARIES} ${BROTLI_STATIC_LIBRARIES}
    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
  )

  install(
    DIRECTORY ${BROTLI_INCLUDE_DIRS}/brotli
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
  )
endif()  # BROTLI_BUNDLED_MODE

# Tests

# Integration tests, those depend on `brotli` binary
if (NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
  # If we're targeting Windows but not running on Windows, we need Wine
  # to run the tests...
  if (WIN32 AND NOT CMAKE_HOST_WIN32)
    find_program(BROTLI_WRAPPER NAMES wine)

    if (NOT BROTLI_WRAPPER)
      message(STATUS "wine not found, disabling tests")
      set(BROTLI_DISABLE_TESTS TRUE)
    endif()
  endif()  # WIN32 emulation
  if (BROTLI_EMSCRIPTEN)
    find_program(BROTLI_WRAPPER NAMES node)
    if (NOT BROTLI_WRAPPER)
      message(STATUS "node not found, disabling tests")
      set(BROTLI_DISABLE_TESTS TRUE)
    endif()
  endif()  # BROTLI_EMSCRIPTEN
endif()  # BROTLI_DISABLE_TESTS

# NB: BROTLI_DISABLE_TESTS might have changed.
if (NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
  # If our compiler is a cross-compiler that we know about (arm/aarch64),
  # then we need to use qemu to execute the tests.
  if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabihf-.*$")
    message(STATUS "Detected arm-linux-gnueabihf cross-compilation")
    set(BROTLI_WRAPPER "qemu-arm")
    set(BROTLI_WRAPPER_LD_PREFIX "/usr/arm-linux-gnueabihf")
  endif()

  if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabi-.*$")
    message(STATUS "Detected arm-linux-gnueabi cross-compilation")
    set(BROTLI_WRAPPER "qemu-arm")
    set(BROTLI_WRAPPER_LD_PREFIX "/usr/arm-linux-gnueabi")
  endif()

  if ("${CMAKE_C_COMPILER}" MATCHES "^.*/aarch64-linux-gnu-.*$")
    message(STATUS "Detected aarch64-linux-gnu cross-compilation")
    set(BROTLI_WRAPPER "qemu-aarch64")
    set(BROTLI_WRAPPER_LD_PREFIX "/usr/aarch64-linux-gnu")
  endif()

  include(CTest)
  enable_testing()

  set(ROUNDTRIP_INPUTS
    tests/testdata/alice29.txt
    tests/testdata/asyoulik.txt
    tests/testdata/lcet10.txt
    tests/testdata/plrabn12.txt
    c/enc/encode.c
    c/common/dictionary.h
    c/dec/decode.c)

  foreach(INPUT ${ROUNDTRIP_INPUTS})
    get_filename_component(OUTPUT_NAME "${INPUT}" NAME)

    set(OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME}")
    set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}")

    if (EXISTS "${INPUT_FILE}")
      foreach(quality 1 6 9 11)
        add_test(NAME "${BROTLI_TEST_PREFIX}roundtrip/${INPUT}/${quality}"
          COMMAND "${CMAKE_COMMAND}"
            -DBROTLI_WRAPPER=${BROTLI_WRAPPER}
            -DBROTLI_WRAPPER_LD_PREFIX=${BROTLI_WRAPPER_LD_PREFIX}
            -DBROTLI_CLI=$<TARGET_FILE:brotli>
            -DQUALITY=${quality}
            -DINPUT=${INPUT_FILE}
            -DOUTPUT=${OUTPUT_FILE}.${quality}
            -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-roundtrip-test.cmake)
      endforeach()
    else()
      message(NOTICE "Test file ${INPUT} does not exist; OK on tarball builds; consider running scripts/download_testdata.sh before configuring.")
    endif()
  endforeach()

  file(GLOB_RECURSE
    COMPATIBILITY_INPUTS
    RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
    tests/testdata/*.compressed*)

  foreach(INPUT ${COMPATIBILITY_INPUTS})
    string(REGEX REPLACE "([a-zA-Z0-9\\.]+)\\.compressed(\\.[0-9]+)?$" "\\1" UNCOMPRESSED_INPUT "${INPUT}")
    if (EXISTS ${UNCOMPRESSED_INPUT})
      add_test(NAME "${BROTLI_TEST_PREFIX}compatibility/${INPUT}"
        COMMAND "${CMAKE_COMMAND}"
          -DBROTLI_WRAPPER=${BROTLI_WRAPPER}
          -DBROTLI_WRAPPER_LD_PREFIX=${BROTLI_WRAPPER_LD_PREFIX}
          -DBROTLI_CLI=$<TARGET_FILE:brotli>
          -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}
          -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-compatibility-test.cmake)
    endif()
  endforeach()
endif()  # BROTLI_DISABLE_TESTS

# Generate a pkg-config files

function(generate_pkg_config_path outvar path)
  string(LENGTH "${path}" path_length)

  set(path_args ${ARGV})
  list(REMOVE_AT path_args 0 1)
  list(LENGTH path_args path_args_remaining)

  set("${outvar}" "${path}")

  while(path_args_remaining GREATER 1)
    list(GET path_args 0 name)
    list(GET path_args 1 value)

    get_filename_component(value_full "${value}" ABSOLUTE)
    string(LENGTH "${value}" value_length)

    if (path_length EQUAL value_length AND path STREQUAL value)
      set("${outvar}" "\${${name}}")
      break()
    elseif (path_length GREATER value_length)
      # We might be in a subdirectory of the value, but we have to be
      # careful about a prefix matching but not being a subdirectory
      # (for example, /usr/lib64 is not a subdirectory of /usr/lib).
      # We'll do this by making sure the next character is a directory
      # separator.
      string(SUBSTRING "${path}" ${value_length} 1 sep)
      if (sep STREQUAL "/")
        string(SUBSTRING "${path}" 0 ${value_length} s)
        if (s STREQUAL value)
          string(SUBSTRING "${path}" "${value_length}" -1 suffix)
          set("${outvar}" "\${${name}}${suffix}")
          break()
        endif()
      endif()
    endif()

    list(REMOVE_AT path_args 0 1)
    list(LENGTH path_args path_args_remaining)
  endwhile()

  set("${outvar}" "${${outvar}}" PARENT_SCOPE)
endfunction(generate_pkg_config_path)

function(transform_pc_file INPUT_FILE OUTPUT_FILE VERSION)
  file(READ ${INPUT_FILE} TEXT)

  set(PREFIX "${CMAKE_INSTALL_PREFIX}")
  string(REGEX REPLACE "@prefix@" "${PREFIX}" TEXT ${TEXT})
  string(REGEX REPLACE "@exec_prefix@" "${PREFIX}" TEXT ${TEXT})
  string(REGEX REPLACE "@libm@" "${LIBM_DEP}" TEXT ${TEXT})

  generate_pkg_config_path(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}" prefix "${PREFIX}")
  string(REGEX REPLACE "@libdir@" "${LIBDIR}" TEXT ${TEXT})

  generate_pkg_config_path(INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}" prefix "${PREFIX}")
  string(REGEX REPLACE "@includedir@" "${INCLUDEDIR}" TEXT ${TEXT})

  string(REGEX REPLACE "@PACKAGE_VERSION@" "${VERSION}" TEXT ${TEXT})

  file(WRITE ${OUTPUT_FILE} ${TEXT})
endfunction()

transform_pc_file("scripts/libbrotlicommon.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc" "${BROTLI_VERSION}")

transform_pc_file("scripts/libbrotlidec.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlidec.pc" "${BROTLI_VERSION}")

transform_pc_file("scripts/libbrotlienc.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc" "${BROTLI_VERSION}")

if (NOT BROTLI_BUNDLED_MODE)
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlicommon.pc"
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlidec.pc"
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libbrotlienc.pc"
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()  # BROTLI_BUNDLED_MODE

if (BROTLI_BUILD_TOOLS)
  install(FILES "docs/brotli.1"
    DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
endif()

install(FILES docs/constants.h.3 docs/decode.h.3 docs/encode.h.3 docs/types.h.3
  DESTINATION "${CMAKE_INSTALL_MANDIR}/man3")

if (ENABLE_COVERAGE STREQUAL "yes")
  setup_target_for_coverage(coverage test coverage)
endif()
