Move tools in their own folder instead of Bigfoot Sources
This commit is contained in:
@@ -0,0 +1 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/SasquatchBaker)
|
||||
@@ -0,0 +1,11 @@
|
||||
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
project(${PackageName}Benchmarks)
|
||||
|
||||
bigfoot_create_package_benchmarks(
|
||||
"Tools")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
$<LINK_LIBRARY:WHOLE_ARCHIVE,AssetsForBenchmarking>)
|
||||
|
||||
bigfoot_create_bigfile("Benchmarks/Tools")
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// AUTO-GENERATED DO NOT TOUCH
|
||||
|
||||
/*********************************************************************
|
||||
* \file BigFileInfo.generated.hpp
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_SASQUATCHBAKERBENCHMARKS_BIGFILEINFO_GENERATED_HPP
|
||||
#define BIGFOOT_SASQUATCHBAKERBENCHMARKS_BIGFILEINFO_GENERATED_HPP
|
||||
|
||||
#include <EASTL/string_view.h>
|
||||
|
||||
#if defined BIGFOOT_TOOLMODE
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
/*
|
||||
* BigFile location
|
||||
*/
|
||||
constexpr eastl::string_view BIGFILE_SASQUATCHBAKERBENCHMARKS_LOCATION {"./SasquatchBakerBenchmarks.db"};
|
||||
} // namespace Bigfoot
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/*********************************************************************
|
||||
* \file SasquatchBaker.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <SasquatchBaker/SasquatchBaker.hpp>
|
||||
|
||||
#include <Engine/BigFile/BigFile.hpp>
|
||||
#include <Engine/Sasquatch/Sasquatch.hpp>
|
||||
|
||||
#include <System/File/File.hpp>
|
||||
|
||||
#include <AssetsForBenchmarking/Asset/BenchmarkAsset.hpp>
|
||||
|
||||
#include <SasquatchBakerBenchmarks/BigFileInfo_generated.hpp>
|
||||
|
||||
#include <EASTL/vector.h>
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
class SasquatchBakerFixture: public benchmark::Fixture
|
||||
{
|
||||
protected:
|
||||
static constexpr std::uint32_t ASSET_COUNT = 20'000;
|
||||
static constexpr std::size_t ASSET_PAYLOAD_SIZE = 256;
|
||||
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
m_bigFile.Clear();
|
||||
m_outputFile.Delete();
|
||||
|
||||
eastl::vector<UUID> uuids;
|
||||
eastl::vector<eastl::vector<std::byte>> flatbuffers;
|
||||
eastl::vector<eastl::vector<UUID>> hardReferences;
|
||||
uuids.reserve(ASSET_COUNT);
|
||||
flatbuffers.reserve(ASSET_COUNT);
|
||||
hardReferences.reserve(ASSET_COUNT);
|
||||
|
||||
for (std::uint32_t i = 0; i < ASSET_COUNT; ++i)
|
||||
{
|
||||
BenchmarkAsset asset;
|
||||
asset.SetName(asset.GetHeader().uuid.ToString());
|
||||
asset.GetAsset().payload.assign(ASSET_PAYLOAD_SIZE, std::uint8_t {0xAB});
|
||||
|
||||
const eastl::vector<std::byte> flatbuffer = asset.Pack();
|
||||
flatbuffers.push_back(flatbuffer);
|
||||
hardReferences.push_back(asset.GetHardReferences(flatbuffer));
|
||||
uuids.push_back(asset.GetHeader().uuid);
|
||||
}
|
||||
|
||||
m_bigFile.SaveAssetFlatbuffers(uuids, flatbuffers, hardReferences);
|
||||
}
|
||||
|
||||
void TearDown(benchmark::State&) override
|
||||
{
|
||||
m_outputFile.Delete();
|
||||
}
|
||||
|
||||
static constexpr eastl::string_view SASQUATCH_SASQUATCHBAKERBENCHMARKS_LOCATION {
|
||||
"./SasquatchBakerBenchmarks.sasquatch"};
|
||||
BigFile m_bigFile {File {BIGFILE_SASQUATCHBAKERBENCHMARKS_LOCATION}};
|
||||
File m_outputFile {SASQUATCH_SASQUATCHBAKERBENCHMARKS_LOCATION};
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
BENCHMARK_DEFINE_F(SasquatchBakerFixture, Bake)(benchmark::State& state)
|
||||
{
|
||||
std::int64_t bytesProcessed = 0;
|
||||
|
||||
for (auto _: state)
|
||||
{
|
||||
Bake(m_bigFile, m_outputFile);
|
||||
bytesProcessed += static_cast<std::int64_t>(m_outputFile.GetSize());
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations() * ASSET_COUNT);
|
||||
state.SetBytesProcessed(bytesProcessed);
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(SasquatchBakerFixture, Bake)->Name("SasquatchBaker/Bake")->Unit(benchmark::kMillisecond);
|
||||
} // namespace Bigfoot
|
||||
@@ -0,0 +1,2 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/SasquatchBaker)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Executables/SasquatchBaker)
|
||||
@@ -0,0 +1,33 @@
|
||||
project(SasquatchBakerCLI)
|
||||
|
||||
add_executable(${PROJECT_NAME})
|
||||
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
BigfootCompileAndLinkFlags
|
||||
bfg::lyra
|
||||
$<LINK_LIBRARY:WHOLE_ARCHIVE,SasquatchBaker>)
|
||||
|
||||
file(GLOB_RECURSE _SOURCES
|
||||
CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE _HEADERS
|
||||
CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
|
||||
)
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${_SOURCES}
|
||||
${_HEADERS}
|
||||
)
|
||||
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${_SOURCES} ${_HEADERS})
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bigfoot/Tools/Executables)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME SasquatchBaker)
|
||||
@@ -0,0 +1,50 @@
|
||||
/*********************************************************************
|
||||
* \file main.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <System/File/File.hpp>
|
||||
|
||||
#include <Utils/Log/LogMacros.hpp>
|
||||
#include <Utils/TargetMacros.h>
|
||||
|
||||
#include <SasquatchBaker/SasquatchBaker.hpp>
|
||||
|
||||
#include <EASTL/string_view.h>
|
||||
#include <lyra/lyra.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
BIGFOOT_NOT_OPTIMIZED_ONLY(::Bigfoot::Singleton<::Bigfoot::Log>::Lifetime logLifetime);
|
||||
|
||||
bool showHelp = false;
|
||||
std::string bigFilePath;
|
||||
std::string outputPath;
|
||||
|
||||
const auto& cli = lyra::help(showHelp) |
|
||||
lyra::opt(bigFilePath, "bigfile")["-b"]["--bigfile"]("The BigFile to bake (must exist)")
|
||||
.required() |
|
||||
lyra::opt(outputPath, "output")["-o"]["--output"]("The Sasquatch file to write").required();
|
||||
|
||||
const lyra::parse_result result = cli.parse({argc, argv});
|
||||
if (!result)
|
||||
{
|
||||
std::cerr << result.message() << "\n\n" << cli << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (showHelp)
|
||||
{
|
||||
std::cout << cli << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Bigfoot::BigFile bigFile {Bigfoot::File {eastl::string_view {bigFilePath.c_str()}}};
|
||||
Bigfoot::Bake(bigFile, Bigfoot::File {eastl::string_view {outputPath.c_str()}});
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
project(${PackageName})
|
||||
|
||||
set(PublicDependencies)
|
||||
set(PrivateDependencies)
|
||||
set(BigfootPublicDependencies
|
||||
Engine)
|
||||
set(BigfootPrivateDependencies
|
||||
Utils)
|
||||
|
||||
bigfoot_create_package_lib(
|
||||
"${PublicDependencies}"
|
||||
"${PrivateDependencies}"
|
||||
"${BigfootPublicDependencies}"
|
||||
"${BigfootPrivateDependencies}"
|
||||
"Tools")
|
||||
|
||||
bigfoot_create_logger()
|
||||
@@ -0,0 +1,24 @@
|
||||
/*********************************************************************
|
||||
* \file SasquatchBaker.hpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKER_HPP
|
||||
#define BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKER_HPP
|
||||
#include <Engine/BigFile/BigFile.hpp>
|
||||
|
||||
#include <System/File/File.hpp>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
/**
|
||||
* Bake every Asset of a BigFile into a Sasquatch file
|
||||
*
|
||||
* \param p_bigFile The BigFile to bake
|
||||
* \param p_outputFile The file to write to
|
||||
*/
|
||||
void Bake(const BigFile& p_bigFile, const File& p_outputFile);
|
||||
} // namespace Bigfoot
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/*********************************************************************
|
||||
* \file SasquatchBakerAssertHandler.hpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKERASSERTHANDLER_HPP
|
||||
#define BIGFOOT_TOOLS_SASQUATCHBAKER_SASQUATCHBAKERASSERTHANDLER_HPP
|
||||
#include <Utils/Assert/AssertHandler.hpp>
|
||||
|
||||
#include <SasquatchBaker/SasquatchBakerLogger_generated.hpp>
|
||||
|
||||
#ifdef BIGFOOT_NOT_OPTIMIZED
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
using SasquatchBakerAssertHandler = AssertHandler<SASQUATCHBAKER_LOGGER>;
|
||||
} // namespace Bigfoot
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// AUTO-GENERATED DO NOT TOUCH
|
||||
|
||||
/*********************************************************************
|
||||
* \file SasquatchBakerLogger.generated.hpp
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_SASQUATCHBAKERLOGGER_GENERATED_HPP
|
||||
#define BIGFOOT_SASQUATCHBAKERLOGGER_GENERATED_HPP
|
||||
#include <Utils/Log/LogMacros.hpp>
|
||||
|
||||
#if defined BIGFOOT_NOT_OPTIMIZED
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
/*
|
||||
* Logger
|
||||
*/
|
||||
inline Log::LoggerInfo SASQUATCHBAKER_LOGGER { .m_name = "SASQUATCHBAKER_LOGGER", .m_level = Flat::LogLevel::Trace};
|
||||
} // namespace Bigfoot
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/*********************************************************************
|
||||
* \file SasquatchBaker.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <SasquatchBaker/SasquatchBaker.hpp>
|
||||
|
||||
#include <Engine/Sasquatch/Sasquatch.hpp>
|
||||
|
||||
#include <SasquatchBaker/SasquatchBakerAssertHandler.hpp>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
void Bake(const BigFile& p_bigFile, const File& p_outputFile)
|
||||
{
|
||||
std::uint64_t assetCount = 0;
|
||||
{
|
||||
BigFile::Request countRequest {p_bigFile, "SELECT COUNT(*) FROM Asset;"};
|
||||
[[maybe_unused]]
|
||||
const bool hasCount = countRequest.Step();
|
||||
ASSERT(SasquatchBakerAssertHandler, hasCount, "Failed to count the assets of the BigFile");
|
||||
assetCount = countRequest.Get(0);
|
||||
}
|
||||
|
||||
std::uint64_t totalFlatbufferBytes = 0;
|
||||
{
|
||||
BigFile::Request sizeRequest {p_bigFile, "SELECT COALESCE(SUM(LENGTH(Asset)), 0) FROM Asset;"};
|
||||
[[maybe_unused]]
|
||||
const bool hasSize = sizeRequest.Step();
|
||||
ASSERT(SasquatchBakerAssertHandler, hasSize, "Failed to sum the asset sizes of the BigFile");
|
||||
totalFlatbufferBytes = sizeRequest.Get(0);
|
||||
}
|
||||
|
||||
std::uint64_t totalHardReferencesBytes = 0;
|
||||
{
|
||||
BigFile::Request sizeRequest {p_bigFile,
|
||||
"SELECT COALESCE(SUM(LENGTH(HardReference)), 0) FROM AssetHardReference;"};
|
||||
[[maybe_unused]]
|
||||
const bool hasSize = sizeRequest.Step();
|
||||
ASSERT(SasquatchBakerAssertHandler, hasSize, "Failed to sum the hardreferences sizes of the BigFile");
|
||||
totalHardReferencesBytes = sizeRequest.Get(0);
|
||||
}
|
||||
|
||||
SasquatchWriter writer {p_outputFile, assetCount, totalFlatbufferBytes, totalHardReferencesBytes};
|
||||
|
||||
BigFile::Request request {p_bigFile, "SELECT UUID FROM Asset;"};
|
||||
while (request.Step())
|
||||
{
|
||||
const std::span<const std::byte> rawUUID = request.Get(0);
|
||||
|
||||
ASSERT(SasquatchBakerAssertHandler,
|
||||
rawUUID.size() == UUID::UUID_BYTE_SIZE,
|
||||
"Unexpected UUID blob size in BigFile (got {} / expected {})",
|
||||
rawUUID.size(),
|
||||
UUID::UUID_BYTE_SIZE);
|
||||
|
||||
const UUID uuid {std::span<const std::byte, UUID::UUID_BYTE_SIZE> {rawUUID.data(), UUID::UUID_BYTE_SIZE}};
|
||||
const eastl::vector<std::byte> flatbuffer = p_bigFile.GetAssetFlatbuffer(uuid);
|
||||
const eastl::vector<UUID> hardReferences = p_bigFile.GetAssetHardReferences(uuid);
|
||||
|
||||
writer.WriteAsset(uuid, flatbuffer, hardReferences);
|
||||
}
|
||||
}
|
||||
} // namespace Bigfoot
|
||||
@@ -0,0 +1 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/SasquatchBaker)
|
||||
@@ -0,0 +1,13 @@
|
||||
get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
project(${PackageName}Tests)
|
||||
|
||||
set(Dependencies)
|
||||
set(BigfootDependencies
|
||||
AssetsForTesting)
|
||||
|
||||
bigfoot_create_package_tests(
|
||||
"${Dependencies}"
|
||||
"${BigfootDependencies}"
|
||||
"Tools")
|
||||
|
||||
bigfoot_create_bigfile("Tests/Tools")
|
||||
@@ -0,0 +1,22 @@
|
||||
// AUTO-GENERATED DO NOT TOUCH
|
||||
|
||||
/*********************************************************************
|
||||
* \file BigFileInfo.generated.hpp
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BIGFOOT_SASQUATCHBAKERTESTS_BIGFILEINFO_GENERATED_HPP
|
||||
#define BIGFOOT_SASQUATCHBAKERTESTS_BIGFILEINFO_GENERATED_HPP
|
||||
|
||||
#include <EASTL/string_view.h>
|
||||
|
||||
#if defined BIGFOOT_TOOLMODE
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
/*
|
||||
* BigFile location
|
||||
*/
|
||||
constexpr eastl::string_view BIGFILE_SASQUATCHBAKERTESTS_LOCATION {"./SasquatchBakerTests.db"};
|
||||
} // namespace Bigfoot
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
/*********************************************************************
|
||||
* \file SasquatchBaker.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <SasquatchBaker/SasquatchBaker.hpp>
|
||||
|
||||
#include <Engine/Sasquatch/Sasquatch.hpp>
|
||||
|
||||
#include <System/File/File.hpp>
|
||||
|
||||
#include <AssetsForTesting/Asset/AssetA.hpp>
|
||||
#include <AssetsForTesting/Asset/AssetB.hpp>
|
||||
|
||||
#include <SasquatchBakerTests/BigFileInfo_generated.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Bigfoot
|
||||
{
|
||||
class SasquatchBakerFixture: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
m_bigFile.Clear();
|
||||
m_outputFile.Delete();
|
||||
}
|
||||
|
||||
/*
|
||||
* Packs an asset and saves it to the BigFile
|
||||
*
|
||||
* \param p_asset The asset to save
|
||||
* \return The UUID the asset was saved under
|
||||
*/
|
||||
template<class ASSET>
|
||||
UUID SaveAsset(ASSET& p_asset)
|
||||
{
|
||||
const eastl::vector<std::byte> flatbuffer = p_asset.Pack();
|
||||
m_bigFile.SaveAssetFlatbuffer(p_asset.GetHeader().uuid, flatbuffer, p_asset.GetHardReferences(flatbuffer));
|
||||
return p_asset.GetHeader().uuid;
|
||||
}
|
||||
|
||||
static constexpr eastl::string_view SASQUATCH_SASQUATCHBAKERTESTS_LOCATION {"./SasquatchBakerTests.sasquatch"};
|
||||
BigFile m_bigFile {File {BIGFILE_SASQUATCHBAKERTESTS_LOCATION}};
|
||||
File m_outputFile {SASQUATCH_SASQUATCHBAKERTESTS_LOCATION};
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SasquatchBakerFixture, Bake_ShouldWriteAnEmptyFileWhenTheBigFileIsEmpty)
|
||||
{
|
||||
Bake(m_bigFile, m_outputFile);
|
||||
Sasquatch sasquatch {m_outputFile};
|
||||
|
||||
const eastl::vector<std::byte> data = m_outputFile.Read(0, m_outputFile.GetSize());
|
||||
ASSERT_EQ(m_outputFile.GetSize(), sizeof(SasquatchHeader));
|
||||
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_magic, SasquatchHeader::MAGIC);
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_version, SasquatchHeader::VERSION);
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_assetCount, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(SasquatchBakerFixture, Bake_ShouldWriteEveryAssetOfTheBigFile)
|
||||
{
|
||||
AssetA assetA;
|
||||
assetA.SetName("hello");
|
||||
SaveAsset(assetA);
|
||||
|
||||
AssetB assetB;
|
||||
assetB.SetName("world");
|
||||
assetB.GetAsset().ref_a = HardReference<AssetA> {assetA.GetHeader().uuid};
|
||||
SaveAsset(assetB);
|
||||
|
||||
Bake(m_bigFile, m_outputFile);
|
||||
Sasquatch sasquatch {m_outputFile};
|
||||
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_magic, SasquatchHeader::MAGIC);
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_version, SasquatchHeader::VERSION);
|
||||
EXPECT_EQ(sasquatch.GetHeader().m_assetCount, 2);
|
||||
|
||||
EXPECT_FALSE(sasquatch.GetAssetFlatbuffer(assetA.GetHeader().uuid).empty());
|
||||
EXPECT_FALSE(sasquatch.GetAssetFlatbuffer(assetB.GetHeader().uuid).empty());
|
||||
|
||||
EXPECT_FALSE(sasquatch.GetAssetHardReferences(assetB.GetHeader().uuid).empty());
|
||||
}
|
||||
} // namespace Bigfoot
|
||||
@@ -0,0 +1,21 @@
|
||||
/*********************************************************************
|
||||
* \file main.cpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date August 2026
|
||||
*********************************************************************/
|
||||
#include <Utils/Log/LogMacros.hpp>
|
||||
#include <Utils/TargetMacros.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||
|
||||
BIGFOOT_NOT_OPTIMIZED_ONLY(::Bigfoot::Singleton<::Bigfoot::Log>::Lifetime m_lifetime);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user