Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce RISC-V support #48

Merged
merged 11 commits into from
Nov 8, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,27 @@
import org.slf4j.LoggerFactory;

import com.badlogic.gdx.jnigen.BuildTarget;
import com.badlogic.gdx.jnigen.BuildTarget.TargetOs;
import com.badlogic.gdx.utils.Architecture;
import com.badlogic.gdx.utils.Os;

/**
* @author Desu
*/
public class JnigenExtension {
private static final Logger log = LoggerFactory.getLogger(JnigenExtension.class);

public static final boolean x32 = false;
public static final boolean x64 = true;
public static final boolean ARM = true;
public static final TargetOs Windows = TargetOs.Windows;
public static final TargetOs Linux = TargetOs.Linux;
public static final TargetOs MacOsX = TargetOs.MacOsX;
public static final TargetOs Android = TargetOs.Android;
public static final TargetOs IOS = TargetOs.IOS;

public static final Architecture.Bitness x32 = Architecture.Bitness._32;
public static final Architecture.Bitness x64 = Architecture.Bitness._64;
public static final Architecture.Bitness x128 = Architecture.Bitness._128;
public static final Architecture x86 = Architecture.x86;
public static final Architecture ARM = Architecture.ARM;
public static final Architecture RISCV = Architecture.RISCV;
public static final Os Windows = Os.Windows;
public static final Os Linux = Os.Linux;
public static final Os MacOsX = Os.MacOsX;
public static final Os Android = Os.Android;
public static final Os IOS = Os.IOS;

final Project project;

/**
Expand Down Expand Up @@ -82,36 +86,52 @@ public void all(Action<BuildTarget> container) {
public void robovm(Action<RoboVMXml> action) {
action.execute(robovm);
}

public void add(TargetOs type) {
add(type, false, false, null);

public void add(Os type) {
add(type, Architecture.Bitness._32);
}

public void add(Os type, Architecture.Bitness bitness) {
add(type, bitness, Architecture.x86);
}

public void add(TargetOs type, boolean is64Bit) {
public void add(Os type, Architecture.Bitness bitness, Architecture architecture) {
add(type, bitness, architecture, null);
}

@Deprecated
public void add(Os type, boolean is64Bit) {
add(type, is64Bit, false, null);
}

public void add(TargetOs type, boolean is64Bit, boolean isARM) {
@Deprecated
public void add(Os type, boolean is64Bit, boolean isARM) {
add(type, is64Bit, isARM, null);
}

public void add(TargetOs type, Action<BuildTarget> container) {
add(type, false, false, container);
public void add(Os type, Action<BuildTarget> container) {
add(type, Architecture.Bitness._32, Architecture.x86, container);
}

public void add(TargetOs type, boolean is64Bit, Action<BuildTarget> container) {
@Deprecated
public void add(Os type, boolean is64Bit, Action<BuildTarget> container) {
add(type, is64Bit, false, container);
}

public void add(TargetOs type, boolean is64Bit, boolean isARM, Action<BuildTarget> container) {
String name = type + (isARM ? "ARM" : "") + (is64Bit ? "64" : "");

if(get(type, is64Bit, isARM) != null)
@Deprecated
public void add(Os type, boolean is64Bit, boolean isARM, Action<BuildTarget> container) {
add(type, is64Bit ? Architecture.Bitness._64 : Architecture.Bitness._32, isARM ? Architecture.ARM : Architecture.x86, container);
}

public void add(Os type, Architecture.Bitness bitness, Architecture architecture, Action<BuildTarget> container) {
String name = type + architecture.toSuffix().toUpperCase() + bitness.toSuffix();

if(get(type, bitness, architecture) != null)
throw new RuntimeException("Attempt to add duplicate build target " + name);
if((type == Android || type == IOS) && (is64Bit || isARM))
throw new RuntimeException("Android and iOS must not have is64Bit or isARM.");
BuildTarget target = BuildTarget.newDefaultTarget(type, is64Bit, isARM);
if((type == Android || type == IOS) && bitness != Architecture.Bitness._32 && architecture != Architecture.x86)
throw new RuntimeException("Android and iOS must not have is64Bit or isARM or isRISCV.");

BuildTarget target = BuildTarget.newDefaultTarget(type, bitness, architecture);

if (all != null)
all.execute(target);
Expand Down Expand Up @@ -172,30 +192,46 @@ public void add(TargetOs type, boolean is64Bit, boolean isARM, Action<BuildTarge
jarDesktopNatives.add(target, this);
}
}
public BuildTarget get(TargetOs type) {
return get(type, false, false, null);

public BuildTarget get(Os type) {
return get(type, Architecture.Bitness._32, Architecture.x86, null);
}

public BuildTarget get(TargetOs type, boolean is64Bit) {
public BuildTarget get(Os type, Architecture.Bitness bitness) {
return get(type, bitness, Architecture.x86);
}

@Deprecated
public BuildTarget get(Os type, boolean is64Bit) {
return get(type, is64Bit, false, null);
}

public BuildTarget get(TargetOs type, boolean is64Bit, boolean isARM) {
@Deprecated
public BuildTarget get(Os type, boolean is64Bit, boolean isARM) {
return get(type, is64Bit, isARM, null);
}

public BuildTarget get(TargetOs type, Action<BuildTarget> container) {
return get(type, false, false, container);
public BuildTarget get(Os type, Architecture.Bitness bitness, Architecture architecture) {
return get(type, bitness, architecture, null);
}

public BuildTarget get(Os type, Action<BuildTarget> container) {
return get(type, Architecture.Bitness._32, Architecture.x86, container);
}

public BuildTarget get(TargetOs type, boolean is64Bit, Action<BuildTarget> container) {
@Deprecated
public BuildTarget get(Os type, boolean is64Bit, Action<BuildTarget> container) {
return get(type, is64Bit, false, container);
}

public BuildTarget get(TargetOs type, boolean is64Bit, boolean isARM, Action<BuildTarget> container) {
@Deprecated
public BuildTarget get(Os type, boolean is64Bit, boolean isARM, Action<BuildTarget> container) {
return get(type, is64Bit ? Architecture.Bitness._64 : Architecture.Bitness._32, isARM ? Architecture.ARM : Architecture.x86, container);
}

public BuildTarget get(Os type, Architecture.Bitness bitness, Architecture architecture, Action<BuildTarget> container) {
for(BuildTarget target : targets) {
if(target.os == type && target.is64Bit == is64Bit && target.isARM == isARM) {
if(target.os == type && target.bitness == bitness && target.architecture == architecture) {
if(container != null)
container.execute(target);
return target;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.w3c.dom.Element;

import com.badlogic.gdx.jnigen.BuildTarget;
import com.badlogic.gdx.jnigen.BuildTarget.TargetOs;
import com.badlogic.gdx.utils.Os;
import com.badlogic.gdx.jnigen.gradle.JnigenExtension.RoboVMXml.RoboVMXmlLib;

/**
Expand All @@ -47,7 +47,7 @@ public JnigenGenerateRoboVMXml(JnigenExtension ext) {

@TaskAction
public void run() {
BuildTarget target = ext.get(TargetOs.IOS);
BuildTarget target = ext.get(Os.IOS);
if (target == null) {
log.info("Nothing to do because no IOS BuildTarget");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import java.io.File;

import com.badlogic.gdx.jnigen.BuildTarget;
import com.badlogic.gdx.jnigen.BuildTarget.TargetOs;
import com.badlogic.gdx.utils.Os;

public class JnigenIOSJarTask extends JnigenJarTask {
public JnigenIOSJarTask() {
super(TargetOs.IOS);
super(Os.IOS);
}

public void add(BuildTarget target, JnigenExtension ext, String abi) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import org.gradle.api.tasks.bundling.Jar;

import com.badlogic.gdx.jnigen.BuildTarget;
import com.badlogic.gdx.jnigen.BuildTarget.TargetOs;
import com.badlogic.gdx.utils.Os;

/**
* @author Desu
*/
public class JnigenJarTask extends Jar {
@Inject
public JnigenJarTask(TargetOs os) {
public JnigenJarTask(Os os) {
switch(os) {
case Android:
getArchiveClassifier().set("natives-android");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.badlogic.gdx.utils;

public enum Architecture {
x86, ARM, RISCV;

public String toSuffix() {
if (this == x86) return "";
else return this.name().toLowerCase();
}

public enum Bitness {
_32, _64, _128;

public String toSuffix() {
if (this == _32) return "";
else return this.name().substring(1);
}
}
}
27 changes: 27 additions & 0 deletions gdx-jnigen-loader/src/main/java/com/badlogic/gdx/utils/Os.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.badlogic.gdx.utils;

/** The target operating system of a build target. */
public enum Os {
Windows, Linux, MacOsX, Android, IOS;

public String getJniPlatform () {
if (this == Os.Windows) return "win32";
if (this == Os.Linux) return "linux";
if (this == Os.MacOsX) return "mac";
return "";
}

public String getLibPrefix () {
if (this == Os.Linux || this == Os.Android || this == Os.MacOsX) {
return "lib";
}
return "";
}

public String getLibExtension () {
if (this == Os.Windows) return "dll";
if (this == Os.Linux) return "so";
if (this == Os.MacOsX) return "dylib";
return "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,60 @@
* @author mzechner
* @author Nathan Sweet */
public class SharedLibraryLoader {
static public boolean isWindows = System.getProperty("os.name").contains("Windows");
static public boolean isLinux = System.getProperty("os.name").contains("Linux");
static public boolean isMac = System.getProperty("os.name").contains("Mac");
static public boolean isIos = false;
static public boolean isAndroid = false;
static public boolean isARM = System.getProperty("os.arch").startsWith("arm") || System.getProperty("os.arch").startsWith("aarch64");
static public boolean is64Bit = System.getProperty("os.arch").contains("64") || System.getProperty("os.arch").startsWith("armv8");

static public Os os;
static public Architecture.Bitness bitness = Architecture.Bitness._32;
static public Architecture architecture = Architecture.x86;

static {
if (System.getProperty("os.name").contains("Windows"))
os = Os.Windows;
else if (System.getProperty("os.name").contains("Linux"))
os = Os.Linux;
else if (System.getProperty("os.name").contains("Mac"))
os = Os.MacOsX;

if (System.getProperty("os.arch").startsWith("arm") || System.getProperty("os.arch").startsWith("aarch64"))
architecture = Architecture.ARM;
else if (System.getProperty("os.arch").startsWith("riscv"))
architecture = Architecture.RISCV;

if (System.getProperty("os.arch").contains("64") || System.getProperty("os.arch").startsWith("armv8"))
bitness = Architecture.Bitness._64;
else if (System.getProperty("os.arch").contains("128"))
bitness = Architecture.Bitness._128;

boolean isMOEiOS = System.getProperty("moe.platform.name") != null;
String vm = System.getProperty("java.runtime.name");
if (vm != null && vm.contains("Android Runtime")) {
isAndroid = true;
isWindows = false;
isLinux = false;
isMac = false;
is64Bit = false;
os = Os.Android;
bitness = Architecture.Bitness._32;
architecture = Architecture.x86;
}
if (isMOEiOS || (!isAndroid && !isWindows && !isLinux && !isMac)) {
isIos = true;
isAndroid = false;
isWindows = false;
isLinux = false;
isMac = false;
is64Bit = false;
if (isMOEiOS || (os != Os.Android && os != Os.Windows && os != Os.Linux && os != Os.MacOsX)) {
os = Os.IOS;
bitness = Architecture.Bitness._32;
architecture = Architecture.x86;
}
}

@Deprecated
static public boolean isWindows = os == Os.Windows;
@Deprecated
static public boolean isLinux = os == Os.Linux;
@Deprecated
static public boolean isMac = os == Os.MacOsX;
@Deprecated
static public boolean isIos = os == Os.IOS;
@Deprecated
static public boolean isAndroid = os == Os.Android;
@Deprecated
static public boolean isARM = architecture == Architecture.ARM;
@Deprecated
static public boolean isRISCV = architecture == Architecture.RISCV;
@Deprecated
static public boolean is64Bit = bitness == Architecture.Bitness._64;

static private final HashSet<String> loadedLibraries = new HashSet<>();
static private final Random random = new Random();

Expand Down Expand Up @@ -102,30 +128,27 @@ public String crc (InputStream input) {

/** Maps a platform independent library name to a platform dependent name. */
public String mapLibraryName (String libraryName) {
if (isWindows) return libraryName + (is64Bit ? "64.dll" : ".dll");
if (isLinux) return "lib" + libraryName + (isARM ? "arm" : "") + (is64Bit ? "64.so" : ".so");
if (isMac) return "lib" + libraryName + (isARM ? "arm" : "") + (is64Bit ? "64.dylib" : ".dylib");
return libraryName;
return os.getLibPrefix() + libraryName + architecture.toSuffix() + bitness.toSuffix() + "." + os.getLibExtension();
}

/** Loads a shared library for the platform the application is running on.
* @param libraryName The platform independent library name. If not contain a prefix (eg lib) or suffix (eg .dll). */
public void load (String libraryName) {
// in case of iOS, it's unnecessary to dlopen
if (isIos) return;
if (os == Os.IOS) return;

synchronized (SharedLibraryLoader.class) {
if (isLoaded(libraryName)) return;
String platformName = mapLibraryName(libraryName);
try {
if (isAndroid)
if (os == Os.Android)
System.loadLibrary(platformName);
else
loadFile(platformName);
setLoaded(libraryName);
} catch (Throwable ex) {
throw new SharedLibraryLoadRuntimeException("Couldn't load shared library '" + platformName + "' for target: "
+ (isAndroid ? "Android" : (System.getProperty("os.name") + (isARM ? ", ARM" : "") + (is64Bit ? ", 64-bit" : ", 32-bit"))),
+ (os == Os.Android ? "Android" : (System.getProperty("os.name") + ", " + architecture.name() + ", " + bitness.name().substring(1) + "-bit")),
ex);
}
}
Expand Down
2 changes: 1 addition & 1 deletion gdx-jnigen/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies {
implementation "com.github.javaparser:javaparser-core:3.14.14"
testImplementation project(":gdx-jnigen-loader")
api project(":gdx-jnigen-loader")
testImplementation "junit:junit:4.12"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

import java.util.ArrayList;

import com.badlogic.gdx.jnigen.BuildTarget.TargetOs;
import com.badlogic.gdx.jnigen.FileDescriptor.FileType;
import com.badlogic.gdx.utils.Os;

public class AndroidNdkScriptGenerator {
public void generate (BuildConfig config, BuildTarget target) {
if (target.os != TargetOs.Android) throw new IllegalArgumentException("target os must be Android");
if (target.os != Os.Android) throw new IllegalArgumentException("target os must be Android");

// create all the directories for outputing object files, shared libs and natives jar as well as build scripts.
if (!config.libsDir.exists()) {
Expand Down
Loading