Add Termux package build system wrapper to build GNU Parted
This commit is contained in:
parent
f63ff76a1a
commit
abc6fe3db2
13 changed files with 281 additions and 3 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -10,3 +10,6 @@
|
|||
[submodule "app/src/c/libressl"]
|
||||
path = dmg2img/src/c/libressl
|
||||
url = https://github.com/libressl-portable/portable.git
|
||||
[submodule "termux-packages/src/c/termux-packages"]
|
||||
path = termux-packages/src/c/termux-packages
|
||||
url = https://github.com/Depau/termux-packages.git
|
||||
|
|
|
@ -8,7 +8,7 @@ android {
|
|||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "eu.depau.etchdroid"
|
||||
minSdkVersion 19
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
@ -37,7 +37,7 @@ dependencies {
|
|||
// implementation 'com.github.mjdev:libaums:0.5.5'
|
||||
implementation project(':libaums')
|
||||
implementation project(':dmg2img')
|
||||
|
||||
implementation project(':termux-packages')
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.2.61'
|
||||
ext.kotlin_version = '1.2.50'
|
||||
repositories {
|
||||
google()
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
include ':app', ':libaums', ':dmg2img'
|
||||
include ':app', ':libaums', ':dmg2img', ':termux-packages'
|
||||
project(':libaums').projectDir = new File('libaums/libaums')
|
10
termux-packages/CMakeLists.txt
Normal file
10
termux-packages/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
set(ASSETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/main/assets/termux/${ANDROID_ABI}")
|
||||
|
||||
add_subdirectory(src/c/termux-wrapper)
|
||||
|
||||
# Dummy target for Gradle to pick up termux_wrapper
|
||||
add_executable(termux_packages
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/c/dummy.c)
|
||||
add_dependencies(termux_packages termux_build)
|
33
termux-packages/build.gradle
Normal file
33
termux-packages/build.gradle
Normal file
|
@ -0,0 +1,33 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
targets "termux_packages"
|
||||
arguments "-DAPP_PKGNAME=eu.depau.etchdroid", "-DTERMUX_PACKAGES=parted"
|
||||
}
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
assets.srcDirs('src/main/assets')
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
compile "org.kamranzafar:jtar:2.3"
|
||||
compile "commons-io:commons-io:2.6"
|
||||
}
|
1
termux-packages/src/c/dummy.c
Normal file
1
termux-packages/src/c/dummy.c
Normal file
|
@ -0,0 +1 @@
|
|||
int main() {}
|
1
termux-packages/src/c/termux-packages
Submodule
1
termux-packages/src/c/termux-packages
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e45ad0d7e998fc707dbf4e0f578482b32218e418
|
33
termux-packages/src/c/termux-wrapper/CMakeLists.txt
Normal file
33
termux-packages/src/c/termux-wrapper/CMakeLists.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# NDK is assumed to be placed inside SDK directory
|
||||
# Should be implemented better
|
||||
get_filename_component(ANDROID_SDK ${ANDROID_NDK} DIRECTORY)
|
||||
|
||||
if(${ANDROID_ABI} STREQUAL "x86")
|
||||
set(TERMUX_ARCH "i686")
|
||||
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
|
||||
set(TERMUX_ARCH "aarch64")
|
||||
elseif(${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
||||
set(TERMUX_ARCH "arm")
|
||||
else()
|
||||
set(TERMUX_ARCH "${ANDROID_ABI}")
|
||||
endif()
|
||||
|
||||
set(TERMUX_TOPDIR "${PROJECT_BINARY_DIR}/termux-topdir")
|
||||
set(TERMUX_DEBDIR "${Project_BINARY_DIR}/termux-debs")
|
||||
set(TERMUX_PREFIX "/data/data/${APP_PKGNAME}/files/termux/usr")
|
||||
set(TERMUX_ANDROID_HOME "/data/data/${APP_PKGNAME}/files/termux/home")
|
||||
|
||||
add_custom_target(termux_build
|
||||
${CMAKE_COMMAND} -E env
|
||||
ASSETS_PATH=${ASSETS_PATH}
|
||||
NDK=${ANDROID_NDK}
|
||||
ANDROID_HOME=${ANDROID_SDK}
|
||||
TERMUX_TOPDIR=${TERMUX_TOPDIR}
|
||||
TERMUX_DEBDIR=${TERMUX_DEBDIR}
|
||||
TERMUX_PREFIX=${TERMUX_PREFIX}
|
||||
TERMUX_ANDROID_HOME=${TERMUX_ANDROID_HOME}
|
||||
TERMUX_ARCH=${TERMUX_ARCH}
|
||||
${CMAKE_CURRENT_LIST_DIR}/build-packages.sh ${TERMUX_PACKAGES}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
12
termux-packages/src/c/termux-wrapper/build-packages.sh
Executable file
12
termux-packages/src/c/termux-wrapper/build-packages.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd ../termux-packages
|
||||
|
||||
for package in "$@"
|
||||
do
|
||||
./build-package.sh -a $TERMUX_ARCH $package
|
||||
done
|
||||
|
||||
cd ../termux-wrapper
|
||||
|
||||
./install-packages.sh $TERMUX_DEBDIR $ASSETS_PATH
|
50
termux-packages/src/c/termux-wrapper/install-packages.sh
Executable file
50
termux-packages/src/c/termux-wrapper/install-packages.sh
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
DEBDIR="$1"
|
||||
DESTDIR="$2"
|
||||
|
||||
echo "Creating output tarball"
|
||||
|
||||
cd "$DEBDIR"
|
||||
|
||||
(
|
||||
rm -f pkg_info.txt
|
||||
rm -Rf root
|
||||
rm -Rf tmp
|
||||
) > /dev/null 2>&1
|
||||
|
||||
mkdir root
|
||||
|
||||
# Extract packages
|
||||
ls | sort | grep \\.deb | grep -v -- '-dev_' | while read pkg; do
|
||||
mkdir tmp
|
||||
cd tmp
|
||||
ar -x ../$pkg
|
||||
tar -xJf control.tar.xz
|
||||
cat control >> ../pkg_info.txt
|
||||
echo >> ../pkg_info.txt
|
||||
cd ../root
|
||||
tar -xJf ../tmp/data.tar.xz
|
||||
cd ..
|
||||
rm -Rf tmp
|
||||
done
|
||||
|
||||
mkdir -p $DESTDIR
|
||||
|
||||
# Create info files
|
||||
sha256sum pkg_info.txt > pkg_fprint.txt
|
||||
cp pkg_info.txt pkg_fprint.txt root/data/data/*/files/termux
|
||||
cp pkg_info.txt pkg_fprint.txt $DESTDIR
|
||||
|
||||
# Cleanup unneeded files
|
||||
pushd root/data/data/*/files/termux/usr > /dev/null
|
||||
rm -Rf include
|
||||
rm -Rf share/doc share/info share/man
|
||||
|
||||
# Create output tar
|
||||
cd ../..
|
||||
tar -cf $DESTDIR/packages.tar termux
|
||||
|
||||
# Cleanup
|
||||
popd > /dev/null
|
||||
rm -Rf root pkg_info.txt pkg_fprint.txt
|
3
termux-packages/src/main/AndroidManifest.xml
Normal file
3
termux-packages/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="eu.depau.termux_wrapper" >
|
||||
</manifest>
|
|
@ -0,0 +1,131 @@
|
|||
package eu.depau.termux_wrapper
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.kamranzafar.jtar.TarEntry
|
||||
import org.kamranzafar.jtar.TarInputStream
|
||||
import java.io.*
|
||||
import java.nio.file.attribute.PosixFilePermission
|
||||
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun InputStream.readString(): String {
|
||||
val baos = ByteArrayOutputStream()
|
||||
val buffer = ByteArray(1024)
|
||||
var length = this.read(buffer)
|
||||
|
||||
while (length != -1) {
|
||||
baos.write(buffer, 0, length)
|
||||
length = this.read(buffer)
|
||||
}
|
||||
return baos.toString("UTF-8")
|
||||
}
|
||||
|
||||
|
||||
class TermuxWrapper(val context: Context) {
|
||||
public var path: MutableList<String> = mutableListOf(
|
||||
"/usr/local/sbin",
|
||||
"/usr/local/bin",
|
||||
"/usr/sbin",
|
||||
"/usr/bin",
|
||||
"/sbin",
|
||||
"/bin"
|
||||
)
|
||||
|
||||
val arch: String
|
||||
get() {
|
||||
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
Build.SUPPORTED_ABIS[0]
|
||||
else
|
||||
Build.CPU_ABI
|
||||
|
||||
return when {
|
||||
abi.contains("armeabi-v7a") -> "armeabi-v7a"
|
||||
abi.contains("x86_64") -> "x86_64"
|
||||
abi.contains("x86") -> "x86"
|
||||
abi.contains("arm64-v8a") -> "arm64-v8a"
|
||||
else -> null!!
|
||||
}
|
||||
}
|
||||
|
||||
val needsUpdate: Boolean
|
||||
get() {
|
||||
val assetManager = context.assets
|
||||
val hashAssets = assetManager.open("termux/$arch/pkg_fprint.txt").readString()
|
||||
val hashFilesFile = File("${context.filesDir}/termux/pkg_fprint.txt")
|
||||
|
||||
if (!hashFilesFile.exists())
|
||||
return true
|
||||
|
||||
val hashFiles = FileInputStream(hashFilesFile).readString()
|
||||
|
||||
return hashAssets != hashFiles
|
||||
}
|
||||
|
||||
private fun applyPerms(tarEntry: TarEntry, file: File) {
|
||||
// u 2 g 1 o 0
|
||||
// [rwx] [rwx] [rwx]
|
||||
|
||||
val mode = tarEntry.header.mode
|
||||
val permSet: MutableSet<PosixFilePermission> = mutableSetOf()
|
||||
|
||||
// Get owner permissions. On Android API < 26 there's no easy way to set the others
|
||||
val stepInt = (mode shr (6)) and 0xFFF8
|
||||
|
||||
// Iterate over permission bits
|
||||
for (bit in listOf(1, 2, 4)) {
|
||||
val bool = (stepInt and bit) > 0
|
||||
when (bit) {
|
||||
1 -> file.setExecutable(bool, true)
|
||||
2 -> file.setWritable(bool, true)
|
||||
4 -> file.setReadable(bool, true)
|
||||
else -> null!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun doUpdate() {
|
||||
val oldTarDir = File("${context.filesDir}/termux")
|
||||
if (oldTarDir.exists())
|
||||
FileUtils.deleteDirectory(oldTarDir)
|
||||
|
||||
val destDir = context.filesDir!!
|
||||
|
||||
val assetManager = context.assets
|
||||
val termuxTar = TarInputStream(assetManager.open("termux/$arch/packages.tar").buffered())
|
||||
var tarEntry = termuxTar.nextEntry
|
||||
|
||||
termuxTar.use { tis ->
|
||||
while (tarEntry != null) {
|
||||
val data = ByteArray(2048)
|
||||
val destFile = File("$destDir/${tarEntry.name}")
|
||||
val fos = FileOutputStream(destFile)
|
||||
val dest = BufferedOutputStream(fos)
|
||||
var count = tis.read(data)
|
||||
|
||||
while (count != -1) {
|
||||
dest.write(data, 0, count)
|
||||
count = tis.read(data)
|
||||
}
|
||||
|
||||
dest.close()
|
||||
applyPerms(tarEntry, destFile)
|
||||
|
||||
tarEntry = tis.nextEntry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getFile(path: String) = File("${context.filesDir}/termux/$path")
|
||||
|
||||
fun which(cmd: String): File? {
|
||||
for (p in path) {
|
||||
val file = getFile("$p/$cmd")
|
||||
|
||||
if (file.exists() && file.isFile && file.canExecute())
|
||||
return file
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue