
import testing ;
import feature : feature ;

import os ;
local BOOST_ROOT            = [ os.environ BOOST_ROOT    ] ;
local BOOST_BUILD_PATH      = [ os.environ BOOST_BUILD_PATH    ] ;
local SOCKET_NAME_1         = [ os.environ SOCKET_NAME_1    ] ;
local SOCKET_NAME_2         = [ os.environ SOCKET_NAME_2    ] ;
local OPENSSL_ROOT          = [ os.environ OPENSSL_ROOT    ] ;
local OPENSSL_NAME_1        = [ os.environ OPENSSL_NAME_1    ] ;
local OPENSSL_NAME_2        = [ os.environ OPENSSL_NAME_2    ] ;
local ZLIB_ROOT             = [ os.environ ZLIB_ROOT    ] ;
local ZLIB_NAME             = [ os.environ ZLIB_NAME    ] ;
local BUILD_CONFIG_TEMP_DIR = [ os.environ BUILD_CONFIG_TEMP_DIR    ] ;

ECHO "BOOST_ROOT =" $(BOOST_ROOT) ;
ECHO "BOOST_BUILD_PATH =" $(BOOST_BUILD_PATH) ;
ECHO "OS =" [ os.name ] ;

LIBS = ;
DEFINES = ;


if [ os.name ] = NT
{  
    lib ws2_32          : : <name>ws2_32 ;
    lib mswsock         : : <name>mswsock ;
    lib advapi32        : : <name>advapi32 ;
    lib user32          : : <name>user32 ;
    
    LIBS += ws2_32 ;
    LIBS += mswsock ;
    LIBS += advapi32 ;
    LIBS += user32 ;
    
    #Defining _WIN32_WINNT, with or without a value, causes problems on a number of compilers...
    #DEFINES += _WIN32_WINNT=0x0500 ;
    #DEFINES += _WINSOCKAPI_ ;
    DEFINES += WIN32_LEAN_AND_MEAN ;
}   

if [ os.name ] = SOLARIS
{
    lib nsl             : : <name>nsl ;
    lib socket          : : <name>socket ;
    
    LIBS += nsl ;
    LIBS += socket ;
}

feature with-spc : on off : composite propagated symmetric link-incompatible ;
feature.compose <with-spc>off : ;
feature.compose <with-spc>on : <define>BOOST_SP_ENABLE_DEBUG_HOOKS ;

feature with-asio : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-asio>off : ;
feature.compose <with-asio>on : <define>RCF_USE_BOOST_ASIO ;

feature with-bthread : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-bthread>off : ;
feature.compose <with-bthread>on : <define>RCF_USE_BOOST_THREADS ;

feature with-sf : on off : composite propagated symmetric link-incompatible ;
feature.compose <with-sf>off : ;
feature.compose <with-sf>on : <define>RCF_USE_SF_SERIALIZATION ;

feature with-bser : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-bser>off : ;
feature.compose <with-bser>on : <define>RCF_USE_BOOST_SERIALIZATION ;

feature with-zlib : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-zlib>off : ;
feature.compose <with-zlib>on : <define>RCF_USE_ZLIB <include>$(ZLIB_ROOT) ;

feature with-ssl : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-ssl>off : ;
feature.compose <with-ssl>on : <define>RCF_USE_OPENSSL <include>$(OPENSSL_ROOT) ;

feature with-all : off on : composite propagated symmetric link-incompatible ;
feature.compose <with-all>off : ;
feature.compose <with-all>on : <with-spc>on <with-asio>on <with-sf>on <with-bser>on <with-zlib>on <with-ssl>on ;

project RCF
:
    requirements
    <include>../../include
    <include>$(BOOST_ROOT)
    <define>BOOST_ALL_NO_LIB
    <define>TEMP_DIR_UNQUOTED=$(BUILD_CONFIG_TEMP_DIR)
    <define>UTIL_OUTPUTDEBUGSTRING_TO_STDOUT
    <warnings>off
    <define>$(DEFINES)
    <library>$(LIBS)    
    <address-model>64:<cxxflags>/bigobj # TODO: only for msvc
;

