Gradle Project Reference
- Skip App Projects
- Building Locally
- Skip Framework Transpilation
- Building an app project APK
- Building a framework project AAR
- Gradle Dependencies
Gradle is the build system for Kotlin, and is the equivalent of SwiftPM for Swift development. When Skip transpiles your project, it converts your Swift code into Kotlin, and it also converts your Package.swift
file into a build.gradle.kts
file in the transpiler pluginβs output directory. This conversion happens transitively on all your projectβs Skip-enabled dependencies, including the core SkipStack
modules. This results in a local inter-connected network of Gradle projects containing the entirety of your projectβs source dependency tree.
The following sections detail Skipβs use of Gradle, including how to build with Gradle from the command line.
Skip App Projects
Consider a minimal Swift app project created by the commands:
skip init
command output
% brew install skiptools/skip/skip
% skip init --show-tree --no-build --no-test --no-module-tests --free --icon-color '' --appid=skip.hello.App --version 1.0.0 hello-skip HelloSkip
.
ββ Android
β ββ app
β β ββ build.gradle.kts
β β ββ proguard-rules.pro
β β ββ src
β β ββ main
β β ββ AndroidManifest.xml
β β ββ kotlin
β β ββ hello
β β ββ skip
β β ββ Main.kt
β ββ gradle
β β ββ wrapper
β β ββ gradle-wrapper.properties
β ββ gradle.properties
β ββ settings.gradle.kts
ββ Darwin
β ββ Assets.xcassets
β β ββ AccentColor.colorset
β β β ββ Contents.json
β β ββ AppIcon.appiconset
β β β ββ Contents.json
β β ββ Contents.json
β ββ Entitlements.plist
β ββ HelloSkip.xcconfig
β ββ HelloSkip.xcodeproj
β β ββ project.pbxproj
β ββ Sources
β ββ HelloSkipAppMain.swift
ββ LICENSE.LGPL
ββ Package.swift
ββ README.md
ββ Skip.env
ββ Sources
ββ HelloSkip
ββ ContentView.swift
ββ HelloSkip.swift
ββ HelloSkipApp.swift
ββ Resources
β ββ Localizable.xcstrings
ββ Skip
ββ skip.yml
Running swift build
in the hello-skip
folder builds the module and performs the transpilation.
This derived project hierarchy will look like:
hello-skip
swift build output
hello-skip % tree .build/plugins/outputs/hello-skip/HelloSkip/skipstone/
.build/plugins/outputs/hello-skip/HelloSkip/skipstone/
βββ HelloSkip
βΒ Β βββ build.gradle.kts
βΒ Β βββ proguard-rules.pro
βΒ Β βββ src
βΒ Β βββ main
βΒ Β βββ kotlin
βΒ Β βΒ Β βββ hello
βΒ Β βΒ Β βββ skip
βΒ Β βΒ Β βββ ContentView.kt
βΒ Β βΒ Β βββ HelloSkip.kt
βΒ Β βΒ Β βββ HelloSkipApp.kt
βΒ Β βββ resources
βΒ Β βββ hello
βΒ Β βββ skip
βΒ Β βββ Resources
βΒ Β βββ Localizable.xcstrings -> /private/tmp/hello-skip/Sources/HelloSkip/Resources/Localizable.xcstrings
βΒ Β βββ resources.lst
βββ HelloSkip.skipcode.json
βββ SkipFoundation -> ../../../skip-foundation/SkipFoundation/skipstone/SkipFoundation
βββ SkipLib -> ../../../skip-lib/SkipLib/skipstone/SkipLib
βββ SkipModel -> ../../../skip-model/SkipModel/skipstone/SkipModel
βββ SkipUI -> ../../../skip-ui/SkipUI/skipstone/SkipUI
βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βββ gradle
βΒ Β βββ wrapper
βΒ Β βββ gradle-wrapper.properties
βββ gradle.properties
βββ settings.gradle.kts
The resulting Gradle project hierarchy contains not only the links to the transpiled output for the current project, but also links to the project output for each dependent module. These dependencies are automatically created as a result of the Skip transpiler plugin being run on the dependent projects.
Building Locally
Gradle projects can be run manually, either from Android Studio or using the gradle
command-line tool. Skip app projects created with skip init
have a root Android/
folder that contains a settings.gradle.kts
file. This can be opened in Android Studio, or it can be run directly from the command line.
The Android build folder is configured by settings.gradle.kts
to output to the root .build/Android/
folder. This centralizes the location of the build artifacts and enables a single folder to be ignored in a .gitignore
file (rather than the default Gradle folder name of build/
).
skip init command output
$ skip init --appid=com.xyz.HelloSkip hello-skip HelloSkip
Initializing Skip library hello-skip
[β] Create project hello-skip (0.73s)
[β] Resolve dependencies (5.89s)
[β] Build hello-skip (15.2s)
[β] Created module HelloSkip in ~/Desktop/hello-skip/HelloSkip.xcodeproj
$ cd hello-skip
$ swift build --build-tests
Fetched https://source.skip.tools/skip.git (0.92s)
β¦
[294/294] Linking libHelloSkip.dylib
Build complete! (23.13s)
$ skip gradle -p .build/plugins/outputs/hello-skip/HelloSkip/skipstone/HelloSkip test
GRADLE> > Task :HelloSkip:preBuild UP-TO-DATE
β¦
GRADLE> > Task :HelloSkip:testDebugUnitTest
GRADLE> > Task :HelloSkip:test
GRADLE>
GRADLE> BUILD SUCCESSFUL in 20s
GRADLE> 204 actionable tasks: 204 executed
note: Gradle SUCCESSFUL
$ skip gradle -p Android/ assemble
GRADLE> > Task :app:preBuild UP-TO-DATE
GRADLE> > Task :app:preDebugBuild UP-TO-DATE
GRADLE> > Task :app:mergeDebugNativeDebugMetadata NO-SOURCE
GRADLE> > Task :app:generateDebugBuildConfig
GRADLE> > Task :HelloSkip:preBuild UP-TO-DATE
β¦
GRADLE> > Task :SkipUI:bundleReleaseAar
GRADLE> > Task :HelloSkip:compileDebugJavaWithJavac NO-SOURCE
β¦
GRADLE> > Task :app:processReleaseJavaRes
GRADLE> > Task :HelloSkip:extractDebugAnnotations
GRADLE> > Task :HelloSkip:mergeDebugGeneratedProguardFiles
GRADLE> > Task :HelloSkip:mergeDebugConsumerProguardFiles
GRADLE> > Task :SkipUI:assembleRelease
GRADLE> > Task :SkipUI:assemble
GRADLE> > Task :HelloSkip:mergeDebugJavaResource
GRADLE> > Task :app:compileDebugKotlin
GRADLE> > Task :HelloSkip:syncDebugLibJars
GRADLE> > Task :app:compileDebugJavaWithJavac
GRADLE> > Task :app:mergeReleaseJavaResource
GRADLE> > Task :app:dexBuilderDebug
GRADLE> > Task :app:processDebugJavaRes
GRADLE> > Task :app:mergeDebugGlobalSynthetics
GRADLE> > Task :app:mergeProjectDexDebug
GRADLE> > Task :app:mergeLibDexDebug
GRADLE> > Task :HelloSkip:bundleDebugAar
GRADLE> > Task :HelloSkip:assembleDebug
GRADLE> > Task :HelloSkip:assemble
GRADLE> > Task :app:mergeDebugJavaResource
GRADLE> > Task :app:minifyReleaseWithR8
GRADLE> > Task :app:shrinkReleaseRes
GRADLE> > Task :app:packageRelease
GRADLE> > Task :app:createReleaseApkListingFileRedirect
GRADLE> > Task :app:assembleRelease
GRADLE> > Task :app:assemble
GRADLE>
GRADLE> BUILD SUCCESSFUL in 53s
GRADLE> 403 actionable tasks: 403 executed
The .apk
from the build will be placed in the .build/Android/app/outputs/apk/
folder:
$ ls -lah .build/Android/app/outputs/apk/*/*.apk
57M .build/Android/app/outputs/apk/debug/app-debug.apk
13M .build/Android/app/outputs/apk/release/app-release-unsigned.apk
Skip Framework Transpilation
A valid Skip project must contain a Skip/skip.yml
file in each Skip-enabled module. This file is a YAML document that describes the moduleβs representation in the Kotlin/Gradle world. During transpilation, this file is combined with all the dependency projectβs skip.yml
files and used to affect how the Gradle project is created. Use skip.yml
to customize the Gradle build process, or to add dependencies on external Java or Kotlin libraries that you can then use directly from Skip code.
Gradle projects use the files settings.gradle.kts
and build.gradle.kts
for configuration, much like a Swift Package Manager project uses Package.swift
. These are kotlin-script files that can configure all aspects of the build process, from compilation arguments to output post-processing. More can be read on the topic at https://docs.gradle.org/current/userguide/writing_build_scripts.html.
Skip abstracts away the details of the Gradle project configuration for Framework projects by automatically deriving a valid Gradle project from the SwiftPM Package.swift
dependencies combined with the contents of each projectβs Skip/skip.yml
file. The Skip transpiler outputs a Gradle project folder hierarchy as part of its output process.
Framework Build Outputs
Framework projects differ from app projects in that while app projects surface the various Gradle app-level build files (Android/settings.gradle.kts
and Android/app/build.gradle.kts
), framework projects generate and maintain the build structures for the transpiled projects. Skip considers the generated Gradle project, along with the transpiled Kotlin code, to be ephemeral. Cleaning the build may delete the files, and re-running the transpiler will override any changes. Unless you (manually) export or archive the Gradle project, it may be overwritten at any time.
When building from the command-line using swift build
or skip test
, the gradle projects will be output to the .build/plugins/outputs/
folder, each in its own package-named directory. When building from Xcode, the outputs are instead placed in ~/Library/Developer/Xcode/DerivedData/ProjectName-identifier/SourcePackages/plugins/
.
The Skip plugin is run in a restrictive sandbox that limits the output folders that the transpiler can write to. For this reason, each separate dependency is output to its own separate folder, and each depending project references it by making a symbol link to the local output for that project. For example, the HelloSkip
appβs local dependencies on the SkipStack
frameworks can be seen:
Skip build output file layout
$ tree -L 5 .build/plugins/outputs
.build/plugins/outputs
βββ hello-skip
βΒ Β βββ HelloSkip
βΒ Β βββ skipstone
βΒ Β βββ HelloSkip
βΒ Β βΒ Β βββ build.gradle.kts
βΒ Β βΒ Β βββ proguard-rules.pro
βΒ Β βΒ Β βββ src
βΒ Β βββ HelloSkip.skipcode.json
βΒ Β βββ SkipFoundation -> ../../../skip-foundation/SkipFoundation/skipstone/SkipFoundation
βΒ Β βββ SkipLib -> ../../../skip-lib/SkipLib/skipstone/SkipLib
βΒ Β βββ SkipModel -> ../../../skip-model/SkipModel/skipstone/SkipModel
βΒ Β βββ SkipUI -> ../../../skip-ui/SkipUI/skipstone/SkipUI
βΒ Β βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βΒ Β βββ gradle
βΒ Β βΒ Β βββ wrapper
βΒ Β βββ gradle.properties
βΒ Β βββ settings.gradle.kts
βββ skip-foundation
βΒ Β βββ SkipFoundation
βΒ Β βββ skipstone
βΒ Β βββ SkipFoundation
βΒ Β βΒ Β βββ build.gradle.kts
βΒ Β βΒ Β βββ proguard-rules.pro
βΒ Β βΒ Β βββ src
βΒ Β βββ SkipFoundation.skipcode.json
βΒ Β βββ SkipLib -> ../../../skip-lib/SkipLib/skipstone/SkipLib
βΒ Β βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βΒ Β βββ gradle
βΒ Β βΒ Β βββ wrapper
βΒ Β βββ gradle.properties
βΒ Β βββ settings.gradle.kts
βββ skip-lib
βΒ Β βββ SkipLib
βΒ Β βββ skipstone
βΒ Β βββ SkipLib
βΒ Β βΒ Β βββ build.gradle.kts
βΒ Β βΒ Β βββ proguard-rules.pro
βΒ Β βΒ Β βββ src
βΒ Β βββ SkipLib.skipcode.json
βΒ Β βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βΒ Β βββ gradle
βΒ Β βΒ Β βββ wrapper
βΒ Β βββ gradle.properties
βΒ Β βββ settings.gradle.kts
βββ skip-model
βΒ Β βββ SkipModel
βΒ Β βββ skipstone
βΒ Β βββ SkipLib -> ../../../skip-lib/SkipLib/skipstone/SkipLib
βΒ Β βββ SkipModel
βΒ Β βΒ Β βββ build.gradle.kts
βΒ Β βΒ Β βββ proguard-rules.pro
βΒ Β βΒ Β βββ src
βΒ Β βββ SkipModel.skipcode.json
βΒ Β βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βΒ Β βββ gradle
βΒ Β βΒ Β βββ wrapper
βΒ Β βββ gradle.properties
βΒ Β βββ settings.gradle.kts
βββ skip-ui
βΒ Β βββ SkipUI
βΒ Β βββ skipstone
βΒ Β βββ SkipFoundation -> ../../../skip-foundation/SkipFoundation/skipstone/SkipFoundation
βΒ Β βββ SkipLib -> ../../../skip-lib/SkipLib/skipstone/SkipLib
βΒ Β βββ SkipModel -> ../../../skip-model/SkipModel/skipstone/SkipModel
βΒ Β βββ SkipUI
βΒ Β βΒ Β βββ build.gradle.kts
βΒ Β βΒ Β βββ proguard-rules.pro
βΒ Β βΒ Β βββ src
βΒ Β βββ SkipUI.skipcode.json
βΒ Β βββ SkipUnit -> ../../../skip-unit/SkipUnit/skipstone/SkipUnit
βΒ Β βββ gradle
βΒ Β βΒ Β βββ wrapper
βΒ Β βββ gradle.properties
βΒ Β βββ settings.gradle.kts
βββ skip-unit
βββ SkipUnit
βββ skipstone
βββ SkipUnit
βΒ Β βββ build.gradle.kts
βΒ Β βββ proguard-rules.pro
βΒ Β βββ src
βββ SkipUnit.skipcode.json
βββ gradle
βΒ Β βββ wrapper
βββ gradle.properties
βββ settings.gradle.kts
Building an app project APK
Building a framework project AAR
For more information on the published output format Publishing a project as module and Android Gradle Plugin Upload your library.
Gradle Dependencies
Every Skip App project depends on the SkipStack frameworks, which contain the five core modules for any application, and whose skip.yml
files can serve as useful examples: SkipUI, SkipModel, SkipFoundation, SkipLib, and SkipUnit. Each of these projects are automatically transpiled in turn, resulting in a web of project links that constitute a buildable Gradle project. As these are dependencies that are locally checked out, their transpiled output can be referenced from Gradle through the relative symbolic links that are created as part of a moduleβs transpilation.
Read the Dependencies documentation to learn more about using skip.yml
to add Java/Kotlin dependencies.