Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/workflows/build-addon-on-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,15 @@ jobs:
- name: Create extension library
run: |
cd godot_meta_toolkit
scons platform=${{ matrix.platform }} target=template_debug ${{ matrix.flags }} build_profile=thirdparty/godot_cpp_build_profile/build_profile.json
scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }} build_profile=thirdparty/godot_cpp_build_profile/build_profile.json
scons platform=${{ matrix.platform }} target=template_debug ${{ matrix.flags }} custom_api_file=thirdparty/godot_cpp_gdextension_api/extension_api.json build_profile=thirdparty/godot_cpp_build_profile/build_profile.json
scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }} custom_api_file=thirdparty/godot_cpp_gdextension_api/extension_api.json build_profile=thirdparty/godot_cpp_build_profile/build_profile.json
cd ..
- name: Create Android editor extension library
run: |
cd godot_meta_toolkit
scons platform=${{ matrix.platform }} target=editor ${{ matrix.flags }} custom_api_file=thirdparty/godot_cpp_gdextension_api/extension_api.json build_profile=thirdparty/godot_cpp_build_profile/build_profile.json
cd ..
if: matrix.platform == 'android'
- name: Save Godot build cache
uses: ./godot_meta_toolkit/thirdparty/godot-cpp/.github/actions/godot-cache-save
with:
Expand All @@ -124,6 +130,7 @@ jobs:
uses: actions/checkout@v4
with:
path: godot_meta_toolkit
submodules: recursive
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4
- name: Download Meta Platform SDK
Expand All @@ -141,6 +148,13 @@ jobs:
distribution: "adopt"
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v3
- name: Set up Python (for SCons)
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install scons
run: |
python -m pip install scons==4.0.0
- name: Copy Android binaries
run: |
mkdir -p godot_meta_toolkit/toolkit/src/main/libs/debug/arm64-v8a/arm64-v8a
Expand All @@ -152,6 +166,8 @@ jobs:
run: |
cd godot_meta_toolkit
./gradlew build
git clone --branch 4.4.1-stable https://github.com/godotengine/godot.git
./gradlew generatePrebuiltApks -PgodotDir=godot
cd ..
- name: Create Godot Meta Toolkit Addon
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
local.properties
/thirdparty/ovr_platform_sdk/
/toolkit/src/gen/
compile_commands.json

# Binaries
*.o
Expand Down
15 changes: 13 additions & 2 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ binary_path = '#demo/addons/godot_meta_toolkit/.bin'
android_src_path = '#toolkit/src'
project_name = 'godot_meta_toolkit'

if env['platform'] == "android":
if env['platform'] == "android" and env["target"] != "editor":
env.Append(LIBPATH=['thirdparty/ovr_platform_sdk/Android/libs/arm64-v8a'])
env.Append(LIBS=['ovrplatformloader'])

Expand Down Expand Up @@ -70,7 +70,18 @@ else:

Default(library)

if env["platform"] == "android":
if env["platform"] == "android" and env["target"] != "editor":
# Copy the libovrplatformloader.so files to the addon
ovrplatformloader_copy_path = "#thirdparty/ovr_platform_sdk/Android/libs/arm64-v8a/libovrplatformloader.so"
ovrplatformloader_copy_dest = "{}/{}/{}/{}/libovrplatformloader.so".format(
binary_path,
env["platform"],
env["target"],
env["arch"])
ovrplatformloader_copy = env.Command(ovrplatformloader_copy_dest, ovrplatformloader_copy_path, Copy('$TARGET', '$SOURCE'))
Default(ovrplatformloader_copy)

# Copy the libgodot_meta_toolkit.so files to the project libs directory
android_target = "release" if env["target"] == "template_release" else "debug"
android_arch = ""
if env["arch"] == "arm64":
Expand Down
260 changes: 238 additions & 22 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@ plugins {}

apply from: 'config.gradle'

ext {
godotDir = project.hasProperty("godotDir") ? project.property("godotDir") : ""
godotJavaDir = "${godotDir}/platform/android/java/"

godotAppStandardManifestDir = "${godotJavaDir}/app/src/standard/"
godotAppOutputDir = "${godotJavaDir}/app/build/outputs/apk/standard/"

toolkitAarOutputDir = "toolkit/build/outputs/aar/"
toolkitDebugAar = "${toolkitAarOutputDir}/godot_meta_toolkit-debug.aar"
toolkitReleaseAar = "${toolkitAarOutputDir}/godot_meta_toolkit-release.aar"
}

task clean(type: Delete) {
delete rootProject.buildDir

// Delete the bin directory for the 'godot_meta_toolkit' addon
delete("demo/addons/godot_meta_toolkit/.bin")

dependsOn 'cleanPrebuiltApks'

dependsOn 'cleanScons'

dependsOn ':toolkit:clean'
}

Expand All @@ -39,10 +55,16 @@ task buildToolkit {
}

