<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lunar</title>
    <description>The latest articles on DEV Community by Lunar (@retrolunar).</description>
    <link>https://dev.to/retrolunar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4023479%2F1e501583-9413-4a05-90c7-55cf44758214.png</url>
      <title>DEV Community: Lunar</title>
      <link>https://dev.to/retrolunar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/retrolunar"/>
    <language>en</language>
    <item>
      <title>Using mise to install dependencies in Android development</title>
      <dc:creator>Lunar</dc:creator>
      <pubDate>Fri, 10 Jul 2026 05:01:34 +0000</pubDate>
      <link>https://dev.to/retrolunar/using-mise-to-install-dependencies-in-android-development-gjc</link>
      <guid>https://dev.to/retrolunar/using-mise-to-install-dependencies-in-android-development-gjc</guid>
      <description>&lt;p&gt;There is a large and complex Gradle build system and the Android Gradle Plugin (AGP) to install most of the Android SDK components required for your application. But what if you don't want to manually install Android Studio, Android SDK, CMake, scrcpy, and other necessary tools? This is where mise &lt;a href="https://mise.jdx.dev/" rel="noopener noreferrer"&gt;https://mise.jdx.dev/&lt;/a&gt; comes in—despite its apparent simplicity, it can do everything we need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing mise itself
&lt;/h2&gt;

&lt;p&gt;By default, the documentation suggests the following installation method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl https://mise.run | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those who do not like this installation method, alternative options are available: &lt;a href="https://mise.jdx.dev/installing-mise.html" rel="noopener noreferrer"&gt;https://mise.jdx.dev/installing-mise.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will also need to activate mise in your shell, which allows mise to function similarly to direnv. I have not tested the instructions in this article without this one-time activation.&lt;/p&gt;

&lt;p&gt;For bash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo 'eval "$(mise activate bash)"' &amp;gt;&amp;gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For fish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo 'mise activate fish | source' &amp;gt;&amp;gt; ~/.config/fish/config.fish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For zsh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo 'eval "$(mise activate zsh)"' &amp;gt;&amp;gt; "${ZDOTDIR-$HOME}/.zshrc"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And don't forget to restart your terminal for these settings to take effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Capabilities
&lt;/h2&gt;

&lt;p&gt;If desired, mise allows you to install software globally; the list of available packages can be checked with the &lt;code&gt;mise registry&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mise use -g bun deno go java gradle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let's not dwell on the basics. How can we use mise to simply download my project—let's say &lt;a href="https://github.com/lunardoesdev/raytris" rel="noopener noreferrer"&gt;https://github.com/lunardoesdev/raytris&lt;/a&gt;—and build it for Android, without having anything on our system other than mise itself? Let's clone the project (if you don't have git, you can just download the archive from GitHub's website):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;satori@fedora ~ [1]&amp;gt; git clone --depth=1 'https://github.com/lunardoesdev/raytris'
Cloning into 'raytris'...
remote: Enumerating objects: 33, done.
remote: Counting objects: 100% (33/33), done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 33 (delta 0), reused 27 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (33/33), 1.39 MiB | 1.02 MiB/s, done.
satori@fedora ~&amp;gt; cd raytris/
mise ERROR error parsing config file: ~/raytris/mise.toml
mise ERROR Config files in ~/raytris/mise.toml are not trusted.
Trust them with `mise trust`. See https://mise.en.dev/cli/trust.html for more information.
mise ERROR Version: 2026.7.2 linux-x64 (2026-07-07)
mise ERROR Run with --verbose or MISE_VERBOSE=1 for more information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mise warns that it will not automatically install dependencies and add them to your PATH when entering the directory without your permission, which you grant using the &lt;code&gt;mise trust&lt;/code&gt; command. After running this command, you can immediately run the &lt;code&gt;mise apk&lt;/code&gt; task defined in my &lt;code&gt;mise.toml&lt;/code&gt; and build the APK! Yes, it's that simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakdown of the Reproducible Environment
&lt;/h2&gt;

&lt;p&gt;Let's look at the &lt;code&gt;mise.toml&lt;/code&gt; itself (below, I will show snippets from this file and explain what they do):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[tools]
android-sdk = "latest"
"github:Genymobile/scrcpy" = "4.0"
"github:cesarferreira/byedroid" = "0.9.0"
gradle = "9.6.1"
java = "26.0.1"
zig = "0.15.1"

[env]
_.path = {tools = true, path = [
 "${ANDROID_HOME}/platform-tools",
 "${ANDROID_HOME}/build-tools/36.0.0",
 ]}
CPM_SOURCE_CACHE = "${HOME}/.cache/cpm-source-cache"

[settings]
env_shell_expand = true

[tasks.accept-android-licenses]
sources = ['settings.gradle.kts']
run = """
  yes | sdkmanager --licenses
  yes | sdkmanager "cmake;4.1.2"
  yes | sdkmanager "platform-tools"
"""

[tasks.debug-apk]
depends = ["accept-android-licenses"]
sources = [
  'build.gradle.kts',
  'gradle.properties',
  'src/**',
  'settings.gradle.kts',
  'android-sdk-packages.txt',
  'CMakeLists.txt'
]
run = "gradle assembleDebug"
alias = "apk"

[tasks.debug-native]
sources = [
  'src/**/*',
  '*.txt'
]
run = """
  mkdir -p build/debug
  cd build/debug
  cmake ../..
  make
"""

[tasks.debug]
depends = ['debug-native']
run = '''
  ./build/debug/raytris
'''
alias = 'debug'

