Updated ModSDK packaging and launching scripts

Updates SDK scripts to match the current latest version of OpenRA (coming up on a 12.2022 release).
 - Launch scripts - OpenRA PRs 17578, 19317, 19486.
 - Make scripts - OpenRA PRs 16529, 19379, 19671, 19737, 19747, 19780, 20559.
 - Packaging scripts - OpenRA PRs 19780, 19782, 19886, 20559, 20610.
This commit is contained in:
penev92 2022-12-30 00:12:02 +02:00 committed by Matthias Mailänder
parent a044069173
commit b03c98b462
13 changed files with 358 additions and 344 deletions

View File

@ -3,6 +3,12 @@
# to compile, run: # to compile, run:
# make # make
# #
# to compile using Mono (version 6.4 or greater) instead of .NET 6, run:
# make RUNTIME=mono
#
# to compile using system libraries for native dependencies, run:
# make [RUNTIME=net6] TARGETPLATFORM=unix-generic
#
# to remove the files created by compiling, run: # to remove the files created by compiling, run:
# make clean # make clean
# #
@ -13,7 +19,10 @@
# make check-scripts # make check-scripts
# #
# to check the engine and your mod dlls for StyleCop violations, run: # to check the engine and your mod dlls for StyleCop violations, run:
# make check # make [RUNTIME=net6] check
#
# to check your mod yaml for errors, run:
# make [RUNTIME=net6] test
# #
# the following are internal sdk helpers that are not intended to be run directly: # the following are internal sdk helpers that are not intended to be run directly:
# make check-variables # make check-variables
@ -36,31 +45,39 @@ MOD_ID = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/MOD_ID/ { p
ENGINE_DIRECTORY = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/ENGINE_DIRECTORY/ { print $$2; exit }') ENGINE_DIRECTORY = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/ENGINE_DIRECTORY/ { print $$2; exit }')
MOD_SEARCH_PATHS = "$(shell $(PYTHON) -c "import os; print(os.path.realpath('.'))")/mods,./mods" MOD_SEARCH_PATHS = "$(shell $(PYTHON) -c "import os; print(os.path.realpath('.'))")/mods,./mods"
WHITELISTED_OPENRA_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_OPENRA_ASSEMBLIES/ { print $$2; exit }')"
WHITELISTED_THIRDPARTY_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_THIRDPARTY_ASSEMBLIES/ { print $$2; exit }')"
WHITELISTED_CORE_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_CORE_ASSEMBLIES/ { print $$2; exit }')"
WHITELISTED_MOD_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_MOD_ASSEMBLIES/ { print $$2; exit }')"
MANIFEST_PATH = "mods/$(MOD_ID)/mod.yaml" MANIFEST_PATH = "mods/$(MOD_ID)/mod.yaml"
HAS_LUAC = $(shell command -v luac 2> /dev/null) HAS_LUAC = $(shell command -v luac 2> /dev/null)
LUA_FILES = $(shell find mods/*/maps/* -iname '*.lua' 2> /dev/null) LUA_FILES = $(shell find mods/*/maps/* -iname '*.lua' 2> /dev/null)
MOD_SOLUTION_FILES = $(shell find . -maxdepth 1 -iname '*.sln' 2> /dev/null) MOD_SOLUTION_FILES = $(shell find . -maxdepth 1 -iname '*.sln' 2> /dev/null)
MSBUILD = msbuild -verbosity:m -nologo MSBUILD = msbuild -verbosity:m -nologo
DOTNET = dotnet
RUNTIME ?= net6
CONFIGURATION ?= Release
DOTNET_RID = $(shell ${DOTNET} --info | grep RID: | cut -w -f3)
ifndef TARGETPLATFORM ifndef TARGETPLATFORM
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m) UNAME_M := $(shell uname -m)
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
ifeq ($(RUNTIME)-$(DOTNET_RID),net6-osx-arm64)
TARGETPLATFORM = osx-arm64
else
TARGETPLATFORM = osx-x64 TARGETPLATFORM = osx-x64
endif
else else
ifeq ($(UNAME_M),x86_64) ifeq ($(UNAME_M),x86_64)
TARGETPLATFORM = linux-x64 TARGETPLATFORM = linux-x64
else else
ifeq ($(UNAME_M),aarch64)
TARGETPLATFORM = linux-arm64
else
TARGETPLATFORM = unix-generic TARGETPLATFORM = unix-generic
endif endif
endif endif
endif endif
endif
check-sdk-scripts: check-sdk-scripts:
@awk '/\r$$/ { exit(1); }' mod.config || (printf "Invalid mod.config format: file must be saved using unix-style (CR, not CRLF) line endings.\n"; exit 1) @awk '/\r$$/ { exit(1); }' mod.config || (printf "Invalid mod.config format: file must be saved using unix-style (CR, not CRLF) line endings.\n"; exit 1)
@ -123,18 +140,25 @@ check-variables:
engine: check-variables check-sdk-scripts engine: check-variables check-sdk-scripts
@./fetch-engine.sh || (printf "Unable to continue without engine files\n"; exit 1) @./fetch-engine.sh || (printf "Unable to continue without engine files\n"; exit 1)
@cd $(ENGINE_DIRECTORY) && make TARGETPLATFORM=$(TARGETPLATFORM) all @cd $(ENGINE_DIRECTORY) && make RUNTIME=$(RUNTIME) TARGETPLATFORM=$(TARGETPLATFORM) all
all: engine all: engine
@command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1) ifeq ($(RUNTIME), mono)
@command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.4."; exit 1)
ifneq ("$(MOD_SOLUTION_FILES)","") ifneq ("$(MOD_SOLUTION_FILES)","")
@find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=Release -p:TargetPlatform=$(TARGETPLATFORM) \; @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true \;
endif
else
@find . -maxdepth 1 -name '*.sln' -exec $(DOTNET) build -c ${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) \;
endif endif
clean: engine clean: engine
@command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1)
ifneq ("$(MOD_SOLUTION_FILES)","") ifneq ("$(MOD_SOLUTION_FILES)","")
ifeq ($(RUNTIME), mono)
@find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:clean \; @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:clean \;
else
@find . -maxdepth 1 -name '*.sln' -exec $(DOTNET) clean \;
endif
endif endif
@cd $(ENGINE_DIRECTORY) && make clean @cd $(ENGINE_DIRECTORY) && make clean
@ -154,11 +178,15 @@ endif
check: engine check: engine
ifneq ("$(MOD_SOLUTION_FILES)","") ifneq ("$(MOD_SOLUTION_FILES)","")
@echo "Compiling in debug mode..." @echo "Compiling in Debug mode..."
@find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=Debug -p:TargetPlatform=$(TARGETPLATFORM) \; ifeq ($(RUNTIME), mono)
# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise.
@$(MSBUILD) -t:build -restore -p:Configuration=Debug -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
else
# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise.
@$(DOTNET) build -c Debug -nologo -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
endif
endif endif
@echo "Checking runtime assemblies..."
@./utility.sh --check-runtime-assemblies $(WHITELISTED_OPENRA_ASSEMBLIES) $(WHITELISTED_THIRDPARTY_ASSEMBLIES) $(WHITELISTED_CORE_ASSEMBLIES) $(WHITELISTED_MOD_ASSEMBLIES)
@echo "Checking for explicit interface violations..." @echo "Checking for explicit interface violations..."
@./utility.sh --check-explicit-interfaces @./utility.sh --check-explicit-interfaces
@echo "Checking for incorrect conditional trait interface overrides..." @echo "Checking for incorrect conditional trait interface overrides..."

View File

@ -6,6 +6,7 @@ set Name="Dedicated Server"
set ListenPort=1234 set ListenPort=1234
set AdvertiseOnline=True set AdvertiseOnline=True
set Password="" set Password=""
set RecordReplays=False
set RequireAuthentication=False set RequireAuthentication=False
set ProfileIDBlacklist="" set ProfileIDBlacklist=""
@ -14,8 +15,11 @@ set ProfileIDWhitelist=""
set EnableSingleplayer=False set EnableSingleplayer=False
set EnableSyncReports=False set EnableSyncReports=False
set EnableGeoIP=True set EnableGeoIP=True
set EnableLintChecks=True
set ShareAnonymizedIPs=True set ShareAnonymizedIPs=True
set JoinChatDelay=5000
@echo off @echo off
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
@ -33,7 +37,7 @@ if not exist %ENGINE_DIRECTORY%\bin\OpenRA.exe goto noengine
cd %ENGINE_DIRECTORY% cd %ENGINE_DIRECTORY%
:loop :loop
bin\OpenRA.Server.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.RequireAuthentication=%RequireAuthentication% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% Server.EnableGeoIP=%EnableGeoIP% Server.ShareAnonymizedIPs=%ShareAnonymizedIPs% Engine.SupportDir=%SupportDir% bin\OpenRA.Server.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.RequireAuthentication=%RequireAuthentication% Server.RecordReplays=%RecordReplays% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% Server.EnableGeoIP=%EnableGeoIP% Server.ShareAnonymizedIPs=%ShareAnonymizedIPs% Server.EnableLintChecks=%EnableLintChecks% Engine.SupportDir=%SupportDir% Server.JoinChatDelay=%JoinChatDelay%
goto loop goto loop
:noengine :noengine

View File

@ -5,7 +5,10 @@
# Read the file to see which settings you can override # Read the file to see which settings you can override
set -e set -e
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; } if ! command -v mono >/dev/null 2>&1; then
command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; }
fi
if command -v python3 >/dev/null 2>&1; then if command -v python3 >/dev/null 2>&1; then
PYTHON="python3" PYTHON="python3"
else else
@ -39,11 +42,18 @@ fi
require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY"
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.Server.dll)" = "0" ]; then
RUNTIME_LAUNCHER="mono --debug"
else
RUNTIME_LAUNCHER="dotnet"
fi
NAME="${Name:-"Dedicated Server"}" NAME="${Name:-"Dedicated Server"}"
LAUNCH_MOD="${Mod:-"${MOD_ID}"}" LAUNCH_MOD="${Mod:-"${MOD_ID}"}"
LISTEN_PORT="${ListenPort:-"1234"}" LISTEN_PORT="${ListenPort:-"1234"}"
ADVERTISE_ONLINE="${AdvertiseOnline:-"True"}" ADVERTISE_ONLINE="${AdvertiseOnline:-"True"}"
PASSWORD="${Password:-""}" PASSWORD="${Password:-""}"
RECORD_REPLAYS="${RecordReplays:-"False"}"
REQUIRE_AUTHENTICATION="${RequireAuthentication:-"False"}" REQUIRE_AUTHENTICATION="${RequireAuthentication:-"False"}"
PROFILE_ID_BLACKLIST="${ProfileIDBlacklist:-""}" PROFILE_ID_BLACKLIST="${ProfileIDBlacklist:-""}"
@ -52,12 +62,15 @@ PROFILE_ID_WHITELIST="${ProfileIDWhitelist:-""}"
ENABLE_SINGLE_PLAYER="${EnableSingleplayer:-"False"}" ENABLE_SINGLE_PLAYER="${EnableSingleplayer:-"False"}"
ENABLE_SYNC_REPORTS="${EnableSyncReports:-"False"}" ENABLE_SYNC_REPORTS="${EnableSyncReports:-"False"}"
ENABLE_GEOIP="${EnableGeoIP:-"True"}" ENABLE_GEOIP="${EnableGeoIP:-"True"}"
ENABLE_LINT_CHECKS="${EnableLintChecks:-"True"}"
SHARE_ANONYMISED_IPS="${ShareAnonymizedIPs:-"True"}" SHARE_ANONYMISED_IPS="${ShareAnonymizedIPs:-"True"}"
JOIN_CHAT_DELAY="${JoinChatDelay:-"5000"}"
SUPPORT_DIR="${SupportDir:-""}" SUPPORT_DIR="${SupportDir:-""}"
cd "${TEMPLATE_ROOT}" cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Server.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Server.dll" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then
echo "Required engine files not found." echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1 exit 1
@ -66,16 +79,21 @@ fi
cd "${ENGINE_DIRECTORY}" cd "${ENGINE_DIRECTORY}"
while true; do while true; do
MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug bin/OpenRA.Server.exe Engine.EngineDir=".." Game.Mod="${LAUNCH_MOD}" \ MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}"
Server.Name="${NAME}" Server.ListenPort="${LISTEN_PORT}" \ ${RUNTIME_LAUNCHER} bin/OpenRA.Server.dll Engine.EngineDir=".." Game.Mod="${LAUNCH_MOD}" \
Server.Name="${NAME}" \
Server.ListenPort="${LISTEN_PORT}" \
Server.AdvertiseOnline="${ADVERTISE_ONLINE}" \ Server.AdvertiseOnline="${ADVERTISE_ONLINE}" \
Server.Password="${PASSWORD}" \ Server.Password="${PASSWORD}" \
Server.RecordReplays="${RECORD_REPLAYS}" \
Server.RequireAuthentication="${REQUIRE_AUTHENTICATION}" \ Server.RequireAuthentication="${REQUIRE_AUTHENTICATION}" \
Server.ProfileIDBlacklist="${PROFILE_ID_BLACKLIST}" \ Server.ProfileIDBlacklist="${PROFILE_ID_BLACKLIST}" \
Server.ProfileIDWhitelist="${PROFILE_ID_WHITELIST}" \ Server.ProfileIDWhitelist="${PROFILE_ID_WHITELIST}" \
Server.EnableSingleplayer="${ENABLE_SINGLE_PLAYER}" \ Server.EnableSingleplayer="${ENABLE_SINGLE_PLAYER}" \
Server.EnableSyncReports="${ENABLE_SYNC_REPORTS}" \ Server.EnableSyncReports="${ENABLE_SYNC_REPORTS}" \
Server.EnableGeoIP="${ENABLE_GEOIP}" \ Server.EnableGeoIP="${ENABLE_GEOIP}" \
Server.EnableLintChecks="${ENABLE_LINT_CHECKS}" \
Server.ShareAnonymizedIPs="${SHARE_ANONYMISED_IPS}" \ Server.ShareAnonymizedIPs="${SHARE_ANONYMISED_IPS}" \
Server.JoinChatDelay="${JOIN_CHAT_DELAY}" \
Engine.SupportDir="${SUPPORT_DIR}" Engine.SupportDir="${SUPPORT_DIR}"
done done

View File

@ -16,7 +16,7 @@ if not exist %ENGINE_DIRECTORY%\bin\OpenRA.exe goto noengine
>nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine >nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine
cd %ENGINE_DIRECTORY% cd %ENGINE_DIRECTORY%
bin\OpenRA.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Engine.LaunchPath="%TEMPLATE_LAUNCHER%" "Engine.ModSearchPaths=%MOD_SEARCH_PATHS%" "%*" bin\OpenRA.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Engine.LaunchPath="%TEMPLATE_LAUNCHER%" Engine.ModSearchPaths="%MOD_SEARCH_PATHS%" "%*"
set ERROR=%errorlevel% set ERROR=%errorlevel%
cd %TEMPLATE_DIR% cd %TEMPLATE_DIR%

View File

@ -1,7 +1,10 @@
#!/bin/sh #!/bin/sh
set -e set -e
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; } if ! command -v mono >/dev/null 2>&1; then
command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; }
fi
if command -v python3 >/dev/null 2>&1; then if command -v python3 >/dev/null 2>&1; then
PYTHON="python3" PYTHON="python3"
else else
@ -36,11 +39,17 @@ fi
require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY"
cd "${TEMPLATE_ROOT}" cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.dll" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then
echo "Required engine files not found." echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1 exit 1
fi fi
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.dll)" = "0" ]; then
RUNTIME_LAUNCHER="mono --debug"
else
RUNTIME_LAUNCHER="dotnet"
fi
cd "${ENGINE_DIRECTORY}" cd "${ENGINE_DIRECTORY}"
mono --debug bin/OpenRA.exe Engine.EngineDir=".." Engine.LaunchPath="${TEMPLATE_LAUNCHER}" "Engine.ModSearchPaths=${MOD_SEARCH_PATHS}" Game.Mod="${MOD_ID}" "$@" ${RUNTIME_LAUNCHER} bin/OpenRA.dll Game.Mod="${MOD_ID}" Engine.EngineDir=".." Engine.LaunchPath="${TEMPLATE_LAUNCHER}" Engine.ModSearchPaths="${MOD_SEARCH_PATHS}" "$@"

View File

@ -7,6 +7,7 @@ function All-Command
{ {
If (!(Test-Path "*.sln")) If (!(Test-Path "*.sln"))
{ {
Write-Host "No custom solution file found. Aborting." -ForegroundColor Red
return return
} }
@ -15,7 +16,9 @@ function All-Command
return return
} }
dotnet build /p:Configuration=Release /nologo Write-Host "Building in" $configuration "configuration..." -ForegroundColor Cyan
dotnet build -c $configuration --nologo -p:TargetPlatform=win-x64
if ($lastexitcode -ne 0) if ($lastexitcode -ne 0)
{ {
Write-Host "Build failed. If just the development tools failed to build, try installing Visual Studio. You may also still be able to run the game." -ForegroundColor Red Write-Host "Build failed. If just the development tools failed to build, try installing Visual Studio. You may also still be able to run the game." -ForegroundColor Red
@ -30,6 +33,7 @@ function Clean-Command
{ {
If (!(Test-Path "*.sln")) If (!(Test-Path "*.sln"))
{ {
Write-Host "No custom solution file found - nothing to clean. Aborting." -ForegroundColor Red
return return
} }
@ -110,8 +114,10 @@ function Check-Command
return return
} }
Write-Host "Compiling in debug configuration..." -ForegroundColor Cyan Write-Host "Compiling in Debug configuration..." -ForegroundColor Cyan
dotnet build /p:Configuration=Debug /nologo
# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise.
dotnet build -c Debug --nologo -warnaserror -p:TargetPlatform=win-x64 -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
if ($lastexitcode -ne 0) if ($lastexitcode -ne 0)
{ {
Write-Host "Build failed." -ForegroundColor Red Write-Host "Build failed." -ForegroundColor Red
@ -119,9 +125,6 @@ function Check-Command
if ((CheckForUtility) -eq 0) if ((CheckForUtility) -eq 0)
{ {
Write-Host "Checking runtime assemblies..." -ForegroundColor Cyan
InvokeCommand "$utilityPath $modID --check-runtime-assemblies $env:WHITELISTED_OPENRA_ASSEMBLIES $env:WHITELISTED_THIRDPARTY_ASSEMBLIES $env:WHITELISTED_CORE_ASSEMBLIES $env:WHITELISTED_MOD_ASSEMBLIES"
Write-Host "Checking for explicit interface violations..." -ForegroundColor Cyan Write-Host "Checking for explicit interface violations..." -ForegroundColor Cyan
InvokeCommand "$utilityPath $modID --check-explicit-interfaces" InvokeCommand "$utilityPath $modID --check-explicit-interfaces"
@ -160,9 +163,9 @@ function CheckForUtility
function CheckForDotnet function CheckForDotnet
{ {
if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -eq $null) if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -eq $null)
{ {
Write-Host "The 'dotnet' tool is required to compile OpenRA. Please install the .NET Core SDK or Visual Studio and try again. https://dotnet.microsoft.com/download" -ForegroundColor Red Write-Host "The 'dotnet' tool is required to compile OpenRA. Please install the .NET 6.0 SDK and try again. https://dotnet.microsoft.com/download/dotnet/6.0" -ForegroundColor Red
return 1 return 1
} }
@ -171,7 +174,7 @@ function CheckForDotnet
function WaitForInput function WaitForInput
{ {
echo "Press enter to continue." Write-Host "Press enter to continue."
while ($true) while ($true)
{ {
if ([System.Console]::KeyAvailable) if ([System.Console]::KeyAvailable)
@ -194,9 +197,7 @@ function ReadConfigLine($line, $name)
function ParseConfigFile($fileName) function ParseConfigFile($fileName)
{ {
$names = @("MOD_ID", "ENGINE_VERSION", "AUTOMATIC_ENGINE_MANAGEMENT", "AUTOMATIC_ENGINE_SOURCE", $names = @("MOD_ID", "ENGINE_VERSION", "AUTOMATIC_ENGINE_MANAGEMENT", "AUTOMATIC_ENGINE_SOURCE",
"AUTOMATIC_ENGINE_EXTRACT_DIRECTORY", "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME", "ENGINE_DIRECTORY", "AUTOMATIC_ENGINE_EXTRACT_DIRECTORY", "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME", "ENGINE_DIRECTORY")
"WHITELISTED_OPENRA_ASSEMBLIES", "WHITELISTED_THIRDPARTY_ASSEMBLIES", "WHITELISTED_CORE_ASSEMBLIES",
"WHITELISTED_MOD_ASSEMBLIES")
$reader = [System.IO.File]::OpenText($fileName) $reader = [System.IO.File]::OpenText($fileName)
while($null -ne ($line = $reader.ReadLine())) while($null -ne ($line = $reader.ReadLine()))
@ -219,12 +220,12 @@ function ParseConfigFile($fileName)
if ($missing) if ($missing)
{ {
echo "Required mod.config variables are missing:" Write-Host "Required mod.config variables are missing:"
foreach ($m in $missing) foreach ($m in $missing)
{ {
echo " $m" Write-Host " $m"
} }
echo "Repair your mod.config (or user.config) and try again." Write-Host "Repair your mod.config (or user.config) and try again."
WaitForInput WaitForInput
exit exit
} }
@ -249,24 +250,24 @@ function InvokeCommand
############################################################### ###############################################################
if ($PSVersionTable.PSVersion.Major -clt 3) if ($PSVersionTable.PSVersion.Major -clt 3)
{ {
echo "The makefile requires PowerShell version 3 or higher." Write-Host "The makefile requires PowerShell version 3 or higher." -ForegroundColor Red
echo "Please download and install the latest Windows Management Framework version from Microsoft." Write-Host "Please download and install the latest Windows Management Framework version from Microsoft." -ForegroundColor Red
WaitForInput WaitForInput
} }
if ($args.Length -eq 0) if ($args.Length -eq 0)
{ {
echo "Command list:" Write-Host "Command list:"
echo "" Write-Host ""
echo " all Builds the game, its development tools and the mod dlls." Write-Host " all Builds the game, its development tools and the mod dlls."
echo " version Sets the version strings for all mods to the latest" Write-Host " version Sets the version strings for all mods to the latest"
echo " version for the current Git branch." Write-Host " version for the current Git branch."
echo " clean Removes all built and copied files." Write-Host " clean Removes all built and copied files."
echo " from the mods and the engine directories." Write-Host " from the mods and the engine directories."
echo " test Tests the mod's MiniYAML for errors." Write-Host " test Tests the mod's MiniYAML for errors."
echo " check Checks .cs files for StyleCop violations." Write-Host " check Checks .cs files for StyleCop violations."
echo " check-scripts Checks .lua files for syntax errors." Write-Host " check-scripts Checks .lua files for syntax errors."
echo "" Write-Host ""
$command = (Read-Host "Enter command").Split(' ', 2) $command = (Read-Host "Enter command").Split(' ', 2)
} }
else else
@ -308,34 +309,34 @@ if ($command -eq "all" -or $command -eq "clean" -or $command -eq "check")
{ {
cd $env:ENGINE_DIRECTORY cd $env:ENGINE_DIRECTORY
Invoke-Expression ".\make.cmd $command" Invoke-Expression ".\make.cmd $command"
echo "" Write-Host ""
cd $templateDir cd $templateDir
} }
elseif ($env:AUTOMATIC_ENGINE_MANAGEMENT -ne "True") elseif ($env:AUTOMATIC_ENGINE_MANAGEMENT -ne "True")
{ {
echo "Automatic engine management is disabled." Write-Host "Automatic engine management is disabled."
echo "Please manually update the engine to version $env:ENGINE_VERSION." Write-Host "Please manually update the engine to version $env:ENGINE_VERSION."
WaitForInput WaitForInput
} }
else else
{ {
echo "OpenRA engine version $env:ENGINE_VERSION is required." Write-Host "OpenRA engine version $env:ENGINE_VERSION is required."
if (Test-Path $env:ENGINE_DIRECTORY) if (Test-Path $env:ENGINE_DIRECTORY)
{ {
if ($currentEngine -ne "") if ($currentEngine -ne "")
{ {
echo "Deleting engine version $currentEngine." Write-Host "Deleting engine version $currentEngine."
} }
else else
{ {
echo "Deleting existing engine (unknown version)." Write-Host "Deleting existing engine (unknown version)."
} }
rm $env:ENGINE_DIRECTORY -r rm $env:ENGINE_DIRECTORY -r
} }
echo "Downloading engine..." Write-Host "Downloading engine..."
if (Test-Path $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY) if (Test-Path $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY)
{ {
@ -366,13 +367,19 @@ if ($command -eq "all" -or $command -eq "clean" -or $command -eq "check")
cd $env:ENGINE_DIRECTORY cd $env:ENGINE_DIRECTORY
Invoke-Expression ".\make.cmd version $env:ENGINE_VERSION" Invoke-Expression ".\make.cmd version $env:ENGINE_VERSION"
Invoke-Expression ".\make.cmd $command" Invoke-Expression ".\make.cmd $command"
echo "" Write-Host ""
cd $templateDir cd $templateDir
} }
} }
$utilityPath = $env:ENGINE_DIRECTORY + "/bin/OpenRA.Utility.exe" $utilityPath = $env:ENGINE_DIRECTORY + "/bin/OpenRA.Utility.exe"
$configuration = "Release"
if ($args.Contains("CONFIGURATION=Debug"))
{
$configuration = "Debug"
}
$execute = $command $execute = $command
if ($command.Length -gt 1) if ($command.Length -gt 1)
{ {
@ -387,7 +394,7 @@ switch ($execute)
"test" { Test-Command } "test" { Test-Command }
"check" { Check-Command } "check" { Check-Command }
"check-scripts" { Check-Scripts-Command } "check-scripts" { Check-Scripts-Command }
Default { echo ("Invalid command '{0}'" -f $command) } Default { Write-Host ("Invalid command '{0}'" -f $command) }
} }
# In case the script was called without any parameters we keep the window open # In case the script was called without any parameters we keep the window open

View File

@ -11,9 +11,6 @@ MOD_ID="example"
# The OpenRA engine version to use for this project. # The OpenRA engine version to use for this project.
ENGINE_VERSION="release-20210321" ENGINE_VERSION="release-20210321"
# .dll filenames compiled by the mod solution for use by the runtime assembly check
WHITELISTED_MOD_ASSEMBLIES="OpenRA.Mods.Example.dll"
############################################################################## ##############################################################################
# Packaging # Packaging
# #
@ -53,10 +50,6 @@ PACKAGING_FAQ_URL="http://wiki.openra.net/FAQ"
# - Windows "Add/Remove Programs" list # - Windows "Add/Remove Programs" list
PACKAGING_AUTHORS="Example Mod authors" PACKAGING_AUTHORS="Example Mod authors"
# Space delimited list of dll files compiled by the mod, which
# should be copied from the bin directory into your installers
PACKAGING_COPY_MOD_BINARIES="OpenRA.Mods.Example.dll"
# If your mod depends on OpenRA.Mods.Cnc.dll from the engine set # If your mod depends on OpenRA.Mods.Cnc.dll from the engine set
# this to "True" to package the dll in your installers. # this to "True" to package the dll in your installers.
# Accepts values "True" or "False". # Accepts values "True" or "False".
@ -72,9 +65,6 @@ PACKAGING_COPY_D2K_DLL="False"
# and define the client id here and in your mod.yaml # and define the client id here and in your mod.yaml
PACKAGING_DISCORD_APPID="" PACKAGING_DISCORD_APPID=""
# The git tag to use for the macOS Launcher files.
PACKAGING_OSX_MONO_TAG="osx-launcher-20200830"
# The macOS disk image icon positions, matched to the background artwork # The macOS disk image icon positions, matched to the background artwork
PACKAGING_OSX_DMG_MOD_ICON_POSITION="190, 210" PACKAGING_OSX_DMG_MOD_ICON_POSITION="190, 210"
PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION="410, 210" PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION="410, 210"
@ -93,9 +83,6 @@ PACKAGING_WINDOWS_REGISTRY_KEY="OpenRAExampleMod"
# Path to the file containing the text to show in the Windows installer license dialog # Path to the file containing the text to show in the Windows installer license dialog
PACKAGING_WINDOWS_LICENSE_FILE="./COPYING" PACKAGING_WINDOWS_LICENSE_FILE="./COPYING"
# The git tag to use for the AppImage dependencies.
PACKAGING_APPIMAGE_DEPENDENCIES_TAG="20200328"
# Space delimited list of additional files/directories to copy from the engine directory # Space delimited list of additional files/directories to copy from the engine directory
# when packaging your mod. e.g. "./mods/modcontent" # when packaging your mod. e.g. "./mods/modcontent"
PACKAGING_COPY_ENGINE_FILES="" PACKAGING_COPY_ENGINE_FILES=""
@ -122,25 +109,3 @@ AUTOMATIC_ENGINE_SOURCE="https://github.com/OpenRA/OpenRA/archive/${ENGINE_VERSI
AUTOMATIC_ENGINE_EXTRACT_DIRECTORY="./engine_temp" AUTOMATIC_ENGINE_EXTRACT_DIRECTORY="./engine_temp"
AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME="engine.zip" AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME="engine.zip"
ENGINE_DIRECTORY="./engine" ENGINE_DIRECTORY="./engine"
# The url to download the OpenRA macOS mono runtime.
PACKAGING_OSX_MONO_SOURCE="https://github.com/OpenRA/OpenRALauncherOSX/releases/download/${PACKAGING_OSX_MONO_TAG}/mono.zip"
# Temporary file name used when downloading the OpenRA macOS launcher files.
PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME="mono.zip"
# The url to download the OpenRA AppImage dependencies.
PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE="https://github.com/OpenRA/AppImageSupport/releases/download/${PACKAGING_APPIMAGE_DEPENDENCIES_TAG}/mono.tar.bz2"
# Temporary file name used when downloading the OpenRA AppImage dependencies.
PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME="mono.tar.bz2"
# List of .NET assemblies that we can guarantee exist
WHITELISTED_OPENRA_ASSEMBLIES="OpenRA.exe OpenRA.Utility.exe OpenRA.Server.exe OpenRA.Platforms.Default.dll OpenRA.Game.dll OpenRA.Mods.Common.dll OpenRA.Mods.Cnc.dll OpenRA.Mods.D2k.dll"
# These are explicitly shipped alongside our core files by the packaging script
WHITELISTED_THIRDPARTY_ASSEMBLIES="ICSharpCode.SharpZipLib.dll FuzzyLogicLibrary.dll Eluant.dll BeaconLib.dll Open.Nat.dll SDL2-CS.dll OpenAL-CS.Core.dll DiscordRPC.dll Newtonsoft.Json.dll"
# These are shipped in our custom minimal mono runtime and also available in the full system-installed .NET/mono stack
# This list *must* be kept in sync with the files packaged by the AppImageSupport and OpenRALauncherOSX repositories
WHITELISTED_CORE_ASSEMBLIES="mscorlib.dll System.dll System.Configuration.dll System.Core.dll System.Numerics.dll System.Security.dll System.Xml.dll Mono.Security.dll netstandard.dll"

53
packaging/functions.sh Normal file
View File

@ -0,0 +1,53 @@
#!/bin/sh
# Helper functions for packaging and installing projects using the OpenRA Mod SDK
####
# This file must stay /bin/sh and POSIX compliant for macOS and BSD portability.
# Copy-paste the entire script into http://shellcheck.net to check.
####
# Compile and publish any mod assemblies to the target directory
# Arguments:
# SRC_PATH: Path to the root SDK directory
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
# TARGETPLATFORM: Platform type (win-x86, win-x64, osx-x64, osx-arm64, linux-x64, linux-arm64, unix-generic)
# RUNTIME: Runtime type (net6, mono)
# ENGINE_PATH: Path to the engine root directory
install_mod_assemblies() {
SRC_PATH="${1}"
DEST_PATH="${2}"
TARGETPLATFORM="${3}"
RUNTIME="${4}"
ENGINE_PATH="${5}"
ORIG_PWD=$(pwd)
cd "${SRC_PATH}" || exit 1
if [ "${RUNTIME}" = "mono" ]; then
echo "Building assemblies"
rm -rf "${ENGINE_PATH:?}/bin"
find . -maxdepth 1 -name '*.sln' -exec msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}" -p:Mono=true \;
cd "${ORIG_PWD}" || exit 1
for LIB in "${ENGINE_PATH}/bin/"*.dll "${ENGINE_PATH}/bin/"*.dll.config; do
install -m644 "${LIB}" "${DEST_PATH}"
done
if [ "${TARGETPLATFORM}" = "linux-x64" ] || [ "${TARGETPLATFORM}" = "linux-arm64" ]; then
for LIB in "${ENGINE_PATH}/bin/"*.so; do
install -m755 "${LIB}" "${DEST_PATH}"
done
fi
if [ "${TARGETPLATFORM}" = "osx-x64" ] || [ "${TARGETPLATFORM}" = "osx-arm64" ]; then
for LIB in "${ENGINE_PATH}/bin/"*.dylib; do
install -m755 "${LIB}" "${DEST_PATH}"
done
fi
else
find . -maxdepth 1 -name '*.sln' -exec dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -r "${TARGETPLATFORM}" -o "${DEST_PATH}" --self-contained true \;
cd "${ORIG_PWD}" || exit 1
fi
}

View File

@ -4,7 +4,6 @@ set -e
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires make."; exit 1; } command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires make."; exit 1; }
command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires python 3."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires python 3."; exit 1; }
command -v tar >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires tar."; exit 1; }
command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires curl or wget."; exit 1; } command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires curl or wget."; exit 1; }
require_variables() { require_variables() {
@ -37,7 +36,6 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then
fi fi
require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \ require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \
"PACKAGING_APPIMAGE_DEPENDENCIES_TAG" "PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE" "PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME" \
"PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION"
TAG="$1" TAG="$1"
@ -59,6 +57,7 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then
fi fi
. "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh"
. "${TEMPLATE_ROOT}/packaging/functions.sh"
if [ ! -d "${OUTPUTDIR}" ]; then if [ ! -d "${OUTPUTDIR}" ]; then
echo "Output directory '${OUTPUTDIR}' does not exist."; echo "Output directory '${OUTPUTDIR}' does not exist.";
@ -66,7 +65,7 @@ if [ ! -d "${OUTPUTDIR}" ]; then
fi fi
echo "Building core files" echo "Building core files"
install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" "linux-x64" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra"
for f in ${PACKAGING_COPY_ENGINE_FILES}; do for f in ${PACKAGING_COPY_ENGINE_FILES}; do
@ -75,17 +74,10 @@ for f in ${PACKAGING_COPY_ENGINE_FILES}; do
done done
echo "Building mod files" echo "Building mod files"
pushd "${TEMPLATE_ROOT}" > /dev/null install_mod_assemblies "${TEMPLATE_ROOT}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}"
make all
popd > /dev/null
cp -Lr "${TEMPLATE_ROOT}/mods/"* "${APPDIR}/usr/lib/openra/mods" cp -Lr "${TEMPLATE_ROOT}/mods/"* "${APPDIR}/usr/lib/openra/mods"
for f in ${PACKAGING_COPY_MOD_BINARIES}; do
mkdir -p "${APPDIR}/usr/lib/openra/$(dirname "${f}")"
cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${APPDIR}/usr/lib/openra/${f}"
done
set_engine_version "${ENGINE_VERSION}" "${APPDIR}/usr/lib/openra" set_engine_version "${ENGINE_VERSION}" "${APPDIR}/usr/lib/openra"
if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then
set_mod_version "${TAG}" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}/mod.yaml" set_mod_version "${TAG}" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}/mod.yaml"
@ -95,27 +87,15 @@ else
fi fi
# Add native libraries # Add native libraries
echo "Downloading dependencies" echo "Downloading appimagetool"
if command -v curl >/dev/null 2>&1; then if command -v curl >/dev/null 2>&1; then
curl -s -L -o "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" || exit 3
curl -s -L -O https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 curl -s -L -O https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3
else else
wget -cq "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" -O "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" || exit 3
wget -cq https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 wget -cq https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3
fi fi
echo "Building AppImage" echo "Building AppImage"
tar xf "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" -C "${APPDIR}"
chmod 0755 "${APPDIR}/usr/bin/mono"
chmod 0644 "${APPDIR}/etc/mono/config"
chmod 0644 "${APPDIR}/etc/mono/4.5/machine.config"
chmod 0644 "${APPDIR}/usr/lib/mono/4.5/Facades/"*.dll
chmod 0644 "${APPDIR}/usr/lib/mono/4.5/"*.dll "${APPDIR}/usr/lib/mono/4.5/"*.exe
chmod 0755 "${APPDIR}/usr/lib/"*.so
rm -rf "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}"
# Add launcher and icons # Add launcher and icons
sed "s/{MODID}/${MOD_ID}/g" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/AppRun.in" | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" > "${APPDIR}/AppRun" sed "s/{MODID}/${MOD_ID}/g" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/AppRun.in" | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" > "${APPDIR}/AppRun"
chmod 0755 "${APPDIR}/AppRun" chmod 0755 "${APPDIR}/AppRun"
@ -162,7 +142,6 @@ sed "s/{MODID}/${MOD_ID}/g" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linu
chmod 0755 "${APPDIR}/usr/bin/openra-${MOD_ID}-utility" chmod 0755 "${APPDIR}/usr/bin/openra-${MOD_ID}-utility"
install -m 0755 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/gtk-dialog.py" "${APPDIR}/usr/bin/gtk-dialog.py" install -m 0755 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/gtk-dialog.py" "${APPDIR}/usr/bin/gtk-dialog.py"
install -m 0755 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/restore-environment.sh" "${APPDIR}/usr/bin/restore-environment.sh"
chmod a+x appimagetool-x86_64.AppImage chmod a+x appimagetool-x86_64.AppImage
ARCH=x86_64 ./appimagetool-x86_64.AppImage "${APPDIR}" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}-x86_64.AppImage" ARCH=x86_64 ./appimagetool-x86_64.AppImage "${APPDIR}" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}-x86_64.AppImage"

View File

@ -13,7 +13,7 @@
# MACOS_DEVELOPER_USERNAME: Email address for the developer account # MACOS_DEVELOPER_USERNAME: Email address for the developer account
# MACOS_DEVELOPER_PASSWORD: App-specific password for the developer account # MACOS_DEVELOPER_PASSWORD: App-specific password for the developer account
# #
set -e set -o errexit -o pipefail || exit $?
if [[ "$OSTYPE" != "darwin"* ]]; then if [[ "$OSTYPE" != "darwin"* ]]; then
echo >&2 "macOS packaging requires a macOS host" echo >&2 "macOS packaging requires a macOS host"
@ -22,6 +22,7 @@ fi
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires make."; exit 1; } command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires make."; exit 1; }
command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires python 3."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires python 3."; exit 1; }
command -v clang >/dev/null 2>&1 || { echo >&2 "macOS packaging requires clang."; exit 1; }
require_variables() { require_variables() {
missing="" missing=""
@ -35,8 +36,8 @@ require_variables() {
fi fi
} }
if [ $# -eq "0" ]; then if [ $# -ne "2" ]; then
echo "Usage: $(basename "$0") version [outputdir]" echo "Usage: $(basename "$0") tag outputdir"
exit 1 exit 1
fi fi
@ -53,7 +54,6 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then
fi fi
require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \ require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \
"PACKAGING_OSX_MONO_TAG" "PACKAGING_OSX_MONO_SOURCE" "PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME" \
"PACKAGING_OSX_DMG_MOD_ICON_POSITION" "PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION" "PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION" \ "PACKAGING_OSX_DMG_MOD_ICON_POSITION" "PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION" "PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION" \
"PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION"
@ -64,6 +64,7 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then
fi fi
. "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh"
. "${TEMPLATE_ROOT}/packaging/functions.sh"
# Import code signing certificate # Import code signing certificate
if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
@ -99,215 +100,161 @@ modify_plist() {
sed "s|$1|$2|g" "$3" > "$3.tmp" && mv "$3.tmp" "$3" sed "s|$1|$2|g" "$3" > "$3.tmp" && mv "$3.tmp" "$3"
} }
build_platform() { LAUNCHER_DIR="${BUILTDIR}/${PACKAGING_OSX_APP_NAME}"
PLATFORM="${1}" LAUNCHER_CONTENTS_DIR="${LAUNCHER_DIR}/Contents"
DMG_NAME="${2}" LAUNCHER_ASSEMBLY_DIR="${LAUNCHER_CONTENTS_DIR}/MacOS"
LAUNCHER_DIR="${BUILTDIR}/${PACKAGING_OSX_APP_NAME}" LAUNCHER_RESOURCES_DIR="${LAUNCHER_CONTENTS_DIR}/Resources"
LAUNCHER_CONTENTS_DIR="${LAUNCHER_DIR}/Contents"
LAUNCHER_MACOS_DIR="${LAUNCHER_CONTENTS_DIR}/MacOS"
LAUNCHER_RESOURCES_DIR="${LAUNCHER_CONTENTS_DIR}/Resources"
echo "Building launcher (${PLATFORM})" echo "Building launcher"
mkdir -p "${LAUNCHER_RESOURCES_DIR}" mkdir -p "${LAUNCHER_RESOURCES_DIR}"
mkdir -p "${LAUNCHER_CONTENTS_DIR}/MacOS" mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/x86_64"
echo "APPL????" > "${LAUNCHER_CONTENTS_DIR}/PkgInfo" mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/arm64"
cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/Info.plist.in" "${LAUNCHER_CONTENTS_DIR}/Info.plist" mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/mono"
echo "APPL????" > "${LAUNCHER_CONTENTS_DIR}/PkgInfo"
cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/Info.plist.in" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{DEV_VERSION}" "${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" modify_plist "{DEV_VERSION}" "${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{MOD_ID}" "${MOD_ID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" modify_plist "{MOD_ID}" "${MOD_ID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.11" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
if [ -n "${DISCORD_APPID}" ]; then
modify_plist "{DISCORD_URL_SCHEME}" "discord-${DISCORD_APPID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
else
modify_plist "<string>{DISCORD_URL_SCHEME}</string>" "" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
fi
if [ -n "${DISCORD_APPID}" ]; then # Compile universal (x86_64 + arm64) Launcher and arch-specific apphosts
modify_plist "{DISCORD_URL_SCHEME}" "discord-${DISCORD_APPID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-x86_64" -framework AppKit -target x86_64-apple-macos10.15
else clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-arm64" -framework AppKit -target arm64-apple-macos10.15
modify_plist "<string>{DISCORD_URL_SCHEME}</string>" "" "${LAUNCHER_CONTENTS_DIR}/Info.plist" clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost-mono.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-mono" -framework AppKit -target x86_64-apple-macos10.11
fi clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/checkmono.c" -o "${LAUNCHER_ASSEMBLY_DIR}/checkmono" -framework AppKit -target x86_64-apple-macos10.11
clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.11
clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64" -framework AppKit -target arm64-apple-macos10.15
lipo -create -output "${LAUNCHER_ASSEMBLY_DIR}/Launcher" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64"
rm "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64"
if [ "${PLATFORM}" = "compat" ]; then install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/x86_64" "osx-x64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.9" "${LAUNCHER_CONTENTS_DIR}/Info.plist" install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/arm64" "osx-arm64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
clang -m64 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher-mono.m" -o "${LAUNCHER_MACOS_DIR}/OpenRA" -framework AppKit -mmacosx-version-min=10.9 install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/mono" "osx-x64" "mono" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
else install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}"
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.13" "${LAUNCHER_CONTENTS_DIR}/Info.plist"
clang -m64 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_MACOS_DIR}/OpenRA" -framework AppKit -mmacosx-version-min=10.13
curl -s -L -o "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_OSX_MONO_SOURCE}" || exit 3 for f in ${PACKAGING_COPY_ENGINE_FILES}; do
unzip -qq -d "${BUILTDIR}" "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")"
rm "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" cp -r "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}"
done
mv "${BUILTDIR}/mono" "${LAUNCHER_MACOS_DIR}" echo "Building mod files"
mv "${BUILTDIR}/etc" "${LAUNCHER_RESOURCES_DIR}" install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/x86_64" "osx-x64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}"
mv "${BUILTDIR}/lib" "${LAUNCHER_RESOURCES_DIR}" install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/arm64" "osx-arm64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}"
fi install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/mono" "osx-x64" "mono" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}"
echo "Building core files" cp -LR "${TEMPLATE_ROOT}mods/"* "${LAUNCHER_RESOURCES_DIR}/mods"
install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}" "osx-x64" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}"
for f in ${PACKAGING_COPY_ENGINE_FILES}; do set_engine_version "${ENGINE_VERSION}" "${LAUNCHER_RESOURCES_DIR}"
mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")" if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then
cp -r "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}" set_mod_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml"
done else
MOD_VERSION=$(grep 'Version:' "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" | awk '{print $2}')
echo "Mod version ${MOD_VERSION} will remain unchanged.";
fi
echo "Building mod files" # Assemble multi-resolution icon
pushd "${TEMPLATE_ROOT}" > /dev/null mkdir "${BUILTDIR}/mod.iconset"
make all cp "${ARTWORK_DIR}/icon_16x16.png" "${BUILTDIR}/mod.iconset/icon_16x16.png"
popd > /dev/null cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_16x16@2.png"
cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_32x32.png"
cp "${ARTWORK_DIR}/icon_64x64.png" "${BUILTDIR}/mod.iconset/icon_32x32@2x.png"
cp "${ARTWORK_DIR}/icon_128x128.png" "${BUILTDIR}/mod.iconset/icon_128x128.png"
cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_128x128@2x.png"
cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_256x256.png"
cp "${ARTWORK_DIR}/icon_512x512.png" "${BUILTDIR}/mod.iconset/icon_256x256@2x.png"
iconutil --convert icns "${BUILTDIR}/mod.iconset" -o "${LAUNCHER_RESOURCES_DIR}/${MOD_ID}.icns"
rm -rf "${BUILTDIR}/mod.iconset"
cp -LR "${TEMPLATE_ROOT}mods/"* "${LAUNCHER_RESOURCES_DIR}/mods" # Sign binaries with developer certificate
if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" --deep "${LAUNCHER_DIR}"
fi
for f in ${PACKAGING_COPY_MOD_BINARIES}; do echo "Packaging disk image"
mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")" hdiutil create "build.dmg" -format UDRW -volname "${PACKAGING_DISPLAY_NAME}" -fs HFS+ -srcfolder "${BUILTDIR}"
cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}" DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${PACKAGING_DIR}/build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}')
done sleep 2
set_engine_version "${ENGINE_VERSION}" "${LAUNCHER_RESOURCES_DIR}" # Background image is created from source svg in artsrc repository
if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then mkdir "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/"
set_mod_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" tiffutil -cathidpicheck "${ARTWORK_DIR}/macos-background.png" "${ARTWORK_DIR}/macos-background-2x.png" -out "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/background.tiff"
else
MOD_VERSION=$(grep 'Version:' "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" | awk '{print $2}')
echo "Mod version ${MOD_VERSION} will remain unchanged.";
fi
# Assemble multi-resolution icon cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns"
mkdir "${BUILTDIR}/mod.iconset"
cp "${ARTWORK_DIR}/icon_16x16.png" "${BUILTDIR}/mod.iconset/icon_16x16.png"
cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_16x16@2.png"
cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_32x32.png"
cp "${ARTWORK_DIR}/icon_64x64.png" "${BUILTDIR}/mod.iconset/icon_32x32@2x.png"
cp "${ARTWORK_DIR}/icon_128x128.png" "${BUILTDIR}/mod.iconset/icon_128x128.png"
cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_128x128@2x.png"
cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_256x256.png"
cp "${ARTWORK_DIR}/icon_512x512.png" "${BUILTDIR}/mod.iconset/icon_256x256@2x.png"
iconutil --convert icns "${BUILTDIR}/mod.iconset" -o "${LAUNCHER_RESOURCES_DIR}/${MOD_ID}.icns"
rm -rf "${BUILTDIR}/mod.iconset"
# Sign binaries with developer certificate echo '
if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then tell application "Finder"
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" "${LAUNCHER_RESOURCES_DIR}/"*.dylib tell disk "'${PACKAGING_DISPLAY_NAME}'"
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" --deep "${LAUNCHER_DIR}" open
fi set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 1000, 550}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 72
set background picture of theViewOptions to file ".background:background.tiff"
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
set position of item "'${PACKAGING_OSX_APP_NAME}'" of container window to {'${PACKAGING_OSX_DMG_MOD_ICON_POSITION}'}
set position of item "Applications" of container window to {'${PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION}'}
set position of item ".background" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
set position of item ".fseventsd" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
set position of item ".VolumeIcon.icns" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
update without registering applications
delay 5
close
end tell
end tell
' | osascript
echo "Packaging disk image" # HACK: Copy the volume icon again - something in the previous step seems to delete it...?
hdiutil create "${PACKAGING_DIR}/${DMG_NAME}" -format UDRW -volname "${PACKAGING_DISPLAY_NAME}" -fs HFS+ -srcfolder "${BUILTDIR}" cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns"
DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${PACKAGING_DIR}/${DMG_NAME}" | egrep '^/dev/' | sed 1q | awk '{print $1}') SetFile -c icnC "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns"
sleep 2 SetFile -a C "/Volumes/${PACKAGING_DISPLAY_NAME}"
# Background image is created from source svg in artsrc repository chmod -Rf go-w "/Volumes/${PACKAGING_DISPLAY_NAME}"
mkdir "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/" sync
tiffutil -cathidpicheck "${ARTWORK_DIR}/macos-background.png" "${ARTWORK_DIR}/macos-background-2x.png" -out "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/background.tiff" sync
cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" hdiutil detach "${DMG_DEVICE}"
rm -rf "${BUILTDIR}"
echo '
tell application "Finder"
tell disk "'${PACKAGING_DISPLAY_NAME}'"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 1000, 550}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 72
set background picture of theViewOptions to file ".background:background.tiff"
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
set position of item "'${PACKAGING_OSX_APP_NAME}'" of container window to {'${PACKAGING_OSX_DMG_MOD_ICON_POSITION}'}
set position of item "Applications" of container window to {'${PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION}'}
set position of item ".background" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
set position of item ".fseventsd" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
set position of item ".VolumeIcon.icns" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'}
update without registering applications
delay 5
close
end tell
end tell
' | osascript
# HACK: Copy the volume icon again - something in the previous step seems to delete it...?
cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns"
SetFile -c icnC "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns"
SetFile -a C "/Volumes/${PACKAGING_DISPLAY_NAME}"
chmod -Rf go-w "/Volumes/${PACKAGING_DISPLAY_NAME}"
sync
sync
hdiutil detach "${DMG_DEVICE}"
rm -rf "${BUILTDIR}"
}
notarize_package() {
DMG_PATH="${1}"
NOTARIZE_DMG_PATH="${DMG_PATH%.*}"-notarization.dmg
echo "Submitting ${DMG_PATH} for notarization"
# Reset xcode search path to fix xcrun not finding altool
sudo xcode-select -r
# Create a temporary read-only dmg for submission (notarization service rejects read/write images)
hdiutil convert "${DMG_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${NOTARIZE_DMG_PATH}"
NOTARIZATION_UUID=$(xcrun altool --notarize-app --primary-bundle-id "net.openra.modsdk" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" --file "${NOTARIZE_DMG_PATH}" 2>&1 | awk -F' = ' '/RequestUUID/ { print $2; exit }')
if [ -z "${NOTARIZATION_UUID}" ]; then
echo "Submission failed"
exit 1
fi
echo "${DMG_PATH} submission UUID is ${NOTARIZATION_UUID}"
rm "${NOTARIZE_DMG_PATH}"
while :; do
sleep 30
NOTARIZATION_RESULT=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/Status/ { print $2; exit }')
echo "${DMG_PATH}: ${NOTARIZATION_RESULT}"
if [ "${NOTARIZATION_RESULT}" == "invalid" ]; then
NOTARIZATION_LOG_URL=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/LogFileURL/ { print $2; exit }')
echo "${NOTARIZATION_UUID} failed notarization with error:"
curl -s "${NOTARIZATION_LOG_URL}" -w "\n"
exit 1
fi
if [ "${NOTARIZATION_RESULT}" == "success" ]; then
echo "${DMG_PATH}: Stapling tickets"
DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_PATH}" | egrep '^/dev/' | sed 1q | awk '{print $1}')
sleep 2
xcrun stapler staple "/Volumes/${PACKAGING_DISPLAY_NAME}/${PACKAGING_OSX_APP_NAME}"
sync
sync
hdiutil detach "${DMG_DEVICE}"
break
fi
done
}
finalize_package() {
DMG_PATH="${1}"
OUTPUT_PATH="${2}"
hdiutil convert "${DMG_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}"
rm "${DMG_PATH}"
}
build_platform "standard" "build.dmg"
build_platform "compat" "build-compat.dmg"
if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
security delete-keychain build.keychain security delete-keychain build.keychain
fi fi
if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ]; then if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
# Parallelize processing echo "Submitting build for notarization"
(notarize_package "build.dmg") &
(notarize_package "build-compat.dmg") & # Reset xcode search path to fix xcrun not finding altool
wait sudo xcode-select -r
# Create a temporary read-only dmg for submission (notarization service rejects read/write images)
hdiutil convert "build.dmg" -format ULFO -ov -o "build-notarization.dmg"
xcrun notarytool submit "build-notarization.dmg" --wait --apple-id "${MACOS_DEVELOPER_USERNAME}" --password "${MACOS_DEVELOPER_PASSWORD}" --team-id "${MACOS_DEVELOPER_IDENTITY}"
rm "build-notarization.dmg"
echo "Stapling tickets"
DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}')
sleep 2
xcrun stapler staple "/Volumes/${PACKAGING_DISPLAY_NAME}/${PACKAGING_OSX_APP_NAME}"
sync
sync
hdiutil detach "${DMG_DEVICE}"
fi fi
finalize_package "build.dmg" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.dmg" hdiutil convert "build.dmg" -format ULFO -ov -o "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.dmg"
finalize_package "build-compat.dmg" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}-compat.dmg" rm "build.dmg"

View File

@ -93,14 +93,16 @@ Section "Game" GAME
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
File "${SRCDIR}\*.exe" File "${SRCDIR}\*.exe"
File "${SRCDIR}\*.exe.config" File "${SRCDIR}\*.dll.config"
File "${SRCDIR}\*.dll" File "${SRCDIR}\*.dll"
File "${SRCDIR}\*.ico" File "${SRCDIR}\*.ico"
File "${SRCDIR}\*.deps.json"
File "${SRCDIR}\*.runtimeconfig.json"
File "${SRCDIR}\global mix database.dat"
File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP"
File "${SRCDIR}\VERSION" File "${SRCDIR}\VERSION"
File "${SRCDIR}\AUTHORS" File "${SRCDIR}\AUTHORS"
File "${SRCDIR}\COPYING" File "${SRCDIR}\COPYING"
File "${SRCDIR}\global mix database.dat"
File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP"
File /r "${SRCDIR}\mods" File /r "${SRCDIR}\mods"
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
@ -123,6 +125,7 @@ Section "Game" GAME
SetShellVarContext all SetShellVarContext all
CreateDirectory "$APPDATA\OpenRA\ModMetadata" CreateDirectory "$APPDATA\OpenRA\ModMetadata"
SetOutPath "$INSTDIR"
nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --register-mod "$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" system' nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --register-mod "$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" system'
nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --clear-invalid-mod-registrations system' nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --clear-invalid-mod-registrations system'
SetShellVarContext current SetShellVarContext current
@ -135,21 +138,6 @@ Section "Desktop Shortcut" DESKTOPSHORTCUT
"$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" "" "" "" "" "$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" "" "" "" ""
SectionEnd SectionEnd
;***************************
;Dependency Sections
;***************************
Section "-DotNet" DotNet
ClearErrors
; https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release"
IfErrors error 0
IntCmp $0 461808 done error done
error:
MessageBox MB_OK ".NET Framework v4.7.2 or later is required to run OpenRA."
Abort
done:
SectionEnd
;*************************** ;***************************
;Uninstaller Sections ;Uninstaller Sections
;*************************** ;***************************
@ -176,14 +164,17 @@ Function ${UN}Clean
RMDir /r $INSTDIR\glsl RMDir /r $INSTDIR\glsl
RMDir /r $INSTDIR\lua RMDir /r $INSTDIR\lua
Delete $INSTDIR\*.exe Delete $INSTDIR\*.exe
Delete $INSTDIR\*.exe.config
Delete $INSTDIR\*.dll Delete $INSTDIR\*.dll
Delete $INSTDIR\*.ico Delete $INSTDIR\*.ico
Delete $INSTDIR\*.dll.config
Delete $INSTDIR\*.deps.json
Delete $INSTDIR\*.runtimeconfig.json
Delete $INSTDIR\VERSION Delete $INSTDIR\VERSION
Delete $INSTDIR\AUTHORS Delete $INSTDIR\AUTHORS
Delete $INSTDIR\COPYING Delete $INSTDIR\COPYING
Delete "$INSTDIR\global mix database.dat" Delete "$INSTDIR\global mix database.dat"
Delete $INSTDIR\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP Delete $INSTDIR\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
RMDir /r $INSTDIR\Support RMDir /r $INSTDIR\Support
!ifndef USE_PROGRAMFILES32 !ifndef USE_PROGRAMFILES32
@ -194,7 +185,7 @@ Function ${UN}Clean
DeleteRegKey HKLM "Software\Classes\openra-${MOD_ID}-${TAG}" DeleteRegKey HKLM "Software\Classes\openra-${MOD_ID}-${TAG}"
!ifdef USE_DISCORDID !ifdef USE_DISCORDID
DeleteRegKey HKLM "Software\Classes\discord-${DISCORD_APP_ID}" DeleteRegKey HKLM "Software\Classes\discord-${USE_DISCORDID}"
!endif !endif
Delete $INSTDIR\uninstaller.exe Delete $INSTDIR\uninstaller.exe

View File

@ -1,8 +1,10 @@
#!/bin/bash #!/bin/bash
set -e set -e
command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires curl or wget."; exit 1; }
command -v makensis >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires makensis."; exit 1; } command -v makensis >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires makensis."; exit 1; }
command -v convert >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires ImageMagick."; exit 1; } command -v convert >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires ImageMagick."; exit 1; }
command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires python 3."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires python 3."; exit 1; }
command -v wine64 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires wine64."; exit 1; }
require_variables() { require_variables() {
missing="" missing=""
@ -56,12 +58,19 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then
fi fi
. "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh"
. "${TEMPLATE_ROOT}/packaging/functions.sh"
if [ ! -d "${OUTPUTDIR}" ]; then if [ ! -d "${OUTPUTDIR}" ]; then
echo "Output directory '${OUTPUTDIR}' does not exist."; echo "Output directory '${OUTPUTDIR}' does not exist.";
exit 1 exit 1
fi fi
if command -v curl >/dev/null 2>&1; then
curl -s -L -O https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3
else
wget -cq https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3
fi
function build_platform() function build_platform()
{ {
PLATFORM="${1}" PLATFORM="${1}"
@ -78,7 +87,7 @@ function build_platform()
fi fi
echo "Building core files (${PLATFORM})" echo "Building core files (${PLATFORM})"
install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "False" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "False" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}"
install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}"
for f in ${PACKAGING_COPY_ENGINE_FILES}; do for f in ${PACKAGING_COPY_ENGINE_FILES}; do
@ -87,17 +96,10 @@ function build_platform()
done done
echo "Building mod files (${PLATFORM})" echo "Building mod files (${PLATFORM})"
pushd "${TEMPLATE_ROOT}" > /dev/null install_mod_assemblies "${TEMPLATE_ROOT}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}"
make all
popd > /dev/null
cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/mods" cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/mods"
for f in ${PACKAGING_COPY_MOD_BINARIES}; do
mkdir -p "${BUILTDIR}/$(dirname "${f}")"
cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${BUILTDIR}/${f}"
done
set_engine_version "${ENGINE_VERSION}" "${BUILTDIR}" set_engine_version "${ENGINE_VERSION}" "${BUILTDIR}"
if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then
set_mod_version "${TAG}" "${BUILTDIR}/mods/${MOD_ID}/mod.yaml" set_mod_version "${TAG}" "${BUILTDIR}/mods/${MOD_ID}/mod.yaml"
@ -110,7 +112,9 @@ function build_platform()
convert "${ARTWORK_DIR}/icon_16x16.png" "${ARTWORK_DIR}/icon_24x24.png" "${ARTWORK_DIR}/icon_32x32.png" "${ARTWORK_DIR}/icon_48x48.png" "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/${MOD_ID}.ico" convert "${ARTWORK_DIR}/icon_16x16.png" "${ARTWORK_DIR}/icon_24x24.png" "${ARTWORK_DIR}/icon_32x32.png" "${ARTWORK_DIR}/icon_48x48.png" "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/${MOD_ID}.ico"
echo "Compiling Windows launcher (${PLATFORM})" echo "Compiling Windows launcher (${PLATFORM})"
install_windows_launcher "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${PACKAGING_WINDOWS_LAUNCHER_NAME}" "${PACKAGING_DISPLAY_NAME}" "${BUILTDIR}/${MOD_ID}.ico" "${PACKAGING_FAQ_URL}" install_windows_launcher "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${PACKAGING_WINDOWS_LAUNCHER_NAME}" "${PACKAGING_DISPLAY_NAME}" "${PACKAGING_FAQ_URL}"
wine64 rcedit-x64.exe "${BUILTDIR}/${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" --set-icon "${BUILTDIR}/${MOD_ID}.ico"
echo "Building Windows setup.exe (${PLATFORM})" echo "Building Windows setup.exe (${PLATFORM})"
pushd "${PACKAGING_DIR}" > /dev/null pushd "${PACKAGING_DIR}" > /dev/null

View File

@ -5,7 +5,10 @@
set -e set -e
command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires make."; exit 1; } command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires make."; exit 1; }
command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; }
if ! command -v mono >/dev/null 2>&1; then
command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; }
fi
if command -v python3 >/dev/null 2>&1; then if command -v python3 >/dev/null 2>&1; then
PYTHON="python3" PYTHON="python3"
@ -43,11 +46,17 @@ require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY"
LAUNCH_MOD="${Mod:-"${MOD_ID}"}" LAUNCH_MOD="${Mod:-"${MOD_ID}"}"
cd "${TEMPLATE_ROOT}" cd "${TEMPLATE_ROOT}"
if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Utility.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Utility.dll" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then
echo "Required engine files not found." echo "Required engine files not found."
echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; echo "Run \`make\` in the mod directory to fetch and build the required files, then try again.";
exit 1 exit 1
fi fi
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.Utility.dll)" = "0" ]; then
RUNTIME_LAUNCHER="mono --debug"
else
RUNTIME_LAUNCHER="dotnet"
fi
cd "${ENGINE_DIRECTORY}" cd "${ENGINE_DIRECTORY}"
MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" ENGINE_DIR=".." mono --debug bin/OpenRA.Utility.exe "${LAUNCH_MOD}" "$@" MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" ENGINE_DIR=".." ${RUNTIME_LAUNCHER} bin/OpenRA.Utility.dll "${LAUNCH_MOD}" "$@"