Files
wwtools/mbproxy/src/Mbproxy/Mbproxy.csproj
T
Joseph Doherty 1d48b15ece mbproxy: embed debug symbols in the RID publish, drop the loose .pdb
A Release publish with an explicit RID emitted a separate Mbproxy.pdb
alongside the single-file binary. Set DebugType=embedded for that
publish so the output folder is just the binary plus appsettings.json;
symbols stay available for exception stack traces, only the loose file
is gone. A plain RID-less build is unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:30:03 -04:00

101 lines
5.4 KiB
XML

<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<RootNamespace>Mbproxy</RootNamespace>
<AssemblyName>Mbproxy</AssemblyName>
<!-- Assembly version. CI can override via /p:InformationalVersion=... -->
<InformationalVersion>1.0.0</InformationalVersion>
</PropertyGroup>
<!-- Single-file publish settings — apply only to a Release publish with an explicit RID.
Publishing with -r <rid> produces a single-file binary, self-contained by default
(bundles the .NET 10 + ASP.NET Core runtime, ~100 MB) so no .NET install is needed on
the target. Override with -p:SelfContained=false for a framework-dependent build
(~1.6 MB) when the target already has the .NET 10 + ASP.NET Core runtime.
The RID is supplied per publish (win-x64, linux-x64, ...) and is deliberately NOT
hardcoded here — see install/publish.ps1 / install/publish.sh. The
'$(RuntimeIdentifier)' != '' guard means a plain `dotnet build -c Release` with no RID
stays an ordinary framework build (SelfContained without a RID is an SDK error). -->
<PropertyGroup Condition="'$(Configuration)' == 'Release' and '$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<!-- Embed debug symbols into the assembly instead of emitting a loose .pdb, so a
RID publish produces a clean folder (single binary + appsettings.json). Symbols
stay available for exception stack traces; there is just no separate file. -->
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<!-- ASP.NET Core for the Kestrel-hosted admin endpoint. -->
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<!-- Microsoft.Extensions.Hosting is already included transitively via
Microsoft.AspNetCore.App — do not re-add it explicitly.
The two init-system integration packages are both portable: each is
safe to reference and call on any OS (the helper self-detects its host
and no-ops otherwise), so no conditional reference is needed. -->
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="10.0.8" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<!-- Local-syslog sink for the Linux diagnostic bridge (Error+ events).
Serilog.Sinks.SyslogMessages is the maintained IonxSolutions package. -->
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="4.1.0" />
<!-- Polly: backend-connect retry pipeline (PolicyFactory.BuildBackendConnect) and
listener-recovery pipeline (PolicyFactory.BuildListenerRecovery). -->
<PackageReference Include="Polly" Version="8.6.6" />
</ItemGroup>
<ItemGroup>
<!-- Allow test project to access internal types (HeartbeatWorker, HostingExtensions, etc.) -->
<InternalsVisibleTo Include="Mbproxy.Tests" />
</ItemGroup>
<ItemGroup>
<!-- Admin web-UI assets — Bootstrap, the SignalR JS client, vendored fonts, and the
dashboard's own HTML/CSS/JS. Embedded into the assembly so the single-file binary
serves the whole UI with no CDN dependency (firewalled networks). Resource names
are Mbproxy.Admin.wwwroot.<filename>; AdminEndpointHost streams them on
GET /assets/<filename>. The directory is intentionally flat to keep the
resource-name → request-path mapping trivial. -->
<EmbeddedResource Include="Admin\wwwroot\*.*" />
</ItemGroup>
<!-- Link the platform-appropriate install template as the published appsettings.json so
the binary ships with a fully-commented, usable example config (PLCs, BCD tags, all
sections present) instead of an empty stub. The .NET configuration loader supports
JSONC (comments) under the default Host.CreateApplicationBuilder path, so the comments
in the template are valid at runtime.
The two templates differ only in OS-specific paths (log directory) and platform
notes. A `dotnet publish -r linux-*` (or any non-win RID) ships the Linux template;
win-* and a plain RID-less dev build ship the Windows one. -->
<ItemGroup>
<None Remove="appsettings.json" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == '' or $(RuntimeIdentifier.StartsWith('win'))">
<Content Include="..\..\install\mbproxy.config.template.json"
Link="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' != '' and !$(RuntimeIdentifier.StartsWith('win'))">
<Content Include="..\..\install\mbproxy.linux.config.template.json"
Link="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>