Add Termux package build system wrapper to build GNU Parted

This commit is contained in:
Davide Depau 2018-08-23 18:52:30 +02:00
parent f63ff76a1a
commit abc6fe3db2
Signed by: depau
GPG Key ID: C7D999B6A55EFE86
13 changed files with 281 additions and 3 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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'

View File

@ -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()

View File

@ -1,2 +1,2 @@
include ':app', ':libaums', ':dmg2img'
include ':app', ':libaums', ':dmg2img', ':termux-packages'
project(':libaums').projectDir = new File('libaums/libaums')

View 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)

View 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"
}

View File

@ -0,0 +1 @@
int main() {}

@ -0,0 +1 @@
Subproject commit e45ad0d7e998fc707dbf4e0f578482b32218e418

View 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})

View 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

View 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

View File

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.depau.termux_wrapper" >
</manifest>

View File

@ -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
}
}