-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Termux Libraries
- Importing Libraries
- Remove Extra Dependency Files
- Target SDK 30 Package Visibility
- Forking and Local Development
The termux-app
repository publishes 3
libraries that are used by Termux plugin apps and can also be used by 3rd party apps as long as they agree to the terms of the relevant Licenses. The versions of termux-app
and all libraries are updated together.
Termux plugins and 3rd party apps only need to import termux-shared
library for interacting with the termux-app
, like for using TermuxConstants
and all other utilities provided by it.
However, if the app needs to use the terminal provided by termux-app
, then import terminal-view
library as well. The terminal-emulator
library will be automatically imported since its a dependency of terminal-view
. The termux-shared
library also depends on terminal-view
and terminal-emulator
libraries, but an explicit additional import of terminal-view
is necessary if using the terminal.
The libraries are being published on https://jitpack.io for termux-app
version >= 0.116
.
For importing the libraries in your project, you need to follow the following instructions.
- Add repository url for the libraries to
root
level ofbuild.gradle
file.
allprojects {
repositories {
...
//mavenLocal()
maven { url "https://jitpack.io" }
}
}
- Add
termux-shared
library dependency or other termux libraries toapp
module levelbuild.gradle
file.
dependencies {
implementation "com.termux:termux-shared:0.118.0"
}
- Add
empty-to-avoid-conflict-with-guava
library dependency toapp
module levelbuild.gradle
file to prevent errors likeDuplicate class com.google.common.util.concurrent.ListenableFuture found in modules
when building.
dependencies {
implementation "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
}
- Run
Sync Gradle with Project Files
in Android Studio inFile
drop down menu orSync Now
popup button that may appear at the top ofbuild.gradle
file.
-
The Termux libraries are published under both the
com.termux
andcom.github.termux
groupId
by JitPack since https://termux.com has aDNS TXT
record fromgit.termux.com
to https://github.com/termux as per JitPack custom domain requirements. You can confirm by runningdig txt git.termux.com
and should get something like following in the output. Usingcom.termux
is preferred.;; ANSWER SECTION: git.termux.com. 300 IN TXT "https://github.com/termux"
Both group ids have separate JitPack pages that can be used to trigger and view builds. They both also have separate build logs and artifacts and one may fail while the other may not. Additionally, there is an API page too, e.g like https://jitpack.io/api/resolve/com.termux/termux-app/master-SNAPSHOT.
-
com.termux
: https://jitpack.io/#com.termux/termux-app -
com.github.termux
: https://jitpack.io/#termux/termux-app
-
-
When the first time a library version is imported, like via
gradle
, then a build is automatically triggered on JitPack servers if build artifacts do not already exist for it, and it does not need to be manually triggered on the site. However, building the library artifacts on JitPack servers will take some time and you may get errors locally likeUnable to resolve dependency for ':app@debug/compileClasspath'
and localgradle
builds will expire eventually. You can check on the JitPack site to see if the required build has succeeded and it will take a few minutes for builds to be downloadable even afterbuild.log
shows them to have been succeeded, runSync Project with Gradle Files
again to try to re-download. -
The versions
=< 0.118.0
and older commits useminSdkVersion
24
. However, latest commits onmaster
branch after version0.118.0
useminSdkVersion
21
since support for Android5/6
was re-added. -
When
termux-app
publishes GitHub releases, a build on JitPack servers is automatically triggered via theTrigger Termux Library Builds on JitPack
workflow so that imports are instant for that release version when someone tries to import them for the first time. The version build triggered will be for without thev
prefix, like0.118.0
. A version with thev
prefix likev0.118.0
, triggers a separate build on JitPack.
Check https://github.com/jitpack/jitpack.io#building-with-jitpack for details, like including commit or branch level import.
implementation "com.termux.termux-app:termux-shared:0.118.0"
implementation "com.termux.termux-app:termux-shared:master-SNAPSHOT"
implementation "com.termux.termux-app:termux-shared:8e3a8980a8"
implementation "com.github.termux.termux-app:termux-shared:0.118.0"
implementation "com.termux.termux-app:terminal-view:0.118.0"
The builds logs at https://jitpack.io/#termux/termux-app will list the paths for the files generated at the end under Files:
section. You can append those paths to "https://jitpack.io/" to download a specific file.
- https://jitpack.io/com/github/termux/termux-app/termux-shared/v0.118.0/termux-shared-v0.118.0-sources.jar
- https://jitpack.io/com/github/termux/termux-app/termux-shared/v0.118.0/termux-shared-v0.118.0.aar
- https://jitpack.io/com/github/termux/termux-app/terminal-view/v0.118.0/terminal-view-v0.118.0-sources.jar
- https://jitpack.io/com/github/termux/termux-app/terminal-view/v0.118.0/terminal-view-v0.118.0.aar
The Termux libraries were published on GitHub Packages for versions 0.109-0.114
but has since been stopped. GitHub Package hosting is considered a private repository since it requires github API keys if a hosted library needs to be imported as a dependency. Importing from private repositories is not allowed as per F-Droid
policy so Termux plugin apps can't import Termux libraries as dependencies when building on F-Droid
, so we moved to JitPack publishing.
There are plans to continue publishing on GitHub Packages as well in future, but requires modifying build.gradle
maven-publish
tasks to publish both on GitHub and JitPack and also support local publishing. This should also allow comparisons of GitHub
and F-Droid
releases against each other for security reasons (software supply chain attacks), assuming any problems of reproducible builds are solved.
For importing the libraries in your project, you need to follow the following instructions.
-
Create a GitHub access
token
to download packages. You can create it from your GitHub account fromSettings
->Developer settings
->Personal access tokens
->Generate new token
. You must enable theread:packages
scope when creating the token. You can get more details at AndroidLibraryForGitHubPackagesDemo. -
Create
github.properties
file in projectroot
directory, and set your username and token. Also optionally add thegithub.properties
entry to.gitignore
file so that yourtoken
doesn't accidentally get added togit
, most of the Termux apps already have it ignored.
GH_USERNAME=<username>
GH_TOKEN=<token>
- Add to
app
module levelbuild.gradle
if you want to importtermux-shared
.
def githubProperties = new Properties()
githubProperties.load(new FileInputStream(rootProject.file("github.properties")))
dependencies {
implementation "com.termux:termux-shared:0.114"
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/termux/termux-app")
credentials {
username = githubProperties['GH_USERNAME'] ?: System.getenv("GH_USERNAME")
password = githubProperties['GH_TOKEN'] ?: System.getenv("GH_TOKEN")
}
}
}
If you don't plan on using the following specific classes in your app, then remove their JNI
lib dependency from APK
file during build time as well.
-
libtermux.so
:TerminalSession
/TermuxSession
-
liblocal-socket.so
:Local*Socket*
/AmSocketServer
android {
packagingOptions {
// Remove terminal-emulator and termux-shared JNI libs added via termux-shared dependency
exclude 'lib/*/libtermux.so'
exclude 'lib/*/liblocal-socket.so'
}
}
If your third-party app has set targetSdkVersion
to >=30
(android >= 11
), then it needs to add com.termux
package to the queries
element or request QUERY_ALL_PACKAGES
permission in its AndroidManifest.xml
. Otherwise it will get PackageSetting{...... com.termux/......} BLOCKED
errors in logcat
when interacting with termux-app
, like with RUN_COMMAND
intent and it will not work.
<manifest
<queries>
<package android:name="com.termux" />
</queries>
<application
....
</application>
</manifest>
Check package-visibility, QUERY_ALL_PACKAGES
googleplay policy and this article for more info.
If you are forking the termux-app
plugins, then you will need to import your own modified version of the termux-shared
library in which you updated the package name, etc in the TermuxConstants
class. By default, the build.gradle
file of plugin apps will import the libraries published for com.termux
package name and you can't use them in your forked plugins. You can either publish your modified termux-shared
library via local maven publishing to build your apps or publishing your libraries on JitPack or GitHub and import them instead, i.e with your groupId
com.github.<user>
.
If you are a maintainer/contributor of the termux-app
plugins and need to update the termux-shared
or the other libraries and want to test the updates locally before pushing them upstream, then you can use local maven publishing for that too.
For updating and publishing the libraries locally, you need to follow the following instructions.
-
Firstly
git clone
thetermux-app
repo. Make whatever changes you need to make totermux-shared
or other libraries. Then from theroot
directory oftermux-app
, run./gradlew publishReleasePublicationToMavenLocal
. This should build a release version of all the libraries and publish them locally. You can view the published files at~/.m2/repository/com/termux/
. The version with which they are published will be defined by theversionName
value in thebuild.gradle
file. -
In the
root
levelbuild.gradle
file of the plugin, uncomment themavenLocal()
line so that local version oftermux-shared
that was published in1
gets sourced. You should also keep themaven { url "https://jitpack.io" }
line uncommented in case other JitPack dependencies need to be sourced remotely, that are not available locally.
allprojects {
repositories {
...
mavenLocal()
//maven { url "https://jitpack.io" }
}
}
- In the
app
levelbuild.gradle
file of the plugin, comment out the originalcom.termux.termux-app:termux-shared:*
dependency line and replace it withcom.termux:termux-shared:*
. Note that thegroupId
used byJitPack
iscom.termux.termux-app
, but when publishing locally, itscom.termux
.
dependencies {
//implementation "com.termux.termux-app:termux-shared:0.118.0"
// Use if below libraries are published locally by termux-app with `./gradlew publishReleasePublicationToMavenLocal` and used with `mavenLocal()`.
// If updates are done, republish there and sync project with gradle files here
implementation "com.termux:termux-shared:0.118.0"
}
- Run
Sync Gradle with Project Files
in Android Studio inFile
drop down menu of the plugin app window to import the locally published library. You can check theBuild
tab at the bottom of Android Studio for any import errors.
Now every time you make changes in termux-app
libraries, run ./gradlew publishReleasePublicationToMavenLocal
to publish the changes and then in the plugin app, run Sync Gradle with Project Files
to import the changes.
-
When testing is complete, make appropriate commits in
termux-app
and push them totermux-app
upstream. If you are making a pull request, you will need to wait for changes to be merged withmaster
before you will be able to push the plugins to their upstream. Once changes have been committed tomaster
, find the commit hash from GitHub for your commit or the latest commit, then go to https://jitpack.io/#com.termux/termux-app and trigger a build for that commit under theCommits
tab withGet it
button and make sure it succeeds. You necessarily don't need to trigger build manually, importing it in plugin app in5
will automatically do it, but since it may timeout/fail the first time, best do it before pushing changes to upstream. Note that by default, JitPack uses first10
characters for versions based on commit hashes. -
In your plugin app, revert the changes made in
2
and3
but update the original dependency line with the commit hash from JitPack, like for example8e3a8980a8
. If instead of commit hash, a new versiontermux-app
was published, like0.118
, then use that instead of commit hash as version. Then make a commit likeChanged: Bump termux-shared to 8e3a8980a8
and push changes to plugin upstream.
dependencies {
implementation "com.termux.termux-app:termux-shared:8e3a8980a8"
// Use if below libraries are published locally by termux-app with `./gradlew publishReleasePublicationToMavenLocal` and used with `mavenLocal()`.
// If updates are done, republish there and sync project with gradle files here
//implementation "com.termux:termux-shared:0.118.0"
}
Note that making changes to library after dependencies have already been cached without incrementing version number may need deleting gradle
cache if syncing gradle files doesn't work after publishing changes. This shouldn't normally happen, but sometimes does. Open Gradle
right sidebar in Android Studio, then right click on top level entry, then select Refresh Gradle Dependencies
, which will redownload/refresh all dependencies and will take a lot of time. Instead you can run find ~/.gradle/caches/ -type d -name "*.termux*" -prune -exec rm -rf "{}" \; -print
to just remove termux
cached libraries, and then running gradle sync again.