Merge pull request #351 from kiwix/no_android

No android
This commit is contained in:
Kelson 2019-12-05 14:25:47 +01:00 committed by GitHub
commit 97bcc3e991
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 23 additions and 846 deletions

View File

@ -69,7 +69,7 @@ By default, `kiwix-build` will build `kiwix-tools` .
If no target platform is specified, a default one will be infered from
the specified target :
- `kiwix-android` will be build using the platform `android`
- `kiwix-lib-app` will be build using the platform `android`
- Other targets will be build using the platform `native_dyn`
But you can select another target platform using the option
@ -93,9 +93,14 @@ kiwix-build --target-platform win32_dyn
## Android
Android apk (kiwix-android) is a bit a special case.
`kiwix-android` itself is architecture independent (it is written in
java) but it use `kiwix-lib` who is architecture dependent.
`kiwix-android` (https://github.com/kiwix/kiwix-android) depends of
the `kiwix-lib` project.
It uses a special `.aar` file that represent (and embed) the kiwix-lib for
all supported android arch. This is a kind of fat archive we have for MacOs.
The `.aar` file is build using the `kiwix-lib-app` project.
`kiwix-lib-app` itself is architecture independent (it is just a packaging of
other archives) but it use `kiwix-lib` who is architecture dependent.
When building `kiwix-lib`, you should directly use the
target-platform `android_<arch>`:
@ -103,22 +108,23 @@ target-platform `android_<arch>`:
kiwix-build kiwix-lib --target-platform android_arm
```
But, `kiwix-android` apk can also be multi arch (ie, it includes
`kiwix-lib` for several architectures). To do so, you must ask to build
`kiwix-android` using the `android` platform:
But, `kiwix-lib-app` is mainly multi arch.
To compile `kiwix-lib-app`, you must use the `android` platform:
```bash
kiwix-build --target-platform android kiwix-android
kiwix-build kiwix-android # because `android` platform is the default for `kiwix-android`
$ kiwix-build --target-platform android kiwix-lib-app
$ kiwix-build kiwix-lib-app # because `android` platform is the default for `kiwix-lib-app`
```
By default, when using platform `android`, `kiwix-lib` will be build for
all architectures. This can be changed by using the option `--android-arch` :
```bash
kiwix-build kiwix-android # apk for all architectures
kiwix-build kiwix-android --android-arch arm # apk for arm architecture
kiwix-build kiwix-anrdoid --android-arch arm --android-arch arm64 # apk for arm and arm64 architectures
$ kiwix-build kiwix-lib-app # aar with all architectures
$ kiwix-build kiwix-lib-app --android-arch arm # aar with arm architecture
$ kiwix-build kiwix-lib-app --android-arch arm --android-arch arm64 # aan with arm and arm64 architectures
```
To build `kiwix-android` itself, you should see the documentation of `kiwix-android`.
## IOS
When building for ios, we may want to compile a "fat library", a library

View File

@ -1,85 +0,0 @@
#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use Getopt::Long;
# get the params
my $zim_url;
my $custom_app;
my $keystore;
my $api_key;
my $version = "0";
my $cmd;
# Get console line arguments
GetOptions('zim_url=s' => \$zim_url,
'custom_app=s' => \$custom_app,
'keystore=s' => \$keystore,
'api_key=s' => \$api_key,
'version=s' => \$version
);
# Print usage() if necessary
if (!$zim_url || !$custom_app || !$keystore || !$api_key) {
print "usage: ./build_custom_app.pl --keystore=kiwix-android.keystore --api_key=google.json --zim_url=\"https://download.kiwix.org/zim/wikipedia_en_medicine_novid.zim\" --custom_app=wikimed [--version=1]\n";
exit;
}
# Clean signed ap
$cmd = "rm ./signed_apks/*apk"; `$cmd`;
# Download ZIM file
$cmd = "wget \"$zim_url\" -O content.zim"; `$cmd`;
# Get ZIM file size
$cmd = "stat -c %s content.zim";
my $zim_size = `$cmd` =~ s/\n//gr ;
$ENV{ZIM_SIZE} = $zim_size;
# Compute version code base
$cmd = "date +%y%j";
my $version_code_base = `$cmd` =~ s/\n//gr . $version;
# Compute content version code
my $content_version_code = $version_code_base;
$ENV{CONTENT_VERSION_CODE} = $content_version_code;
# Compute custom app date
$cmd = "date +%Y-%m";
my $date = `$cmd` =~ s/\n//gr;
$ENV{VERSION_NAME} = $date;
# Compile apps
$ENV{VERSION_CODE} = $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_arm --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "1" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_arm64 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "2" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_x86 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
$ENV{VERSION_CODE} = "3" . $version_code_base;
$cmd = "./kiwix-build.py --target-platform android_x86_64 --android-custom-app $custom_app --zim-file-size $zim_size kiwix-android-custom"; system $cmd;
# Sign apps
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-${version_code_base}-release-signed.apk BUILD_android_arm/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-1${version_code_base}-release-signed.apk BUILD_android_arm64/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-2${version_code_base}-release-signed.apk BUILD_android_x86/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
$cmd = "./TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign -ks \"${keystore}\" --out signed_apks/app-3${version_code_base}-release-signed.apk BUILD_android_x86_64/kiwix-android-custom_${custom_app}/app/build/outputs/apk/${custom_app}/release/app-${custom_app}-release-unsigned.apk";
system $cmd;
# Upload
$cmd = "./build_custom_app.py --step publish --custom-app ${custom_app} --google-api-key ${api_key} --zim-path content.zim --apks-dir signed_apks --content-version-code ${content_version_code}";
system $cmd;
exit;

View File

@ -1,430 +0,0 @@
#!/usr/bin/env python3
import \
argparse, \
datetime, \
glob, \
json, \
os, \
ssl, \
sys, \
tempfile, \
time, \
urllib
from uuid import uuid4
from contextlib import contextmanager
from urllib.parse import urlparse
from utils import (
Remotefile,
download_remote
)
import requests
import httplib2
from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client import client
from oauth2client.service_account import ServiceAccountCredentials
tmpl_request_url = "https://api.travis-ci.org/repo/{organisation}%2F{repository}/{endpoint}"
tmpl_message = """Build of custom app {app} with zim file {zim}.
UUID:#{uuid}#"""
description = """Launch a custom application build.
This command will launch a custom application build on Travis-CI.
Travis-CI jobs will compile the application and upload the build apks on
google play, using tha 'alpha' track of the application.
You will need to have a valid TRAVIS_TOKEN associated to your personnal account
and the kiwix-build repository on travis.
Use the 'travis' command line tool (https://github.com/travis-ci/travis.rb)
to generate a token.
"""
def parse_args():
parser = argparse.ArgumentParser(description=description,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--custom-app')
parser.add_argument('--travis-token')
advance = parser.add_argument_group('advance', "Some advanced options.")
advance.add_argument('--extra-code', type=int, default=0)
advance.add_argument('--version-name', default=None,
help="The version of the application (seen by user). Get from json info file by default.")
advance.add_argument('--check-certificate', default=True)
advance.add_argument('--zim-url', default=None, help="Get from json info file by default.")
advance.add_argument('--no-android-upload', action='store_false', dest='android_upload')
# Hidden options
parser.add_argument('--step', default='launch', choices=['launch', 'publish'], help=argparse.SUPPRESS)
parser.add_argument('--apks-dir', help=argparse.SUPPRESS)
parser.add_argument('--zim-path', default=None, help=argparse.SUPPRESS)
parser.add_argument('--content-version-code', type=int, help=argparse.SUPPRESS)
parser.add_argument('--package-name', default=None, help=argparse.SUPPRESS)
parser.add_argument('--google-api-key', help=argparse.SUPPRESS)
options = parser.parse_args()
if (not options.package_name
or not (options.zim_url or options.zim_path)
or not options.version_name):
if not options.package_name:
print("Try to get package name from info.json file")
if not options.zim_url:
print("Try to get zim url from info.json file")
if not options.version_name:
print("Try to get version_name form info.json file")
request_url = ('https://raw.githubusercontent.com/kiwix/kiwix-android-custom/master/{}/info.json'
.format(options.custom_app))
json_request = requests.get(request_url)
if json_request.status_code != 200:
print("Error while getting json file.")
print("Reason is '{}'".format(json_request.reason))
sys.exit(-1)
json_data = json.loads(json_request.text)
if not options.package_name:
print("Found package_name '{}'".format(json_data['package']))
options.package_name = json_data['package']
if not options.zim_url:
print("Found zim_url '{}'".format(json_data['zim_url']))
options.zim_url = json_data['zim_url']
if not options.version_name:
print("Found version_name '{}'".format(json_data['version_name']))
options.version_name = json_data['version_name']
options.base_version = "{}{}".format(
datetime.date.today().strftime('%y%j'),
options.extra_code)
return options
def download_zim_file(zim_url, dest_dir=None):
if dest_dir is None:
dest_dir = os.getcwd()
out_filename = urlparse(zim_url).path
out_filename = os.path.basename(out_filename)
zim_file = Remotefile(out_filename, '', zim_url)
download_remote(zim_file, dest_dir)
return os.path.join(dest_dir, out_filename)
def get_zim_size(*, zim_url=None, zim_path=None, check_certificate=True):
print("Try to get zim size")
if not zim_path:
if not check_certificate:
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
else:
context = None
extra_args = {'context':context} if sys.version_info >= (3, 4, 3) else {}
with urllib.request.urlopen(zim_url, **extra_args) as resource:
size = resource.getheader('Content-Length', None)
if size is not None:
size = int(size)
print("Zim size is {}".format(size))
return size
else:
print("No 'Content-Length' header in http answer from the server.\n"
"We need to download the zim file to get its size.")
zim_path = download_zim_file(zim_url, tempfile.gettempdir())
size = os.path.getsize(zim_path)
print("Zim size is {}".format(size))
return size
def do_launch(options):
if options.zim_path:
zim_size = get_zim_size(zim_path=options.zim_path)
else:
zim_size = get_zim_size(zim_url=options.zim_url,
check_certificate=options.check_certificate)
travis_launch_build('kiwix', 'kiwix-build', options, zim_size)
print("Travis build has been launch.")
def do_publish(options):
zim_path = options.zim_path or download_zim_file(options.zim_url)
googleService = Google(options)
with googleService.new_request():
versionCodes = []
for apk in glob.iglob(options.apks_dir+"/*.apk"):
result = googleService.upload_apk(apk)
versionCodes.append(result['versionCode'])
googleService.upload_expansionfile(
zim_path, options.content_version_code, versionCodes)
googleService.publish_release(options, versionCodes)
def travis_launch_build(organisation, repository, options, zim_size):
request_url = tmpl_request_url.format(
organisation=organisation,
repository=repository,
endpoint='requests')
headers = {
"Travis-API-Version": "3",
"Content-Type": "application/json",
"Authorization": "token {}".format(options.travis_token),
"User-Agent": "kiwix-build"
}
uuid = uuid4()
envs = []
for platform_index, platform in enumerate(['arm', 'arm64', 'x86', 'x86_64']):
d = {
'PLATFORM': "android_{}".format(platform),
'VERSION_CODE': gen_version_code(platform_index, options.base_version)
}
envs.append(d)
global_env = [
{ 'CUSTOM_APP': options.custom_app},
{ 'ZIM_FILE_SIZE': zim_size},
{ 'PACKAGE_NAME': options.package_name},
{ 'ZIM_URL': options.zim_url},
{ 'EXTRA_CODE': options.extra_code},
{ 'CONTENT_VERSION_CODE': gen_version_code(0, options.base_version)},
{ 'VERSION_NAME': options.version_name},
# google_key
{ 'secure': ('VAgKBMx0KEIyJlSnpM4YrHKLALIbaibkhlsgiv19ITa6dODoEIqeYHz'
'wFTiL3mRHU6HwtXtdNb/JeMle9NfHJVFSV56ZgFzX7ev9zr0YG0qZQv'
'tl8vHQlFPBErARder/L2tblOTM194/TiJk/q89a0XWDanKswXExwjcW'
'Z0tnDYQXTHSAKEt+xW8hjbnhqqB/v16lX6dUjZI+sVlsw+qAM4VT/qf'
'FCyDO5eJCzWIEL2LDUWI7jKSETNih5hl5fMMvCCNRPnkgGnytw5kF/t'
'Lw8YAbLRxkGsO4FCx5mB7HF5pNHyWOCCalMTKheyg/qUV/VcXW9Unlr'
'puMu0+d3hpLZESplS/NkvDxSrx16ank7EORS8OxLOufu56TW2hDuBzz'
'w1CBAj1p6s+Z6Kc4RMYYdxRgR1TjXg/ZVUn3T69d9igdS/5lAPFx2Ww'
'8x82FWCLSaiXymxXRNsNcKx5ifuvtv307r4yh31QjlKFYwadOCaCHHZ'
'zGE1mXcOu3j6W9WIaZfYRTpxmOrcfDIHxZSdLf11hOSZEUUFpj9hQlV'
'Op0RHkDEJUMNs6vkXUhZq9yPuqgrcb6GaN+UhOT8iHlijKmlG8NJEPk'
'Hp8RnL1hsr44N57ZzLqmSUZtvC83u/5e+YUb7beUDGsMyJV/fcMiGMM'
'LVtRnuPCFyNVNQUf2CphtG0=') },
# pass
{ 'secure': ('AtbgKUukES2uJPpEWNEDHLg0WcghLlCGL171Ah3+4CckBI8y1Fn+VpH'
'U2vEXzsV8tKoxX1IyB2tFivzuyo6CQXHSuWGJYQexwkBeGCgOfzKJLj'
'MAy75ATYA6JnFrikV+UcqdEz/9Dow3J1K7Slp3jpsQhERHbNeqkr4I+'
'XCL1LLnpewfOZo9OIEu93p6b6YlqvIPXJHyQe5xnMd8jFWg3/uIYqFn'
'XPvigeZqC2lhNp48mj4JdwwF2tmiArgyXOmgxiuHJNVVI7okbhc7kmI'
'Y3MmCSFgG0XPUEBU3Kdr4o/2hy8DDP6Gff+rUZW8nPI/2UWXRLWtOxv'
'XGGRyjHHTxGWzI4JyZbli9dls5M32MMjsXVKtciSFVwsMM8qn7wFnRi'
'q248a1Sg5fDNX/WYowmsHlWjffHZ7+UqUqJxAKtZ0vpQL+4SPIALPnK'
'V6j6CoorQp+VhMF01EFlZ0c8bkNmk4YW7R7RyNLIcaHKfd1ud8QF9PD'
'AnQ7Jr1GRBxzkjHvHfFrE14WPUu+FjVvDO7UPVMNQX7RS1IVACpKSRu'
'7N8KnIK3vSnLpn5GXKsbx0JB2vtyoTaFZvC9c3qyAw1nlpn7Lp3sPs3'
'bgIBU4tWOzg5g46eHbc4ad5nyB9Soz715lbMdECvKs2HHJUG3tubLKj'
'L0S/LRGRQ+IDgC7xrjQj8aA=') },
]
env = {
'matrix': envs,
'global': global_env
}
data = {
'request': {
'message' : tmpl_message.format(app=options.custom_app, zim=options.zim_url, uuid=uuid),
'branch' : "custom_app",
'config' : {
'before_install' : [
( 'pip3 install pyOpenSSl google-api-python-client'
' httplib2 apiclient requests'),
( 'openssl aes-256-cbc -k $google_key'
' -in travis/googleplay_android_developer-5a411156212c.json.enc'
' -out travis/googleplay_android_developer-5a411156212c.json'
' -d'),
( 'openssl aes-256-cbc -k $google_key'
' -in travis/kiwix-android.keystore.enc'
' -out travis/kiwix-android.keystore -d'),
( 'openssl aes-256-cbc -K $encrypted_eba2f7543984_key'
' -iv $encrypted_eba2f7543984_iv'
' -in travis/travisci_builder_id_key.enc'
' -out travis/travisci_builder_id_key -d'),
'chmod 600 travis/travisci_builder_id_key'
],
'env' : env,
'script' : 'travis_wait 30 travis/compile_custom_app.sh',
'deploy' : {
'provider': 'script',
'skip_cleanup': True,
'script': 'travis/deploy_apk.sh',
'on': {
'branch': 'custom_app'
}
}
}
}
}
if options.android_upload:
data['request']['config']['jobs'] = {
'include': [
{
'stage' : 'make_release',
'install': 'pip3 install -r requirements_build_custom_app.txt',
'script': True,
'env': global_env,
'deploy' : {
'provider': 'script',
'skip_cleanup': True,
'script': 'travis/make_release.sh',
'on': {
'branch': 'custom_app'
}
}
}
]
}
global_env.append({
'DEPLOY_DIR' : '/home/nightlybot/apks/{}_{}'.format(
options.custom_app, options.base_version)
})
else:
global_env.append({
'DEPLOY_DIR' : '/data/tmp/custom_apps/{}_{}'.format(
options.custom_app, options.base_version)
})
r = requests.post(request_url, headers=headers, json=data)
if r.status_code != 202:
print("Error while requesting build:")
print(r.reason)
print("Have you forget to give the travis token ?")
sys.exit(-1)
else:
request_id = r.json()['request']['id']
print("Request {} has been schedule.".format(request_id))
request_left = 10
found = False
request_url = tmpl_request_url.format(
organisation=organisation,
repository=repository,
endpoint='builds')
while request_left:
time.sleep(1)
print("Try to get associated build.")
r = requests.get(request_url, headers=headers)
json_data = json.loads(r.text)
for build in json_data['builds']:
if build['event_type'] != 'api':
continue
message = build['commit']['message']
if str(uuid) in message:
found = True
break
if found:
break
print("Cannot find build. Wait 1 second and try again")
print("{} tries left".format(request_left))
request_left -= 1
if found:
print("Associated build found: {}.".format(build['number']))
print("https://travis-ci.org/kiwix/kiwix-build/builds/{}".format(build['id']))
else:
print("Request has been accepted by travis-ci but I cannot found "
"the associated build. Have a look here "
"https://travis-ci.org/kiwix/kiwix-build/builds"
"if you found it.")
if not options.android_upload:
print(("Automatic upload to android play store has been deactivated.\n"
"You will find the apks at this address once they have been compiled :"
" http://tmp.kiwix.org/custom_apps/{}_{}").format(
options.custom_app, options.base_version))
ERROR_MSG_EDIT_CHANGE = "A change was made to the application outside of this Edit, please create a new edit."
class Google:
def __init__(self, options):
scope = 'https://www.googleapis.com/auth/androidpublisher'
key = options.google_api_key
credentials = ServiceAccountCredentials.from_json_keyfile_name(
key,
scopes=[scope])
http = httplib2.Http()
http = credentials.authorize(http)
self.service = build('androidpublisher', 'v2', http=http)
self.packageName = options.package_name
self.edit_id = None
@contextmanager
def new_request(self):
edit_request = self.service.edits().insert(
packageName=self.packageName,
body={})
result = edit_request.execute()
print("create", result)
self.edit_id = result['id']
yield
commit_request = self.service.edits().commit(
editId=self.edit_id,
packageName=self.packageName)
result = commit_request.execute()
print("commit", result)
self.edit_id = None
def make_request(self, section, method, **kwargs):
request_content = self._build_request_content(kwargs)
_section = getattr(self._edits, section)()
_method = getattr(_section, method)
print(">", request_content)
request = _method(**request_content)
result = request.execute()
print("<", result)
return result
def _build_request_content(self, kwargs):
d = kwargs.copy()
d['editId'] = self.edit_id
d['packageName'] = self.packageName
return d
@property
def _edits(self):
return self.service.edits()
def upload_expansionfile(self, comp_file, contentVersionCode, versionCodes):
versionCodes = [int(v) for v in versionCodes]
self.make_request('expansionfiles', 'upload',
expansionFileType='main',
apkVersionCode=contentVersionCode,
media_body=comp_file,
media_mime_type='application/octet-stream')
for versionCode in versionCodes:
if versionCode == contentVersionCode:
continue
self.make_request('expansionfiles', 'update',
expansionFileType='main',
apkVersionCode=versionCode,
body={'referencesVersion': contentVersionCode}
)
def upload_apk(self, apk_file):
return self.make_request('apks', 'upload',
media_body=apk_file)
def publish_release(self, options, versionCodes):
return self.make_request('tracks', 'update',
track="alpha",
body={'versionCodes': versionCodes})
def gen_version_code(platform_index, base_version):
str_version = "{platform}{base_version}".format(
platform=platform_index,
base_version=base_version
)
return int(str_version)
if __name__ == "__main__":
options = parse_args()
func = globals()['do_{}'.format(options.step)]
func(options)

View File

@ -48,35 +48,15 @@ def parse_args():
help=("Specify the architecture to build for ios application/libraries.\n"
"Can be specified several times to build for several architectures.\n"
"If not specified, all architectures will be build."))
subgroup = parser.add_argument_group('custom app',
description="Android custom app specific options")
subgroup.add_argument('--android-custom-app',
help="The custom android app to build")
subgroup.add_argument('--zim-file-url',
help="The url of the zim file to download")
subgroup.add_argument('--zim-file-size',
help="The size of the zim file.")
options = parser.parse_args()
if options.target == 'kiwix-android-custom':
err = False
if not options.android_custom_app:
print("You need to specify ANDROID_CUSTOM_APP if you "
"want to build a kiwix-android-custom target")
err = True
if not options.zim_file_url and not options.zim_file_size:
print("You need to specify ZIM_FILE_SIZE or ZIM_FILE_URL if you "
"want to build a kiwix-android-custom target")
err = True
if err:
sys.exit(1)
if not options.android_arch:
options.android_arch = ['arm', 'arm64', 'x86', 'x86_64']
if not options.ios_arch:
options.ios_arch = ['armv7', 'arm64', 'i386', 'x86_64']
if not options.target_platform:
if options.target in ('kiwix-android', 'kiwix-android-custom'):
if options.target in ('kiwix-lib-app',):
options.target_platform = 'android'
else:
options.target_platform = 'native_dyn'

View File

@ -7,13 +7,10 @@ from . import (
aria2,
armhf,
flatpak,
gradle,
gumbo,
icu4c,
ios_fat_lib,
mustache,
kiwix_android,
kiwix_custom_app,
kiwix_desktop,
kiwix_lib,
kiwix_tools,

View File

@ -525,7 +525,7 @@ class GradleBuilder(Builder):
shutil.copytree(self.source_path, self.build_path)
def _compile(self, context):
command = "gradle {gradle_target} {gradle_option}"
command = "./gradlew {gradle_target} {gradle_option}"
command = command.format(
gradle_target=self.gradle_target,
gradle_option=self.gradle_option)

View File

@ -1,32 +0,0 @@
from .base import (
Dependency,
ReleaseDownload,
Builder as BaseBuilder)
from kiwixbuild.utils import Remotefile, pj, copy_tree, add_execution_right
class Gradle(Dependency):
neutral = True
name = "gradle"
class Source(ReleaseDownload):
archive = Remotefile('gradle-5.2-bin.zip',
'ff322863250159595e93b5a4d17a6f0d21c59a1a0497c1e1cf1d53826485503f',
'https://services.gradle.org/distributions/gradle-5.2-bin.zip')
class Builder(BaseBuilder):
@property
def install_path(self):
return self.buildEnv.install_dir
def build(self):
self.command('install', self._install)
def _install(self, context):
copy_tree(
pj(self.source_path, "bin"),
pj(self.install_path, "bin"),
post_copy_function = add_execution_right)
copy_tree(
pj(self.source_path, "lib"),
pj(self.install_path, "lib"))

View File

@ -1,64 +0,0 @@
import shutil, os
from .base import (
Dependency,
GitClone,
GradleBuilder)
from kiwixbuild.utils import pj, copy_tree
from kiwixbuild._global import option, get_target_step
class KiwixAndroid(Dependency):
name = "kiwix-android"
class Source(GitClone):
git_remote = "https://github.com/kiwix/kiwix-android"
git_dir = "kiwix-android"
class Builder(GradleBuilder):
dependencies = ["kiwix-lib"]
@classmethod
def get_dependencies(cls, platformInfo, allDeps):
if not allDeps:
return super().get_dependencies(platformInfo, allDeps)
else:
deps = [('android_{}'.format(arch), 'kiwix-lib')
for arch in option('android_arch')]
return deps
def build(self):
if option('target') == 'kiwix-android-custom':
print("SKIP")
else:
super().build()
def _configure(self, context):
if not os.path.exists(self.build_path):
shutil.copytree(self.source_path, self.build_path, symlinks=True)
try:
shutil.rmtree(pj(self.build_path, 'kiwixlib', 'src', 'main'))
except FileNotFoundError:
pass
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
copy_tree(pj(kiwix_builder.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
os.makedirs(
pj(self.build_path, 'app', 'src', 'main', 'assets', 'icu'),
exist_ok=True)
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
shutil.copy2(pj(kiwix_builder.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
break

View File

@ -1,120 +0,0 @@
import shutil, os, json
from urllib.parse import urlparse
from .base import (
Dependency,
GitClone,
GradleBuilder)
from kiwixbuild.utils import Remotefile, pj, copy_tree, SkipCommand, run_command
from kiwixbuild._global import option, get_target_step
class KiwixCustomApp(Dependency):
name = "kiwix-android-custom"
class Source(GitClone):
git_remote = "https://github.com/kiwix/kiwix-android-custom"
git_dir = "kiwix-android-custom"
class Builder(GradleBuilder):
dependencies = ["kiwix-android", "kiwix-lib"]
@property
def gradle_target(self):
return "assemble{}".format(option('android_custom_app'))
@property
def gradle_option(self):
template = ("-i -P customDir={customDir}"
" -P zim_file_size={zim_size}"
" -P version_code={version_code}"
" -P version_name={version_name}"
" -P content_version_code={content_version_code}")
return template.format(
customDir=pj(self.build_path, 'custom'),
zim_size=self._get_zim_size(),
version_code=os.environ['VERSION_CODE'],
version_name=os.environ['VERSION_NAME'],
content_version_code=os.environ['CONTENT_VERSION_CODE'])
@property
def build_path(self):
return pj(self.buildEnv.build_dir, "{}_{}".format(self.target.full_name(), option('android_custom_app')))
@property
def custom_build_path(self):
return pj(self.build_path, 'custom', option('android_custom_app'))
def _get_zim_size(self):
try:
zim_size = option('zim_file_size')
except AttributeError:
with open(pj(self.source_path, option('android_custom_app'), 'info.json')) as f:
app_info = json.load(f)
zim_size = os.path.getsize(pj(self.custom_build_path, app_info['zim_file']))
return zim_size
def build(self):
self.command('configure', self._configure)
self.command('download_zim', self._download_zim)
self.command('compile', self._compile)
def _download_zim(self, context):
zim_url = option('zim_file_url')
if zim_url is None:
raise SkipCommand()
with open(pj(self.source_path, option('android_custom_app'), 'info.json')) as f:
app_info = json.load(f)
zim_url = app_info.get('zim_url', zim_url)
out_filename = urlparse(zim_url).path
out_filename = os.path.basename(out_filename)
zim_file = Remotefile(out_filename, '', zim_url)
self.buildEnv.download(zim_file)
shutil.copy(pj(self.buildEnv.archive_dir, out_filename),
pj(self.custom_build_path, app_info['zim_file']))
def _configure(self, context):
# Copy kiwix-android in build dir.
kiwix_android_source = get_target_step('kiwix-android', 'source')
if not os.path.exists(self.build_path):
shutil.copytree(kiwix_android_source.source_path, self.build_path)
# Copy kiwix-lib application in build dir
try:
shutil.rmtree(pj(self.build_path, 'kiwixlib', 'src', 'main'))
except FileNotFoundError:
pass
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
copy_tree(pj(kiwix_builder.buildEnv.install_dir, 'kiwix-lib'),
pj(self.build_path, 'kiwixlib', 'src', 'main'))
os.makedirs(
pj(self.build_path, 'app', 'src', 'main', 'assets', 'icu'),
exist_ok=True)
for arch in option('android_arch'):
try:
kiwix_builder = get_target_step('kiwix-lib', 'android_{}'.format(arch))
except KeyError:
pass
else:
shutil.copy2(pj(kiwix_builder.buildEnv.install_dir, 'share', 'icu', '58.2',
'icudt58l.dat'),
pj(self.build_path, 'app', 'src', 'main', 'assets',
'icu', 'icudt58l.dat'))
break
# Generate custom directory
try:
shutil.rmtree(pj(self.build_path, 'custom'))
except FileNotFoundError:
pass
os.makedirs(pj(self.build_path, 'custom'))
command = "./gen-custom-android-directory.py {custom_name} --output-dir {custom_dir}"
command = command.format(
custom_name=option('android_custom_app'),
custom_dir=pj(self.build_path, 'custom', option('android_custom_app'))
)
run_command(command, self.source_path, context, buildEnv=self.buildEnv)

View File

@ -123,7 +123,7 @@ class AndroidX8664(AndroidPlatformInfo):
class Android(MetaPlatformInfo):
name = "android"
toolchain_names = ['android-sdk', 'gradle']
toolchain_names = ['android-sdk']
compatible_hosts = ['fedora', 'debian']
@property
@ -131,7 +131,7 @@ class Android(MetaPlatformInfo):
return ['android_{}'.format(arch) for arch in option('android_arch')]
def add_targets(self, targetName, targets):
if targetName not in ('kiwix-android', 'kiwix-android-custom', 'kiwix-lib-app'):
if targetName not in ('kiwix-lib-app',):
return super().add_targets(targetName, targets)
else:
return AndroidPlatformInfo.add_targets(self, targetName, targets)
@ -143,10 +143,5 @@ class Android(MetaPlatformInfo):
def sdk_builder(self):
return get_target_step('android-sdk', 'neutral')
@property
def gradle_builder(self):
return get_target_step('gradle', 'neutral')
def set_env(self, env):
env['ANDROID_HOME'] = self.sdk_builder.install_path
env['PATH'] = ':'.join([pj(self.gradle_builder.install_path, 'bin'), env['PATH']])

View File

@ -112,7 +112,6 @@ class MetaPlatformInfo(PlatformInfo):
def add_targets(self, targetName, targets):
targetDefs = []
for platformName in self.subPlatformNames:
print("radd {}".format(platformName))
platform = self.get_platform(platformName, targets)
targetDefs += platform.add_targets(targetName, targets)
return targetDefs

View File

@ -54,7 +54,6 @@ base_deps_versions = {
'libmicrohttpd' : '0.9.66',
'gumbo' : '0.10.1',
'icu4c' : '58.2',
'gradle' : '5.2',
'libaria2' : '1.33.1',
'libmagic' : '5.35',
'android-sdk' : 'r25.2.3',

View File

@ -1,3 +0,0 @@
requests==2.20.0
apiclient==1.0.3

View File

@ -91,7 +91,7 @@ def run_kiwix_build(target, platform,
command.append('--hide-progress')
if platform == 'flatpak' or platform.startswith('win32_'):
command.append('--assume-packages-installed')
if target == 'kiwix-android' and platform.startswith('android_'):
if target == 'kiwix-lib-app' and platform.startswith('android_'):
command.extend(['--target-platform', 'android', '--android-arch', platform[8:]])
elif platform == 'android':
command.extend(['--target-platform', 'android'])

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -e
cd ${HOME}
${TRAVIS_BUILD_DIR}/kiwix-build.py \
--target-platform $PLATFORM \
--hide-progress \
--android-custom-app $CUSTOM_APP \
--zim-file-size $ZIM_FILE_SIZE \
kiwix-android-custom

View File

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
KEYSTORE_FILE=${TRAVIS_BUILD_DIR}/travis/kiwix-android.keystore
GOOGLE_API_KEY=${TRAVIS_BUILD_DIR}/travis/googleplay_android_developer-5a411156212c.json
cd ${HOME}
# Sign apk file
BASE_DIR="BUILD_${PLATFORM}"
INPUT_APK_FILE=${BASE_DIR}/kiwix-android-custom_${CUSTOM_APP}/app/build/outputs/apk/${CUSTOM_APP}/release/app-${CUSTOM_APP}-release-unsigned.apk
SIGNED_APK=${BASE_DIR}/app-${CUSTOM_APP}_${VERSION_CODE}-release-signed.apk
TOOLCHAINS/android-sdk-r25.2.3/build-tools/25.0.2/apksigner sign \
--ks ${KEYSTORE_FILE} \
--ks-pass env:KEYSTORE_PASS \
--out ${SIGNED_APK} \
${INPUT_APK_FILE}
ssh -i ${SSH_KEY} ci@download.kiwix.org "mkdir -p ${DEPLOY_DIR}"
scp -i ${SSH_KEY} \
${SIGNED_APK} \
ci@download.kiwix.org:${DEPLOY_DIR}

Binary file not shown.

View File

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
KEYSTORE_FILE=${TRAVIS_BUILD_DIR}/travis/test_ks.ks
GOOGLE_API_KEY=${TRAVIS_BUILD_DIR}/travis/googleplay_android_developer-5a411156212c.json
cd ${HOME}
BASE_DIR="BUILD_${PLATFORM}"
mkdir -p ${HOME}/APKS
scp -i ${SSH_KEY} ci@download.kiwix.org:${DEPLOY_DIR}/* ${HOME}/APKS
ssh -i ${SSH_KEY} ci@download.kiwix.org "rm -rf ${DEPLOY_DIR}"
${TRAVIS_BUILD_DIR}/build_custom_app.py \
--step publish \
--custom-app ${CUSTOM_APP} \
--package-name ${PACKAGE_NAME} \
--google-api-key ${GOOGLE_API_KEY} \
--zim-url ${ZIM_URL} \
--apks-dir ${HOME}/APKS \
--content-version-code ${CONTENT_VERSION_CODE}