-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDirectory.Build.props
More file actions
144 lines (126 loc) · 10.9 KB
/
Copy pathDirectory.Build.props
File metadata and controls
144 lines (126 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?xml version="1.0" encoding="utf-8"?>
<!--
Build wiring shared by every project in this repo.
Why this file and not the .csproj: JotunnLib's Paths.props fills in VALHEIM_INSTALL,
VALHEIM_MANAGED and BEPINEX_PATH itself, each guarded on "only if this is still empty".
Property assignments are evaluated in import order, so whoever gets there first wins -
and MSBuild imports Directory.Build.props before NuGet's generated props, which is what
lets these values beat JotunnLib's own defaults instead of losing to them.
Reference HintPaths are NOT the reason: MSBuild evaluates every property before any
item, so a HintPath declared in an earlier import still picks up a value assigned later
in the .csproj. It is the property-precedence race above that needs winning.
Everything below only fills in values that are still empty, so an explicit
environment variable, an Environment.props, or -p:NAME=... always wins.
-->
<Project>
<!-- ==================== solution root ==================== -->
<!-- Post-build targets reach for the Unity project, scripts/publish.ps1 and similar as
$(SolutionDir)X. MSBuild only defines SolutionDir when the build goes through the .sln;
a direct `dotnet build Foo.csproj` leaves it undefined, and those paths then resolve to
the literal "*Undefined*X" - a silently skipped copy at best, MSB3073 at worst. This file
sits at the repo root, so its own directory is the right answer. When a .sln is driving,
SolutionDir is a global property and this assignment is ignored, which is what we want.
Must stay above the Environment.props import below, whose condition reads it. -->
<PropertyGroup>
<SolutionDir Condition="'$(SolutionDir)' == '' Or !Exists('$(SolutionDir)')">$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
<!-- ==================== machine-local overrides (gitignored) ==================== -->
<!-- Copy Environment.props.example to Environment.props to point the build at a
different game install, BepInEx, or to turn the publicizer off.
Skipped only when $(SolutionDir) is this very directory, because JotunnLib's
Paths.props then imports the same $(SolutionDir)Environment.props itself, and
importing one file twice in a single evaluation warns MSB4011 on every build.
A solution somewhere else is the gap this covers, since JotunnLib's import
resolves to a different path there. -->
<Import Project="$(MSBuildThisFileDirectory)Environment.props"
Condition="Exists('$(MSBuildThisFileDirectory)Environment.props') And '$(SolutionDir)' != '$(MSBuildThisFileDirectory)'" />
<!-- ==================== publicize the game assemblies ==================== -->
<!-- JotunnLib ships the publicizer (JotunnBuildTask): with ExecutePrebuild=true it
hashes every assembly_*.dll / SoftReferenceableAssets.dll / gui_framework.dll in
the game's Managed folder and regenerates Managed/publicized_assemblies/*_publicized.dll
when they differ, which is exactly what JotunnLibRefsCorlib.props references.
Left off, the build silently depends on someone having publicized by hand.
JotunnLib itself only imports $(SolutionDir)DoPrebuild.props, and SolutionDir is
literally "*Undefined*" whenever the .csproj is built directly (dotnet build, CI,
`mod-tools`), so that file never took effect. Import it here, where it always does. -->
<Import Project="$(MSBuildThisFileDirectory)DoPrebuild.props"
Condition="'$(ExecutePrebuild)' == '' And Exists('$(MSBuildThisFileDirectory)DoPrebuild.props')" />
<PropertyGroup>
<ExecutePrebuild Condition="'$(ExecutePrebuild)' == ''">true</ExecutePrebuild>
</PropertyGroup>
<!-- ==================== Valheim install ==================== -->
<!-- Same probe order JotunnLib uses, hoisted here because BEPINEX_PATH below needs
the answer before JotunnLib's Paths.props gets a turn. -->
<PropertyGroup Condition="'$(VALHEIM_INSTALL)' == '' And '$(OS)' == 'Windows_NT'">
<VALHEIM_INSTALL>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 892970', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32))</VALHEIM_INSTALL>
<_SteamLibraryPath>$([MSBuild]::GetRegistryValueFromView('HKEY_CURRENT_USER\SOFTWARE\Valve\Steam', 'SteamPath', null, RegistryView.Registry32))</_SteamLibraryPath>
<VALHEIM_INSTALL Condition="!Exists('$(VALHEIM_INSTALL)') And '$(_SteamLibraryPath)' != ''">$(_SteamLibraryPath)\steamapps\common\Valheim</VALHEIM_INSTALL>
<VALHEIM_INSTALL Condition="!Exists('$(VALHEIM_INSTALL)')">C:\Program Files\Steam\steamapps\common\Valheim</VALHEIM_INSTALL>
<VALHEIM_INSTALL Condition="!Exists('$(VALHEIM_INSTALL)')">C:\Program Files (x86)\Steam\steamapps\common\Valheim</VALHEIM_INSTALL>
</PropertyGroup>
<PropertyGroup Condition="'$(VALHEIM_INSTALL)' == '' And '$(OS)' != 'Windows_NT'">
<VALHEIM_INSTALL>$(HOME)/.steam/steam/steamapps/common/Valheim</VALHEIM_INSTALL>
<VALHEIM_INSTALL Condition="!Exists('$(VALHEIM_INSTALL)')">$(HOME)/Library/Application Support/Steam/steamapps/common/Valheim/Contents/MacOS</VALHEIM_INSTALL>
</PropertyGroup>
<PropertyGroup Condition="'$(VALHEIM_MANAGED)' == '' And '$(VALHEIM_INSTALL)' != ''">
<VALHEIM_MANAGED Condition="Exists('$(VALHEIM_INSTALL)/Valheim_Data/Managed')">$(VALHEIM_INSTALL)/Valheim_Data/Managed</VALHEIM_MANAGED>
<VALHEIM_MANAGED Condition="'$(VALHEIM_MANAGED)' == '' And Exists('$(VALHEIM_INSTALL)/valheim_Data/Managed')">$(VALHEIM_INSTALL)/valheim_Data/Managed</VALHEIM_MANAGED>
<VALHEIM_MANAGED Condition="'$(VALHEIM_MANAGED)' == '' And Exists('$(VALHEIM_INSTALL)/valheim_server_Data/Managed')">$(VALHEIM_INSTALL)/valheim_server_Data/Managed</VALHEIM_MANAGED>
</PropertyGroup>
<!-- ==================== BepInEx ==================== -->
<!-- JotunnLib assumes BepInEx sits in the game folder. It does not when the game is
modded through Gale / r2modman / Thunderstore MM, which keep a BepInEx per profile
and leave the install vanilla - and then every BepInEx, Harmony, Mono.Cecil and
MonoMod reference fails to resolve and the compile dies in hundreds of CS0246s.
Fall back to the first profile that actually has a BepInEx core; any BepInEx 5 is
fine to compile against, and Environment.props can pin a specific one. -->
<PropertyGroup Condition="'$(BEPINEX_PATH)' == ''">
<BEPINEX_PATH Condition="Exists('$(VALHEIM_INSTALL)\BepInEx\core\BepInEx.dll')">$(VALHEIM_INSTALL)\BepInEx</BEPINEX_PATH>
</PropertyGroup>
<PropertyGroup Condition="'$(BEPINEX_PATH)' == '' And '$(OS)' == 'Windows_NT'">
<_VhGaleProfiles>$(AppData)\com.kesomannen.gale\valheim\profiles</_VhGaleProfiles>
<_VhR2Profiles>$(AppData)\r2modmanPlus-local\Valheim\profiles</_VhR2Profiles>
<_VhTsmmProfiles>$(AppData)\Thunderstore Mod Manager\DataFolder\Valheim\profiles</_VhTsmmProfiles>
<!-- GetFiles returns absolute paths joined by ';', and only profiles that really have
a BepInEx show up at all, so the first hit is a usable one. Each manager is
searched only while nothing has been found yet. -->
<_VhBepInExHits Condition="'$(_VhBepInExHits)' == '' And Exists('$(_VhGaleProfiles)')">$([System.IO.Directory]::GetFiles('$(_VhGaleProfiles)', 'BepInEx.dll', SearchOption.AllDirectories))</_VhBepInExHits>
<_VhBepInExHits Condition="'$(_VhBepInExHits)' == '' And Exists('$(_VhR2Profiles)')">$([System.IO.Directory]::GetFiles('$(_VhR2Profiles)', 'BepInEx.dll', SearchOption.AllDirectories))</_VhBepInExHits>
<_VhBepInExHits Condition="'$(_VhBepInExHits)' == '' And Exists('$(_VhTsmmProfiles)')">$([System.IO.Directory]::GetFiles('$(_VhTsmmProfiles)', 'BepInEx.dll', SearchOption.AllDirectories))</_VhBepInExHits>
<_VhBepInExDll Condition="'$(_VhBepInExHits)' != ''">$(_VhBepInExHits.Split(';')[0])</_VhBepInExDll>
<BEPINEX_PATH Condition="'$(_VhBepInExDll)' != ''">$([System.IO.Path]::GetFullPath($([System.IO.Path]::Combine($([System.IO.Path]::GetDirectoryName('$(_VhBepInExDll)')), '..'))))</BEPINEX_PATH>
<!-- A BepInEx.dll somewhere other than a core folder is not a BepInEx install. -->
<BEPINEX_PATH Condition="'$(BEPINEX_PATH)' != '' And !Exists('$(BEPINEX_PATH)\core\0Harmony.dll')"></BEPINEX_PATH>
</PropertyGroup>
<!-- ==================== alternate property names ==================== -->
<!-- Not every repo is Jotunn-template shaped. The Azu-style projects reach the game through
GamePath / GamePathManaged / BepInExPath / PublicizedAssembliesPath instead, and resolve
them with their own Choose blocks that are all guarded on "empty" or "does not exist" -
so filling them in here wins the same race, and one file covers both conventions.
A project that computes its own values still keeps them. -->
<PropertyGroup>
<GamePath Condition="'$(GamePath)' == ''">$(VALHEIM_INSTALL)</GamePath>
<GamePathManaged Condition="'$(GamePathManaged)' == '' And '$(VALHEIM_MANAGED)' != ''">$(VALHEIM_MANAGED)</GamePathManaged>
<BepInExPath Condition="'$(BepInExPath)' == '' And '$(BEPINEX_PATH)' != ''">$(BEPINEX_PATH)</BepInExPath>
<PublicizedAssembliesPath Condition="'$(PublicizedAssembliesPath)' == '' And '$(VALHEIM_MANAGED)' != ''">$(VALHEIM_MANAGED)\publicized_assemblies</PublicizedAssembliesPath>
</PropertyGroup>
<!-- ==================== diagnostics ==================== -->
<!-- Only for the projects that actually consume the vanilla and BepInEx references, which
here means the ones referencing JotunnLib: it is JotunnLib's props that turn
VALHEIM_MANAGED and BEPINEX_PATH into <Reference> HintPaths. A solution can also hold a
preloader patcher that gets its references from a NuGet package, or a standalone tool
that never touches the game at all and may be built in a container with no Valheim
installed. Warning about a missing game install there would be noise. -->
<Target Name="CheckValheimBuildPaths" BeforeTargets="BeforeBuild">
<ItemGroup>
<_VhJotunnPackage Include="@(PackageReference)" Condition="'%(PackageReference.Identity)' == 'JotunnLib'" />
</ItemGroup>
<PropertyGroup>
<_VhUsesGameAssemblies Condition="'@(_VhJotunnPackage)' != ''">true</_VhUsesGameAssemblies>
</PropertyGroup>
<Warning Condition="'$(_VhUsesGameAssemblies)' == 'true' And !Exists('$(VALHEIM_MANAGED)')"
Text="Valheim's Managed folder was not found (VALHEIM_INSTALL='$(VALHEIM_INSTALL)'). Vanilla references will not resolve and the assemblies cannot be publicized. Set VALHEIM_INSTALL in Environment.props - see Environment.props.example." />
<Warning Condition="'$(_VhUsesGameAssemblies)' == 'true' And !Exists('$(BEPINEX_PATH)\core\BepInEx.dll')"
Text="BepInEx was not found (BEPINEX_PATH='$(BEPINEX_PATH)'). BepInEx, Harmony, Mono.Cecil and MonoMod references will not resolve. Set BEPINEX_PATH in Environment.props - see Environment.props.example." />
</Target>
</Project>