Skip to content

Instantly share code, notes, and snippets.

@bkase
Last active February 24, 2020 02:00
Show Gist options
  • Save bkase/ee3e3019776fd68fa27b to your computer and use it in GitHub Desktop.
Save bkase/ee3e3019776fd68fa27b to your computer and use it in GitHub Desktop.
Kotlin Buck build files
android_binary(
name = 'app',
manifest = 'AndroidManifest.xml',
keystore = ':debug_keystore',
use_split_dex = True,
primary_dex_patterns = [
'^com/tryroll/roll/AppShell^',
'^com/tryroll/roll/debug/AppShell^',
'^com/tryroll/roll/BuildConfig^',
'^com/tryroll/roll/debug/BuildConfig^',
'^com/google/',
],
deps = [
'//app:app',
'//app:res',
'//kotlin-lib:runtime',
],
)
keystore(
name = 'debug_keystore',
store = 'debug.keystore',
properties = 'debug.keystore.properties',
)
# Use the kotlinLib helper to make kotlinLibs
#
# Forked from: https://github.com/zserge/buckbone
#
import urllib
#
# This is a very quick-n-dirty bucklet for maven packages (jar and aar)
#
def mavensha1(group, name, version, ar):
try:
link = 'http://repo1.maven.org/maven2/{0}/{1}/{2}/{1}-{2}.{3}.sha1'.format(group.replace('.', '/'), name, version, ar)
f = urllib.urlopen(link)
cksum = f.read()
# print 'cksum'
int(cksum, 16) # will throw an error if cksum is not a hexadecimal string
return cksum
except ValueError:
return None
def maven(pkg):
group, name, version = pkg.split(':', 3)
for ar in ['aar', 'jar']:
cksum = mavensha1(group, name, version, ar)
if cksum != None:
if ar == 'aar':
#print 'android_prebuild_aar(name = %s, arr = %s)' % (name, ':'+name+'-maven')
#print 'remote_file(name = %s, sha1 = %s, url = %s, out = %s)' % (name + '-maven', cksum, 'mvn:'+group+':'+name+':'+ar+':'+version, name+'.'+ar)
android_prebuilt_aar(
name = name,
visibility = [ 'PUBLIC' ],
aar = ':'+name+'-maven',
)
remote_file(
name = name + '-maven',
sha1 = cksum,
url = 'mvn:' + group + ':' + name + ':' + ar + ':' + version,
out = name + '.' + ar,
)
else:
#print 'remote_file(name = %s, sha1 = %s, url = %s, out = %s)' % (name, cksum, 'mvn:'+group+':'+name+':'+ar+':'+version, name+'.'+ar)
prebuilt_jar(
name = name,
visibility = [ 'PUBLIC' ],
binary_jar = ':'+name+'-maven',
)
remote_file(
name = name + '-maven',
sha1 = cksum,
url = 'mvn:' + group + ':' + name + ':' + ar + ':' + version,
out = name + '.' + ar,
)
return
print 'Not found ' + pkg
def required(d, name):
try:
return d[name]
except KeyError:
raise KeyError('%s is a Required Argument' % name)
def kotlinLib(**kwargs):
name = required(kwargs, 'name')
visibility = required(kwargs, 'visibility')
srcs = required(kwargs, 'srcs')
android_library(
name = name,
visibility = visibility,
srcs = [':kotlin-src-' + name],
compiler = 'kotlincw',
deps = kwargs.get('deps', []),
exported_deps = kwargs.get('exported_deps', []),
)
genrule(
name = 'kotlin-src-' + name,
srcs = srcs,
out = 'kotlin-' + name + '.src.zip',
cmd = 'echo "$SRCS" | awk -F" " \'{ for(i = 0; ++i <= NF;) print $i }\' | xargs -I{} cp {} {}.java && echo "$SRCS" | awk -F" " \'{ for(i = 0; ++i <= NF;) print $i }\' | xargs -I{} echo {}.java | zip -@ "$OUT"',
)
#!/bin/bash
# Run this to build and install the app
JAVA_OPTS="-Xmx8192M -Xms256M -noverify" buck install --run app
find . -name "*.kt.java" | xargs rm
# Assuming KOTLINPATH is in env
import os
prebuilt_jar(
name = 'runtime',
binary_jar = ':kotlin-runtime-jar',
visibility = ['PUBLIC'],
)
genrule(
name = 'kotlin-runtime-jar',
out = 'kotlin-runtime.jar',
cmd = 'ln -s ' + os.environ["KOTLINPATH"] + '/dist/kotlinc/lib/kotlin-runtime.jar $OUT',
)
#!/usr/bin/python
#
# NOTE:
# * Expects KOTLINPATH env variable defined
#
# Put this file in the top level of your app directory, and symlink to it from ALL buck modules that build with kotlin
#
# Forked from: https://github.com/kar/buckexp/blob/master/kotlin/gs.kar.buckexp/kotlincw
#
# A simple wrapper around kotlinc and javac required to make buck compile Kotlin code with Android
# dependencies (like R.java).
#
# Buck will invoke the compiler (this file) multiple times during the build process. This wrapper
# accounts for it and does the following:
#
# - If R.java is detected in sources, everything is simply passed to 'javac'.
# - For any other invocation, 'kotlinc' is invoked with adapted argument list:
# - Remove -source, -target, -sourcepath, -g
# - -bootclasspath is merged with -classpath
# - @argfiles are read, transformed into file list, and provided directly in the argument list
#
# Because of the fact that buck's 'src' property for 'java_library' and derived rules accepts only
# .java files, we rename all '.kt' files so they will be passed to the compiler. Here we rename them
# back before providing to kotlinc.
#
# Note that all of this was derived empirically, and might not work in general sense.
import sys
import os
from subprocess import call
# Expand @argfile into a list of filepaths to compile.
def processArgfile(item):
sources = []
with open(item[1:]) as f:
for x in f.readlines():
x = x.strip('\n')
x = renameExtension(x)
sources.append(x)
return sources
# Rename each .java file back to .kt (both in the filesystem and in the string).
def renameExtension(filename):
call(["rename", "s/.kt.java/.kt/", filename])
return filename.replace(".kt.java", ".kt")
# Compiling R.java has to be done by javac
if any("R.java" in s for s in sys.argv):
exit(call(["javac"] + sys.argv[1:]))
else:
params = []
sources = [] # Expanded source filenames from @argfile
cp = [] # Merged classpath arguments
cpNext = False # If next item will be classpath to merge
skipNext = False
for item in sys.argv[1:]:
if item == "-source" or item == "-target":
skipNext = True
continue
elif item == "-sourcepath" or item == "-g":
continue
elif item == "-bootclasspath" or item == "-classpath":
cpNext = True
elif cpNext:
cp.append(item)
cpNext = False
continue
elif skipNext:
skipNext = False
continue
elif item.startswith("@"):
sources = processArgfile(item)
elif not item:
continue
else:
params.append(item)
# Make one classpath separated by colon
cpAll = []
for i in cp:
cpAll += i.split(':')
if cpAll:
params.append("-classpath")
params.append(':'.join(cpAll))
params += sources
print str(params)
exit(call([os.environ["KOTLINPATH"] + "/dist/kotlinc/bin/kotlinc"] + params))
# example libs module
# rules for maven libs
maven('com.jakewharton.timber:timber:2.7.1')
maven('com.google.code.gson:gson:2.3.1')
# rules for local libs
# play services
android_prebuilt_aar(
name = 'play-services-base',
visibility = [ 'PUBLIC' ],
aar = 'play-services-base-7.5.0.aar'
)
android_prebuilt_aar(
name = 'play-services-gcm',
visibility = [ 'PUBLIC' ],
aar = 'play-services-gcm-7.5.0.aar'
)
android_prebuilt_aar(
name = 'play-services-analytics',
visibility = [ 'PUBLIC' ],
aar = 'play-services-analytics-7.5.0.aar'
)
# google
android_prebuilt_aar(
name = 'multidex',
visibility = [ 'PUBLIC' ],
aar = 'multidex-1.0.0.aar'
)
android_prebuilt_aar(
name = 'support-v4',
visibility = [ 'PUBLIC' ],
aar = 'support-v4-22.1.1.aar'
)
android_prebuilt_aar(
name = 'appcompat-v7',
visibility = [ 'PUBLIC' ],
aar = 'appcompat-v7-22.1.1.aar'
)
android_prebuilt_aar(
name = 'recyclerview-v7',
visibility = [ 'PUBLIC' ],
aar = 'recyclerview-v7-22.1.1.aar'
)
# buck android
prebuilt_jar(
name = 'buck-android-support',
visibility = [ 'PUBLIC' ],
binary_jar = 'buck-android-support.jar',
)
# This is an example of a module that has kotlin code and java code
kotlinLib(
name = 'pojo',
visibility = [ 'PUBLIC' ],
srcs = glob(['src/main/**/*.kt']),
deps = [
':res',
'//res-base:res',
'//libs:timber',
'//libs:gson',
'//libs:rxjava',
'//rxstoredobject:rxstoredobject',
'//libdi:libdi',
'//kotlinutils:kotlinutils',
'//androiddi:androiddi',
],
exported_deps = [
':java-deps',
],
)
android_library(
name = 'java-deps',
visibility = ['PUBLIC'],
srcs = glob(['src/**/*.java']),
deps = [
':res',
'//res-base:res',
'//libs:timber',
'//libs:gson',
'//libs:rxjava',
'//rxstoredobject:rxstoredobject',
'//libdi:libdi',
'//kotlinutils:kotlinutils',
'//androiddi:androiddi',
]
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.example.appname',
visibility = [ 'PUBLIC' ],
)
project_config(src_target = ':pojo')
# All my res goes in this module
# Replace the 'com.example.appname' with your package name
kotlinLib(
name = 'res-base',
visibility = [ 'PUBLIC' ],
srcs = glob(['src/main/**/*.kt']),
deps = [
':res',
],
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.example.appname',
visibility = [ 'PUBLIC' ]
)
project_config(src_target = ':res-base')
@bkase
Copy link
Author

bkase commented Nov 24, 2015

replace _ with /in file names

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment