Skip to content

Commit

Permalink
feat: No require discord flags CreateParams method, fix macOS (#14)
Browse files Browse the repository at this point in the history
* feat: No require discord flags CreateParams method

* possible macos fix

* more possible macos fix

* more cmake tweaks

* don't hard code path

* fix macos amd64

* wrong arch

* readme update

* last readme update

* remove outdated building from source comment

* last few readme touchups (real)

* chore: bump version to 0.2.0
  • Loading branch information
ryanzhoudev authored Jul 13, 2023
1 parent 6043af3 commit 8baf489
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 37 deletions.
76 changes: 47 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,17 @@ You do **not** need to download the .dll or .so files! They are packed in the JA
After downloading those JARs, just add the main JAR to your project's classpath.

### Building from source

To obtain the native libraries you can build them from source too (see below) or just download them [here](https://dl-game-sdk.discordapp.net/3.2.1/discord_game_sdk.zip).
For the Windows files, you should rename them to `discord_game_sdk_jni.dll` and place them under `src/main/resources/native/windows/amd64` and `src/main/resources/native/windows/x86` respectively.
For macOS, you should rename the file to `libdiscord_game_sdk_jni.dylib` and place it under `src/main/resources/native/macosx/amd64`.
For Linux, you should rename the file to `libdiscord_game_sdk_jni.so` and place it under `src/main/resources/native/linux/amd64`.

Finally, build (and install) the library with Maven:
Build (and install) the library with Maven:
```shell
mvn clean install -Dmaven.antrun.skip=true
```

## Building the native library from source
### This is required for any changes to the C code.
This is required for any changes to the C code.

This guide is for WSL (Ubuntu) and it also probably works on normal Linux. It definitely does not work on macOS/Windows.

### Prerequisites
Start by installing a lot of dependencies:
```shell
sudo apt update
Expand All @@ -59,46 +54,66 @@ sudo apt install -y g++-mingw-w64-i686 g++-mingw-w64-x86-64 gcc-mingw-w64-i686 g

And also download [Maven](https://maven.apache.org/download.cgi) if you don't have it. Extract it somewhere and add the `bin` folder to your `PATH`.
It is possible to download Maven to the host Windows machine and add it to Windows' `PATH`.
By default, this will also make them available in WSL.

Lastly, note that you can access Windows host machine files from WSL at `/mnt/c/` (or any other drive letter).
Note that you can access Windows host machine files from WSL at `/mnt/c/` (or any other drive letter).

At this point, you should have folder `/usr/lib/jvm` with some copies of your Linux JDK.
Ensure your `JAVA_HOME` is pointed to the correct directory (probably some variation of `/usr/lib/jvm/java-11-openjdk-amd64/`).
You can check with `echo ${JAVA_HOME}`.
If it's not there, you can run `export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64`.
You can check with `echo $JAVA_HOME`.
If it's not there, you should create a .sh file in `/etc/profile.d/` with the following contents (filename does not matter):
```shell
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
```
Then reload by logging out and back in (reconnect ssh session or close WSL window).

#### Prepare for Windows cross-compilation
### Download other platform JDKs
You will need to download copies of OpenJDK 11 for Windows x64, macOS x64 and macOS aarch64. The compressed archive version, not the installer.
Unzip each archive and place them in `/usr/lib/jvm`.
You should rename the folders to `windows-x64-jdk-11.0.19`, `macos-x64-jdk-11.0.19` and `macos-aarch64-jdk-11.0.19` respectively.
If you are using 11.0.19 and have named the folders exactly like the above, you can skip this next step.

You will need to download some copy of OpenJDK 11 for Windows. The compressed archive version, not the installer.
Unzip the archive and place it in `/usr/lib/jvm`. You should rename the folder to `windows-x64-jdk-11.0.19`, or whatever version you have.
#### Update .cmake files
If your JDK versions are different, you will need to update the `.cmake` files in the `toolchains` folder.
For each file, there are paths pointing to the JDKs. Simply edit them so the paths point to your jdk folders.

Next, go to the `toolchains` folder in this project directory. You may need to edit both `windows-x86.cmake` and `windows-amd64.cmake`.
At the end of each file, there are two lines:
```
set(JAVA_INCLUDE_PATH /usr/lib/jvm/windows-x64-jdk-11.0.19/include/)
set(JAVA_INCLUDE_PATH2 /usr/lib/jvm/windows-x64-jdk-11.0.19/include/win32/)
```
Ensure that the paths are correct. They should be pointing to the `include` and `include/win32` folders in your Windows JDK.
Note that it does have to point to the `/include/` subdirectory as shown.
### Prepare for Windows cross-compilation
Nothing to do! Everything has been completed in the previous steps already.

#### Prepare for macOS cross-compilation
### Prepare for macOS cross-compilation

For macOS, this part is a bit more complicated.
You will need to follow the instructions [here](https://github.com/tpoechtrager/osxcross#packaging-the-sdk), but they are slightly wrong.
In `~`, clone the repository.
In `~`, clone the repository. (`git clone https://github.com/tpoechtrager/osxcross`)

You should be using the **"Packing the SDK on Linux - Method 1 (Xcode > 8.0)"** option.
Xcode version 12.5.1 is tested and working. Version 14.3.1 and newer does **not** work.
**You can skip step 2.** We have installed the correct dependencies already, and the ones listed here are wrong.
Xcode version 12.5.1 is tested and working. Version 14.3.1 and newer does **not** work. These docs assume you are using 12.5.1.
After that, **you can skip step 2.** We have installed the correct dependencies already, and the ones listed here are wrong.
Finish with steps 3 and 4 as normal.

Once you do the above, you can proceed to their [installation instructions](https://github.com/tpoechtrager/osxcross#installation).
Again, note that the packages mentioned are wrong. You should exclude `xz` and `libbz2`. **Do not run their `get_dependencies.sh` script, it does not work.**
You can run `./build.sh` immediately after manually ensuring that the dependencies are installed.

Lastly, you will have to edit `macos-amd64.cmake` and change the paths (lines 2 and 4) to point to your installation.
Note that line 4 does not allow you to use `~`, so you will have to use the full path.
Next, install cctools from [here](https://github.com/tpoechtrager/cctools-port). You do not need the TAPI library.
When you run `./configure`, you should use the following command:
```shell script
./configure --prefix=/home/<username>/cctools --target=aarch64-apple-darwin20.4
```
(Replacing `<username>` with your username, and `darwin20.4` if you are using some other Xcode version).
Complete installation as normal.

Now add both osxcross and cctools to PATH. As mentioned above in the prerequisites, you can create (or use your existing) .sh file in `/etc/profile.d/`.
Add the following contents:
```shell
export PATH=$PATH:$JAVA_HOME/bin:/home/<username>/cctools-port/cctools:/home/<username>/osxcross/target/bin
```
(Again, replace `<username>` with your username).

Lastly, you will have to edit `macos-amd64.cmake` and `macos-aarch64.cmake` in the `toolchains` folder.
Search for the line `set(CMAKE_C_FLAGS` and change the username in the path to your own.

#### Build the native library
### Build the native library

Finally, download [Discord's native library](https://discord.com/developers/docs/game-sdk/sdk-starter-guide)
and extract it to ``./discord_game_sdk/``. You should be using v3.2.1 (or other compatible version) as v2.5.6 does not have ARM support.
Expand All @@ -109,6 +124,9 @@ mvn clean install
```
The output dll/so/dylib files will be placed in the `target/native` directory. For convenience, you can run `copy-natives.sh` to copy them to `src/main/resources/native`.

Once you copy them over, you can run `test.java` (changing the client ID to your own application) to test if it works.
If "got new core" is printed out, that specific platform is working.

## Usage

In code, the first step is initializing the Core. To do this you need to pass the path to Discord's native library as an argument.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.wynntils</groupId>
<artifactId>antiope</artifactId>
<version>0.1.0</version>
<version>0.2.0</version>
<name>Antiope</name>

<description>Java bindings for Discord's Game SDK</description>
Expand Down
2 changes: 1 addition & 1 deletion src/main/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.4.1)

project(discord_game_sdk_jni)
project(discord_game_sdk_jni C)

find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
Expand Down
4 changes: 4 additions & 0 deletions src/main/c/com_wynntils_antiope_core_type_CreateParams.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ JNIEXPORT jlong JNICALL Java_com_wynntils_antiope_core_type_CreateParams_getDefa
{
return DiscordCreateFlags_Default;
}

JNIEXPORT jlong JNICALL Java_com_wynntils_antiope_core_type_CreateParams_getNoRequireDiscordFlags(JNIEnv *env, jclass clazz) {
return DiscordCreateFlags_NoRequireDiscord;
}
8 changes: 8 additions & 0 deletions src/main/c/com_wynntils_antiope_core_type_CreateParams.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ public void registerEventHandler(DiscordEventAdapter eventHandler) {
*/
public static native long getDefaultFlags();

/**
* @return Flags that do not require Discord to be active and do not automatically start Discord.
*/
public static native long getNoRequireDiscordFlags();

/**
* <p>Frees the allocated native structure.</p>
* <p>You should call this when you do not need the structure anymore.
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/wynntils/antiope/test.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ public static void main(String[] args) {
try (CreateParams params = new CreateParams()) {
System.out.println("setting client id");
params.setClientID(1121410048996954192L);
params.setFlags(CreateParams.getDefaultFlags());
params.setFlags(CreateParams.getNoRequireDiscordFlags());
try {
core = new DiscordGameSDKCore(params);
System.out.println("got new core");
} catch (RuntimeException e) {
throw new RuntimeException(e);
System.out.println("discord is not running, exiting");
return;
}
} catch (RuntimeException e) {
e.printStackTrace();
Expand Down
Binary file modified src/main/resources/native/linux/amd64/libdiscord_game_sdk_jni.so
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified src/main/resources/native/windows/amd64/discord_game_sdk_jni.dll
Binary file not shown.
Binary file modified src/main/resources/native/windows/x86/discord_game_sdk_jni.dll
Binary file not shown.
11 changes: 8 additions & 3 deletions toolchains/macos-aarch64.cmake
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
set(CMAKE_SYSTEM_NAME macOS)
set(CMAKE_SYSTEM_PROCESSOR arm64)
LIST(APPEND CMAKE_PROGRAM_PATH ~/osxcross/target/bin)

set(CMAKE_C_COMPILER oa64-clang)
set(CMAKE_C_COMPILER_TARGET arm64-apple-darwin20.4)
set(CMAKE_C_FLAGS -fuse-ld=/home/ryan/osxcross/target/bin/arm64-apple-darwin20.4-ld)

set(CMAKE_C_COMPILER o64-clang)
set(CMAKE_C_COMPILER_WORKS 1)

set(CMAKE_SHARED_LIBRARY_SUFFIX_C ".dylib")
set(JAVA_INCLUDE_PATH /usr/lib/jvm/macos-aarch64-jdk-11.0.19/Contents/Home/include)
set(JAVA_INCLUDE_PATH2 /usr/lib/jvm/macos-aarch64-jdk-11.0.19/Contents/Home/include/darwin)
set(JAVA_AWT_INCLUDE_PATH NotNeeded)
set(JAVA_AWT_LIBRARY NotNeeded)
set(JAVA_JVM_LIBRARY /usr/lib/jvm/macos-aarch64-jdk-11.0.19/Contents/Home)
6 changes: 5 additions & 1 deletion toolchains/macos-amd64.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ LIST(APPEND CMAKE_PROGRAM_PATH ~/osxcross/target/bin)
set(CMAKE_C_FLAGS -fuse-ld=/home/ryan/osxcross/target/bin/x86_64-apple-darwin20.4-ld)

set(CMAKE_C_COMPILER o64-clang)
set(CMAKE_C_COMPILER_WORKS 1)

set(CMAKE_SHARED_LIBRARY_SUFFIX_C ".dylib")
set(JAVA_INCLUDE_PATH /usr/lib/jvm/macos-x64-jdk-11.0.19/Contents/Home/include)
set(JAVA_INCLUDE_PATH2 /usr/lib/jvm/macos-x64-jdk-11.0.19/Contents/Home/include/darwin)
set(JAVA_AWT_INCLUDE_PATH NotNeeded)
set(JAVA_AWT_LIBRARY NotNeeded)
set(JAVA_JVM_LIBRARY /usr/lib/jvm/macos-x64-jdk-11.0.19/Contents/Home)
1 change: 1 addition & 0 deletions toolchains/windows-amd64.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
# these are probably not needed but it works so I'm not touching it
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
Expand Down
1 change: 1 addition & 0 deletions toolchains/windows-x86.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(TOOLCHAIN_PREFIX i686-w64-mingw32)
# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--add-stdcall-alias")
# these are probably not needed but it works so I'm not touching it
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
Expand Down

0 comments on commit 8baf489

Please sign in to comment.