Rewrote build script, improved packaging

- Renamed :packageWindows to :packageNsis
- ImageMagick now required for :packageNsis
- Packaging output is now in build/packages
- Rewrote build script
  - Packaging logic and LWJGL dependencies now in separate files
  - Packaging logic now implemented with Gradle, not Bash scripts
    - Cross-platform?
- Added :packageZip
  - Universal ZIP with start scripts
- Changed version detection logic
  - Tags of ancestor commits are now considered
  - Only tags with format vMAJOR.MINOR.PATCH[-SUFFIX] are considered
  - If the tag's commit isn't HEAD, PATCH is incremented
  - When version detection fails, dummy version is 999.0.0-<buildID or date>
- LWJGL target platforms can be overridden with forceTargets project property
This commit is contained in:
OLEGSHA 2022-01-07 21:21:10 +03:00
parent dececb4589
commit 162b2249b1
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
16 changed files with 838 additions and 619 deletions

2
.gitattributes vendored
View File

@ -6,4 +6,4 @@
* text=auto eol=lf * text=auto eol=lf
*.bat text eol=crlf *.bat text eol=crlf
*.nsi text eol=crlf

View File

@ -1,5 +1,12 @@
/* /*
* build.gradle for Progressia * Build logic for Progressia
* build.gradle
*
* Please refer to
*
* docs/building/BuildScriptReference.md
*
* for user reference.
*/ */
plugins { plugins {
@ -8,19 +15,15 @@ plugins {
// GrGit // GrGit
// A JGit wrapper for Groovy used to access git commit info // A JGit wrapper for Groovy used to access git commit info
id 'org.ajoberstar.grgit' version '4.1.1' id 'org.ajoberstar.grgit' version '4.1.1'
/*
* Uncomment the following line to enable the Eclipse plugin.
* This is only necessary if you don't use Buildship plugin from the IDE
*/
//id 'eclipse'
} }
/*
* Configure Java version
*/
java { java {
/*
* We're Java 8 for now.
* Why? As of 2020, most users have Oracle Java, which only supports Java 8.
*/
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
} }
@ -37,6 +40,8 @@ compileJava {
} }
} }
/* /*
* Dependencies * Dependencies
*/ */
@ -45,7 +50,7 @@ repositories {
mavenCentral() mavenCentral()
/* /*
* Specify Windcorp Maven repository * Windcorp Maven repository
* Currently used by: * Currently used by:
* - ru.windcorp.fork.io.github.java-graphics:glm:1.0.1 * - ru.windcorp.fork.io.github.java-graphics:glm:1.0.1
*/ */
@ -75,262 +80,308 @@ dependencies {
// A unit-testing library // A unit-testing library
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
// See LWJGL dependencies below // Also see LWJGL dependencies in build_logic/lwjgl.gradle
} }
/* /*
* Progressia uses the following LWJGL libraries: * Version resolution
* - Core libraries
* - OpenGL
* - OpenAL
* - GLFW
* - STB
*/ */
/* import org.ajoberstar.grgit.*
* LWJGL
* (auto-generated script)
* ((here be dragons))
*/
import org.gradle.internal.os.OperatingSystem // Pattern: vMAJOR.MINOR.PATCH[-SUFFIX]
project.ext.tagFormat = /^v(\d+)\.(\d+)\.(\d+)(-[\w\-]*)?$/
project.ext.lwjglVersion = "3.2.3" String version_parseVersion(String tag, boolean increment) {
try {
switch (OperatingSystem.current()) {
case OperatingSystem.LINUX: def data = (tag =~ tagFormat)[0]
def osArch = System.getProperty("os.arch")
project.ext.lwjglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64") def major = data[1]
? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}" def minor = data[2]
: "natives-linux" def patch = data[3] as int
break def suffix = data[4] ?: ''
case OperatingSystem.MAC_OS:
project.ext.lwjglNatives = "natives-macos" if (increment) {
break def oldVersion = "$major.$minor.$patch$suffix"
case OperatingSystem.WINDOWS: patch++
project.ext.lwjglNatives = System.getProperty("os.arch").contains("64") ? "natives-windows" : "natives-windows-x86" def newVersion = "$major.$minor.$patch$suffix"
break
} logger.info "Version parsed from Git: $oldVersion, incremented to $newVersion"
return newVersion
dependencies { } else {
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion") def newVersion = "$major.$minor.$patch$suffix"
logger.info "Version parsed from Git: $newVersion"
implementation "org.lwjgl:lwjgl" return newVersion
implementation "org.lwjgl:lwjgl-glfw"
implementation "org.lwjgl:lwjgl-openal"
implementation "org.lwjgl:lwjgl-opengl"
implementation "org.lwjgl:lwjgl-stb"
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
}
// LWJGL END
/*
* Tasks
*/
/*
* Additional native libraries specification
*/
project.ext.platforms = new HashSet<>()
task addNativeDependencies {
doFirst {
def archs = project.ext.platforms
switch (archs.size()) {
case 0:
println "Adding LWJGL native dependencies for local platform only:\n\t$lwjglNatives"
archs.add project.ext.lwjglNatives
break
case 1:
println "Adding LWJGL native dependencies for platform\n\t" + archs.get(0)
break
default:
println "Adding LWJGL native dependencies for platforms:\n\t" + archs.join("\n\t")
}
if (project.ext.lwjglNatives.isEmpty()) println "WTF"
dependencies {
archs.each { arch ->
runtimeOnly "org.lwjgl:lwjgl::$arch"
runtimeOnly "org.lwjgl:lwjgl-glfw::$arch"
runtimeOnly "org.lwjgl:lwjgl-openal::$arch"
runtimeOnly "org.lwjgl:lwjgl-opengl::$arch"
runtimeOnly "org.lwjgl:lwjgl-stb::$arch"
}
}
}
}
compileJava.mustRunAfter addNativeDependencies // Make sure runtimeOnly has not been resolved
task requestLinuxDependencies {
description 'Adds linux, linux-arm64 and linux-arm32 native libraries to built artifacts.'
doFirst {
project.ext.platforms.addAll([
'natives-linux',
'natives-linux-arm64',
'natives-linux-arm32'
])
}
}
task requestWindowsDependencies {
description 'Adds windows and windows-x86 native libraries to built artifacts.'
doFirst {
project.ext.platforms.addAll([
'natives-windows',
'natives-windows-x86'
])
}
}
task requestMacOSDependencies {
description 'Adds macos native libraries to built artifacts.'
doFirst {
project.ext.platforms.addAll(['natives-macos'])
}
}
def dependencySpecificationTasks = tasks.findAll { task -> task.name.startsWith('request') && task.name.endsWith('Dependencies') }
task requestCrossPlatformDependencies {
description 'Adds native libraries for all available platforms to built artifacts.'
dependsOn dependencySpecificationTasks
}
addNativeDependencies.mustRunAfter dependencySpecificationTasks
/*
* Determines if the provided dependency should be packaged
*/
def isDependencyRequested(String dep) {
if (dep.endsWith(".jar")) {
dep = dep.substring(0, dep.length() - ".jar".length())
}
return !dep.contains("natives-") ||
project.ext.platforms.contains(dep.substring(dep.indexOf("natives-"), dep.length()))
}
/*
* Manifest specification
*/
task specifyLocalManifest {
dependsOn addNativeDependencies // Make sure all native dependencies are specified
doFirst {
def classPath = []
configurations.runtimeClasspath.each {
if (isDependencyRequested(it.getName())) {
classPath.add("lib/" + it.getName())
} else {
println "\tRemoving from JAR classpath (not requested): " + it.getName()
}
}
if (classPath.size() == configurations.runtimeClasspath.size()) {
println "Nothing removed from JAR classpath"
} }
def version = "dev"; } catch (any) {
def commit = "-"; logger.warn "Could not parse version from tag \"$tag\""
def branch = "-"; return tag
def buildId = project.findProperty('buildId') ?: "-"; }
}
Tag version_findRelevantTag(Grgit git) {
def tags = git.tag.list()
def commits = [ git.head() ]
def visited = new HashSet<>()
while (true) {
if (commits.isEmpty()) return null
def nextCommits = new HashSet<>()
def formatSpecificationPrinted = false
for (def commit : commits) {
def tag = tags.findAll { it.commit == commit } ?.max { it.dateTime }
if (tag != null) {
if (tag.name ==~ tagFormat) {
return tag
} else {
if (!formatSpecificationPrinted) {
formatSpecificationPrinted = true
logger.info 'Expecting tag format: vMAJOR.MINOR.PATCH[-SUFFIX]'
}
logger.info 'Ignoring tag due to invalid format: {}', tag.name
}
}
nextCommits.addAll commit.parentIds.collect(git.resolve.&toCommit)
}
visited.addAll commits
nextCommits.removeAll visited
commits = nextCommits
}
}
task resolveVersion {
description 'Resolves version information from Git repository or project properties.'
doFirst {
try { try {
def git = org.ajoberstar.grgit.Grgit.open() def git = Grgit.open(dir: project.projectDir)
def head = git.head()
commit = head.id project.ext.commit = git.head().id
branch = git.branch.current().name project.ext.branch = git.branch.current().name
def newestTag = git.tag.list().findAll { it.commit == head } ?.max { it.dateTime } ?.name if (project.version != 'unspecified') {
if (newestTag != null) { // Leave version as-is
version = newestTag; return
} else if (project.hasProperty('buildId')) { }
version = project.buildId;
def tag = version_findRelevantTag(git)
if (tag == null) {
String suffix
if (project.hasProperty('buildId')) {
suffix = project.buildId;
} else {
suffix = java.time.ZonedDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern('yyyy_MM_dd'))
}
project.version = "999.0.0-$suffix"
logger.warn 'Git repository does not contain an applicable tag, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
} else { } else {
version = head.dateTime.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE);
project.version = version_parseVersion(tag.name, tag.commit != git.head())
} }
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) { } catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
println "No Git repository found in project root" if (project.version == 'unspecified') project.version = 'dev'
} project.ext.commit = '-'
project.ext.branch = '-'
jar { logger.warn 'No Git repository found in project root, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
manifest { }
attributes( }
"Main-Class": "ru.windcorp.progressia.client.ProgressiaClientMain",
"Class-Path": configurations.runtimeClasspath.collect { "lib/" + it.getName() } .findAll { isDependencyRequested(it) } .join(' '), doLast {
if (!project.hasProperty('buildId')) {
"Specification-Title": "Progressia", project.ext.buildId = '-'
"Implementation-Title": "Progressia",
"Implementation-Version": version,
"Implementation-Version-Git-Commit": commit,
"Implementation-Version-Git-Branch": branch,
"Implementation-Version-BuildId": buildId,
)
}
} }
} }
} }
jar.dependsOn specifyLocalManifest
/* /*
* Library export * Configure JAR manifest
*/
task configureManifest {
description 'Populates JAR manifest with Main-Class, Class-Path and version metadata.'
jar.dependsOn configureManifest
dependsOn resolveVersion
doFirst {
jar.manifest.attributes(
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
'Class-Path': configurations.runtimeClasspath.collect { "lib/${it.name}" } .join(' '),
'Specification-Title': 'Progressia',
'Implementation-Title': 'Progressia',
'Implementation-Version': project.version,
'Implementation-Version-Git-Commit': project.commit,
'Implementation-Version-Git-Branch': project.branch,
'Implementation-Version-BuildId': project.buildId,
)
}
}
/*
* Copy libraries into buil/libs/lib directory, next to Progressia.jar
*/ */
task exportLibs(type: Sync) { task exportLibs(type: Sync) {
mustRunAfter addNativeDependencies description 'Copies runtime libraries into a subdirectory next to the output JAR.'
jar.dependsOn exportLibs
into libsDirectory.get().getAsFile().getPath() + "/lib"
exclude { !isDependencyRequested(it.getName()) }
from configurations.runtimeClasspath from configurations.runtimeClasspath
into 'build/libs/lib'
} }
jar.dependsOn(exportLibs)
/* /*
* Packaging * Apply LWJGL logic
*/
apply from: 'build_logic/lwjgl.gradle'
/*
* Packaging working directory configuration
*/ */
task packageDebian(type: Exec) { import java.nio.file.*
description 'Builds the project and creates a Debain package.' import java.nio.file.attribute.*
group 'Progressia'
dependsOn build
dependsOn requestLinuxDependencies
commandLine './buildPackages.sh', 'debian'
task createPackagingDirs() {
description 'Resets build/tmp/packaging directory.'
doLast { doLast {
println "Debian package available in build_packages/" def tmpDir = buildDir.toPath().resolve 'tmp/packaging'
def nuke = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
} else {
// directory iteration failed
throw e;
}
}
}
// Fckn nuke tmpDir from orbit
// I'm so done with deleting file trees in Java/Groovy/whatever
// ...Not using File.deleteDir() because the latter recurses into symlinks, and we don't want to wipe build/libs/lib
if (Files.exists(tmpDir)) {
Files.walkFileTree tmpDir, nuke
}
Files.createDirectories tmpDir.resolve('workingDir')
Files.createDirectories buildDir.toPath().resolve('packages')
}
}
task linkBuildOutputForPackaging() {
description 'Symlinks the contents of build/libs into packaging working directory.'
dependsOn build
dependsOn createPackagingDirs
onlyIf { preparePackaging.ext.mode == 'symlink' }
doLast {
def from = buildDir.toPath().resolve 'libs'
def into = buildDir.toPath().resolve "tmp/packaging/workingDir/${preparePackaging.ext.buildDest}"
Files.createDirectories into
Files.list(from).each {
def fileName = it.fileName.toString()
// Exclude all JARs except the current one
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
return
Files.createSymbolicLink into.resolve(it.fileName), it
}
}
}
task copyBuildOutputForPackaging(type: Copy) {
description 'Copies the contents of build/libs into packaging working directory.'
dependsOn build
dependsOn createPackagingDirs
onlyIf { preparePackaging.ext.mode == 'copy' }
from 'build/libs'
filesMatching("${project.name}*.jar") {
include tasks.jar.archiveFileName.get()
}
into "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
}
task preparePackaging {
preparePackaging.ext.buildDest = ''
preparePackaging.ext.mode = 'symlink'
dependsOn createPackagingDirs
dependsOn linkBuildOutputForPackaging
dependsOn copyBuildOutputForPackaging
}
/*
* Apply all packaging scripts
*/
new File(projectDir, 'build_logic/packaging').list().each {
apply from: "build_logic/packaging/$it/script.gradle"
}
/*
* Ensure no more than one packaging task is scheduled
*/
gradle.taskGraph.whenReady { graph ->
if (graph.allTasks.count { it.name ==~ /package[^_]*/ } > 1) {
def offenders = graph.allTasks.findAll { it.name ==~ /package[^_]*/ }
throw new GradleException("Cannot execute multiple package tasks within a single build\n" +
"\tOffending tasks: $offenders")
} }
} }
task packageWindows(type: Exec) {
description 'Builds the project and creates a Windows installer.'
group 'Progressia'
dependsOn build
dependsOn requestWindowsDependencies
commandLine './buildPackages.sh', 'windows' /*
* Convenience build tasks
doLast { */
println "Windows installer available in build_packages/"
}
}
task buildCrossPlatform { task buildCrossPlatform {
description 'Builds the project including native libraries for all available platforms.' description 'Builds the project including native libraries for all available platforms.'
@ -340,17 +391,17 @@ task buildCrossPlatform {
dependsOn build dependsOn build
doLast { doLast {
println "Native libraries for all platforms have been added" logger.info 'Native libraries for all platforms have been added'
} }
} }
task buildLocal { task buildLocal {
description "Builds the project including only native libraries for current platform ($lwjglNatives)." description "Builds the project including only native libraries for current platform (${lwjgl.localArch})."
group 'Progressia' group 'Progressia'
dependsOn build dependsOn build
doLast { doLast {
println "Native libraries only for platform $lwjglNatives have been added" logger.info "Native libraries only for platform ${lwjgl.localArch} have been added"
} }
} }

View File

@ -1,191 +0,0 @@
#!/bin/bash
#
# Progressia
# Copyright (C) 2020-2021 Wind Corporation and contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
echoerr() { echo "$@" 1>&2; }
buildDebianPackage() {
# Commands that must be available to execute this action
requiredCommands='dpkg-deb fakeroot'
# Package name. Sync with control file manually!
name='progressia-techdemo'
# Version that the package will receive. Sync with control file manually!
version='1.0_all'
# This directory will be copied into $tmpDir
templateDirectory="build_packages/DEB/template"
# Files that must be present
requiredFiles="$templateDirectory/DEBIAN/control"
nameAndVersion="$name-$version"
tmpDir="build_packages/DEB/$nameAndVersion"
outputFile="build_packages/DEB/$nameAndVersion.deb"
echo "Checking environment to build Debian package"
for item in $requiredCommands; do
if command -v "$item" &> /dev/null; then
echo "- $item found"
else
echoerr "Command $item not found, cannot package"
exit 100
fi
done
for file in $requiredFiles; do
if ! [ -r "$file" ]; then
echoerr "$file is missing or not readable, cannot package"
exit 101
else
echo "- $file is present and readable"
fi
done
echo "Environment OK; packaging Debian package"
exitCode=0
{
shareDir="$tmpDir/usr/share/progressia"
mkdir -p "$tmpDir" &&
mkdir -p "$shareDir" &&
cp -r "$templateDirectory"/* "$tmpDir" &&
cp -r 'build/libs/lib' "$shareDir/lib" &&
cp 'build/libs/Progressia.jar' "$shareDir/Progressia.jar" &&
echo "------ DPKG-DEB ------" &&
fakeroot dpkg-deb --build "$tmpDir" &&
echo "---- DPKG-DEB END ----" &&
mv "$outputFile" build_packages
} || {
echoerr "Could not create Debian package"
exitCode=1
}
{
if [ -d "$tmpDir" ]; then
rm -r "$tmpDir"
fi
echo "Cleaned up"
} || {
echoerr "Could not clean up after packaging Debian package"
exitCode=2
}
exit "$exitCode"
}
buildWindowsInstaller() {
# Commands that must be available to execute this action
requiredCommands='makensis'
# NSIS configuration file that must be present
configurationFile='build_packages/NSIS/ProgressiaInstaller.nsi'
# File that will be output
outputFile='build_packages/NSIS/ProgressiaInstaller.exe'
echo "Checking environment to build Windows installer"
for item in $requiredCommands; do
if command -v "$item" &> /dev/null; then
echo "- $item found"
else
echoerr "Command $item not found, cannot build"
exit 100
fi
done
if ! [ -r "$configurationFile" ]; then
echoerr "$configurationFile is missing or not readable, cannot build"
exit 101
else
echo "- $configurationFile is present and readable"
fi
echo "Environment OK; building Windows installer"
exitCode=0
{
cp -r 'build/libs/lib' 'build_packages/NSIS/lib' &&
cp 'build/libs/Progressia.jar' 'build_packages/NSIS/Progressia.jar' &&
cp 'LICENSE' 'build_packages/NSIS/LICENSE.txt' &&
echo "------ NSIS ------" &&
makensis "$configurationFile" &&
echo "---- NSIS END ----" &&
mv "$outputFile" build_packages
} || {
echoerr "Could not build Windows installer"
exitCode=1
}
{
if [ -d 'build_packages/NSIS/lib' ]; then
rm -r 'build_packages/NSIS/lib'
fi
if [ -e 'build_packages/NSIS/Progressia.jar' ]; then
rm 'build_packages/NSIS/Progressia.jar'
fi
if [ -e 'build_packages/NSIS/LICENSE.txt' ]; then
rm 'build_packages/NSIS/LICENSE.txt'
fi
echo "Cleaned up"
} || {
echoerr "Could not clean up after building Windows installer"
exitCode=2
}
exit "$exitCode"
}
printUsage() {
echoerr "Usage: $0 TARGET"
echoerr " where TARGET is 'debian' or 'windows'"
}
if [ -n "$2" ]; then
echoerr "Too many arguments."
printUsage
exit 202
fi
case "$1" in
"debian")
buildDebianPackage
;;
"windows")
buildWindowsInstaller
;;
"")
echoerr "No action specified"
printUsage
exit 200
;;
"--help" | "-help" | "help" | "?")
printUsage
;;
*)
echoerr "Unknown action '$1'"
printUsage
exit 201
;;
esac

117
build_logic/lwjgl.gradle Normal file
View File

@ -0,0 +1,117 @@
/*
* Build logic for Progressia
* LWJGL dependency logic
*/
project.ext.lwjgl = new HashMap<>()
// Version of LWJGL
lwjgl.version = '3.2.3'
/*
* Target platforms for current operation.
* This is filled in by the request* tasks. This is referenced by the addLwjglNatives task.
* When empty, current platform is assumed.
*/
lwjgl.targets = new HashSet<>()
// LWJGL components. To include org.lwjgl:lwjgl-foobar, add 'foobar' to this list.
lwjgl.libraries = [
'opengl',
'glfw',
'openal',
'stb'
]
// Determine the architecture of the build environment
import org.gradle.internal.os.OperatingSystem
switch (OperatingSystem.current()) {
case OperatingSystem.LINUX:
def osArch = System.getProperty('os.arch')
lwjgl.localArch = osArch.startsWith('arm') || osArch.startsWith('aarch64')
? "linux-${osArch.contains('64') || osArch.startsWith('armv8') ? 'arm64' : 'arm32'}"
: 'linux'
break
case OperatingSystem.MAC_OS:
lwjgl.localArch = 'macos'
break
case OperatingSystem.WINDOWS:
lwjgl.localArch = System.getProperty('os.arch').contains('64') ? 'windows' : 'windows-x86'
break
}
// Declare pure-Java dependencies
dependencies {
// BOM
implementation platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
// Core
implementation 'org.lwjgl:lwjgl'
// Components
lwjgl.libraries.each { implementation "org.lwjgl:lwjgl-$it" }
}
/*
* Adds LWJGL native libraries to runtimeOnly configuration
*/
task lwjgl_addNativesToRuntimeOnly {
// Make sure runtimeOnly has not been resolved
compileJava.dependsOn lwjgl_addNativesToRuntimeOnly
configureManifest.dependsOn lwjgl_addNativesToRuntimeOnly
exportLibs.dependsOn lwjgl_addNativesToRuntimeOnly
doFirst {
if (project.hasProperty('forceTargets')) {
try {
def oldTargets = lwjgl.targets.join(',')
lwjgl.targets.clear()
lwjgl.targets.addAll project.forceTargets.split(',')*.trim().collect { it == 'local' ? lwjgl.localArch : it }
logger.info 'Overriding selected platforms {} with {}', oldTargets, lwjgl.targets.join(',')
} catch (Exception e) {
throw new GradleException("Could not parse forceTargets \"${project.forceTargets}\", expecting platform-1,platform-2,local", e)
}
}
if (lwjgl.targets.isEmpty()) {
logger.info 'Adding LWJGL native dependencies for local platform only: {}', lwjgl.localArch
lwjgl.targets.add lwjgl.localArch
} else {
logger.info 'Adding LWJGL native dependencies for platforms: {}', lwjgl.targets.sort().join(', ')
}
dependencies {
lwjgl.targets.each { target ->
runtimeOnly "org.lwjgl:lwjgl::natives-$target"
lwjgl.libraries.each { lib ->
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-$target"
}
}
}
}
}
task requestCrossPlatformDependencies {
description 'Adds LWJGL natives for all available platforms.'
lwjgl_addNativesToRuntimeOnly.mustRunAfter requestCrossPlatformDependencies
}
def requestTask(String name, String... targets) {
def theTask = task "request${name}Dependencies"
theTask.doFirst {
lwjgl.targets.addAll targets
}
theTask.description "Adds LWJGL natives for $name (${targets.join(', ')})."
requestCrossPlatformDependencies.dependsOn theTask
lwjgl_addNativesToRuntimeOnly.mustRunAfter theTask
}
requestTask 'Linux', 'linux', 'linux-arm32', 'linux-arm64'
requestTask 'Windows', 'windows', 'windows-x86'
requestTask 'MacOS', 'macos'

View File

@ -0,0 +1,38 @@
task packageDeb_processResources(type: Copy) {
dependsOn resolveVersion
dependsOn preparePackaging
from 'src/packaging/deb'
filesMatching('DEBIAN/control') {
expand(version: { -> project.version})
}
into 'build/tmp/packaging/workingDir'
}
task packageDeb_configure() {
preparePackaging.mustRunAfter packageDeb_configure
doLast {
tasks.preparePackaging.ext.buildDest = '/usr/share/progressia'
tasks.preparePackaging.ext.mode = 'copy'
}
}
task packageDeb(type: Exec) {
description 'Builds the project and creates a Debian package.'
group 'Progressia'
dependsOn packageDeb_configure
dependsOn requestLinuxDependencies
dependsOn build
dependsOn preparePackaging
dependsOn packageDeb_processResources
executable 'dpkg-deb'
args '--root-owner-group'
args '--build', 'build/tmp/packaging/workingDir'
args 'build/packages'
}

View File

@ -0,0 +1,50 @@
task packageNsis_processResources(type: Copy) {
dependsOn preparePackaging
from ('src/packaging/nsis') {
exclude 'left_side.png'
}
from('LICENSE') {
rename 'LICENSE', 'LICENSE.txt'
}
into 'build/tmp/packaging/workingDir'
}
task packageNsis_generateIcon(type: Exec) {
mustRunAfter preparePackaging
executable 'convert'
args files('src/main/resources/assets/icons/*.original.png').files*.path
args 'build/tmp/packaging/workingDir/logo.ico'
}
task packageNsis_generateLeftSide(type: Exec) {
mustRunAfter preparePackaging
executable 'convert'
args 'src/packaging/nsis/left_side.png'
args '-alpha', 'off'
args 'BMP3:build/tmp/packaging/workingDir/left_side.bmp'
}
task packageNsis(type: Exec) {
description 'Builds the project and creates a Windows NSIS installer.'
group 'Progressia'
dependsOn requestWindowsDependencies
dependsOn build
dependsOn resolveVersion
dependsOn preparePackaging
dependsOn packageNsis_processResources
dependsOn packageNsis_generateIcon
dependsOn packageNsis_generateLeftSide
executable 'makensis'
args '-NOCONFIG'
args "-DPROJECT_NAME=${project.name}"
args "-DPROJECT_VERSION=${ -> project.version}"
args "-DMAIN_JAR_FILE=${ -> project.tasks.jar.archiveFileName.get()}"
args "-DOUTPUT_DIR=${project.buildDir.absolutePath}/packages"
args 'build/tmp/packaging/workingDir/config.nsi'
}

View File

@ -0,0 +1,41 @@
task packageZip_processResources(type: Copy) {
dependsOn preparePackaging
from ('src/packaging/zip') {
filesMatching('start.*') {
filter(
org.apache.tools.ant.filters.ReplaceTokens,
tokens: [mainJarFile: project.tasks.jar.archiveFileName.get()]
)
}
}
from ('src/main/resource/assets/icons/logo256.original.png') {
rename 'logo256.original.png', 'logo.png'
}
from('LICENSE') {
rename 'LICENSE', 'LICENSE.txt'
}
into 'build/tmp/packaging/workingDir'
}
task packageZip(type: Zip) {
description 'Builds the project and creates a cross-platform ZIP package.'
group 'Progressia'
dependsOn resolveVersion
dependsOn requestCrossPlatformDependencies
dependsOn build
dependsOn preparePackaging
dependsOn packageZip_processResources
archiveBaseName = project.name
archiveAppendix = 'universal'
doFirst {
archiveVersion = project.version
}
from 'build/tmp/packaging/workingDir'
destinationDirectory = file('build/packages')
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

View File

@ -1,8 +1,10 @@
# Build Guide # Build Guide
This document is a guide to building Progressia from source. This document is a guide to building Progressia from source. For quick reference, see
[Build Script Reference](BuildScriptReference.md).
Compilation should be possible on all platforms that support JDK 8 or later, however, packaging scripts require Bash. Compilation should be possible on all platforms that support JDK 8 or later, however, packaging scripts require
additional programs in `PATH`.
This guide assumes you are familiar with using a terminal or Windows Command Prompt or PowerShell. This guide assumes you are familiar with using a terminal or Windows Command Prompt or PowerShell.
@ -150,54 +152,46 @@ GNU/Linux and Windows natives:
./gradlew build requestLinuxDependencies requestWindowsDependencies ./gradlew build requestLinuxDependencies requestWindowsDependencies
``` ```
For finer control please edit `build.gradle` manually by adding the desired natives to the `project.ext.platforms` set like so:
```
project.ext.platforms = new HashSet<>()
project.ext.platforms.add 'natives-windows-x86'
```
## Packaging ## Packaging
A Debian package and a Windows installer can be created automatically on systems that support Bash. These tasks are delegated A universal ZIP distribution, a Debian package and a Windows NSIS installer may be created automatically by the build
by Gradle to `buildPackages.sh` in repository root. This script checks the environment and assembles the requested output; the script.
resulting files are moved into `build_packages`.
### Creating a universal ZIP package
A universal cross-platform ZIP archive can be created with the following Gradle task:
```
./gradlew packageZip
```
Gradle will then build all artifacts necessary to run the game on all available platforms and package game files,
libraries, launch scripts, etc. into a compressed ZIP archive.
The resulting file can be found in `build/packages/`
### Creating a Debian package ### Creating a Debian package
A Debian package can be created with the following Gradle task: A Debian package can be created with the following Gradle task:
``` ```
./gradlew packageDebian ./gradlew packageDeb
``` ```
Gradle will then build all artifacts necessary to run the game on GNU/Linux (all three architectures) and invoke Gradle will then build all artifacts necessary to run the game on GNU/Linux (all three architectures) and invoke
`./buildPackages.sh debian`. Commands `dpkg-deb` and `fakeroot` must be available in system path in order to build the package. `dpkg-deb`. Commands `dpkg-deb` must be available in system path in order to build the package.
### Creating a Windows installer ### Creating a Windows installer
A Windows installer can be created with the following Gradle task: A Windows NSIS installer can be created with the following Gradle task:
``` ```
./gradlew packageWindows ./gradlew packageNsis
``` ```
Gradle will then build all artifacts necessary to run the game on Windows (both x64 and x86 architectures) and invoke Gradle will then build all artifacts necessary to run the game on Windows (both x64 and x86 architectures) and invoke
`./buildPackages.sh windows`. `makensis`.
Windows installers are implemented with [NSIS](https://nsis.sourceforge.io/). Command `makensis` must be available in system Windows installers are implemented with [NSIS](https://nsis.sourceforge.io/). [ImageMagick](https://imagemagick.org),
path in order to build the installer. a command-line image editing tool, is used to generate some assets for the installer. Commands `makensis` and
`convert` (from ImageMagick) must be available in system path in order to build the installer.
## Gradle tasks summary
- `buildLocal` creates a build optimized for current platform. Use this to quickly build the game during development.
- `buildCrossPlatform` creates a build that supports all known architectures. Use this to build a universal version of the game.
- `build` currently a synonym of `buildLocal`; creates a default build.
- `packageDebian` creates a Debian package. Do not invoke together with `packageWindows`.
- `packageWindows` creates a Windows installer. Do not invoke together with `packageDebian`.
- `requestLinuxDependencies` requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included when building.
- `requestWindowsDependencies` requests that `natives-windows` and `natives-windows-x86` binaries are included when building.
- `requestMacOSDependencies` requests that `natives-macos` binaries are included when building.
- `requestCrossPlatformDependencies` requests that all binaries are included when building.
All other basic and Java-related Gradle tasks are available as well.

View File

@ -0,0 +1,103 @@
# Build Script Reference
This document is a user's reference for the build script of Progressia. For a beginner-friendly guide, see
[Build Guide](BuildGuide.md).
## Gradle tasks summary
- `buildLocal` creates a build optimized for current platform. Use this to quickly build the game during development.
- `buildCrossPlatform` creates a build that supports all known architectures. Use this to build a universal version of the game.
- `build` currently a synonym of `buildLocal`; creates a default build.
- `packageZip` creates a universal ZIP. Incompatible with other `package` tasks.
- `packageDeb` creates a Debian package. Incompatible with other `package` tasks.
- `packageNsis` creates a Windows NSIS installer. Incompatible with other `package` tasks.
- `requestLinuxDependencies` requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included when building.
- `requestWindowsDependencies` requests that `natives-windows` and `natives-windows-x86` binaries are included when building.
- `requestMacOSDependencies` requests that `natives-macos` binaries are included when building.
- `requestCrossPlatformDependencies` requests that all binaries are included when building.
To execute a task, run `./gradlew <task-name>`.
`build`-type tasks output the executable JAR and all libraries required at runtime into `build/libs`. `package`-type
tasks output packages into `build/packages`.
## Packaging tasks
Some packaging tasks require additional software in `PATH`.
| Task | Commands required in `PATH` |
|---------------|------------------------------------------|
| `packageDeb` | `dpkg-deb` |
| `packageZip` | _none_ |
| `packageNsis` | `makensis`, `convert` (from ImageMagick) |
## Version and metadata
### Version scheme
Progressia builds are identified by four parameters: version, Git commit, Git branch and build ID.
Versions roughly follow [semantic versioning](https://semver.org/spec/v2.0.0.html), with each version fitting the
`MAJOR.MINOR.PATCH[-SUFFIX]` pattern. Depending on the build environment (see below), version is either "real" with
no metadata (e.g. `0.43.2` or `1.2.1-beta`) or a dummy fallback with build metadata (e.g. `999.0.0-2021_07_23` or
`999.0.0-WJ3`).
### Version detection
Build script considers three scenarios when determining the version:
1. `version` project property is set explicitly. This may be done in a variety of ways, for example with command line
argument `-Pversion=1.2.3`
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties))
2. Local Git repository is found, and HEAD is tagged appropriately: version is the tag name with leading `v`
stripped. Example: `v1.2.3` is version `1.2.3`
3. Local Git repository is found, and some ancestor of HEAD is tagged appropriately: version is the tag name with
leading `v` stripped and PATCH incremented by one. Example: `v1.2.3` is version `1.2.4`
Tags not named like `vMAJOR.MINOR.PATCH[-SUFFIX]` are ignored for cases 2 and 3.
In all other cases, a fallback dummy value is used for version, appended with build ID or current date.
### Git metadata
Git commit and Git branch are correspond to the state of the local Git repository, if any. In case Git metadata is
unavailable, `-` fallback is used for both fields.
### Build ID
Build ID uniquely identifies artifacts produced by automated build systems. For example, builds executed by WindCorp
Jenkins suite have build IDs like `WJ3` or `WJ142`. Build ID must be provided explicitly; it is `-` unless specified
otherwise.
Build ID may be set with `buildId` project property. This may be done in a variety of ways, for example with command
line argument `-PbuildId=WJ3`
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties)).
## Native libraries
LWJGL uses native libraries. Build script declares platform-specific dependencies based on the set of target
platforms, `project.ext.lwjgl.targets` (aka `lwjgl.targets`). These dependencies are added to `runtimeOnly`
configuration.
When this set is empty, the script selects natives for current platform. Otherwise, all platforms in the set are
included.
`lwjgl.targets` is populated automatically by packaging tasks and by `buildCrossPlatform`. To add extra targets,
``requestXxxDependencies` tasks may be used.
Target selection mechanism may be overridden with `forceTargets` project property. This may be done in a variety of
ways, for example with command line argument `-PforceTargets=windows-x86,local`
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties)). The
value is a comma-separated list of target architectures. `local` target will be replaced with the automatically
detected current architecture.
### Available targets
| Name | Task |
|---------------|------------------------------|
| `linux` | `requestLinuxDependencies` |
| `linux-arm32` | `requestLinuxDependencies` |
| `linux-arm64` | `requestLinuxDependencies` |
| `windows` | `requestWindowsDependencies` |
| `windows-x86` | `requestWindowsDependencies` |
| `macos` | `requestMacOSDependencies` |

View File

@ -1,8 +1,8 @@
Package: progressia-techdemo Package: progressia
Version: 1.0 Version: ${version}
Section: custom Section: custom
Priority: optional Priority: optional
Architecture: all Architecture: all
Maintainer: Javapony <kvadropups@gmail.com> Maintainer: Javapony <kvadropups@gmail.com>
Depends: java8-runtime Depends: java8-runtime
Description: Progressia Techdemo release Description: Progressia - a 3D sandbox survival game

View File

@ -1,161 +1,164 @@
;NSIS Modern User Interface ;NSIS Modern User Interface
;Welcome/Finish Page Example Script ;Welcome/Finish Page Example Script
;Written by Joost Verburg ;Written by Joost Verburg
;-------------------------------- ;--------------------------------
;Include Modern UI ;Include Modern UI
!include "MUI2.nsh" !include "MUI2.nsh"
;-------------------------------- ;--------------------------------
;General ;General
!define PROJECT_NAME "Progressia" ; Expecting the following symbols from caller:
; PROJECT_NAME
; MUI Settings / Icons ; PROJECT_VERSION
!define MUI_ICON "logo.ico" ; MAIN_JAR_FILE
;!define MUI_UNICON ;Uninstall icon
; MUI Settings / Icons
; MUI Settings / Header !define MUI_ICON "logo.ico"
; !define MUI_HEADERIMAGE ;!define MUI_UNICON ;Uninstall icon
; !define MUI_HEADERIMAGE_RIGHT
; !define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-r-nsis.bmp" ; MUI Settings / Header
; !define MUI_HEADERIMAGE_UNBITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-uninstall-r-nsis.bmp" ; !define MUI_HEADERIMAGE
; !define MUI_HEADERIMAGE_RIGHT
; MUI Settings / Wizard ; !define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-r-nsis.bmp"
!define MUI_WELCOMEFINISHPAGE_BITMAP "left_side.bmp" ; !define MUI_HEADERIMAGE_UNBITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-uninstall-r-nsis.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "left_side.bmp"
; MUI Settings / Wizard
;Name and file !define MUI_WELCOMEFINISHPAGE_BITMAP "left_side.bmp"
Name "${PROJECT_NAME}" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "left_side.bmp"
OutFile "${PROJECT_NAME}Installer.exe"
Unicode True ;Name and file
Name "${PROJECT_NAME}"
;Default installation folder OutFile "${OUTPUT_DIR}/${PROJECT_NAME}-${PROJECT_VERSION}-installer.exe"
InstallDir "$PROGRAMFILES\${PROJECT_NAME}" Unicode True
;Get installation folder from registry if available ;Default installation folder
InstallDirRegKey HKLM "Software\${PROJECT_NAME}" "" InstallDir "$PROGRAMFILES\${PROJECT_NAME}"
;Request application privileges for Windows Vista ;Get installation folder from registry if available
RequestExecutionLevel admin InstallDirRegKey HKLM "Software\${PROJECT_NAME}" ""
;-------------------------------- ;Request application privileges for Windows Vista
;Interface Settings RequestExecutionLevel admin
!define MUI_ABORTWARNING ;--------------------------------
;Interface Settings
;--------------------------------
;Pages !define MUI_ABORTWARNING
!insertmacro MUI_PAGE_WELCOME ;--------------------------------
!insertmacro MUI_PAGE_LICENSE "LICENSE.txt" ;Pages
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
!define MUI_FINISHPAGE_RUN !insertmacro MUI_PAGE_COMPONENTS
!define MUI_FINISHPAGE_RUN_TEXT "Start ${PROJECT_NAME}" !insertmacro MUI_PAGE_DIRECTORY
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink" !insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH !define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_TEXT "Start ${PROJECT_NAME}"
!insertmacro MUI_UNPAGE_WELCOME !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
!insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_COMPONENTS
!insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_COMPONENTS
;-------------------------------- !insertmacro MUI_UNPAGE_INSTFILES
;Languages !insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English" ;--------------------------------
;Languages
;--------------------------------
;Installer Sections !insertmacro MUI_LANGUAGE "English"
Section "Install ${PROJECT_NAME}" SEC0000 ;--------------------------------
;Installer Sections
SectionIn RO ;Make it read-only
SetOutPath "$INSTDIR" Section "Install ${PROJECT_NAME}" SEC0000
SetOverwrite on
SectionIn RO ;Make it read-only
;Files SetOutPath "$INSTDIR"
File Progressia.jar SetOverwrite on
File logo.ico
File /r lib ;Files
File "${MAIN_JAR_FILE}"
;Store installation folder File logo.ico
WriteRegStr HKLM SOFTWARE\Progressia "Install_Dir" "$INSTDIR" File /r lib
;Create uninstaller ;Store installation folder
WriteRegStr HKLM "SOFTWARE\${PROJECT_NAME}" "Install_Dir" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}" "DisplayName" "${PROJECT_NAME} (remove only)"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe" ;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}" "DisplayName" "${PROJECT_NAME} (remove only)"
SectionEnd WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteUninstaller "$INSTDIR\Uninstall.exe"
Section "Create Desktop Shortcut" SEC0001
SetOutPath "$APPDATA\${PROJECT_NAME}" SectionEnd
CreateShortCut "$DESKTOP\${PROJECT_NAME}.lnk" "$INSTDIR\${PROJECT_NAME}.jar" "" "$INSTDIR\logo.ico"
SectionEnd Section "Create Desktop Shortcut" SEC0001
SetOutPath "$APPDATA\${PROJECT_NAME}"
Section "Start Menu Shortcuts" SEC0002 CreateShortCut "$DESKTOP\${PROJECT_NAME}.lnk" "$INSTDIR\${MAIN_JAR_FILE}" "" "$INSTDIR\logo.ico"
SectionEnd
CreateDirectory "$SMPROGRAMS\${PROJECT_NAME}"
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" Section "Start Menu Shortcuts" SEC0002
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk" "$INSTDIR\${PROJECT_NAME}.jar" "" "$INSTDIR\logo.ico"
CreateDirectory "$SMPROGRAMS\${PROJECT_NAME}"
SectionEnd CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk" "$INSTDIR\${MAIN_JAR_FILE}" "" "$INSTDIR\logo.ico"
;--------------------------------
;Uninstaller Section SectionEnd
Section "Uninstall" ;--------------------------------
;Uninstaller Section
;ADD YOUR OWN FILES HERE...
Section "Uninstall"
Delete $INSTDIR\Uninstall.exe
Delete $INSTDIR\Progressia.jar ;ADD YOUR OWN FILES HERE...
Delete $INSTDIR\lib\*.*
Delete $INSTDIR\logo.ico Delete $INSTDIR\Uninstall.exe
Delete "$INSTDIR\${MAIN_JAR_FILE}"
RMDir $INSTDIR\lib Delete $INSTDIR\lib\*.*
Delete $INSTDIR\logo.ico
Delete $DESKTOP\${PROJECT_NAME}.lnk
RMDir $INSTDIR\lib
Delete $SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk
Delete $SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk Delete $DESKTOP\${PROJECT_NAME}.lnk
RMDir $INSTDIR Delete $SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk
Delete $SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk
RMDir /r $SMPROGRAMS\${PROJECT_NAME}
RMDir $INSTDIR
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}"
DeleteRegKey HKLM "Software\${PROJECT_NAME}" RMDir /r $SMPROGRAMS\${PROJECT_NAME}
SectionEnd DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROJECT_NAME}"
DeleteRegKey HKLM "Software\${PROJECT_NAME}"
Section "un.Remove user data"
SectionEnd
RMDir /r "$APPDATA\${PROJECT_NAME}"
Section "un.Remove user data"
SectionEnd
RMDir /r "$APPDATA\${PROJECT_NAME}"
;--------------------------------
;Functions SectionEnd
Function LaunchLink ;--------------------------------
SetOutPath "$APPDATA\${PROJECT_NAME}" ;Functions
ExecShell "" "$INSTDIR\${PROJECT_NAME}.jar"
FunctionEnd Function LaunchLink
SetOutPath "$APPDATA\${PROJECT_NAME}"
;-------------------------------- ExecShell "" "$INSTDIR\${MAIN_JAR_FILE}"
;Descriptions FunctionEnd
;Language strings ;--------------------------------
LangString DESC_SecDummy ${LANG_ENGLISH} "Install ${PROJECT_NAME}." ;Descriptions
;Assign language strings to sections ;Language strings
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN LangString DESC_SecDummy ${LANG_ENGLISH} "Install ${PROJECT_NAME}."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC0000} $(DESC_SecDummy)
!insertmacro MUI_FUNCTION_DESCRIPTION_END ;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC0000} $(DESC_SecDummy)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,2 @@
@ECHO OFF
java -jar "@mainJarFile@"

11
src/packaging/zip/start.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
jvmFlags=""
case "$OSTYPE" in
"darwin"*)
# On MacOS, use -XstartOnFirstThread to resolve an issue with OpenGL contexts
jvmFlags="$jvmFlags -XstartOnFirstThread"
esac
java $jvmFlags -jar "@mainJarFile@"