# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: Copyright (C) 2026 Max A. Vilkki a.k.a. codise
#
# libarchive (BSD-2-Clause) from lib/libarchive (v3.8.9): reads HVSC's 7z releases
# (DESIGN §8.1). We call its 7z reader and nothing else, so the linker leaves out the
# other formats, the filters and everything that writes.
#
# Why not the LZMA SDK's small 7z reader: it doesn't open HVSC's archives (their SID
# block is LZMA followed by BCJ2 with BCJ2's side streams stored raw, tested on #85).
#
# Built by libarchive's own CMake, like SDL3: its configure checks (about 300, once per
# build directory) fill in config.h for the platform. Every optional library is off, so
# it finds nothing on the build machine; LZMA is ours (lib/cmake/xz, added first).
#
# Size (measured 2026-10-11 outside this build: static, -O2, dead-stripped, a program
# that enables only the 7z reader against an empty one): +169 KB on arm64, +155 KB on
# x86_64, liblzma included.
#
# Built on macOS (arm64 and x86_64) and Windows (MSVC 19.44, x64); Linux is unverified.

if(NOT TARGET liblzma)
    message(FATAL_ERROR "libarchive: add lib/cmake/xz first (it needs the liblzma target).")
endif()

set(BUILD_SHARED_LIBS OFF)
set(BUILD_TESTING OFF)
set(ENABLE_WERROR OFF)
set(ENABLE_TEST OFF)
set(ENABLE_INSTALL OFF)
# Its command-line tools.
set(ENABLE_TAR OFF)
set(ENABLE_CPIO OFF)
set(ENABLE_CAT OFF)
set(ENABLE_UNZIP OFF)
# Libraries it would otherwise look for on the build machine.
set(ENABLE_MBEDTLS OFF)
set(ENABLE_NETTLE OFF)
set(ENABLE_OPENSSL OFF)
set(ENABLE_LIBB2 OFF)
set(ENABLE_LZ4 OFF)
set(ENABLE_LZO OFF)
set(ENABLE_ZSTD OFF)
set(ENABLE_ZLIB OFF)
set(ENABLE_BZip2 OFF)
set(ENABLE_LIBXML2 OFF)
set(ENABLE_EXPAT OFF)
set(ENABLE_WIN32_XMLLITE OFF)
set(ENABLE_PCREPOSIX OFF)
set(ENABLE_PCRE2POSIX OFF)
set(ENABLE_LIBGCC OFF)
set(ENABLE_CNG OFF)
set(ENABLE_XATTR OFF)
set(ENABLE_ACL OFF)
set(ENABLE_ICONV OFF)
# No POSIX regex library either (only bsdtar's -s uses one). Left on AUTO, a platform
# whose C library has no regcomp (MSVC) goes on to look for PCRE, and 3.8.9 stops the
# configure there with "libgcc not found" because ENABLE_LIBGCC is off.
set(POSIX_REGEX_LIB "NONE" CACHE STRING "" FORCE)

# LZMA from our liblzma target. libarchive asks CMake's FindLibLZMA, which looks for a
# built library file and tests it for functions; ours isn't built at configure time and
# has no encoders. So the answers are given here: the module then takes the target's
# name as the library and reads the version from the headers. Without this libarchive
# builds with LZMA off, and the 7z reader fails with "LZMA codec is unsupported".
set(ENABLE_LZMA ON)
set(LIBLZMA_INCLUDE_DIR "${FLIPSID_LIB_DIR}/xz/src/liblzma/api" CACHE PATH "" FORCE)
set(LIBLZMA_LIBRARY liblzma CACHE STRING "" FORCE)
set(LIBLZMA_HAS_AUTO_DECODER TRUE CACHE INTERNAL "")
set(LIBLZMA_HAS_EASY_ENCODER TRUE CACHE INTERNAL "")
set(LIBLZMA_HAS_LZMA_PRESET TRUE CACHE INTERNAL "")
# Its own probes of the library (it can't link at configure time): no multi-threaded
# encoder, and on Windows LZMA_API_STATIC comes from the liblzma target.
set(HAVE_LZMA_STREAM_ENCODER_MT 0 CACHE INTERNAL "")
set(WITHOUT_LZMA_API_STATIC 1 CACHE INTERNAL "")
set(LZMA_API_STATIC 0 CACHE INTERNAL "")

add_subdirectory("${FLIPSID_LIB_DIR}/libarchive" "${CMAKE_CURRENT_BINARY_DIR}/libarchive"
    SYSTEM EXCLUDE_FROM_ALL)

add_library(ext::archive ALIAS archive_static)

# Its headers need this to leave the DLL import marks off.
target_compile_definitions(archive_static INTERFACE LIBARCHIVE_STATIC)

# Windows: archive_util.c calls BCryptGenRandom for temporary file names whatever
# ENABLE_CNG says, and libarchive only links bcrypt with CNG on. Through the property:
# libarchive uses target_link_libraries()'s plain signature, which rules out the keyword one.
if(WIN32)
    set_property(TARGET archive_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES bcrypt)
endif()

# Third-party warnings aren't ours to fix.
if(MSVC)
    target_compile_options(archive_static PRIVATE /w)
else()
    target_compile_options(archive_static PRIVATE -w)
endif()

flipsid_configure_third_party(archive_static)
