379 lines
13 KiB
C++
379 lines
13 KiB
C++
// TestBuildAndLinkLibrary.cpp
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Includes
|
|
//------------------------------------------------------------------------------
|
|
#include "FBuildTest.h"
|
|
|
|
#include "Tools/FBuild/FBuildCore/FBuild.h"
|
|
|
|
#include "Core/FileIO/FileIO.h"
|
|
#include "Core/Process/Process.h"
|
|
#include "Core/Strings/AStackString.h"
|
|
|
|
// TestBuildAndLinkLibrary
|
|
//------------------------------------------------------------------------------
|
|
class TestDLL : public FBuildTest
|
|
{
|
|
private:
|
|
DECLARE_TESTS
|
|
|
|
void TestSingleDLL() const;
|
|
void TestSingleDLL_NoRebuild() const;
|
|
void TestTwoDLLs() const;
|
|
void TestTwoDLLs_NoRebuild() const;
|
|
void TestTwoDLLs_NoUnnecessaryRelink() const;
|
|
void TestDLLWithPCH() const;
|
|
void TestDLLWithPCH_NoRebuild() const;
|
|
void TestExeWithDLL() const;
|
|
void TestExeWithDLL_NoRebuild() const;
|
|
void TestValidExeWithDLL() const;
|
|
|
|
void TestLinkWithCopy() const;
|
|
|
|
const char * GetSingleDLLDBFileName() const { return "../../../../ftmp/Test/DLL/singledll.fdb"; }
|
|
const char * GetTwoDLLsDBFileName() const { return "../../../../ftmp/Test/DLL/twodlls.fdb"; }
|
|
const char * GetDLLWithPCHDBFileName() const { return "../../../../ftmp/Test/DLL/dllwithpch.fdb"; }
|
|
const char * GetExeWithDLLDBFileName() const { return "../../../../ftmp/Test/DLL/dllwithexe.fdb"; }
|
|
};
|
|
|
|
// Register Tests
|
|
//------------------------------------------------------------------------------
|
|
REGISTER_TESTS_BEGIN( TestDLL )
|
|
REGISTER_TEST( TestSingleDLL )
|
|
REGISTER_TEST( TestSingleDLL_NoRebuild )
|
|
REGISTER_TEST( TestTwoDLLs )
|
|
REGISTER_TEST( TestTwoDLLs_NoRebuild )
|
|
REGISTER_TEST( TestTwoDLLs_NoUnnecessaryRelink )
|
|
REGISTER_TEST( TestDLLWithPCH )
|
|
REGISTER_TEST( TestDLLWithPCH_NoRebuild )
|
|
REGISTER_TEST( TestExeWithDLL )
|
|
REGISTER_TEST( TestExeWithDLL_NoRebuild )
|
|
REGISTER_TEST( TestValidExeWithDLL )
|
|
REGISTER_TEST( TestLinkWithCopy )
|
|
REGISTER_TESTS_END
|
|
|
|
// TestSingleDLL
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestSingleDLL() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize() );
|
|
|
|
const AStackString<> dll( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dll.dll" );
|
|
|
|
// clean up anything left over from previous runs
|
|
EnsureFileDoesNotExist( dll );
|
|
|
|
TEST_ASSERT( fBuild.Build( dll ) );
|
|
TEST_ASSERT( fBuild.SaveDependencyGraph( GetSingleDLLDBFileName() ) );
|
|
|
|
// make sure all output files are as expecter
|
|
EnsureFileExists( dll );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 3, 1, Node::FILE_NODE ); // cpp
|
|
CheckStatsNode ( 1, 1, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 1, 1, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 1, 1, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 1, 1, Node::DLL_NODE );
|
|
CheckStatsTotal( 7, 5 );
|
|
}
|
|
|
|
// TestSingleDLL_NoRebuild
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestSingleDLL_NoRebuild() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetSingleDLLDBFileName() ) );
|
|
|
|
const AStackString<> dll( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dll.dll" );
|
|
|
|
TEST_ASSERT( fBuild.Build( dll ) );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 3, 3, Node::FILE_NODE ); // cpp + 2 .h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 1, 0, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 1, 0, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 1, 0, Node::DLL_NODE );
|
|
CheckStatsTotal( 7, 3 );
|
|
}
|
|
|
|
// TestTwoDLLs
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestTwoDLLs() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize() );
|
|
|
|
const AStackString<> dllA( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dlla.dll" );
|
|
const AStackString<> dllB( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dllb.dll" );
|
|
|
|
// clean up anything left over from previous runs
|
|
EnsureFileDoesNotExist( dllA );
|
|
EnsureFileDoesNotExist( dllB );
|
|
|
|
// build dllB which depends on dllA
|
|
TEST_ASSERT( fBuild.Build( dllB ) );
|
|
TEST_ASSERT( fBuild.SaveDependencyGraph( GetTwoDLLsDBFileName() ) );
|
|
|
|
// make sure all output files are as expecter
|
|
EnsureFileExists( dllA );
|
|
EnsureFileExists( dllB );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 5, 2, Node::FILE_NODE ); // 2 cpp files
|
|
CheckStatsNode ( 1, 1, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 2, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 2, 2, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 2, 2, Node::DLL_NODE );
|
|
CheckStatsTotal( 12, 9 );
|
|
}
|
|
|
|
// TestTwoDLLs_NoRebuild
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestTwoDLLs_NoRebuild() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetTwoDLLsDBFileName() ) );
|
|
|
|
// build again
|
|
const AStackString<> dllB( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dllb.dll" );
|
|
TEST_ASSERT( fBuild.Build( dllB ) );
|
|
|
|
// Check stats to be sure nothing was built
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 5, 5, Node::FILE_NODE ); // 2 cpp files + 3 .h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 0, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 2, 0, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 2, 0, Node::DLL_NODE );
|
|
CheckStatsTotal( 12, 5 );
|
|
}
|
|
|
|
// TestTwoDLLs_NoUnnecessaryRelink
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestTwoDLLs_NoUnnecessaryRelink() const
|
|
{
|
|
// 1) Force DLL A to build
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetTwoDLLsDBFileName() ) );
|
|
|
|
const AStackString<> dllA( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dlla.dll" );
|
|
|
|
// delete DLL A to have it relink (and regen the import lib)
|
|
EnsureFileDoesNotExist( dllA );
|
|
TEST_ASSERT( fBuild.Build( dllA ) );
|
|
TEST_ASSERT( fBuild.SaveDependencyGraph( GetTwoDLLsDBFileName() ) );
|
|
|
|
// Check stats to be sure one dll was built
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 3, 3, Node::FILE_NODE ); // 1 cpp files + 2 .h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 1, 0, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 1, 0, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 1, 1, Node::DLL_NODE );
|
|
CheckStatsTotal( 7, 4 );
|
|
}
|
|
|
|
// 2) Ensure DLL B does not relink
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetTwoDLLsDBFileName() ) );
|
|
|
|
// build again
|
|
const AStackString<> dllB( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dllb.dll" );
|
|
TEST_ASSERT( fBuild.Build( dllB ) );
|
|
|
|
// Check stats to be sure nothing was built
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 5, 5, Node::FILE_NODE ); // 2 cpp files + 3 .h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 0, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 2, 0, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 2, 0, Node::DLL_NODE );
|
|
CheckStatsTotal( 12, 5 );
|
|
}
|
|
}
|
|
|
|
// TestDLLWithPCH
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestDLLWithPCH() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize() );
|
|
|
|
const AStackString<> dllPCH( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dllpch.dll" );
|
|
|
|
// clean up anything left over from previous runs
|
|
EnsureFileDoesNotExist( dllPCH );
|
|
|
|
// build dllB which depends on dllA
|
|
TEST_ASSERT( fBuild.Build( dllPCH ) );
|
|
TEST_ASSERT( fBuild.SaveDependencyGraph( GetDLLWithPCHDBFileName() ) );
|
|
|
|
// make sure all output files are as expecter
|
|
EnsureFileExists( dllPCH );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 4, 2, Node::FILE_NODE ); // 1 cpp + 1 pch cpp
|
|
CheckStatsNode ( 1, 1, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 2, Node::OBJECT_NODE );// obj + pch obj
|
|
CheckStatsNode ( 1, 1, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 1, 1, Node::DLL_NODE );
|
|
CheckStatsTotal( 9, 7 );
|
|
}
|
|
|
|
// TestDLLWithPCH_NoRebuild
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestDLLWithPCH_NoRebuild() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetDLLWithPCHDBFileName() ) );
|
|
|
|
const AStackString<> dllPCH( "..\\..\\..\\..\\ftmp\\Test\\DLL\\dllpch.dll" );
|
|
|
|
// build dllB which depends on dllA
|
|
TEST_ASSERT( fBuild.Build( dllPCH ) );
|
|
|
|
// Check we build what was expected
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 4, 4, Node::FILE_NODE ); // 1 cpp + 1 pch cpp + 2 .h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 0, Node::OBJECT_NODE );// obj + pch obj
|
|
CheckStatsNode ( 1, 0, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 1, 0, Node::DLL_NODE );
|
|
CheckStatsTotal( 9, 4 );
|
|
}
|
|
|
|
// TestExeWithDLL
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestExeWithDLL() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize() );
|
|
|
|
const AStackString<> exe( "..\\..\\..\\..\\ftmp\\Test\\DLL\\exe.exe" );
|
|
|
|
// clean up anything left over from previous runs
|
|
EnsureFileDoesNotExist( exe );
|
|
|
|
// build executable with depends on DLLA
|
|
TEST_ASSERT( fBuild.Build( exe ) );
|
|
TEST_ASSERT( fBuild.SaveDependencyGraph( GetExeWithDLLDBFileName() ) );
|
|
|
|
// make sure all output files are as expecter
|
|
EnsureFileExists( exe );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 4, 2, Node::FILE_NODE ); // 2 cpp
|
|
CheckStatsNode ( 1, 1, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 2, Node::OBJECT_NODE ); // exe.obj + a.obj
|
|
CheckStatsNode ( 2, 2, Node::LIBRARY_NODE ); // exe lib + dll lib
|
|
CheckStatsNode ( 1, 1, Node::DLL_NODE );
|
|
CheckStatsNode ( 1, 1, Node::EXE_NODE );
|
|
CheckStatsTotal( 11, 9 );
|
|
}
|
|
|
|
// TestExeWithDLL_NoRebuild
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestExeWithDLL_NoRebuild() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize( GetExeWithDLLDBFileName() ) );
|
|
|
|
const AStackString<> exe( "..\\..\\..\\..\\ftmp\\Test\\DLL\\exe.exe" );
|
|
|
|
// build executable with depends on DLLA
|
|
TEST_ASSERT( fBuild.Build( exe ) );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 4, 4, Node::FILE_NODE ); // 2 cpp + a.h + precompiledheader.h
|
|
CheckStatsNode ( 1, 0, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 0, Node::OBJECT_NODE ); // exe.obj + a.obj
|
|
CheckStatsNode ( 2, 0, Node::LIBRARY_NODE ); // exe lib + dll lib
|
|
CheckStatsNode ( 1, 0, Node::DLL_NODE );
|
|
CheckStatsNode ( 1, 0, Node::EXE_NODE );
|
|
CheckStatsTotal( 11, 4 );
|
|
}
|
|
|
|
// TestValidExeWithDLL
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestValidExeWithDLL() const
|
|
{
|
|
const AStackString<> exe( "..\\..\\..\\..\\ftmp\\Test\\DLL\\exe.exe" );
|
|
|
|
Process p;
|
|
p.Spawn( exe.Get(), nullptr, nullptr, nullptr );
|
|
int ret = p.WaitForExit();
|
|
TEST_ASSERT( ret == 12345678 );
|
|
}
|
|
|
|
// TestLinkWithCopy
|
|
//------------------------------------------------------------------------------
|
|
void TestDLL::TestLinkWithCopy() const
|
|
{
|
|
FBuildOptions options;
|
|
options.m_ConfigFile = "Data/TestDLL/fbuild.bff";
|
|
options.m_ShowSummary = true; // required to generate stats for node count checks
|
|
options.m_ForceCleanBuild = true;
|
|
FBuild fBuild( options );
|
|
TEST_ASSERT( fBuild.Initialize() );
|
|
|
|
//const AStackString<> exe( "..\\..\\..\\..\\ftmp\\Test\\DLL\\Copy\\exe.exe" );
|
|
|
|
// build executable with depends on DLLA
|
|
TEST_ASSERT( fBuild.Build( AStackString<>( "DllBUsingCopy" ) ) );
|
|
|
|
// Check stats
|
|
// Seen, Built, Type
|
|
CheckStatsNode ( 2, 2, Node::COPY_NODE );
|
|
CheckStatsNode ( 5, 2, Node::FILE_NODE );
|
|
CheckStatsNode ( 1, 1, Node::COMPILER_NODE );
|
|
CheckStatsNode ( 2, 2, Node::OBJECT_NODE );
|
|
CheckStatsNode ( 2, 2, Node::LIBRARY_NODE );
|
|
CheckStatsNode ( 2, 2, Node::DLL_NODE );
|
|
CheckStatsNode ( 1, 0, Node::ALIAS_NODE );
|
|
CheckStatsTotal( 15, 11 );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|