diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e623d479..ba5062ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ jobs: build-java: strategy: matrix: - os: [ubuntu-20.04, macos-10.15] + os: [ubuntu-20.04, macos-latest] name: Build Java runs-on: ${{ matrix.os }} steps: @@ -25,7 +25,7 @@ jobs: FREETYPE_URL: https://download.savannah.gnu.org/releases/freetype/freetype-2.10.4.tar.gz strategy: matrix: - os: [ubuntu-20.04, macos-10.15] + os: [ubuntu-20.04, macos-latest] type: [win, linux, mac] freetype: [true, false] include: @@ -35,12 +35,14 @@ jobs: expected: /tmp/imgui/libsNative/linux64/libimgui-java64.so - type: mac expected: /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib + - type: mac + expected: /tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib exclude: - os: ubuntu-20.04 type: mac - - os: macos-10.15 + - os: macos-latest type: win - - os: macos-10.15 + - os: macos-latest type: linux name: Build Native (type=${{ matrix.type }}, freetype=${{ matrix.freetype }}) runs-on: ${{ matrix.os }} @@ -62,6 +64,17 @@ jobs: name: Install MinGW-w64/GCC/G++ run: sudo apt install mingw-w64 + - if: matrix.os == 'macos-latest' + name: Build Setup Mac xcode + run: | + # See https://github.com/actions/virtual-environments/issues/2557 + sudo mv /Library/Developer/CommandLineTools/SDKs/* /tmp + sudo mv /Applications/Xcode.app /Applications/Xcode.app.bak + sudo mv /Applications/Xcode_12.4.app /Applications/Xcode.app + sudo xcode-select -switch /Applications/Xcode.app + /usr/bin/xcodebuild -version + brew install freetype + - if: matrix.os == 'ubuntu-20.04' && matrix.type == 'linux' && matrix.freetype == true name: FreeType - Install run: sudo apt install libfreetype6-dev diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe48b467..d1b1b8fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,4 +57,5 @@ jobs: imgui-lwjgl3/build/libs/*.jar bin/imgui-java64.dll bin/libimgui-java64.dylib + bin/libimgui-javaarm64.dylib bin/libimgui-java64.so diff --git a/README.md b/README.md index 4404e34f..2581fb3d 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,7 @@ dependencies { - imgui-java64.dll - Windows - libimgui-java64.so - Linux - libimgui-java64.dylib - MacOS + - libimgui-javaarm64.dylib - MacOS 3. Add jars to your classpath; 4. Provide a VM option: `imgui.library.path` or `java.library.path`. It should point to the folder where you've placed downloaded native libraries. @@ -365,6 +366,7 @@ Ensure you've downloaded git submodules. That could be achieved: - Check dependencies from "Linux" section and make sure you have them installed. - Build with: `./gradlew :imgui-binding:generateLibs -Denvs=mac -Dlocal` - Run with: `./gradlew :example:run -PlibPath=../imgui-binding/build/libsNative/macosx64` + - Alternatively for M1 Run with: `./gradlew :example:run -PlibPath=../imgui-binding/build/libsNative/macosxarm64` In `envs` parameter next values could be used `win`, `linux` or `mac`.
`-Dlocal` is optional and means that natives will be built under the `./imgui-binding/build/` folder. Otherwise `/tmp/imgui` folder will be used. diff --git a/bin/README.txt b/bin/README.txt index c58aab18..580384b7 100644 --- a/bin/README.txt +++ b/bin/README.txt @@ -9,5 +9,6 @@ You can change that by using 'imgui.library.name' VM option (ex: -Dimgui.library - imgui-java64.dll << Windows - libimgui-java64.so << Linux - libimgui-java64.dylib << MacOS +- libimgui-javaarm64.dylib << MacOS Freetype folder contains same libraries, but with Freetype support. diff --git a/bin/libimgui-javaarm64.dylib b/bin/libimgui-javaarm64.dylib new file mode 100644 index 00000000..2a2c1abc Binary files /dev/null and b/bin/libimgui-javaarm64.dylib differ diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 679f2dbe..6a0b2290 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -7,7 +7,7 @@ repositories { } ext { - jnigenVersion = '2.0.1' + jnigenVersion = '2.2.1' } dependencies { diff --git a/buildSrc/scripts/copy-ft.sh b/buildSrc/scripts/copy-ft.sh index 2aac9bb6..f1460b6e 100644 --- a/buildSrc/scripts/copy-ft.sh +++ b/buildSrc/scripts/copy-ft.sh @@ -10,3 +10,4 @@ mkdir ./bin/freetype [ -e "/tmp/imgui/libsNative/linux32/libimgui-java.so" ] && cp /tmp/imgui/libsNative/linux32/libimgui-java.so ./bin/freetype [ -e "/tmp/imgui/libsNative/linux64/libimgui-java64.so" ] && cp /tmp/imgui/libsNative/linux64/libimgui-java64.so ./bin/freetype [ -e "/tmp/imgui/libsNative/macosx64/libimgui-java64.dylib" ] && cp /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib ./bin/freetype +[ -e "/tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib" ] && cp /tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib ./bin/freetype diff --git a/buildSrc/scripts/copy.sh b/buildSrc/scripts/copy.sh index 37aa4272..da5646d4 100644 --- a/buildSrc/scripts/copy.sh +++ b/buildSrc/scripts/copy.sh @@ -8,3 +8,4 @@ cd $BASEDIR/../.. || exit [ -e "/tmp/imgui/libsNative/linux32/libimgui-java.so" ] && cp /tmp/imgui/libsNative/linux32/libimgui-java.so ./bin [ -e "/tmp/imgui/libsNative/linux64/libimgui-java64.so" ] && cp /tmp/imgui/libsNative/linux64/libimgui-java64.so ./bin [ -e "/tmp/imgui/libsNative/macosx64/libimgui-java64.dylib" ] && cp /tmp/imgui/libsNative/macosx64/libimgui-java64.dylib ./bin +[ -e "/tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib" ] && cp /tmp/imgui/libsNative/macosxarm64/libimgui-javaarm64.dylib ./bin diff --git a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy index bb2d3234..765e187d 100644 --- a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy +++ b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy @@ -19,6 +19,7 @@ class GenerateLibs extends DefaultTask { private final boolean forWindows = buildEnvs?.contains('win') private final boolean forLinux = buildEnvs?.contains('linux') private final boolean forMac = buildEnvs?.contains('mac') + private static final boolean isARM = System.getProperty("os.arch").equals("arm") || System.getProperty("os.arch").startsWith("aarch64"); private final boolean isLocal = System.properties.containsKey('local') private final boolean withFreeType = Boolean.valueOf(System.properties.getProperty('freetype', 'false')) @@ -104,6 +105,13 @@ class GenerateLibs extends DefaultTask { mac64.linkerFlags = mac64.linkerFlags.replace('10.7', minMacOsVersion) addFreeTypeIfEnabled(mac64) buildTargets += mac64 + + def macM1 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.MacOsX, true, true) + macM1.cppFlags += ' -std=c++14' + macM1.cppFlags = macM1.cppFlags.replace('10.7', minMacOsVersion) + macM1.linkerFlags = macM1.linkerFlags.replace('10.7', minMacOsVersion) + addFreeTypeIfEnabled(macM1) + buildTargets += macM1 } new AntScriptGenerator().generate(buildConfig, buildTargets) @@ -117,8 +125,10 @@ class GenerateLibs extends DefaultTask { BuildExecutor.executeAnt(jniDir + '/build-windows64.xml', commonParams) if (forLinux) BuildExecutor.executeAnt(jniDir + '/build-linux64.xml', commonParams) - if (forMac) + if (forMac) { BuildExecutor.executeAnt(jniDir + '/build-macosx64.xml', commonParams) + BuildExecutor.executeAnt(jniDir + '/build-macosxarm64.xml', commonParams) + } BuildExecutor.executeAnt(jniDir + '/build.xml', '-v', 'pack-natives') } @@ -136,7 +146,11 @@ class GenerateLibs extends DefaultTask { target.cppFlags += ' -I/usr/include/freetype2' break case BuildTarget.TargetOs.MacOsX: - target.cppFlags += ' -I/usr/local/include/freetype2' + if (isARM) { + target.cppFlags += " -I/opt/homebrew/Cellar/freetype/2.11.1/include/freetype2" + } else { + target.cppFlags += ' -I/usr/local/include/freetype2' + } break } diff --git a/imgui-app/build.gradle b/imgui-app/build.gradle index 9e70faf0..b69f7871 100644 --- a/imgui-app/build.gradle +++ b/imgui-app/build.gradle @@ -17,7 +17,7 @@ dependencies { api 'org.lwjgl:lwjgl-glfw' api 'org.lwjgl:lwjgl-opengl' - ['natives-linux', 'natives-windows', 'natives-macos'].each { + ['natives-linux', 'natives-windows', 'natives-macos', 'natives-macos-arm64'].each { api "org.lwjgl:lwjgl::$it" api "org.lwjgl:lwjgl-glfw::$it" api "org.lwjgl:lwjgl-opengl::$it" @@ -31,6 +31,7 @@ jar { from('../bin') { include 'libimgui-java64.so' include 'libimgui-java64.dylib' + include 'libimgui-javaarm64.dylib' into 'io/imgui/java/native-bin/' } from('../bin/freetype') { diff --git a/imgui-binding-natives/build.gradle b/imgui-binding-natives/build.gradle index 74abc2eb..463c1b61 100644 --- a/imgui-binding-natives/build.gradle +++ b/imgui-binding-natives/build.gradle @@ -7,23 +7,23 @@ plugins { def packageName = 'imgui-java-natives-linux' def packageDesc = 'Native binaries for imgui-java binding for Linux' def fromDir = '../bin' -def libName = 'libimgui-java64.so' +def libNames = ['libimgui-java64.so'] switch (findProperty('deployType')) { case 'win': packageName = 'imgui-java-natives-windows' packageDesc = 'Native binaries for imgui-java binding for Windows' - libName = 'imgui-java64.dll' + libName = ['imgui-java64.dll'] break case 'linux': packageName = 'imgui-java-natives-linux' packageDesc = 'Native binaries for imgui-java binding for Linux' - libName = 'libimgui-java64.so' + libNames = ['libimgui-java64.so'] break case 'mac': packageName = 'imgui-java-natives-macos' packageDesc = 'Native binaries for imgui-java binding for MacOS' - libName = 'libimgui-java64.dylib' + libNames = ['libimgui-java64.dylib', 'libimgui-javaarm64.dylib'] break } @@ -35,7 +35,7 @@ if (findProperty('freetype') == 'true') { jar { from(fromDir) { - include "$libName" // this is fine + include libNames // this is fine into 'io/imgui/java/native-bin/' } manifest { diff --git a/imgui-binding/src/main/java/imgui/ImGui.java b/imgui-binding/src/main/java/imgui/ImGui.java index 1f8d977d..29925424 100644 --- a/imgui-binding/src/main/java/imgui/ImGui.java +++ b/imgui-binding/src/main/java/imgui/ImGui.java @@ -25,7 +25,10 @@ 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 String LIB_NAME_DEFAULT = System.getProperty("os.arch").contains("64") ? "imgui-java64" : "imgui-java"; + private static final String LIB_NAME_BASE = "imgui-java"; + private static final boolean is64Bit = System.getProperty("os.arch").contains("64") || System.getProperty("os.arch").startsWith("armv8"); + private static final boolean isARM = System.getProperty("os.arch").equals("arm") || System.getProperty("os.arch").startsWith("aarch64"); + private static final String LIB_TMP_DIR_PREFIX = "imgui-java-natives_" + System.currentTimeMillis(); private static final ImGuiContext IMGUI_CONTEXT; @@ -45,7 +48,16 @@ public class ImGui { static { final String libPath = System.getProperty(LIB_PATH_PROP); - final String libName = System.getProperty(LIB_NAME_PROP, LIB_NAME_DEFAULT); + String genLibName = LIB_NAME_BASE; + + if (isARM) { + genLibName += "arm"; + } + if (is64Bit) { + genLibName += "64"; + } + + final String libName = System.getProperty(LIB_NAME_PROP, genLibName); final String fullLibName = resolveFullLibName(); final String extractedLibAbsPath = tryLoadFromClasspath(fullLibName); @@ -104,7 +116,17 @@ private static String resolveFullLibName() { libSuffix = ".so"; } - return System.getProperty(LIB_NAME_PROP, libPrefix + LIB_NAME_DEFAULT + libSuffix); + String genLibName = LIB_NAME_BASE; + + if (isARM) { + genLibName += "arm"; + } + if (is64Bit) { + genLibName += "64"; + } + + + return System.getProperty(LIB_NAME_PROP, libPrefix + genLibName + libSuffix); } // This method tries to unpack the library binary from classpath into the temp dir.