use-project /boost          : $(BOOST_ROOT) ;
alias BoostThread           : /boost/thread//boost_thread : <link>static ;
alias BoostSerialization    : /boost/serialization//boost_serialization : <link>static ;
alias BoostSystem           : /boost/system//boost_system : <link>static ;
lib Zlib                    : : <name>$(ZLIB_NAME) ;
lib OpenSsl1                : : <name>$(OPENSSL_NAME_1) ;
lib OpenSsl2                : : <name>$(OPENSSL_NAME_2) ;

obj SpCollector
:
    $(BOOST_ROOT)/libs/smart_ptr/src/sp_collector.cpp
;

obj RcfMtSrc 
:
    ../../src/RCF/RCF.cpp
:
    <define>RCF_MULTI_THREADED
    <threading>multi
: :
    <define>RCF_MULTI_THREADED
    <threading>multi
;

obj RcfMtSrcDll
:
    ../../src/RCF/RCF.cpp
:
    <define>RCF_MULTI_THREADED
    <define>RCF_BUILD_DLL
    <threading>multi
: :
    <define>RCF_MULTI_THREADED
    <threading>multi
;

obj RcfMtUnicodeSrc 
:
    ../../src/RCF/RCF.cpp
:
    <define>RCF_MULTI_THREADED
    <define>UNICODE
    <define>_UNICODE
    <threading>multi
: :
    <define>RCF_MULTI_THREADED
    <define>UNICODE
    <define>_UNICODE
    <threading>multi
;

obj RcfStSrc
:
    ../../src/RCF/RCF.cpp
:
    <define>RCF_SINGLE_THREADED
: :
    <define>RCF_SINGLE_THREADED
;


lib RcfMt 
: 
    RcfMtSrc
: 
    <link>static 
    <with-spc>on:<library>SpCollector
    <with-bthread>on:<library>BoostThread
    <with-bser>on:<library>BoostSerialization 
    <with-asio>on:<library>BoostSystem 
    <with-zlib>on:<library>Zlib
    <with-ssl>on:<library>OpenSsl1
    <with-ssl>on:<library>OpenSsl2
;

lib RcfMtDll 
: 
    RcfMtSrcDll
:     
    <link>shared 
    <with-spc>on:<library>SpCollector
    <with-bthread>on:<library>BoostThread
    <with-bser>on:<library>BoostSerialization 
    <with-asio>on:<library>BoostSystem 
    <with-zlib>on:<library>Zlib
    <with-ssl>on:<library>OpenSsl1
    <with-ssl>on:<library>OpenSsl2
    <define>RCF_NO_AUTO_INIT_DEINIT
: :
    <define>RCF_NO_AUTO_INIT_DEINIT
    <with-bser>on:<library>BoostSerialization 
    <with-asio>on:<library>BoostSystem
    <with-bthread>on:<library>BoostThread
    <with-spc>on:<library>SpCollector
;

lib RcfSt 
: 
    RcfStSrc
: 
    <link>static 
    <with-spc>on:<library>SpCollector
    <with-bthread>on:<library>BoostThread
    <with-bser>on:<library>BoostSerialization 
    <with-asio>on:<library>BoostSystem 
    <with-zlib>on:<library>Zlib
    <with-ssl>on:<library>OpenSsl1
    <with-ssl>on:<library>OpenSsl2
;

lib RcfMtUnicode 
: 
    RcfMtUnicodeSrc
: 
    <link>static 
    <with-spc>on:<library>SpCollector
    <with-bthread>on:<library>BoostThread
    <with-bser>on:<library>BoostSerialization 
    <with-asio>on:<library>BoostSystem 
    <with-zlib>on:<library>Zlib
    <with-ssl>on:<library>OpenSsl1
    <with-ssl>on:<library>OpenSsl2
;

test-suite Test
: 
    # Typical multithreaded builds
    [ run ../Test_Binding.cpp                       RcfMt ]
    [ run ../Test_ClientConnectionDrop.cpp          RcfMt ]
    [ run ../Test_ClientInfo.cpp                    RcfMt ]
    [ run ../Test_ClientProgress.cpp                RcfMt ]
    [ run ../Test_ClientTimeout.cpp                 RcfMt ]
    [ run ../Test_CycleServer_Mt.cpp                RcfMt ]
    [ run ../Test_Endpoint.cpp                      RcfMt ]
    [ run ../Test_Endurance.cpp                     RcfMt ]
    [ run ../Test_ErrorReporting.cpp                RcfMt ]
    [ run ../Test_FilterPerformance.cpp             RcfMt ]
    [ run ../Test_Filters.cpp                       RcfMt ]
    [ run ../Test_General.cpp                       RcfMt ]
    [ run ../Test_InitDeinit.cpp                    RcfMt ]
    [ run ../Test_IpRestriction.cpp                 RcfMt ]
    [ run ../Test_Minimal.cpp                       RcfMt ]
    [ run ../Test_MultipleClient.cpp                RcfMt ]
    [ run ../Test_Multicast.cpp                     RcfMt ]
    [ run ../Test_MultiThreadedServer.cpp           RcfMt ]
    [ run ../Test_MultiTransportServer.cpp          RcfMt ]
    [ run ../Test_Notification.cpp                  RcfMt : -timelimit 600 ]
    [ run ../Test_ObjectFactoryService.cpp          RcfMt ]
    [ run ../Test_OpenSslFilter.cpp                 RcfMt ]
    [ run ../Test_Performance.cpp                   RcfMt ]
    [ run ../Test_Polymorphic.cpp                   RcfMt ]
    [ run ../Test_Serialization.cpp                 RcfMt ]
    [ run ../Test_ServerTransportConcurrency.cpp    RcfMt ]
    #[ run ../Test_SspiFilter.cpp                    RcfMt ]
    [ run ../Test_StubSerialization.cpp             RcfMt ]
    [ run ../Test_ThreadManager.cpp                 RcfMt ]
    [ run ../Test_Versioning.cpp                    RcfMt ]
    [ run ../Test_Win32NamedPipes.cpp               RcfMt ]
    [ run ../Test_ZeroAllocation.cpp                RcfMt ]
  
    # Singlethreaded builds
    [ run ../Test_CycleServer_St.cpp                RcfSt ]
    [ run ../Test_SingleThreadedServer.cpp          RcfSt ]
  
    # Multithreaded unicode build
    #[ run ../Test_SspiFilterUnicode.cpp             RcfMtUnicode ]
    [ run ../Test_Win32NamedPipesUnicode.cpp        RcfMtUnicode ]

    # Multithreaded DLL build
    [ run ../Test_Minimal_Dll.cpp                   RcfMtDll ]
    
    # Need to define RCF_USE_BOOST_XML_SERIALIZATION for this one.
    # We are maxed out on features already (build directory strucuture 
    # exceeding MAX_PATH), so for now, don't build this.
    #[ run ../Test_XmlSerialization.cpp              RcfMt ]
; 

obj Test_WarningFreeCompile
:
    ../Test_WarningFreeCompile.cpp
:
    <toolset>msvc:<cxxflags>/WX            # Compile with warnings as errors
    <threading>multi
;

# SSPI tests need to be run separately

exe Test_SspiFilter
:
    ../Test_SspiFilter.cpp RcfMt
:
    <with-bthread>on:<library>BoostThread
;

exe Test_SspiFilterUnicode
:
    ../Test_SspiFilterUnicode.cpp RcfMtUnicode
:
    <with-bthread>on:<library>BoostThread
;

alias Targets_Common
: 
    Test_Binding
    Test_ClientConnectionDrop
    Test_ClientInfo    
    Test_ClientProgress
    Test_ClientTimeout
    Test_CycleServer_Mt
    Test_Endpoint
    Test_Endurance
    Test_ErrorReporting
    Test_FilterPerformance
    Test_Filters
    Test_General
    Test_InitDeinit
    Test_IpRestriction
    Test_Minimal
    Test_MultipleClient
    Test_Multicast
    Test_MultiThreadedServer
    Test_MultiTransportServer
    Test_Notification
    Test_ObjectFactoryService
    Test_OpenSslFilter
    Test_Performance
    Test_Polymorphic
    Test_Serialization
    Test_ServerTransportConcurrency
    Test_StubSerialization
    Test_ThreadManager
    Test_Versioning    
;

alias Targets_Win32
:
    Test_Win32NamedPipes
    Test_ZeroAllocation
    Test_CycleServer_St
    Test_SingleThreadedServer
    Test_Win32NamedPipesUnicode
    Test_WarningFreeCompile    
;

alias Targets_Dll
:
    Test_Minimal_Dll
;

alias Targets_Sspi
:
    Test_SspiFilter
    Test_SspiFilterUnicode
;

alias Targets_All
:
    Targets_Common
    Targets_Win32
    Targets_Dll
    Targets_Sspi
;
