diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c2cf29b..f8cf0b1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,5 +1,15 @@
name: CI
-on: [ push, pull_request ]
+
+on:
+ push:
+ branches:
+ - main
+ tags:
+ - v*
+ pull_request:
+ branches:
+ - main
+
jobs:
build-java:
name: Build Java
@@ -20,34 +30,33 @@ jobs:
- name: Build
run: ./gradlew buildAll
+ # This helps to upload only jar files into the build artifact
+ - name: Copy Build Results to Temp
+ run: |
+ mkdir -p tmp/
+ cp imgui-app/build/libs/*.jar tmp/
+ cp imgui-binding/build/libs/*.jar tmp/
+ cp imgui-lwjgl3/build/libs/*.jar tmp/
+
- name: Upload Artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: java-libraries
- path: |
- imgui-app/build/libs/*.jar
- imgui-binding/build/libs/*.jar
- imgui-lwjgl3/build/libs/*.jar
+ path: tmp/*.jar
build-natives:
- name: Build Native (${{ matrix.target.type }}${{ matrix.freetype && ', freetype' || '' }})
+ name: Build Native (${{ matrix.target.os }} - ${{ matrix.target.type }})
+ needs: build-java
strategy:
fail-fast: false
matrix:
- freetype: [ true, false ]
target:
- - os: ubuntu-latest
- type: windows
- expected: /tmp/imgui/libsNative/windows64/imgui-java64.dll
- os: ubuntu-latest
type: linux
- expected: /tmp/imgui/libsNative/linux64/libimgui-java64.so
+ - os: ubuntu-latest
+ type: windows
- os: macos-latest
type: macos
- expected: /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib
- - os: macos-latest
- type: macosarm64
- expected: /tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib
runs-on: ${{ matrix.target.os }}
steps:
- name: Checkout Repository and Submodules
@@ -63,58 +72,44 @@ jobs:
distribution: liberica
cache: gradle
- - name: Ant Version
- run: ant -version
-
- - name: Install MinGW-w64/GCC/G++ (Linux & Windows)
- if: matrix.target.os == 'ubuntu-latest'
+ - name: Install Dependencies (for Windows build)
+ if: matrix.target.type == 'windows'
run: sudo apt install mingw-w64
- - name: FreeType - Install (Linux)
- if: matrix.target.os == 'ubuntu-latest' && matrix.target.type == 'linux' && matrix.freetype == true
- run: sudo apt install libfreetype6-dev
-
- - name: FreeType - Install (Windows)
- if: matrix.target.os == 'ubuntu-latest' && matrix.target.type == 'windows' && matrix.freetype == true
- run: |
- sudo mkdir /freetype
- sudo tar -xzf ./vendor/freetype-2.12.1.tar.gz -C /freetype --strip-components=1
- cd /freetype
- sudo ./configure --with-zlib=no --with-bzip2=no --with-png=no --with-harfbuzz=no --with-brotli=no --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32
- sudo make
- sudo make install
-
- - name: FreeType - Install (MacOS)
- if: matrix.target.os == 'macos-latest' && matrix.freetype == true
- run: |
- sudo mkdir /opt/freetype
- sudo tar -xzf ./vendor/freetype-2.12.1.tar.gz -C /opt/freetype --strip-components=1
- cd /opt/freetype
- sudo ./configure CFLAGS="-arch arm64 -arch x86_64" --with-zlib=no --with-bzip2=no --with-png=no --with-harfbuzz=no --with-brotli=no
- sudo make
- sudo make install
-
- name: Build
- run: ./gradlew imgui-binding:generateLibs -Denvs=${{ matrix.target.type }} -Dfreetype=${{ matrix.freetype }}
+ run: |
+ chmod +x buildSrc/scripts/build.sh
+ buildSrc/scripts/build.sh ${{ matrix.target.type }}
- name: Upload Artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: ${{ matrix.freetype && 'native-libraries-with-freetype' || 'native-libraries' }}
- if-no-files-found: error
- path: ${{ matrix.target.expected }}
+ name: native-library-${{ matrix.target.type }}
+ path: /tmp/imgui/dst/
+
+ # This required to pack all native libraries into single archive
+ archive-natives:
+ name: Archive Natives
+ runs-on: ubuntu-latest
+ needs: build-natives
+ steps:
+ - name: Merge Artifacts
+ uses: actions/upload-artifact/merge@v4
+ with:
+ name: native-libraries
+ pattern: native-library-*
update-bin:
name: Update Binaries
if: github.ref == 'refs/heads/main' && !github.event.repository.fork # runs only on the main branch and not forks (sometimes people do PRs from the main branch)
runs-on: ubuntu-latest
- needs: build-natives
+ needs: archive-natives
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Download Artifacts
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
path: /tmp/artifacts
@@ -133,9 +128,7 @@ jobs:
- name: Update
if: steps.cmp-binding-hash.outcome != 'success'
- run: |
- mv /tmp/artifacts/native-libraries/* bin/
- mv /tmp/artifacts/native-libraries-with-freetype/* bin/freetype/
+ run: mv /tmp/artifacts/native-libraries/* bin/
- name: Commit
if: steps.cmp-binding-hash.outcome != 'success'
@@ -148,7 +141,7 @@ jobs:
name: Release
if: startsWith(github.ref, 'refs/tags/v') # if tag starts with "v"
runs-on: ubuntu-latest
- needs: [ build-java, build-natives ]
+ needs: [ build-java, archive-natives ]
steps:
- name: Checkout Repository
uses: actions/checkout@v4
@@ -163,7 +156,7 @@ jobs:
cache: gradle
- name: Download Artifacts
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
path: out/artifacts
@@ -171,7 +164,6 @@ jobs:
run: |
mkdir out/archives
zip -rj out/archives/native-libraries out/artifacts/native-libraries
- zip -rj out/archives/native-libraries-with-freetype out/artifacts/native-libraries-with-freetype
zip -rj out/archives/java-libraries out/artifacts/java-libraries
- name: Publish
diff --git a/README.md b/README.md
index a4080d8..65f3919 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ To understand how to use ImGui Java - read official [documentation](https://gith
Binding adopts C++ API for Java, but almost everything can be used in the same manner.
ImGui Java has a ready to use implementation for GLFW and OpenGL API using [LWJGL3](https://www.lwjgl.org/) library. See `imgui-lwjgl3` module.
-Implementation is optional, yet optional to use. Advantage of Dear ImGui is total portability, so feel free to copy-paste classes or write your own implementations.
+Implementation is optional to use. Advantage of Dear ImGui is total portability, so feel free to copy-paste classes or write your own implementations.
Additionally, there is an `imgui-app` module, which provides **a high abstraction layer**.
It hides all low-level code under one class to extend. With it, you can build your GUI application instantly.
@@ -70,6 +70,10 @@ Gradle and Maven dependencies could be used for this purpose as well.
Take a note, that integration itself is a very flexible process. It could be done in one way or another. If you just need a framework for your GUI - use [Application](#application) module.
Otherwise, if you need more control, the best way is not just to repeat steps, but to understand what each step does.
+### For macOS M-chip users
+
+The macOS version of the binding is compiled as a universal binary. This means you can use it on both x86_64 and aarch64 platforms without any additional actions.
+
## Application
If you don't care about OpenGL and other low-level stuff, then you can use application layer from `imgui-app` module.
@@ -176,7 +180,6 @@ For simplicity, example of dependencies for Gradle / Maven only shows how to add
| imgui-java-natives-windows | Windows |
| imgui-java-natives-linux | Linux |
| imgui-java-natives-macos | macOS |
-| imgui-java-natives-macos-arm64 | macOS-arm64 |
Take a note, that you also need to add dependencies to [LWJGL](https://www.lwjgl.org/) library. Examples below shows how to do it as well.
@@ -282,10 +285,10 @@ dependencies {
Raw Jars
1. Go to the [release page](https://github.com/SpaiR/imgui-java/releases/latest);
-2. Download `java-libraries.zip` and `native-libraries.zip` (`native-libraries-with-freetype.zip` for FreeType font rendering);
+2. Download `java-libraries.zip` and `native-libraries.zip`;
3. Get `imgui-binding-${version}.jar` and `imgui-lwjgl3-${version}.jar` from `java-libraries`, and binary libraries for required OS from `native-libraries` archive;
4. Add jars to your classpath;
-5. Provide a VM option with location of files from the `native-libraries` (or `native-libraries-with-freetype`) archive.
+5. Provide a VM option with location of files from the `native-libraries` archive.
VM option example:
- **-Dimgui.library.path=_${path}_**
@@ -307,7 +310,6 @@ If using Java 9 modules, ImGui Java has Automatic Module Names:
| imgui-java-natives-windows | imgui.natives.windows |
| imgui-java-natives-linux | imgui.natives.linux |
| imgui-java-natives-macos | imgui.natives.macos |
-| imgui-java-natives-macos-arm64 | imgui.natives.macos-arm64 |
## Extensions
@@ -331,67 +333,14 @@ See examples in the `example` module for more information about how to use them.
## Freetype
-By default, Dear ImGui uses stb-truetype to render fonts. Yet there is an option to use FreeType font renderer.
-Go to the [imgui_freetype](https://github.com/ocornut/imgui/tree/256594575d95d56dda616c544c509740e74906b4/misc/freetype) to read about the difference.
-Binding has this option too. Freetype especially useful when you use custom font with small (~<16px) size.
-If you use the default font or a large font, stb will be fine for you.
+By default, Dear ImGui uses stb-truetype to render fonts. However, there is an option to use the FreeType font renderer.
+To learn about the differences, visit the [imgui_freetype](https://github.com/ocornut/imgui/tree/256594575d95d56dda616c544c509740e74906b4/misc/freetype) page.
-There are two types of precompiled binaries: 1. with stb (the default one) 2. with freetype.
-You can decide by yourself, which kind of libraries for any system you want to use.
+This binding also supports the FreeType option.
+FreeType is statically pre-compiled into the library, meaning it is **enabled by default** and there is no option to disable it.
+Therefore, you can freely use `ImGuiFreeTypeBuilderFlags` in your font configuration.
-Take a note, that for Linux and macOS users using of freetype will add a dependency to the `libfreetype` itself.
-This is not the case for Windows users, since `dll` binaries are compiled fully statically and already include freetype in themselves.
-
-**For fully portable application** use default binaries.
-You can still use freetype binaries for Windows builds without worry though.
-
-**For better fonts** use freetype binaries.
-Don't forget to make clear for your Linux/Mac users, that they will need to install freetype on their systems as well.
-
-### Dependencies
-
-
-
-Use the same native libraries as you would, but with `-ft` suffix in the end.
-
-
- Modified Gradle Example
-
- ```
- repositories {
- mavenCentral()
- }
-
- ext {
- lwjglVersion = '3.3.3'
- imguiVersion = "${version}"
- }
-
- dependencies {
- implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
-
- ['', '-opengl', '-glfw'].each {
- implementation "org.lwjgl:lwjgl$it:$lwjglVersion"
- implementation "org.lwjgl:lwjgl$it::natives-windows"
- }
-
- implementation "io.github.spair:imgui-java-binding:$imguiVersion"
- implementation "io.github.spair:imgui-java-lwjgl3:$imguiVersion"
-
- // This is the main difference
- implementation "io.github.spair:imgui-java-natives-windows-ft:$imguiVersion"
- }
- ```
-
-
-| Native Binaries With FreeType | System |
-|-----------------------------------|-------------|
-| imgui-java-natives-windows-ft | Windows |
-| imgui-java-natives-linux-ft | Linux |
-| imgui-java-natives-macos-ft | macOS |
-| imgui-java-natives-macos-arm64-ft | macOS-arm64 |
-
-If you're using raw dll/so files, go to the [release page](https://github.com/SpaiR/imgui-java/releases/latest) and use libraries from the `native-libraries-with-freetype.zip` archive.
+If you prefer not to use the FreeType font renderer, you will need to build your own binaries and use them instead.
# Binding Notice
@@ -408,7 +357,7 @@ Read [javadoc](https://javadoc.io/doc/io.github.spair/imgui-java-binding) and so
Ensure you've downloaded git submodules. That could be achieved:
- When cloning the repository: `git clone --recurse-submodules https://github.com/SpaiR/imgui-java.git`
-- When the repository cloned: `git submodule init` + `git submodule update`
+- When the repository cloned: `git submodule init` and `git submodule update`
### Windows
@@ -418,6 +367,7 @@ Ensure you've downloaded git submodules. That could be achieved:
* Mingw-w64 (recommended way: use [MSYS2](https://www.msys2.org/) and install [mingw-w64-x86_64-toolchain](https://packages.msys2.org/group/mingw-w64-x86_64-toolchain) group)
- Build with: `./gradlew imgui-binding:generateLibs -Denvs=windows -Dlocal`
- Run with: `./gradlew example:run -PlibPath="../imgui-binding/build/libsNative/windows64"`
+ - Always use `-Dlocal` flag.
### Linux
@@ -431,15 +381,20 @@ Ensure you've downloaded git submodules. That could be achieved:
- Build with: `./gradlew imgui-binding:generateLibs -Denvs=macos -Dlocal`
- Run with: `./gradlew example:run -PlibPath=../imgui-binding/build/libsNative/macosx64`
-### macOS-arm64
+### macOS (arm64)
- Check dependencies from "Linux" section and make sure you have them installed.
- Build with: `./gradlew imgui-binding:generateLibs -Denvs=macosarm64 -Dlocal`
- Run with: `./gradlew example:run -PlibPath=../imgui-binding/build/libsNative/macosxarm64`
-In `envs` parameter next values could be used `windows`, `linux` or `macos` or `macosarm64`.
+In `envs` parameter next values could be used `windows`, `linux` or `macos` or `macosarm64`.
+
`-Dlocal` is optional and means that natives will be built under the `./imgui-binding/build/` folder. Otherwise `/tmp/imgui` folder will be used.
-On Windows always use local build.
+
+## Freetype
+
+To build a version of the libraries with FreeType, you need to run the `buildSrc/scripts/vendor_freetype.sh` script first.
+This script configures the FreeType library to be statically compiled into your project.
# License
diff --git a/bin/README.md b/bin/README.md
index 4038f32..5811c4f 100644
--- a/bin/README.md
+++ b/bin/README.md
@@ -1,10 +1,25 @@
-Folder contains libraries used by the binding and `binding.sha1` sum of the `imgui-binding/src/main` directory libraries has been built upon.
+### Overview
-Provide `imgui.library.path` (or `java.library.path`) VM option to the folder with one of those file (ex: `-Dimgui.library.path=./folder/path`).
-In the same way you can use 'java.library.path' option instead.
+The folder contains libraries used by the binding and the `binding.sha1` checksum for the `imgui-binding/src/main` directory that the libraries are built upon. These libraries are utilized during the release process.
-By default, binding expects `imgui-java64` file name.
-You can change that by using `imgui.library.name` VM option (ex: `-Dimgui.library.name=custom-lib-name.dll`).
+### Specifying the Library Path
+
+To specify the folder containing these files, provide the `imgui.library.path` (or `java.library.path`) VM option. For example:
+```
+-Dimgui.library.path=./folder/path
+```
+You can also use the `java.library.path` option in the same manner.
+
+### Changing the Library Name
+
+By default, the binding expects the file name `imgui-java64`. You can change this by using the `imgui.library.name` VM option. For example:
+```
+-Dimgui.library.name=custom-lib-name.dll
+```
+
+### Expected Library File Names
+
+The expected library file names for different operating systems are:
| OS | Library |
|---------|-----------------------|
@@ -12,6 +27,11 @@ You can change that by using `imgui.library.name` VM option (ex: `-Dimgui.librar
| Linux | libimgui-java64.so |
| macOS | libimgui-java64.dylib |
-Freetype directory contains same libraries, but with Freetype support.
+### Additional Information
-Hash sum in the `binding.sha1` file is used in CI to see, if there is a need to update native binaries.
+- All libraries include statically compiled **FreeType**.
+- The macOS version is a universal library and support x86_64 and arm64 architectures.
+
+### Continuous Integration
+
+The hash sum in the `binding.sha1` file is used in continuous integration (CI) to determine if there is a need to update the native binaries.
diff --git a/bin/freetype/imgui-java64.dll b/bin/freetype/imgui-java64.dll
deleted file mode 100644
index a8a3f46..0000000
Binary files a/bin/freetype/imgui-java64.dll and /dev/null differ
diff --git a/bin/freetype/libimgui-java64.dylib b/bin/freetype/libimgui-java64.dylib
deleted file mode 100644
index c72a40a..0000000
Binary files a/bin/freetype/libimgui-java64.dylib and /dev/null differ
diff --git a/bin/freetype/libimgui-java64.so b/bin/freetype/libimgui-java64.so
deleted file mode 100644
index 5a1cb1e..0000000
Binary files a/bin/freetype/libimgui-java64.so and /dev/null differ
diff --git a/bin/freetype/libimgui-javaarm64.dylib b/bin/freetype/libimgui-javaarm64.dylib
deleted file mode 100644
index 1c726d4..0000000
Binary files a/bin/freetype/libimgui-javaarm64.dylib and /dev/null differ
diff --git a/bin/libimgui-javaarm64.dylib b/bin/libimgui-javaarm64.dylib
deleted file mode 100644
index 7205493..0000000
Binary files a/bin/libimgui-javaarm64.dylib and /dev/null differ
diff --git a/buildSrc/scripts/build.sh b/buildSrc/scripts/build.sh
new file mode 100755
index 0000000..d7d17d6
--- /dev/null
+++ b/buildSrc/scripts/build.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+
+echo "Setting base directory and navigating to project root..."
+BASEDIR=$(dirname "$0")
+cd "$BASEDIR"/../.. || exit 1
+echo "Navigated to $(pwd)"
+
+# Check if vendor type argument is provided
+if [ -z "$1" ]; then
+ echo "Vendor type is required"
+ exit 1
+fi
+
+VTYPE=$1
+echo "Vendor type set to '$VTYPE'"
+
+# Make the vendor FreeType script executable and run it
+echo "Making vendor FreeType script executable and running it..."
+chmod +x buildSrc/scripts/vendor_freetype.sh
+buildSrc/scripts/vendor_freetype.sh "$VTYPE"
+if [ $? -ne 0 ]; then
+ echo "Vendor FreeType script failed"
+ exit 1
+fi
+echo "Vendor FreeType script completed successfully"
+
+# Create the destination directory for imgui libraries
+echo "Creating destination directory for imgui libraries..."
+mkdir -p /tmp/imgui/dst
+echo "Directory /tmp/imgui/dst created successfully"
+
+# Function to check if a file exists
+check_file_exists() {
+ if [ ! -f "$1" ]; then
+ echo "File $1 not found!"
+ exit 1
+ fi
+}
+
+# Determine build process based on vendor type
+case "$VTYPE" in
+ windows)
+ echo "Running Gradle task for Windows..."
+ ./gradlew imgui-binding:generateLibs -Denvs=windows -Dfreetype=true
+ if [ $? -ne 0 ]; then
+ echo "Gradle task for Windows failed"
+ exit 1
+ fi
+
+ echo "Checking if the generated DLL exists..."
+ check_file_exists /tmp/imgui/libsNative/windows64/imgui-java64.dll
+
+ echo "Copying the generated DLL to the destination directory..."
+ cp /tmp/imgui/libsNative/windows64/imgui-java64.dll /tmp/imgui/dst/imgui-java64.dll
+ if [ $? -ne 0 ]; then
+ echo "Failed to copy DLL to /tmp/imgui/dst/imgui-java64.dll"
+ exit 1
+ fi
+ echo "DLL copied to /tmp/imgui/dst/imgui-java64.dll successfully"
+ ;;
+ linux)
+ echo "Running Gradle task for Linux..."
+ ./gradlew imgui-binding:generateLibs -Denvs=linux -Dfreetype=true
+ if [ $? -ne 0 ]; then
+ echo "Gradle task for Linux failed"
+ exit 1
+ fi
+
+ echo "Checking if the generated SO file exists..."
+ check_file_exists /tmp/imgui/libsNative/linux64/libimgui-java64.so
+
+ echo "Copying the generated SO file to the destination directory..."
+ cp /tmp/imgui/libsNative/linux64/libimgui-java64.so /tmp/imgui/dst/libimgui-java64.so
+ if [ $? -ne 0 ]; then
+ echo "Failed to copy SO file to /tmp/imgui/dst/libimgui-java64.so"
+ exit 1
+ fi
+ echo "SO file copied to /tmp/imgui/dst/libimgui-java64.so successfully"
+ ;;
+ macos)
+ echo "Running Gradle task for macOS and macOS ARM..."
+ ./gradlew imgui-binding:generateLibs -Denvs=macos,macosarm64 -Dfreetype=true
+ if [ $? -ne 0 ]; then
+ echo "Gradle task for macOS failed"
+ exit 1
+ fi
+
+ echo "Checking if the generated DYLIB files exist..."
+ check_file_exists /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib
+ check_file_exists /tmp/imgui/libsNative/macosxarm64/libimgui-java64.dylib
+
+ echo "Creating a universal library using lipo..."
+ lipo -create -output /tmp/imgui/dst/libimgui-java64.dylib /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib /tmp/imgui/libsNative/macosxarm64/libimgui-java64.dylib
+ if [ $? -ne 0 ]; then
+ echo "Failed to create universal library with lipo"
+ exit 1
+ fi
+ echo "Universal library created at /tmp/imgui/dst/libimgui-java64.dylib successfully"
+ ;;
+ *)
+ echo "Unknown vendor type: $VTYPE"
+ exit 1
+ ;;
+esac
+
+echo "Script completed successfully."
diff --git a/buildSrc/scripts/publish.sh b/buildSrc/scripts/publish.sh
index 72679f4..d744408 100644
--- a/buildSrc/scripts/publish.sh
+++ b/buildSrc/scripts/publish.sh
@@ -1,30 +1,45 @@
#!/bin/bash
+# Set base directory and navigate to project root
+echo "Setting base directory and navigating to project root..."
BASEDIR=$(dirname "$0")
-cd $BASEDIR/../.. || exit
+cd "$BASEDIR"/../.. || exit 1
+echo "Navigated to $(pwd)"
echo '> Publishing Modules...'
-echo '>> Module [imgui-app]'
-./gradlew imgui-app:publishImguiPublicationToMavenCentralRepository
-echo '>> Module [imgui-lwjgl3]'
-./gradlew imgui-lwjgl3:publishImguiPublicationToMavenCentralRepository
-echo '>> Module [imgui-binding]'
-./gradlew imgui-binding:publishImguiPublicationToMavenCentralRepository
+
+publish_module() {
+ local module=$1
+ echo ">> Publishing Module [$module]"
+ ./gradlew $module:publishImguiPublicationToMavenCentralRepository
+ if [ $? -ne 0 ]; then
+ echo "Failed to publish $module module"
+ exit 1
+ fi
+ echo ">> Module [$module] published successfully"
+}
+
+# Publish each module
+publish_module "imgui-app"
+publish_module "imgui-lwjgl3"
+publish_module "imgui-binding"
echo '> Publishing Natives...'
-echo '>> Natives: [windows, freetype]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=windows -Pfreetype=true
-echo '>> Natives: [windows]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=windows -Pfreetype=false
-echo '>> Natives: [linux, freetype]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=linux -Pfreetype=true
-echo '>> Natives: [linux]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=linux -Pfreetype=false
-echo '>> Natives: [macOS, freetype]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=macos -Pfreetype=true
-echo '>> Natives: [macOS]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=macos -Pfreetype=false
-echo '>> Natives: [macOS-arm64, freetype]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=macosarm64 -Pfreetype=true
-echo '>> Natives: [macOS-arm64]'
-./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=macosarm64 -Pfreetype=false
+
+publish_natives() {
+ local platform=$1
+ echo ">> Publishing Natives: [$platform]"
+ ./gradlew imgui-binding-natives:publishImguiPublicationToMavenCentralRepository -PdeployType=$platform
+ if [ $? -ne 0 ]; then
+ echo "Failed to publish natives for $platform"
+ exit 1
+ fi
+ echo ">> Natives for $platform published successfully"
+}
+
+# Publish natives for each platform
+publish_natives "windows"
+publish_natives "linux"
+publish_natives "macos"
+
+echo "All modules and natives published successfully."
diff --git a/buildSrc/scripts/vendor_freetype.sh b/buildSrc/scripts/vendor_freetype.sh
new file mode 100755
index 0000000..eecb26b
--- /dev/null
+++ b/buildSrc/scripts/vendor_freetype.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+# Set base directory and navigate to project root
+echo "Setting base directory and navigating to project root..."
+BASEDIR=$(dirname "$0")
+cd "$BASEDIR"/../.. || exit 1
+echo "Navigated to $(pwd)"
+
+# Check if vendor type argument is provided
+if [ -z "$1" ]; then
+ echo "Vendor type is required"
+ exit 1
+fi
+
+VTYPE=$1
+echo "Vendor type set to '$VTYPE'"
+
+# Define library directory and version
+LIBDIR=build/vendor/freetype
+VERSION=2.12.1
+
+# Clean and create library directory, then extract FreeType source
+echo "Cleaning and creating library directory, then extracting FreeType source..."
+rm -rf $LIBDIR
+mkdir -p $LIBDIR
+tar -xzf ./vendor/freetype-$VERSION.tar.gz -C $LIBDIR --strip-components=1
+if [ $? -ne 0 ]; then
+ echo "Failed to extract FreeType source"
+ exit 1
+fi
+cd $LIBDIR || exit 1
+echo "FreeType unzipped to $LIBDIR"
+
+# Common configuration flags
+COMMON_FLAGS="--enable-static --disable-shared --without-zlib --without-bzip2 --without-png --without-harfbuzz --without-brotli"
+
+# Function to configure and build FreeType
+build_freetype() {
+ cflags=$1
+ prefix=$2
+ output_dir=$3
+
+ echo "Cleaning previous builds..."
+ make clean
+
+ echo "Configuring FreeType with CFLAGS='$cflags' and PREFIX='$prefix'..."
+ ./configure CFLAGS="$cflags" $COMMON_FLAGS $prefix
+ if [ $? -ne 0 ]; then
+ echo "Failed to configure FreeType"
+ exit 1
+ fi
+
+ echo "Building FreeType..."
+ make
+ if [ $? -ne 0 ]; then
+ echo "Failed to build FreeType"
+ exit 1
+ fi
+
+ echo "Checking if the generated library exists..."
+ if [ ! -f objs/.libs/libfreetype.a ]; then
+ echo "File objs/.libs/libfreetype.a not found!"
+ exit 1
+ fi
+
+ echo "Copying the generated library to $output_dir..."
+ cp objs/.libs/libfreetype.a "$output_dir"
+ if [ $? -ne 0 ]; then
+ echo "Failed to copy library to $output_dir"
+ exit 1
+ fi
+ echo "Library copied to $output_dir"
+}
+
+# Ensure necessary directories exist
+echo "Ensuring necessary directories exist..."
+mkdir -p lib tmp
+
+# Determine build process based on vendor type
+case "$VTYPE" in
+ windows)
+ build_freetype "" "--host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32" "lib/libfreetype.a"
+ ;;
+ linux)
+ build_freetype "-fPIC" "" "lib/libfreetype.a"
+ ;;
+ macos)
+ MACOS_VERSION=10.15
+
+ build_freetype "-arch x86_64 -mmacosx-version-min=$MACOS_VERSION" "" "tmp/libfreetype-x86_64.a"
+ build_freetype "-arch arm64 -mmacosx-version-min=$MACOS_VERSION" "" "tmp/libfreetype-arm64.a"
+
+ echo "Creating universal library using lipo..."
+ lipo -create -output lib/libfreetype.a tmp/libfreetype-x86_64.a tmp/libfreetype-arm64.a
+ if [ $? -ne 0 ]; then
+ echo "Failed to create universal library with lipo"
+ exit 1
+ fi
+ echo "Universal library created at lib/libfreetype.a"
+ ;;
+ *)
+ echo "Unknown vendor type: $VTYPE"
+ exit 1
+ ;;
+esac
+
+echo "Script completed successfully."
diff --git a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy
index 972263f..b0aabf4 100644
--- a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy
+++ b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy
@@ -10,6 +10,18 @@ import org.gradle.api.tasks.TaskAction
@CompileStatic
class GenerateLibs extends DefaultTask {
+ private static final String[] INCLUDES = [
+ 'include/imgui',
+ 'include/imnodes',
+ 'include/imgui-node-editor',
+ 'include/imguizmo',
+ 'include/implot',
+ 'include/ImGuiColorTextEdit',
+ 'include/ImGuiFileDialog',
+ 'include/imgui_club/imgui_memory_editor',
+ 'include/imgui-knobs'
+ ]
+
@Internal
String group = 'build'
@Internal
@@ -26,9 +38,10 @@ class GenerateLibs extends DefaultTask {
private final String sourceDir = project.file('src/main/java')
private final String classpath = project.file('build/classes/java/main')
- private final String jniDir = (isLocal ? project.buildDir.path : '/tmp/imgui') + '/jni'
- private final String tmpFolder = (isLocal ? project.buildDir.path : '/tmp/imgui') + '/tmp'
- private final String libsFolder = 'libsNative'
+ private final String rootDir = (isLocal ? project.buildDir.path : '/tmp/imgui')
+ private final String jniDir = "$rootDir/jni"
+ private final String tmpDir = "$rootDir/tmp"
+ private final String libsDirName = 'libsNative'
@TaskAction
void generate() {
@@ -42,47 +55,46 @@ class GenerateLibs extends DefaultTask {
throw new IllegalStateException('No build targets')
}
+ new File(jniDir).deleteDir()
+ new File(tmpDir).deleteDir()
+ new File("$rootDir/$libsDirName").deleteDir()
+
// Generate h/cpp files for JNI
new NativeCodeGenerator().generate(sourceDir, classpath, jniDir)
// Copy ImGui h/cpp files
project.copy { CopySpec spec ->
- ['include/imgui', 'include/imnodes', 'include/imgui-node-editor',
- 'include/imguizmo', 'include/implot', 'include/ImGuiColorTextEdit',
- 'include/ImGuiFileDialog', 'include/imgui_club/imgui_memory_editor', 'include/imgui-knobs'].each {
+ INCLUDES.each {
spec.from(project.rootProject.file(it)) { CopySpec s -> s.include('*.h', '*.cpp', '*.inl') }
}
spec.from(project.rootProject.file('imgui-binding/src/main/native'))
spec.into(jniDir)
- spec.duplicatesStrategy = DuplicatesStrategy.INCLUDE //Allows for duplicate imconfig.h, we ensure the correct one is copied below
+ spec.duplicatesStrategy = DuplicatesStrategy.INCLUDE // Allows for duplicate imconfig.h, we ensure the correct one is copied below
}
- //Ensure we overwrite imconfig.h with our own
+ // Ensure we overwrite imconfig.h with our own
project.copy { CopySpec spec ->
spec.from(project.rootProject.file('imgui-binding/src/main/native/imconfig.h'))
spec.into(jniDir)
}
- //Copy dirent for ImGuiFileDialog
- project.copy { CopySpec spec ->
- ['include/ImGuiFileDialog/dirent'].each {
- spec.from(project.rootProject.file(it)) { CopySpec s -> s.include('*.h', '*.cpp', '*.inl') }
- }
- spec.into(jniDir + '/dirent')
- }
-
if (withFreeType) {
project.copy { CopySpec spec ->
spec.from(project.rootProject.file('include/imgui/misc/freetype')) { CopySpec it -> it.include('*.h', '*.cpp') }
spec.into("$jniDir/misc/freetype")
}
-
enableDefine('IMGUI_ENABLE_FREETYPE')
}
+ // Copy dirent for ImGuiFileDialog
+ project.copy { CopySpec spec ->
+ spec.from(project.rootProject.file('include/ImGuiFileDialog/dirent')) { CopySpec s -> s.include('*.h', '*.cpp', '*.inl') }
+ spec.into(jniDir + '/dirent')
+ }
+
// Generate platform dependant ant configs and header files
- def buildConfig = new BuildConfig('imgui-java', tmpFolder, libsFolder, jniDir)
- def buildTargets = [] as BuildTarget[]
+ def buildConfig = new BuildConfig('imgui-java', tmpDir, libsDirName, jniDir)
+ BuildTarget[] buildTargets = []
if (forWindows) {
def win64 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.Windows, true)
@@ -97,23 +109,11 @@ class GenerateLibs extends DefaultTask {
}
if (forMac) {
- def minMacOsVersion = '10.15'
- def mac64 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.MacOsX, true)
- mac64.cppFlags += ' -std=c++14'
- mac64.cppFlags = mac64.cppFlags.replace('10.7', minMacOsVersion)
- mac64.linkerFlags = mac64.linkerFlags.replace('10.7', minMacOsVersion)
- addFreeTypeIfEnabled(mac64)
- buildTargets += mac64
+ buildTargets += createMacTarget(false)
}
if (forMacArm64) {
- def minMacOsVersion = '10.15'
- def macArm64 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.MacOsX, true, true)
- macArm64.cppFlags += ' -std=c++14'
- macArm64.cppFlags = macArm64.cppFlags.replace('10.7', minMacOsVersion)
- macArm64.linkerFlags = macArm64.linkerFlags.replace('10.7', minMacOsVersion)
- addFreeTypeIfEnabled(macArm64)
- buildTargets += macArm64
+ buildTargets += createMacTarget(true)
}
new AntScriptGenerator().generate(buildConfig, buildTargets)
@@ -133,6 +133,34 @@ class GenerateLibs extends DefaultTask {
BuildExecutor.executeAnt(jniDir + '/build-macosxarm64.xml', commonParams)
BuildExecutor.executeAnt(jniDir + '/build.xml', '-v', 'pack-natives')
+
+ if (forWindows)
+ checkLibExist("windows64/imgui-java64.dll")
+ if (forLinux)
+ checkLibExist("linux64/libimgui-java64.so")
+ if (forMac)
+ checkLibExist("macosx64/libimgui-java64.dylib")
+ if (forMacArm64)
+ checkLibExist("macosxarm64/libimgui-java64.dylib")
+ }
+
+ void checkLibExist(String libName) {
+ def path = new File("$rootDir/$libsDirName/$libName")
+ if (!path.exists()) {
+ logger.error("Failed to build $libName!")
+ throw new IllegalStateException("$path does not exist")
+ }
+ }
+
+ BuildTarget createMacTarget(Boolean isArm) {
+ def minMacOsVersion = '10.15'
+ def macTarget = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.MacOsX, true, isArm)
+ macTarget.libName = "libimgui-java64.dylib" // Lib for arm64 will be named the same for consistency.
+ macTarget.cppFlags += ' -std=c++14'
+ macTarget.cppFlags = macTarget.cppFlags.replace('10.7', minMacOsVersion)
+ macTarget.linkerFlags = macTarget.linkerFlags.replace('10.7', minMacOsVersion)
+ addFreeTypeIfEnabled(macTarget)
+ return macTarget
}
void addFreeTypeIfEnabled(BuildTarget target) {
@@ -140,22 +168,18 @@ class GenerateLibs extends DefaultTask {
return
}
- switch (target.os) {
- case BuildTarget.TargetOs.Windows:
- target.cppFlags += ' -I/usr/x86_64-w64-mingw32/include/freetype2'
- break
- case BuildTarget.TargetOs.Linux:
- target.cppFlags += ' -I/usr/include/freetype2'
- break
- case BuildTarget.TargetOs.MacOsX:
- target.cppFlags += ' -I/usr/local/include/freetype2'
- break
+ def freetypeVendorDir = project.rootProject.file('build/vendor/freetype')
+ if (!freetypeVendorDir.exists()) {
+ logger.error("$freetypeVendorDir doesn't exist! Run 'buildSrc/scripts/vendor_freetype.sh' for your platform beforehand!")
+ throw new IllegalStateException("Unable to build library for FreeType")
}
+ target.cppFlags += " -I$freetypeVendorDir/include"
+ target.linkerFlags += " -L${project.rootProject.file("$freetypeVendorDir/lib")}"
target.libraries += ' -lfreetype'
}
void enableDefine(String define) {
- project.file("$jniDir/imconfig.h").text += "#define $define"
+ new File("$jniDir/imconfig.h").text += "#define $define"
}
}
diff --git a/example/src/main/java/Main.java b/example/src/main/java/Main.java
index 907f7dd..d70f5a8 100644
--- a/example/src/main/java/Main.java
+++ b/example/src/main/java/Main.java
@@ -72,6 +72,7 @@ public class Main extends Application {
@Override
public void process() {
if (ImGui.begin("Demo", ImGuiWindowFlags.AlwaysAutoResize)) {
+ ImGui.text("OS: [" + System.getProperty("os.name") + "] Arch: [" + System.getProperty("os.arch") + "]");
ImGui.text("Hello, World! " + FontAwesomeIcons.Smile);
if (ImGui.button(FontAwesomeIcons.Save + " Save")) {
count++;
diff --git a/imgui-app/build.gradle b/imgui-app/build.gradle
index 0e630b7..0e2368d 100644
--- a/imgui-app/build.gradle
+++ b/imgui-app/build.gradle
@@ -31,13 +31,9 @@ dependencies {
jar {
from('../bin') {
+ include 'imgui-java64.dll'
include 'libimgui-java64.so'
include 'libimgui-java64.dylib'
- include 'libimgui-javaarm64.dylib'
- into 'io/imgui/java/native-bin/'
- }
- from('../bin/freetype') {
- include 'imgui-java64.dll'
into 'io/imgui/java/native-bin/'
}
manifest {
diff --git a/imgui-binding-natives/build.gradle b/imgui-binding-natives/build.gradle
index 7e690a8..27c79d1 100644
--- a/imgui-binding-natives/build.gradle
+++ b/imgui-binding-natives/build.gradle
@@ -31,22 +31,10 @@ switch (findProperty('deployType')) {
break
case 'macos':
packageName = 'imgui-java-natives-macos'
- packageDesc = 'Native binaries for imgui-java binding for MacOS'
+ packageDesc = 'Native binaries for imgui-java binding for macOS'
moduleName = 'imgui.natives.macos'
libName = 'libimgui-java64.dylib'
break
- case 'macosarm64':
- packageName = 'imgui-java-natives-macos-arm64'
- packageDesc = 'Native binaries for imgui-java binding for MacOS arm64'
- moduleName = 'imgui.natives.macos-arm64'
- libName = 'libimgui-javaarm64.dylib'
- break
-}
-
-if (findProperty('freetype') == 'true') {
- packageName += '-ft'
- packageDesc += ' with Freetype support'
- fromDir += '/freetype'
}
jar {
diff --git a/imgui-binding/src/main/java/imgui/ImGui.java b/imgui-binding/src/main/java/imgui/ImGui.java
index 13b1288..20b0312 100644
--- a/imgui-binding/src/main/java/imgui/ImGui.java
+++ b/imgui-binding/src/main/java/imgui/ImGui.java
@@ -29,8 +29,7 @@ import java.util.Properties;
public class ImGui {
private static final String LIB_PATH_PROP = "imgui.library.path";
private static final String LIB_NAME_PROP = "imgui.library.name";
- private static final boolean isARM = System.getProperty("os.arch").equals("arm") || System.getProperty("os.arch").startsWith("aarch64");
- private static final String LIB_NAME_DEFAULT = "imgui-java" + (isARM ? "arm" : "") + "64";
+ private static final String LIB_NAME_DEFAULT = "imgui-java64";
private static final String LIB_TMP_DIR_PREFIX = "imgui-java-natives";
private static final ImGuiContext IMGUI_CONTEXT;