diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35e8319538..7b541fa789 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -586,8 +586,11 @@ jobs: - name: 'Extract Android SDK from AAR' id: sdk run: | - python "${{ github.workspace }}/${{ needs.android.outputs.android-aar }}" -o /tmp/SDL3-android + cd /tmp + unzip "${{ github.workspace }}/${{ needs.android.outputs.android-aar }}" + python "${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" -o /tmp/SDL3-android echo "prefix=/tmp/SDL3-android" >>$GITHUB_OUTPUT + echo "sdl3-aar=/tmp/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" >>$GITHUB_OUTPUT - name: 'CMake (configure + build) x86, x64, arm32, arm64' run: | android_abis="x86 x86_64 armeabi-v7a arm64-v8a" @@ -617,7 +620,7 @@ jobs: echo "path=/tmp/projects/org.libsdl.testspriteminimal" >>$GITHUB_OUTPUT - name: 'Copy SDL3 aar into Gradle project' run: | - cp "${{ github.workspace }}/${{ needs.android.outputs.android-aar }}" "${{ steps.create-gradle-project.outputs.path }}/app/libs" + cp "${{ steps.sdk.outputs.sdl3-aar }}" "${{ steps.create-gradle-project.outputs.path }}/app/libs" echo "" echo "Project contents:" diff --git a/INSTALL.md b/INSTALL.md index 26ce60a20f..c9f6278a40 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -46,7 +46,7 @@ Read docs/README-cmake.md # Example code -Look at the example programs in ./test, and check out the online +Look at the example programs in ./examples, and check out the online documentation at https://wiki.libsdl.org/SDL3/ # Discussion diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py index 70d71ae091..0e08161960 100755 --- a/build-scripts/build-release.py +++ b/build-scripts/build-release.py @@ -961,7 +961,8 @@ class Releaser: if not cmake_toolchain_file.exists(): logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file) raise SystemExit(1) - aar_path = self.dist_path / f"{self.project}-{self.version}.aar" + aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar" + android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip" android_abis = self.release_info["android"]["abis"] java_jars_added = False module_data_added = False @@ -969,14 +970,24 @@ class Releaser: shutil.rmtree(android_deps_path, ignore_errors=True) for dep, depinfo in self.release_info["android"].get("dependencies", {}).items(): - android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] - with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"): - self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)]) + dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + + dep_extract_path = self.deps_path / f"extract/android/{dep}" + shutil.rmtree(dep_extract_path, ignore_errors=True) + dep_extract_path.mkdir(parents=True, exist_ok=True) + + with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"): + with zipfile.ZipFile(dep_devel_zip, "r") as zf: + zf.extractall(dep_extract_path) + + dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0] + self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)]) for module_name, module_info in self.release_info["android"]["modules"].items(): assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type" - archive_file_tree = ArchiveFileTree() + aar_file_tree = ArchiveFileTree() + android_devel_file_tree = ArchiveFileTree() for android_abi in android_abis: with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): @@ -1027,20 +1038,20 @@ class Releaser: assert library.suffix in (".so", ".a") assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}" arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}" - archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time)) - archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time)) if not module_data_added: library_name = None if module_info["type"] == "library": library_name = Path(module_info["library"]).stem.removeprefix("lib") export_libraries = module_info.get("export-libraries", []) - archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time)) arcdir_prefab_include = f"prefab/modules/{module_name}/include" if "includes" in module_info: - archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time) + aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time) else: - archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time)) module_data_added = True if not java_jars_added: @@ -1053,21 +1064,28 @@ class Releaser: assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})" assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})" - archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time)) - archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time)) - archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time)) assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives" - archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) - archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time)) - archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time)) with Archiver(zip_path=aar_path) as archiver: - archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + aar_file_tree.add_to_archiver(archive_base="", archiver=archiver) archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) - self.artifacts[f"android-aar"] = aar_path + + android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path)) + android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + with Archiver(zip_path=android_dist_path) as archiver: + android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) + + self.artifacts[f"android-aar"] = android_dist_path def download_dependencies(self): shutil.rmtree(self.deps_path, ignore_errors=True) @@ -1104,7 +1122,7 @@ class Releaser: assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" if "android" in self.release_info: android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) - assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" + assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}" @staticmethod def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig: diff --git a/build-scripts/pkg-support/android/INSTALL.md.in b/build-scripts/pkg-support/android/README.md.in similarity index 67% rename from build-scripts/pkg-support/android/INSTALL.md.in rename to build-scripts/pkg-support/android/README.md.in index 6780fe9ae5..4314b74802 100644 --- a/build-scripts/pkg-support/android/INSTALL.md.in +++ b/build-scripts/pkg-support/android/README.md.in @@ -1,7 +1,23 @@ + +The Simple DirectMedia Layer (SDL for short) is a cross-platform library +designed to make it easy to write multi-media software, such as games +and emulators. + +The Simple DirectMedia Layer library source code is available from: +https://www.libsdl.org/ + +This library is distributed under the terms of the zlib license: +http://www.zlib.net/zlib_license.html + +# @<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar + This Android archive allows use of @<@PROJECT_NAME@>@ in your Android project, without needing to copy any SDL source. + +## Gradle integration + For integration with CMake/ndk-build, it uses [prefab](https://google.github.io/prefab/). -Copy this archive (@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar) to a `app/libs` directory of your project. +Copy the aar archive (@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar) to a `app/libs` directory of your project. In `app/build.gradle` of your Android project, add: ``` @@ -40,9 +56,9 @@ $(call import-module,prefab/@<@PROJECT_NAME@>@) --- -For advanced users: +## Other build systems (advanced) -If you want to build a 3rd party library outside Gradle, +If you want to build a project without Gradle, running the following command will extract the Android archive into a more common directory structure. ``` python @<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar -o android_prefix @@ -50,7 +66,7 @@ python @<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar -o android_prefix Add `--help` for a list of all available options. -Look at the example programs in ./test (of the source archive), and check out online documentation: +Look at the example programs in ./examples (of the source archive), and check out online documentation: https://wiki.libsdl.org/SDL3/FrontPage Join the SDL discourse server if you want to join the community: diff --git a/build-scripts/pkg-support/android/__main__.py.in b/build-scripts/pkg-support/android/aar/__main__.py.in similarity index 100% rename from build-scripts/pkg-support/android/__main__.py.in rename to build-scripts/pkg-support/android/aar/__main__.py.in diff --git a/build-scripts/pkg-support/android/cmake/SDL3Config.cmake b/build-scripts/pkg-support/android/aar/cmake/SDL3Config.cmake similarity index 100% rename from build-scripts/pkg-support/android/cmake/SDL3Config.cmake rename to build-scripts/pkg-support/android/aar/cmake/SDL3Config.cmake diff --git a/build-scripts/pkg-support/android/cmake/SDL3ConfigVersion.cmake.in b/build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in similarity index 100% rename from build-scripts/pkg-support/android/cmake/SDL3ConfigVersion.cmake.in rename to build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in diff --git a/build-scripts/pkg-support/android/description.json.in b/build-scripts/pkg-support/android/aar/description.json.in similarity index 100% rename from build-scripts/pkg-support/android/description.json.in rename to build-scripts/pkg-support/android/aar/description.json.in diff --git a/build-scripts/pkg-support/mingw/INSTALL.txt b/build-scripts/pkg-support/mingw/INSTALL.txt index 61dc062e86..9baefeb298 100644 --- a/build-scripts/pkg-support/mingw/INSTALL.txt +++ b/build-scripts/pkg-support/mingw/INSTALL.txt @@ -15,7 +15,7 @@ Use DESTDIR to change the target location mkdir $HOME/mingw32-prefix make install-i686 DESTDIR=$HOME/mingw32-prefix -Look at the example programs in ./test, and check out online documentation: +Look at the example programs in ./examples, and check out online documentation: https://wiki.libsdl.org/SDL3/FrontPage Join the SDL discourse server if you want to join the community: diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json index ab103c8d36..d532114d43 100644 --- a/build-scripts/release-info.json +++ b/build-scripts/release-info.json @@ -151,9 +151,9 @@ "-DSDL_STATIC=OFF", "-DSDL_TEST_LIBRARY=ON", "-DSDL_TESTS=OFF", - "-DSDL_DISABLE_ANDROID_JAR=OFF", - "-DSDL_DISABLE_INSTALL=OFF", - "-DSDL_DISABLE_INSTALL_DOCS=OFF", + "-DSDL_ANDROID_JAR=ON", + "-DSDL_INSTALL=ON", + "-DSDL_INSTALL_DOCS=ON", "-DSDL_VENDOR_INFO=libsdl.org" ] }, @@ -197,20 +197,25 @@ "api-minimum": 19, "api-target": 29, "ndk-minimum": 21, - "files": { + "aar-files": { "": [ "android-project/app/proguard-rules.pro:proguard.txt", - "build-scripts/pkg-support/android/INSTALL.md.in:INSTALL.md", - "build-scripts/pkg-support/android/__main__.py.in:__main__.py", - "build-scripts/pkg-support/android/description.json.in:description.json" + "build-scripts/pkg-support/android/aar/__main__.py.in:__main__.py", + "build-scripts/pkg-support/android/aar/description.json.in:description.json" ], "META-INF": [ "LICENSE.txt" ], "cmake": [ "cmake/sdlcpu.cmake", - "build-scripts/pkg-support/android/cmake/SDL3Config.cmake", - "build-scripts/pkg-support/android/cmake/SDL3ConfigVersion.cmake.in:SDL3ConfigVersion.cmake" + "build-scripts/pkg-support/android/aar/cmake/SDL3Config.cmake", + "build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in:SDL3ConfigVersion.cmake" + ] + }, + "files": { + "": [ + "LICENSE.txt", + "build-scripts/pkg-support/android/README.md.in:README.md" ] } }