/**
* Build the scons artifacts for the project
* Generate the addon by building the 'toolkit' module
*/
task buildSconsArtifacts {
// Find scons' executable path
task generateAddon {
dependsOn buildToolkit
}

/*
* Find scons executable path
*/
def getSconsExecutableFile() {
File sconsExecutableFile = null
def sconsName = "scons"
def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows()
Expand All @@ -66,40 +88,234 @@ task buildSconsArtifacts {
}
}

return sconsExecutableFile
}

/**
* Utility method to create common scons tasks for use by other tasks.
*/
def createSconsTasks(File sconsExecutableFile, boolean clean) {
def defaultArgs = [
"--directory=.",
"custom_api_file=thirdparty/godot_cpp_gdextension_api/extension_api.json",
"build_profile=thirdparty/godot_cpp_build_profile/build_profile.json",
]

if (clean) {
defaultArgs << "-c"
}

def taskPrefix = (clean ? "clean" : "build")

// Android.
tasks.create(name: "${taskPrefix}GodotMetaToolkitAndroidArm64Debug", type: Exec) {
executable sconsExecutableFile.absolutePath
args defaultArgs + ["platform=android", "target=template_debug", "arch=arm64"]
}
tasks.create(name: "${taskPrefix}GodotMetaToolkitAndroidArm64Release", type: Exec) {
executable sconsExecutableFile.absolutePath
args defaultArgs + ["platform=android", "target=template_release", "arch=arm64"]
}
tasks.create(name: "${taskPrefix}GodotMetaToolkitAndroidArm64Editor", type: Exec) {
executable sconsExecutableFile.absolutePath
args defaultArgs + ["platform=android", "target=editor", "arch=arm64"]
}

// Desktop.
tasks.create(name: "${taskPrefix}GodotMetaToolkitDesktopDebug", type: Exec) {
executable sconsExecutableFile.absolutePath
args defaultArgs + ["target=template_debug"]
}
tasks.create(name: "${taskPrefix}GodotMetaToolkitDesktopRelease", type: Exec) {
executable sconsExecutableFile.absolutePath
args defaultArgs + ["target=template_release"]
}
}

/**
* Build the scons artifacts for the project
*/
task buildSconsArtifacts {
File sconsExecutableFile = getSconsExecutableFile()

// Using `doFirst` so the exception doesn't happen until this task actually runs.
doFirst {
if (sconsExecutableFile == null) {
throw new GradleException("Unable to find executable path for the '$sconsName' command.")
throw new GradleException("Unable to find executable path for the 'scons' command.")
} else {
logger.debug("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}")
logger.debug("Found executable path for scons: ${sconsExecutableFile.absolutePath}")
}
}

if (sconsExecutableFile != null) {
// Build the GDExtension library for Android.
tasks.create(name: "buildGodotMetaToolkitAndroidArm64Debug", type: Exec) {
executable sconsExecutableFile.absolutePath
args "--directory=.", "platform=android", "target=template_debug", "arch=arm64", "build_profile=thirdparty/godot_cpp_build_profile/build_profile.json"
}
tasks.create(name: "buildGodotMetaToolkitAndroidArm64Release", type: Exec) {
executable sconsExecutableFile.absolutePath
args "--directory=.", "platform=android", "target=template_release", "arch=arm64", "build_profile=thirdparty/godot_cpp_build_profile/build_profile.json"
}
createSconsTasks(sconsExecutableFile, false)

// Android.
dependsOn 'buildGodotMetaToolkitAndroidArm64Debug'
dependsOn 'buildGodotMetaToolkitAndroidArm64Release'
dependsOn 'buildGodotMetaToolkitAndroidArm64Editor'

// Desktop.
dependsOn 'buildGodotMetaToolkitDesktopDebug'
dependsOn 'buildGodotMetaToolkitDesktopRelease'
}
}

