# Boost Filesystem Library Build Jamfile

# (C) Copyright Beman Dawes 2002-2006
# (C) Copyright Andrey Semashev 2020, 2021
# Distributed under the Boost Software License, Version 1.0.
# See www.boost.org/LICENSE_1_0.txt

# See library home page at http://www.boost.org/libs/filesystem

import project ;
import configure ;

lib bcrypt ;
lib advapi32 ;
lib coredll ;
explicit bcrypt advapi32 coredll ;

# The rule checks if a config macro is defined in the command line or build properties
rule has-config-flag ( flag : properties * )
{
    if ( "<define>$(flag)" in $(properties) || "<define>$(flag)=1" in $(properties) )
    {
        return 1 ;
    }
    else
    {
        return ;
    }
}

# The rule checks we're building for Windows and selects crypto API to be used
rule select-windows-crypto-api ( properties * )
{
    local result ;

    if <target-os>windows in $(properties) || <target-os>cygwin in $(properties)
    {
        if ! [ has-config-flag BOOST_FILESYSTEM_DISABLE_BCRYPT : $(properties) ] &&
            [ configure.builds ../config//has_bcrypt : $(properties) : "has BCrypt API" ]
        {
            result = <define>BOOST_FILESYSTEM_HAS_BCRYPT <library>bcrypt ;
        }
        else
        {
            result = <define>BOOST_FILESYSTEM_HAS_WINCRYPT ;
            if [ configure.builds ../config//is_windows_ce : $(properties) : "is Windows CE" ]
            {
                result += <library>coredll ;
            }
            else
            {
                result += <library>advapi32 ;
            }
        }
    }

    #ECHO Result: $(result) ;
    return $(result) ;
}

# The rule checks if statx syscall is supported
rule check-statx ( properties * )
{
    local result ;

    if ! [ has-config-flag BOOST_FILESYSTEM_DISABLE_STATX : $(properties) ]
    {
        if [ configure.builds ../config//has_statx : $(properties) : "has statx" ]
        {
            result = <define>BOOST_FILESYSTEM_HAS_STATX ;
        }
        else if [ configure.builds ../config//has_statx_syscall : $(properties) : "has statx syscall" ]
        {
            result = <define>BOOST_FILESYSTEM_HAS_STATX_SYSCALL ;
        }
    }

    #ECHO Result: $(result) ;
    return $(result) ;
}

# The rule checks if std::atomic_ref is supported
rule check-cxx20-atomic-ref ( properties * )
{
    local result ;

    if ! <threading>single in $(properties)
    {
        if ! [ configure.builds ../config//has_cxx20_atomic_ref : $(properties) : "has std::atomic_ref" ]
        {
            result = <define>BOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF ;
            result += <library>/boost/atomic//boost_atomic ;
        }
    }
    else
    {
        result = <define>BOOST_FILESYSTEM_SINGLE_THREADED ;
    }

    #ECHO Result: $(result) ;
    return $(result) ;
}

# The rule checks if the linker supports requiring no unresolved symbols
rule check-linkflag-no-undefined ( properties * )
{
    local result ;

    if <link>shared in $(properties)
    {
        if [ configure.builds ../config//has_linkflag_no_undefined : $(properties) : "has -Wl,--no-undefined" ]
        {
            result = <linkflags>"-Wl,--no-undefined" ;
        }
        else if [ configure.builds ../config//has_linkflag_undefined_error : $(properties) : "has -Wl,-undefined,error" ]
        {
            result = <linkflags>"-Wl,-undefined,error" ;
        }
    }

    #ECHO Result: $(result) ;
    return $(result) ;
}

project boost/filesystem
    : requirements
      <host-os>hpux,<toolset>gcc:<define>_INCLUDE_STDC__SOURCE_199901
      [ check-target-builds ../config//has_attribute_init_priority "has init_priority attribute" : <define>BOOST_FILESYSTEM_HAS_INIT_PRIORITY ]
      [ check-target-builds ../config//has_stat_st_mtim "has stat::st_blksize" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BLKSIZE ]
      [ check-target-builds ../config//has_stat_st_mtim "has stat::st_mtim" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_MTIM ]
      [ check-target-builds ../config//has_stat_st_mtimensec "has stat::st_mtimensec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_MTIMENSEC ]
      [ check-target-builds ../config//has_stat_st_mtimespec "has stat::st_mtimespec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_MTIMESPEC ]
      [ check-target-builds ../config//has_stat_st_birthtim "has stat::st_birthtim" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIM ]
      [ check-target-builds ../config//has_stat_st_birthtimensec "has stat::st_birthtimensec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMENSEC ]
      [ check-target-builds ../config//has_stat_st_birthtimespec "has stat::st_birthtimespec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMESPEC ]
      [ check-target-builds ../config//has_fdopendir_nofollow "has fdopendir(O_NOFOLLOW)" : <define>BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW ]
      [ check-target-builds ../config//has_dirent_d_type "has dirent::d_type" : <define>BOOST_FILESYSTEM_HAS_DIRENT_D_TYPE ]
      [ check-target-builds ../config//has_posix_at_apis "has POSIX *at APIs" : <define>BOOST_FILESYSTEM_HAS_POSIX_AT_APIS ]
      <conditional>@check-statx
      <conditional>@select-windows-crypto-api
      <conditional>@check-cxx20-atomic-ref
      # Make sure no undefined references are left from the library
      <conditional>@check-linkflag-no-undefined
      <target-os>windows:<define>_SCL_SECURE_NO_WARNINGS
      <target-os>windows:<define>_SCL_SECURE_NO_DEPRECATE
      <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS
      <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE
      <target-os>windows:<define>BOOST_USE_WINDOWS_H
      <target-os>windows:<define>WIN32_LEAN_AND_MEAN
      <target-os>windows:<define>NOMINMAX
      <target-os>cygwin:<define>BOOST_USE_WINDOWS_H
      <target-os>cygwin:<define>WIN32_LEAN_AND_MEAN
      <target-os>cygwin:<define>NOMINMAX

      # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329
      # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105651
      <toolset>gcc-12:<cxxflags>"-Wno-restrict"

    : source-location ../src
    : usage-requirements # pass these requirement to dependents (i.e. users)
      <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1
      <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1
    ;

SOURCES =
    codecvt_error_category
    exception
    directory
    operations
    path
    path_traits
    portability
    unique_path
    utf8_codecvt_facet
    ;

rule select-platform-specific-sources ( properties * )
{
    local result ;

    if <target-os>windows in $(properties) || <target-os>cygwin in $(properties)
    {
        result += <source>windows_file_codecvt.cpp ;
    }

    return $(result) ;
}

lib boost_filesystem
    : $(SOURCES).cpp
    : <define>BOOST_FILESYSTEM_SOURCE
      <conditional>@select-platform-specific-sources
      <include>../src
      <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1
      <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1
    :
    :
    ;

boost-install boost_filesystem ;
