import intf_libs  = libboost-assert%lib{boost_assert}
import intf_libs += libboost-config%lib{boost_config}
import intf_libs += libboost-container-hash%lib{boost_container_hash}
import intf_libs += libboost-detail%lib{boost_detail}
import intf_libs += libboost-io%lib{boost_io}
import intf_libs += libboost-iterator%lib{boost_iterator}
import intf_libs += libboost-smart-ptr%lib{boost_smart_ptr}
import intf_libs += libboost-system%lib{boost_system}
import intf_libs += libboost-type-traits%lib{boost_type_traits}
import impl_libs  = libboost-atomic%lib{boost_atomic}
import impl_libs += libboost-core%lib{boost_core}
import impl_libs += libboost-predef%lib{boost_predef}
import impl_libs += libboost-scope%lib{boost_scope}
import impl_libs += libboost-winapi%lib{boost_winapi}

intf_libs = $cxx.deduplicate_export_libs($intf_libs)

# Public headers.
#
pub = [dir_path] ../include/boost/

include $pub

pub_hdrs = $($pub/ pub_hdrs)

lib{boost_filesystem}: $pub/{$pub_hdrs}

# BEGIN MANUAL CUSTOMIZATION
#

tclass  = $cxx.target.class
tsys    = $cxx.target.system

# Private headers and sources as well as dependencies.
#
lib{boost_filesystem}: {hxx ixx txx cxx}{** -windows_file_codecvt} \
                       $impl_libs $intf_libs

lib{boost_filesystem}: {hxx cxx}{windows_file_codecvt}: \
  include = ($tclass == 'windows')

#
# END MANUAL CUSTOMIZATION

# Build options.
#
out_pfx_inc = [dir_path] $out_root/include/
src_pfx_inc = [dir_path] $src_root/include/
out_pfx_src = [dir_path] $out_root/src/
src_pfx_src = [dir_path] $src_root/src/

cxx.poptions =+ "-I$out_pfx_src" "-I$src_pfx_src" \
                "-I$out_pfx_inc" "-I$src_pfx_inc"

{hbmi  obj }{*}: cxx.poptions += -DBOOST_FILESYSTEM_SOURCE
{hbmia obja}{*}: cxx.poptions += -DBOOST_FILESYSTEM_STATIC_LINK
{hbmis objs}{*}: cxx.poptions += -DBOOST_FILESYSTEM_DYN_LINK

# BEGIN MANUAL CUSTOMIZATION
#

# Unless BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF is defined, Boost.Filesystem
# uses std::atomic_ref which is currently not well supported by standard
# libraries.
#
# @@ TODO Check whether this is still required whenever upstream is
#    upgraded. See https://en.cppreference.com/w/cpp/compiler_support/20 for
#    the latest support status.
#
# @@ TODO Boost.Filesystem only depends on Boost.Atomic as a fallback in case
#    std::atomic_ref does not exist so break that dependency in `override`
#    when this definition is finally removed.
#
cxx.poptions += -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF

# Enable use of `__attribute__((init_priority(N)))`.
#
if ($cxx.class == 'gcc' && $tclass != 'macos')
  cxx.poptions += -DBOOST_FILESYSTEM_HAS_INIT_PRIORITY

# Define various BOOST_FILESYSTEM_* macros as appropriate for each OS and use
# the appropriate compiler option to link to the bcrypt library on Windows.
# The BOOST_FILESYSTEM_HAS_STAT_* macros pertain to the mtime-, birthtime-,
# and blksize- related fields of `struct stat`. Although these stat macros are
# only used in operations.cpp, the upstream build defines it globally so copy
# them.
#
# BOOST_FILESYSTEM_HAS_POSIX_AT_APIS: Define if the system supports functions
# like openat, unlinkat, renameat, etc. (see
# config/has_posix_at_apis.cpp). Note that although the BSDs and macOS have
# these functions they do not support the AT_NO_AUTOMOUNT flag.
#
# BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE: Define on systems that support the
# d_type field of struct dirent and the associated DT_* macros (DT_REG,
# DT_DIR, DT_UNKNOWN, etc.). Currently supported on Linux, BSD, and macOS.
#
switch $tclass, $tsys
{
  # The statx(2) syscall was added in Linux 4.11 in 2017 and statx() was added
  # to glibc 2.28 in 2018.
  #
  case 'linux'
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_DIRENT_D_TYPE        \
                    -DBOOST_FILESYSTEM_HAS_FALLOCATE            \
                    -DBOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW   \
                    -DBOOST_FILESYSTEM_HAS_POSIX_AT_APIS        \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE      \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_MTIM
                    # -DBOOST_FILESYSTEM_HAS_STATX_SYSCALL \
                    # -DBOOST_FILESYSTEM_HAS_STATX

  case 'bsd', 'freebsd'
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_DIRENT_D_TYPE        \
                    -DBOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW   \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIM     \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE      \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_MTIM

  case 'bsd', 'openbsd'
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_DIRENT_D_TYPE        \
                    -DBOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW   \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE      \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_MTIM

  case 'bsd', 'netbsd'
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_DIRENT_D_TYPE                \
                    -DBOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW           \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMENSEC        \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE              \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_MTIMENSEC

  # The `st_birthtimespec` field is only present if inode_t is 64 bits in size
  # (_DARWIN_FEATURE_64_BIT_INODE is defined). Given that 64-bit (by-default;
  # read about _DARWIN_USE_64_BIT_INODE in stat(2)) inodes were introduced in
  # 2009 with Mac OSX 10.6 Snow Leopard, assume `st_birthtimespec` is present.
  #
  case 'macos'
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_DIRENT_D_TYPE                \
                    -DBOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW           \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMESPEC        \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE              \
                    -DBOOST_FILESYSTEM_HAS_STAT_ST_MTIMESPEC

  case 'windows', 'mingw32'
  {
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_BCRYPT \
                    -DBOOST_USE_WINDOWS_H         \
                    -DWIN32_LEAN_AND_MEAN         \
                    -D_WIN32_WINNT=0x0A00         \
                    -DNOMINMAX
    cxx.libs     += -lbcrypt
  }
  case 'windows'
  {
    cxx.poptions += -DBOOST_FILESYSTEM_HAS_BCRYPT \
                    -DBOOST_USE_WINDOWS_H         \
                    -DWIN32_LEAN_AND_MEAN         \
                    -D_WIN32_WINNT=0x0A00         \
                    -DNOMINMAX
    cxx.libs     += bcrypt.lib
  }
}

#
# END MANUAL CUSTOMIZATION

# Export options.
#
lib{boost_filesystem}:
{
  cxx.export.poptions = "-I$out_pfx_inc" "-I$src_pfx_inc" \
                         -DBOOST_FILESYSTEM_NO_LIB
  cxx.export.libs = $intf_libs
}

liba{boost_filesystem}: cxx.export.poptions += -DBOOST_FILESYSTEM_STATIC_LINK
libs{boost_filesystem}: cxx.export.poptions += -DBOOST_FILESYSTEM_DYN_LINK

# For pre-releases use the complete version to make sure they cannot be used
# in place of another pre-release or the final version. See the version module
# for details on the version.* variable values.
#
if $version.pre_release
  lib{boost_filesystem}: bin.lib.version = "-$version.project_id"
else
  lib{boost_filesystem}: bin.lib.version = "-$version.major.$version.minor"

# Don't install private headers.
#
{hxx ixx txx}{*}: install = false