/**
* Scons clean for the project
*/
task cleanScons {
File sconsExecutableFile = getSconsExecutableFile()

// Using `doFirst` so the exception doesn't happen until this task actually runs.
doFirst {
if (sconsExecutableFile == null) {
throw new GradleException("Unable to find executable path for the 'scons' command.")
} else {
logger.debug("Found executable path for scons: ${sconsExecutableFile.absolutePath}")
}
}

if (sconsExecutableFile != null) {
createSconsTasks(sconsExecutableFile, true)

// Build the GDExtension library for desktop.
tasks.create(name: "buildGodotMetaToolkitDesktopDebug", type: Exec) {
// Android.
dependsOn 'cleanGodotMetaToolkitAndroidArm64Debug'
dependsOn 'cleanGodotMetaToolkitAndroidArm64Release'
dependsOn 'cleanGodotMetaToolkitAndroidArm64Editor'

// Desktop.
dependsOn 'cleanGodotMetaToolkitDesktopDebug'
dependsOn 'cleanGodotMetaToolkitDesktopRelease'
}
}

/**
* Cleans the generated prebuilt apks.
*/
task cleanPrebuiltApks(type: Delete) {
def gradlewExecutablePath = "./gradlew" + (org.gradle.internal.os.OperatingSystem.current().isWindows() ? ".bat" : "")
File gradlewExecutable = file(gradlewExecutablePath)

doFirst {
if (!gradlewExecutable.exists()) {
throw new GradleException("Unable to find executable path for the 'gradlew' script.")
}
}

delete "meta-export-template.zip"

if (godotDir != "") {
delete(godotAppStandardManifestDir)

tasks.create(name: "cleanGodot", type: Exec) {
executable gradlewExecutable.absolutePath
args "-p", godotJavaDir, "clean"
}
dependsOn 'cleanGodot'
}
}

/**
* Copy the prebuilt manifest to the Godot::app module. The manifest contains additional meta-data
* that this plugin modifies at export time based on the project configuration.
*/
task copyPrebuiltManifestToGodotApp(type: Copy) {
// Copy the prebuilt manifest
file(godotAppStandardManifestDir).mkdirs()

from "./prebuilt/AndroidManifest.xml"
into godotAppStandardManifestDir
}

/**
* Zip the generated prebuilt apks
*/
task zipPrebuiltApks(type: Zip) {
from(godotAppOutputDir)
include '**/*.apk'
archiveFileName = "meta-export-template.zip"
destinationDirectory = project.rootDir
}

void verifyGodotDir() {
if (godotDir == "" || !file(godotDir).exists() || !file(godotDir).isDirectory()) {
throw new GradleException("godotDir property is empty or invalid.")
}
}


/**
* Generate the prebuilt apks.
*/
task generatePrebuiltApks() {
def gradlewExecutablePath = "./gradlew" + (org.gradle.internal.os.OperatingSystem.current().isWindows() ? ".bat" : "")
File gradlewExecutable = file(gradlewExecutablePath)

File sconsExecutableFile = getSconsExecutableFile()

doFirst {
if (!gradlewExecutable.exists()) {
throw new GradleException("Unable to find executable path for the 'gradlew' script.")
}
}

if (sconsExecutableFile != null && sconsExecutableFile.exists()) {
tasks.create(name: "buildGodotAndroidArm64Debug", type: Exec) {
doFirst {
verifyGodotDir()
}
executable sconsExecutableFile.absolutePath
args "--directory=.", "target=template_debug", "build_profile=thirdparty/godot_cpp_build_profile/build_profile.json"
args "--directory=${godotDir}", "platform=android", "target=template_debug", "arch=arm64"
}
tasks.create(name: "buildGodotMetaToolkitDesktopRelease", type: Exec) {

tasks.create(name: "buildGodotAndroidArm64Release", type: Exec) {
doFirst {
verifyGodotDir()
}
executable sconsExecutableFile.absolutePath
args "--directory=.", "target=template_release", "build_profile=thirdparty/godot_cpp_build_profile/build_profile.json"
args "--directory=${godotDir}", "platform=android", "target=template_release", "arch=arm64"
}
}

tasks.create(name: "assemblePrebuiltDebugApk", type: Exec) {
dependsOn 'copyPrebuiltManifestToGodotApp'
dependsOn ':toolkit:assembleDebug'

if (sconsExecutableFile != null && sconsExecutableFile.exists()) {
dependsOn 'buildGodotAndroidArm64Debug'
}
doFirst {
verifyGodotDir()
}
executable gradlewExecutable.absolutePath
args "-p",
godotJavaDir,
":app:assembleStandardDebug",
"-Pplugins_remote_binaries=org.godotengine:godot-openxr-vendors-meta:$versions.openxrVendorsVersion",
"-Pplugins_local_binaries=${file(toolkitDebugAar).absolutePath}"
}

dependsOn 'buildGodotMetaToolkitDesktopDebug'
dependsOn 'buildGodotMetaToolkitDesktopRelease'
tasks.create(name: "assemblePrebuiltReleaseApk", type: Exec) {
dependsOn 'copyPrebuiltManifestToGodotApp'
dependsOn ':toolkit:assembleRelease'

if (sconsExecutableFile != null && sconsExecutableFile.exists()) {
dependsOn 'buildGodotAndroidArm64Release'
}
doFirst {
verifyGodotDir()
}
executable gradlewExecutable.absolutePath
args "-p",
godotJavaDir,
":app:assembleStandardRelease",
"-Pplugins_remote_binaries=org.godotengine:godot-openxr-vendors-meta:$versions.openxrVendorsVersion",
"-Pplugins_local_binaries=${file(toolkitReleaseAar).absolutePath}"
}
}

dependsOn 'assemblePrebuiltDebugApk'
dependsOn 'assemblePrebuiltReleaseApk'

finalizedBy 'zipPrebuiltApks'
}
Loading
Loading