[tasks.build-windows]
sources = [
  'src/**',
  '*.txt'
]
run = '''
  mkdir -p build/windows
  cd build/windows
  cmake -DCMAKE_TOOLCHAIN_FILE=cmake/zig-toolchain.cmake \
   -DZIG_TARGET=x86_64-windows \
   ../..
  make
'''
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go in order. The &lt;code&gt;[tools]&lt;/code&gt; section describes the packages that mise will install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[tools]
android-sdk = "latest"
"github:Genymobile/scrcpy" = "4.0"
"github:cesarferreira/byedroid" = "0.9.0"
gradle = "9.6.1"
java = "26.0.1"
zig = "0.15.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you can install not only packages defined in the &lt;code&gt;mise registry&lt;/code&gt;, but also download them directly from GitHub releases. For example, you can globally install a decent build system like xmake like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mise use -g github:xmake-io/xmake[rename_exe=xmake]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read about &lt;code&gt;rename_exe&lt;/code&gt; and other options and their values on the mise website, for example, for their GitHub "backend": &lt;a href="https://mise.jdx.dev/dev-tools/backends/github.html#rename-exe" rel="noopener noreferrer"&gt;https://mise.jdx.dev/dev-tools/backends/github.html#rename-exe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next is &lt;code&gt;[env]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[env]
_.path = {tools = true, path = [
 "${ANDROID_HOME}/platform-tools",
 "${ANDROID_HOME}/build-tools/36.0.0",
 ]}
CPM_SOURCE_CACHE = "${HOME}/.cache/cpm-source-cache"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;_.path&lt;/code&gt; is a special way to override the &lt;code&gt;PATH&lt;/code&gt;. &lt;code&gt;tools = true&lt;/code&gt; means we first install the tools from the &lt;code&gt;[tools]&lt;/code&gt; section and then override this variable. &lt;code&gt;$ANDROID_HOME&lt;/code&gt; is defined by the &lt;code&gt;android-sdk&lt;/code&gt; package; you don't need to do this manually.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CPM_SOURCE_CACHE&lt;/code&gt; is a variable for CMake CPM, a package manager for the CMake build system that I use to install raylib in my project. It prevents downloading the sources over and over again if you delete the build directory or build in different locations for different platforms, as I do.&lt;/p&gt;

&lt;p&gt;Moving on. The &lt;code&gt;[settings]&lt;/code&gt; section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[settings]
env_shell_expand = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;env_shell_expand&lt;/code&gt; allows you to do things like this in &lt;code&gt;[env]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[env]
FOO = "hello"
BAR = "$FOO-world"        # "hello-world"
BAZ = "${FOO}_suffix"     # "hello_suffix"
QUX = "${UNDEF:-fallback}" # "fallback"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, our environment variables are expanded to their values... which is exactly how it should be, in my opinion.&lt;/p&gt;

&lt;p&gt;Next is the &lt;code&gt;[tasks]&lt;/code&gt; section, where we define tasks, their file dependencies, and task dependencies. mise is a powerful task runner with many options for tasks. If you're interested, check out the available options in its documentation: &lt;a href="https://mise.jdx.dev/tasks/" rel="noopener noreferrer"&gt;https://mise.jdx.dev/tasks/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[tasks.accept-android-licenses]
sources = ['settings.gradle.kts']
run = """
  yes | sdkmanager --licenses
  yes | sdkmanager "cmake;4.1.2"
  yes | sdkmanager "platform-tools"
"""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, in the &lt;code&gt;accept-android-licenses&lt;/code&gt; task, we accept SDK component licenses and install the components we need, which Gradle does not always install reliably. In this example, notice that I use a specific version of CMake, which is also specified in my Gradle files. This ensures that exact version is used, as I had issues with CPM or raylib when building with an older version of CMake (which is installed if you simply choose "cmake" instead of "cmake;4.1.2"). It took some trial and error, but in the end, the system installs the required CMake version, and Gradle picks it up even if other CMake versions are installed. I added that this task depends on the &lt;code&gt;settings.gradle.kts&lt;/code&gt; file so that it doesn't re-run on every build.&lt;/p&gt;

&lt;p&gt;And here is the task responsible for the &lt;code&gt;mise apk&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[tasks.debug-apk]
depends = ["accept-android-licenses"]
sources = [
  'build.gradle.kts',
  'gradle.properties',
  'src/**',
  'settings.gradle.kts',
  'android-sdk-packages.txt',
  'CMakeLists.txt'
]
run = "gradle assembleDebug"
alias = "apk"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It depends on the previous task and builds the APK using Gradle. I am not entirely sure about &lt;code&gt;src/**&lt;/code&gt;—the correct glob syntax might be &lt;code&gt;src/**/*&lt;/code&gt;—but overall, the build works for me.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;alias = "apk"&lt;/code&gt; allows us to run our &lt;code&gt;debug-apk&lt;/code&gt; task simply as &lt;code&gt;mise apk&lt;/code&gt;. Note that you should not create aliases named "run" or "watch", as they conflict with mise's own subcommands.&lt;/p&gt;

&lt;p&gt;Next, tasks for native builds, running the native game, and building for Windows are defined in a similar manner. There are no new documentation elements here, but you can appreciate the elegance of this solution, which builds a single codebase for different operating systems.&lt;/p&gt;

&lt;p&gt;mise is a great tool; I really enjoyed working with it. Best regards.&lt;/p&gt;

</description>
      <category>mise</category>
      <category>android</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
