build: VoxelForge compiles in Unreal 5.7 on Linux (L65); Linux-only Unreal trace timing fields
Linux UE builds failed on the Core wrapper module: the Linux-only PerModuleInline.gen.cpp saw Standalone/Compat
shadow headers instead of the engine's, and WITH_EDITOR was redefined under -Werror. Compat headers now forward
to the engine headers with include_next for generated Linux module TUs (canonical Core TUs opt into the Compat
definitions via CoreNamespacePreamble.h); CoreMinimal.h undefines WITH_EDITOR first. VoxelForgeCore.Build.cs
enables that forwarding and AVX2 on Linux only; VoxelForge.Build.cs disables Unity on Linux only. Portability:
std::int64_t consistently in VoxelContentManager.cpp; grouped &&/|| in VoxelRedefinedDensityField.cpp. Linux-only
trace fields split Core generateTile / mesh copy / RMC stream build. Standalone Clang and GCC whole-view hashes
are unchanged vs 3202193. The Unreal spawn trace is blocked by the owner's new assets (SW route sweep fails).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
e157847509
commit
47148e0a0d
47 files changed
+389
-43
No files matched your search
@@ -241,10 +241,10 @@ static std::vector<VoxelForgeCore::WorldAssemblyFeatureQueryV1> VF_ContentFeatur
|
||||
{
|
||||
using namespace VoxelForgeCore;
|
||||
constexpr double Q = WorldAssemblySubvoxelsPerVoxel;
|
||||
const std::array<int64,3> Min{static_cast<int64>(std::floor(MinX*Q)),
|
||||
static_cast<int64>(std::floor(MinY*Q)),static_cast<int64>(std::floor(MinZ*Q))};
|
||||
const std::array<int64,3> Max{static_cast<int64>(std::ceil(MaxX*Q)),
|
||||
static_cast<int64>(std::ceil(MaxY*Q)),static_cast<int64>(std::ceil(MaxZ*Q))};
|
||||
const std::array<std::int64_t,3> Min{static_cast<std::int64_t>(std::floor(MinX*Q)),
|
||||
static_cast<std::int64_t>(std::floor(MinY*Q)),static_cast<std::int64_t>(std::floor(MinZ*Q))};
|
||||
const std::array<std::int64_t,3> Max{static_cast<std::int64_t>(std::ceil(MaxX*Q)),
|
||||
static_cast<std::int64_t>(std::ceil(MaxY*Q)),static_cast<std::int64_t>(std::ceil(MaxZ*Q))};
|
||||
std::vector<WorldAssemblyFeatureQueryV1> Queries;
|
||||
if (Surface)
|
||||
if (const auto* Plan = Surface->FindPlan(StrateIndex))
|
||||
|
||||
@@ -2590,8 +2590,8 @@ static float EvaluateInternal(const UVoxelGenerator& Generator,
|
||||
{
|
||||
EnsurePlan(Generator);
|
||||
}
|
||||
const bool bChunkResolved = Context != nullptr && Context->bChunkResolved
|
||||
|| ParameterizedContext != nullptr && ParameterizedContext->bChunkResolved;
|
||||
const bool bChunkResolved = (Context != nullptr && Context->bChunkResolved)
|
||||
|| (ParameterizedContext != nullptr && ParameterizedContext->bChunkResolved);
|
||||
const FIntVector Chunk = Context != nullptr && Context->bChunkResolved
|
||||
? Context->Chunk
|
||||
: ParameterizedContext != nullptr && ParameterizedContext->bChunkResolved
|
||||
|
||||
@@ -297,7 +297,11 @@ void RecordTile(const FTileSample& Sample)
|
||||
"\"submitted_t_s\":%s,\"worker_start_t_s\":%s,\"worker_end_t_s\":%s,\"worker_thread_id\":%u,"
|
||||
"\"verdict\":%d,\"proof\":%d,\"empty\":%d,\"vertices\":%d,\"triangles\":%d,\"geometry_bytes\":%llu,"
|
||||
"\"request_to_apply_s\":%s,\"queue_wait_s\":%s,\"worker_queue_s\":%s,\"result_queue_s\":%s,\"worker_task_s\":%s,"
|
||||
"\"generation_s\":%s,\"classify_s\":%s,\"mesh_s\":%s,\"stream_s\":%s,\"apply_s\":%s"),
|
||||
"\"generation_s\":%s,"
|
||||
#if PLATFORM_LINUX
|
||||
"\"core_generate_s\":%s,\"mesh_copy_s\":%s,\"rmc_stream_build_s\":%s,"
|
||||
#endif
|
||||
"\"classify_s\":%s,\"mesh_s\":%s,\"stream_s\":%s,\"apply_s\":%s"),
|
||||
Sample.TileX, Sample.TileY, Sample.TileZ,
|
||||
Sample.Level, Sample.WorkPriority,
|
||||
static_cast<unsigned long long>(Sample.RequestOrdinal),
|
||||
@@ -312,8 +316,12 @@ void RecordTile(const FTileSample& Sample)
|
||||
static_cast<unsigned long long>(Sample.GeometryBytes),
|
||||
*Number(Sample.RequestToApplySeconds), *Number(Sample.QueueWaitSeconds),
|
||||
*Number(Sample.WorkerQueueSeconds), *Number(Sample.ResultQueueSeconds),
|
||||
*Number(Sample.WorkerTaskSeconds),
|
||||
*Number(Sample.GenerationSeconds), *Number(Sample.ClassifySeconds),
|
||||
*Number(Sample.WorkerTaskSeconds), *Number(Sample.GenerationSeconds),
|
||||
#if PLATFORM_LINUX
|
||||
*Number(Sample.CoreGenerateSeconds), *Number(Sample.MeshCopySeconds),
|
||||
*Number(Sample.StreamBuildSeconds),
|
||||
#endif
|
||||
*Number(Sample.ClassifySeconds),
|
||||
*Number(Sample.MeshSeconds), *Number(Sample.StreamSeconds), *Number(Sample.ApplySeconds)));
|
||||
}
|
||||
|
||||
|
||||
@@ -9960,6 +9960,9 @@ bool AVoxelWorld::ApplyTileResult(FChunkResult& Result)
|
||||
Sample.QueueWaitSeconds = WorkerQueueSeconds + ResultQueueSeconds;
|
||||
Sample.WorkerTaskSeconds = WorkerTaskSeconds;
|
||||
Sample.GenerationSeconds = GenerationSeconds;
|
||||
Sample.CoreGenerateSeconds = Result.CoreGenerateSeconds;
|
||||
Sample.MeshCopySeconds = Result.MeshCopySeconds;
|
||||
Sample.StreamBuildSeconds = Result.StreamBuildSeconds;
|
||||
Sample.ClassifySeconds = Result.ClassifySeconds;
|
||||
Sample.MeshSeconds = Result.MeshSeconds;
|
||||
Sample.StreamSeconds = Result.StreamSeconds;
|
||||
@@ -13235,6 +13238,11 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
||||
Result.WorkPriority = WorkPriority;
|
||||
Result.GenerationStartCycles = FPlatformTime::Cycles64();
|
||||
Result.GenerationOrdinal = NextStreamingGenerationOrdinal.fetch_add(1, std::memory_order_relaxed) + 1;
|
||||
#if PLATFORM_LINUX
|
||||
const bool bMeasureWorkerPhases = VoxelForgeStartupTrace::IsActive();
|
||||
#else
|
||||
constexpr bool bMeasureWorkerPhases = false;
|
||||
#endif
|
||||
|
||||
auto EnqueueObsolete = [&]()
|
||||
{
|
||||
@@ -13290,7 +13298,14 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
||||
FReadScopeLock Lock(State->WorldLock);
|
||||
if (State->World)
|
||||
{
|
||||
const uint64 CoreGenerateStartCycles = bMeasureWorkerPhases
|
||||
? FPlatformTime::Cycles64() : 0;
|
||||
CoreMesh = State->World->generateTile(CoreKey, Options, CoreError);
|
||||
if (CoreGenerateStartCycles != 0)
|
||||
{
|
||||
Result.CoreGenerateSeconds = FPlatformTime::ToSeconds64(
|
||||
FPlatformTime::Cycles64() - CoreGenerateStartCycles);
|
||||
}
|
||||
}
|
||||
}
|
||||
Result.GenerationEndCycles = FPlatformTime::Cycles64();
|
||||
@@ -13332,6 +13347,8 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
||||
|
||||
if (!Result.bEmpty)
|
||||
{
|
||||
const uint64 MeshCopyStartCycles = bMeasureWorkerPhases
|
||||
? FPlatformTime::Cycles64() : 0;
|
||||
FVoxelMeshData MeshData;
|
||||
MeshData.Vertices.Reserve(Result.NumVertices);
|
||||
MeshData.Normals.Reserve(Result.NumVertices);
|
||||
@@ -13352,8 +13369,20 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
||||
MeshData.NumSurfaceVertices = static_cast<int32>(CoreMesh->groups.surfaceVertexCount);
|
||||
MeshData.NumCeilingTriangles = Result.NumCeilingTriangles;
|
||||
MeshData.NumSkirtTriangles = Result.NumSkirtTriangles;
|
||||
if (MeshCopyStartCycles != 0)
|
||||
{
|
||||
Result.MeshCopySeconds = FPlatformTime::ToSeconds64(
|
||||
FPlatformTime::Cycles64() - MeshCopyStartCycles);
|
||||
}
|
||||
const uint64 StreamBuildStartCycles = bMeasureWorkerPhases
|
||||
? FPlatformTime::Cycles64() : 0;
|
||||
Result.Streams = MakeShared<RealtimeMesh::FRealtimeMeshStreamSet>();
|
||||
BuildTileStreamSet(*Result.Streams, MeshData);
|
||||
if (StreamBuildStartCycles != 0)
|
||||
{
|
||||
Result.StreamBuildSeconds = FPlatformTime::ToSeconds64(
|
||||
FPlatformTime::Cycles64() - StreamBuildStartCycles);
|
||||
}
|
||||
}
|
||||
Result.GenerationEndCycles = FPlatformTime::Cycles64();
|
||||
if (Cancellation->bObsolete.load(std::memory_order_acquire)
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace VoxelForgeStartupTrace
|
||||
double ResultQueueSeconds = 0.0;
|
||||
double WorkerTaskSeconds = 0.0;
|
||||
double GenerationSeconds = 0.0;
|
||||
double CoreGenerateSeconds = 0.0;
|
||||
double MeshCopySeconds = 0.0;
|
||||
double StreamBuildSeconds = 0.0;
|
||||
double ClassifySeconds = 0.0;
|
||||
double MeshSeconds = 0.0;
|
||||
double StreamSeconds = 0.0;
|
||||
|
||||
@@ -145,6 +145,10 @@ struct FChunkResult
|
||||
// per-tile profiling remains opt-in.
|
||||
uint64 GenerationStartCycles = 0;
|
||||
uint64 GenerationEndCycles = 0;
|
||||
// Optional phase timings recorded only while the bounded startup trace is active.
|
||||
double CoreGenerateSeconds = 0.0;
|
||||
double MeshCopySeconds = 0.0;
|
||||
double StreamBuildSeconds = 0.0;
|
||||
uint64 ApplyStartCycles = 0;
|
||||
EVoxelTileWorkPriority WorkPriority = EVoxelTileWorkPriority::Horizon;
|
||||
// Ordinals make admitted order and actual worker start order auditable across MPSC results.
|
||||
|
||||
@@ -7,6 +7,13 @@ public class VoxelForge : ModuleRules
|
||||
{
|
||||
public VoxelForge(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
if (Target.Platform == UnrealTargetPlatform.Linux)
|
||||
{
|
||||
// Test translation units have independent anonymous-namespace helpers that collide in
|
||||
// Linux Unity batches. Keep Linux compilation one source per TU; Windows remains unchanged.
|
||||
bUseUnity = false;
|
||||
}
|
||||
|
||||
// PCH = Precompiled Headers - speeds up compilation
|
||||
// UseExplicitOrSharedPCHs is the modern recommended setting
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
@@ -39,6 +39,13 @@ public class VoxelForgeCore : ModuleRules
|
||||
|
||||
PublicDependencyModuleNames.Add("Core");
|
||||
CppStandard = CppStandardVersion.Cpp20;
|
||||
if (Target.Platform == UnrealTargetPlatform.Linux)
|
||||
{
|
||||
// The compatibility include directory contains Unreal-shaped placeholders. On Linux,
|
||||
// let generated module TUs pass those names through to UE while Core shims opt in.
|
||||
PrivateDefinitions.Add("VFCORE_COMPAT_FORWARD_HEADERS=1");
|
||||
MinCpuArchX64 = MinimumCpuArchitectureX64.AVX2;
|
||||
}
|
||||
// Canonical Standalone code predates UE's stricter warning defaults; keep this narrow to legal local shadowing.
|
||||
CppCompileWarningSettings.ShadowVariableWarningLevel = WarningLevel.Off;
|
||||
FPSemantics = FPSemanticsMode.Precise;
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <AssetRegistry/AssetData.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <AssetRegistry/AssetRegistryModule.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Async/ParallelFor.h>
|
||||
#endif
|
||||
@@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <CoreMinimal.h>
|
||||
#else
|
||||
|
||||
// Deliberately small UE-style surface used by the copied VoxelForge CPU sources.
|
||||
// This is a value/container compatibility layer; it does not start or link Unreal.
|
||||
#include <algorithm>
|
||||
@@ -45,6 +50,9 @@
|
||||
#define GENERATED_UCLASS_BODY()
|
||||
#define VOXELFORGE_API
|
||||
#define FORCEINLINE inline
|
||||
#ifdef WITH_EDITOR
|
||||
#undef WITH_EDITOR
|
||||
#endif
|
||||
#define WITH_EDITOR 0
|
||||
#define TRACE_CPUPROFILER_EVENT_SCOPE(...)
|
||||
#define PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS
|
||||
@@ -705,3 +713,4 @@ struct FParse
|
||||
struct FCrc { static uint32 MemCrc32(const void*Data,int32 Length,uint32 Crc=0){const auto*P=static_cast<const uint8*>(Data);uint32 V=~Crc;for(int32 I=0;I<Length;++I){V^=P[I];for(int J=0;J<8;++J)V=(V>>1)^(0xEDB88320u&static_cast<uint32>(-static_cast<int32>(V&1)));}return ~V;} static uint32 StrCrc32(const char*S,uint32 Crc=0){return MemCrc32(S,static_cast<int32>(std::strlen(S)),Crc);} };
|
||||
template<class T> using TAtomic = std::atomic<T>;
|
||||
class FThreadSafeCounter { public:int32 Increment(){return ++Value;}int32 Decrement(){return --Value;}int32 GetValue()const{return Value.load();}void Reset(){Value.store(0);}private:std::atomic<int32>Value{0};};
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Dom/JsonObject.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Dom/JsonValue.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Engine/DataAsset.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <GameplayTagContainer.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/CriticalSection.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/Event.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/FileManager.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/IConsoleManager.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/PlatformProcess.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <HAL/PlatformTime.h>
|
||||
#endif
|
||||
@@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Json.h>
|
||||
#else
|
||||
|
||||
#include <charconv>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
@@ -162,3 +167,4 @@ namespace VFJson
|
||||
return Parser(std::move(Text)).Parse(Out, Error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Math/RandomStream.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/CommandLine.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/Crc.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/FileHelper.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/Parse.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/Paths.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/ScopeLock.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/ScopeRWLock.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Misc/SecureHash.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Modules/ModuleManager.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <ProfilingDebugging/CpuProfilerTrace.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Serialization/CustomVersion.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Serialization/JsonSerializer.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Serialization/JsonWriter.h>
|
||||
#endif
|
||||
@@ -1,4 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Stats/Stats.h>
|
||||
#else
|
||||
#define STATCAT_Advanced 0
|
||||
#define DECLARE_STATS_GROUP(Name,Group,Category) constexpr int32 Group=0
|
||||
#define DECLARE_DWORD_COUNTER_STAT_EXTERN(Name,Stat,Group,Api) constexpr int32 Stat=0
|
||||
@@ -8,3 +13,4 @@
|
||||
#define SET_DWORD_STAT(Stat,Value) ((void)0)
|
||||
#define SCOPE_CYCLE_COUNTER(Stat) ((void)0)
|
||||
#define QUICK_SCOPE_CYCLE_COUNTER(Stat) ((void)0)
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Templates/SubclassOf.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <Templates/UniquePtr.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <UObject/EnumProperty.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <UObject/FieldIterator.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <UObject/Object.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <UObject/UObjectGlobals.h>
|
||||
#endif
|
||||
@@ -1 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#if defined(VFCORE_COMPAT_FORWARD_HEADERS) && !defined(VFCORE_USE_COMPAT) \
|
||||
&& (defined(__clang__) || defined(__GNUC__))
|
||||
#include_next <UObject/UnrealType.h>
|
||||
#endif
|
||||
@@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// Core implementation TUs opt into the standalone Unreal-shaped compatibility headers. UE's
|
||||
// Linux-generated module TUs leave this unset so those same header names forward to the engine.
|
||||
#define VFCORE_USE_COMPAT 1
|
||||
|
||||
// Every standard or platform header used by the copied implementation must be included before
|
||||
// its wrapper opens vfcore::detail. This prevents system declarations from being nested in the
|
||||
// private namespace when the implementation includes its Unreal-shaped compatibility headers.
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Linux65 report
|
||||
|
||||
Date: 2026-10-26. No commit, push, or stash was made. The pre-existing untracked `Linux18/exports/` was left alone.
|
||||
|
||||
## Linux Unreal build
|
||||
|
||||
UE 5.7.4 / bundled Clang 20 builds pass with zero errors. The clean HEAD build completed 78 actions in 93.54 s; L14 (`a176d07`) completed 157 actions in 170.69 s. Final incremental builds after the Linux-only trace timing guards also pass. Logs are `Saved/Linux/l65/head-build5.log`, `l14-build1.log`, `head-build-final.log`, and `l14-build-final.log`.
|
||||
|
||||
Builds used CPUs 0–11, a 6 GiB RSS limit, at most 8 actions, AVX2, and `-NoUBA`. UBA stalled before starting compiler actions. Three existing RMC deprecation warnings remain: two `RemoveSectionGroup` calls and one `CreateSectionGroup` call in `VoxelWorld.cpp`.
|
||||
|
||||
Fixes:
|
||||
|
||||
- The Compat wrappers now forward to UE headers with `include_next` for generated Linux module TUs. `CoreNamespacePreamble.h` opts canonical Core TUs into the Compat definitions. `CoreMinimal.h` undefines `WITH_EDITOR` before defining the standalone value.
|
||||
- `VoxelForgeCore.Build.cs` enables that forwarding and AVX2 only on Linux. `VoxelForge.Build.cs` disables Unity only on Linux to avoid duplicate anonymous test helpers.
|
||||
- `VoxelContentManager.cpp` uses `std::int64_t` consistently; `VoxelRedefinedDensityField.cpp` groups the mixed `&&`/`||` expression.
|
||||
- Linux-only trace fields measure Core `generateTile`, mesh copy, and RMC stream-set construction. The `PLATFORM_LINUX` guards keep Windows worker behavior and trace JSON unchanged.
|
||||
|
||||
### Files changed for the owner's Windows build review
|
||||
|
||||
All `Source/` changes:
|
||||
|
||||
- `Source/VoxelForge/Private/VoxelContentManager.cpp`
|
||||
- `Source/VoxelForge/Private/VoxelRedefinedDensityField.cpp`
|
||||
- `Source/VoxelForge/Private/VoxelStartupTrace.cpp`
|
||||
- `Source/VoxelForge/Private/VoxelWorld.cpp`
|
||||
- `Source/VoxelForge/Public/VoxelStartupTrace.h`
|
||||
- `Source/VoxelForge/Public/VoxelWorld.h`
|
||||
- `Source/VoxelForge/VoxelForge.Build.cs`
|
||||
- `Source/VoxelForgeCore/VoxelForgeCore.Build.cs`
|
||||
|
||||
All changed `Standalone/Compat` headers:
|
||||
|
||||
- `AssetRegistry/AssetData.h`, `AssetRegistry/AssetRegistryModule.h`
|
||||
- `Async/ParallelFor.h`, `CoreMinimal.h`
|
||||
- `Dom/JsonObject.h`, `Dom/JsonValue.h`, `Engine/DataAsset.h`, `GameplayTagContainer.h`
|
||||
- `HAL/CriticalSection.h`, `HAL/Event.h`, `HAL/FileManager.h`, `HAL/IConsoleManager.h`, `HAL/PlatformProcess.h`, `HAL/PlatformTime.h`
|
||||
- `Json.h`, `Math/RandomStream.h`
|
||||
- `Misc/CommandLine.h`, `Misc/Crc.h`, `Misc/FileHelper.h`, `Misc/Parse.h`, `Misc/Paths.h`, `Misc/ScopeLock.h`, `Misc/ScopeRWLock.h`, `Misc/SecureHash.h`
|
||||
- `Modules/ModuleManager.h`, `ProfilingDebugging/CpuProfilerTrace.h`
|
||||
- `Serialization/CustomVersion.h`, `Serialization/JsonSerializer.h`, `Serialization/JsonWriter.h`, `Stats/Stats.h`
|
||||
- `Templates/SubclassOf.h`, `Templates/UniquePtr.h`
|
||||
- `UObject/EnumProperty.h`, `UObject/FieldIterator.h`, `UObject/Object.h`, `UObject/UObjectGlobals.h`, `UObject/UnrealType.h`
|
||||
|
||||
Also changed: `Standalone/Core/src/CoreNamespacePreamble.h`.
|
||||
|
||||
## Unreal spawn trace
|
||||
|
||||
The U1 trace is `Tools/TestVoxelForgeCoreWorldHost.ps1 -TimeoutSeconds 900 -CoreVoxelSizeCm 25 -StreamingTraceOnly`. It runs `UnrealEditor-Cmd -run=VoxelForgeExplore` with `-coreworldtest=1`, `-coreworldstreamtrace=1`, `/Game/VoxelForge/DA_Settings.DA_Settings`, seed 0, 25 cm Core voxels, 600 cm/s movement, and the Legacy/default streaming flags. It creates a transient `UWorld`; no map is loaded.
|
||||
|
||||
The exact pre-U2 owner packages are unavailable in this Linux workspace. Both hosts used identical copies of the five current `/home/jahni/VoxelM/DA_*.uasset` files (post-U2), with matching SHA-256s in both projects:
|
||||
|
||||
| Asset | SHA-256 |
|
||||
|---|---|
|
||||
| `DA_Settings` | `8abe8243104980260feca0a6f4cf4927768e8e568221a6f6a2c2694f6d15d454` |
|
||||
| `DA_Strate1` | `a9ca6cddd102250a893e379350b1d0f4aaf04c4f7fca70e0db46052a067d2cfb` |
|
||||
| `DA_Strate2` | `8f9a12a3181635149e6f79f192e0ddaf6b6577442ee324071a7749dcc78b9a0c` |
|
||||
| `DA_Strate3` | `5470d538c3c5e88237463e71bca9e2eb170dfe3a0543c0f33298d9fb010fd2f9` |
|
||||
| `DA_Strate4` | `a98e33e1cd42f374d6cb70f5071e8ebba74d91ed59d2fd3201782dab84d28f5c` |
|
||||
|
||||
The minimal host lacked the two First Person Blueprints used by the commandlet's speed fixture. Stock UE template copies also lacked a valid sprint graph, so the isolated trace build trees used the test's established 600/6000 speed defaults only for `-StreamingTraceOnly`; no tracked source was changed for this workaround. The trace loop itself takes its 600 cm/s movement value from the command line.
|
||||
|
||||
| Measure | L14 | HEAD (`e157847`) |
|
||||
|---|---:|---:|
|
||||
| Tiles per LOD | Not reached | Not reached |
|
||||
| Cells per tile | Not reached | Not reached |
|
||||
| Initial worker-seconds | Not reached | Not reached |
|
||||
| LOD0 tile worker p50 / p95 | Not reached | Not reached |
|
||||
| Full initial set ready | Not reached | Not reached |
|
||||
| Walkable ring count / ready time | Not reached | Not reached |
|
||||
| `generateTile` / mesh copy / RMC stream build | Not reached | Not reached |
|
||||
|
||||
Both commandlets stop before spawning `AVoxelWorld` with the same error: `SurfaceWorld route candidates failed the capsule and support sweep.` No tile trace file was produced. Thus this run cannot identify the Windows worker-time regression or separate Core generation from Unreal packaging. The failure is consistent across L14 and HEAD, but whether the post-U2 asset set or the route audit itself is responsible is unresolved; no fix is justified from this run.
|
||||
|
||||
L14 was exported from `a176d07` to the requested `Saved/Linux/l65/l14tree/Plugins/VoxelForge`. The sandbox did not permit creating the sibling `/home/jahni/VFHostL14`, so its second host project is nested at `/home/jahni/VFHost/VFHostL14/VFHostL14.uproject`. The supplied `/home/jahni/VFHost/VFHost.uproject` was restored byte-for-byte after testing. RealtimeMeshComponent's original source tree was not modified.
|
||||
|
||||
## Failed runs
|
||||
|
||||
- Initial builds hit a read-only UBT config path, then a read-only RMC intermediate timestamp, then a UBA stall. The next compile found Linux Unity duplicate test helpers; disabling Unity on Linux fixed it. A final incremental attempt made after restoring the original host descriptor again hit the RMC read-only timestamp; rebuilding with the local RMC copy passed.
|
||||
- Two early trace launches rejected an output directory outside the host project. The next launch stopped on the absent staged character Blueprint. Stock UE template Blueprints then failed to provide a sprint value; the trace-only defaults got past that gate. Both final revisions then stopped at the identical SurfaceWorld route audit above.
|
||||
|
||||
There were 12 build invocations, within the 15-attempt Part A limit.
|
||||
|
||||
## Orchestrator review (Claude)
|
||||
|
||||
Accepted. **The Linux UE build compiles VoxelForge with 0 errors** (HEAD and L14). I checked that the Compat and
|
||||
`Source/` changes don't alter Core output: standalone Clang and GCC rebuilds produce **identical whole-view hashes**
|
||||
to `3202193` on the pre-U2 data, for both SW and FI. The RealtimeMeshComponent tree is unmodified: its 203 git "M"
|
||||
entries are CRLF-only (empty diff with whitespace and CR ignored, no file newer than this round outside
|
||||
Intermediate/Binaries). The Unreal trace is blocked for both L14 and HEAD by the **owner's new assets**:
|
||||
`SurfaceWorld route candidates failed the capsule and support sweep` before `AVoxelWorld` spawns (consistent with
|
||||
L64: SW route 24/33 unsupported). The `verify.py` tiers still assume the old two-strate owner data and fail on the U2
|
||||
export; they need a pinned regression dataset plus new-plan baselines. `Source/` files to include in the owner's next
|
||||
Windows build are listed above.
|
||||
Reference in new issue
Block a user