build(binding): add universal macOS ARM64 dylib and static FreeType compilation

- Static FreeType linking flow for all OS
- Flow to build universal binaries for macOS (x86_64, aarch64)
- Simplified CI workflow by removing FreeType branches from the build matrix

Added 2 new scripts:
1. `buildSrc/scripts/vendor_freetype.sh`
2. `buildSrc/scripts/build.sh`

The first script prepares FreeType for usage in the build process.
The result of this script is used in the `GenerateLibs` task.
Other ways of building with FreeType are removed.
If it's impossible to build with FreeType, it is recommended to set `freetype=false`.

The second script aggregates commands to build native binaries.
It includes specific steps, such as creating a universal library for macOS and copying the result to the specific folder `/tmp/imgui/dst`.

Script 1 can be used for local builds. Script 2 is primarily intended for use in CI.
This commit is contained in:
SpaiR committed 2024-08-07 09:41:09 +03:00
1 parent 66522fa265
commit 46c008eb02
16 files changed
+423 -220

No files matched your search

+50 -58
View File
@@ -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
+23 -68
View File
@@ -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.<br>
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**.<br>
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 {
<summary><b>Raw Jars</b></summary>
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.<br>
You can still use freetype binaries for Windows builds without worry though.
**For better fonts** use freetype binaries.<br>
Don't forget to make clear for your Linux/Mac users, that they will need to install freetype on their systems as well.
### Dependencies
![Maven Central](https://img.shields.io/maven-central/v/io.github.spair/imgui-java-binding?color=green&label=version&style=flat-square)
Use the same native libraries as you would, but with `-ft` suffix in the end.
<details>
<summary><b>Modified Gradle Example</b></summary>
```
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"
}
```
</details>
| 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`.<br>
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
+27 -7
View File
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+106
View File
@@ -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."
+38 -23
View File
@@ -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."
+107
View File
@@ -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."
@@ -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"
}
}
+1
View File
@@ -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++;
+1 -5
View File
@@ -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 {
+1 -13
View File
@@ -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 {
+1 -2
View File
@@ -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;