Skip to content

Well formed SDK archives

Marco Vermeulen edited this page May 21, 2024 · 5 revisions

Unspoken standard

We make certain assumptions about the general shape of archives published on SDKMAN. This helps us reliably install the archives on your machine without needing custom workflows to do the work. We follow the principle of sensible defaults and expect the SDK archives to comply with some basic rules. These basic rules were popularised with the distribution of the earliest JDKs, and have become the unspoken standard for all SDK archives. These standards have never been formalised, yet all the build tools package their distributable archives in this fashion.

So what are these rules? Let's take a closer look at the makeup of a "standard" distribution archive.

The rules

  • The zip archive contains a base directory, usually with the naming convention of ${candidate}-${version}. So, in the case of Kotlin 1.8.0, we would expect this to be kotlin-1.8.0.
  • Beneath this base directory, we expect to see the entire distribution consisting of all the regular directories you would usually see in a UNIX filesystem. This could include lib, etc, usr, and most importantly, a bin folder. Of all these directories, the bin folder is the only mandatory one.
  • The bin folder contains all executable scripts and binaries that will be added to the end user's path. In the case of a UNIX distributable, the scripts and executables need to have the appropriate executable privileges. It is not uncommon to have Windows .bat files here for universal binaries, as they will be ignored on UNIX systems. Likewise, the UNIX scripts will be ignored on Windows systems.
  • This entire folder structure is archived as a .zip or tarball .tar.gz binary.
  • the archive will usually have the naming convention of ${candidate}-${version}.${extension}, so in the case of Kotlin 1.8.0, it would be something like kotlin-1.8.0.zip.

Pictures, please

So to summarise the above rules in a clear representation, once again using Kotlin as an example:

kotlin-1.8.0/               <-- base folder named ${candidate}-${version}
    bin/                    <-- mandatory directory
        kapt                <-- UNIX script with executable privileges
        kapt.bat            <-- Windows bat file without executable privileges
        kotlin
        kotlin.bat
        kotlinc
        kotlinc.bat
        kotlinc-js
        kotlinc-js.bat
        kotlinc-jvm
        kotlinc-jvm.bat
        kotlin-dce-js
        kotlin-dce-js.bat
    build.txt
    lib/                    <-- jar content omitted for brevity
    license                 <-- can contain some info text files

This would then be zipped up and presented as kotlin-1.8.0.zip

Distribution types

Most SDKs are packaged as Universal binaries. An example of this is the Kotlin distribution above. It contains executables for all platforms and will not contain native binaries compiled for specific architects. The executables are usually Bash or Windows batch scripts that invoke some Java process. In this case, a single binary will be published to SDKMAN for a particular candidate version.

With the growing popularity of GraalVM, many vendors are choosing to package Platform Specific binaries for all target architectures. This could include binaries for Linux intel/arm64, macOS intel/arm64 and Windows. These custom-compiled binaries usually perform far better and don't have the cold-start time that a normal Java process has. This is often preferred for CLI tools that are invoked many times and need to be fast responding. To this end, we allow Vendors to publish multi-platform binaries, one binary per target platform or architecture. In cases like this, the zip archive's name will also reflect its target architecture, for example, java-17.0.15-linux-aarch64.tar.gz.

We support the following platform identifiers:

Identifier Platform architecture
UNIVERSAL all platforms
LINUX_64 Linux X64
LINUX_ARM64 Linux ARM 64bit
LINUX_ARM32SF Linux ARM 32bit Soft Float
LINUX_ARM32HF Linux ARM 32bit Hard Float
WINDOWS_64 Windows 64bit
MAC_OSX macOS 64bit (Intel)
MAC_ARM64 macOS ARM 64bit (M1)

The UNIVERSAL versions are mutually exclusive from platform-specific versions. If you decide to publish your version for targeted platforms, you cannot publish a UNIVERSAL binary for that same version.