Merge pull request #947 from opacam/feature-use-p4a-ndk
Add ability to get p4a's recommended android's NDK version
This commit is contained in:
commit
182d13f102
2 changed files with 97 additions and 2 deletions
|
@ -47,6 +47,12 @@ DEPRECATED_TOKENS = (('app', 'android.sdk'), )
|
|||
# does.
|
||||
DEFAULT_SDK_TAG = '4333796'
|
||||
|
||||
MSG_P4A_RECOMMENDED_NDK_ERROR = (
|
||||
"WARNING: Unable to find recommended android's NDK for current "
|
||||
"installation of p4...so returning the recommended buildozer's one, which "
|
||||
"is android's NDK r{android_ndk}".format(android_ndk=ANDROID_NDK_VERSION)
|
||||
)
|
||||
|
||||
|
||||
class TargetAndroid(Target):
|
||||
targetname = 'android'
|
||||
|
@ -54,6 +60,7 @@ class TargetAndroid(Target):
|
|||
p4a_fork = 'kivy'
|
||||
p4a_branch = 'master'
|
||||
p4a_apk_cmd = "apk --debug --bootstrap="
|
||||
p4a_best_ndk_version = None
|
||||
extra_p4a_args = ''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -97,6 +104,47 @@ class TargetAndroid(Target):
|
|||
kwargs.setdefault('cwd', self.pa_dir)
|
||||
return self.buildozer.cmd(self._p4a_cmd + cmd + self.extra_p4a_args, **kwargs)
|
||||
|
||||
@property
|
||||
def p4a_best_android_ndk(self):
|
||||
"""
|
||||
Return the p4a's recommended android's NDK version, depending on the
|
||||
p4a version used for our buildozer build. In case that we don't find
|
||||
it, we will return the buildozer's recommended one, defined by global
|
||||
variable `ANDROID_NDK_VERSION`.
|
||||
"""
|
||||
if self.p4a_best_ndk_version is not None:
|
||||
# make sure to read p4a version only the first time
|
||||
return self.p4a_best_ndk_version
|
||||
|
||||
if not hasattr(self, "pa_dir"):
|
||||
pa_dir = join(self.buildozer.platform_dir, self.p4a_directory)
|
||||
else:
|
||||
pa_dir = self.pa_dir
|
||||
|
||||
# check p4a's recommendation file, and in case that exists find the
|
||||
# recommended android's NDK version, otherwise return buildozer's one
|
||||
ndk_version = ANDROID_NDK_VERSION
|
||||
rec_file = join(pa_dir, "pythonforandroid", "recommendations.py")
|
||||
if not os.path.isfile(rec_file):
|
||||
self.buildozer.error(MSG_P4A_RECOMMENDED_NDK_ERROR)
|
||||
return ndk_version
|
||||
|
||||
for line in open(rec_file, "r"):
|
||||
if line.startswith("RECOMMENDED_NDK_VERSION ="):
|
||||
ndk_version = line.replace(
|
||||
"RECOMMENDED_NDK_VERSION =", "")
|
||||
# clean version of unwanted characters
|
||||
for i in {"'", '"', "\n", " "}:
|
||||
ndk_version = ndk_version.replace(i, "")
|
||||
self.buildozer.info(
|
||||
"Recommended android's NDK version by p4a is: {}".format(
|
||||
ndk_version
|
||||
)
|
||||
)
|
||||
self.p4a_best_ndk_version = ndk_version
|
||||
break
|
||||
return ndk_version
|
||||
|
||||
def _sdkmanager(self, *args, **kwargs):
|
||||
"""Call the sdkmanager in our Android SDK with the given arguments."""
|
||||
# Use the android-sdk dir as cwd by default
|
||||
|
@ -112,7 +160,7 @@ class TargetAndroid(Target):
|
|||
@property
|
||||
def android_ndk_version(self):
|
||||
return self.buildozer.config.getdefault('app', 'android.ndk',
|
||||
ANDROID_NDK_VERSION)
|
||||
self.p4a_best_android_ndk)
|
||||
|
||||
@property
|
||||
def android_api(self):
|
||||
|
|
|
@ -8,7 +8,9 @@ from buildozer import Buildozer, IS_PY3
|
|||
from six import StringIO
|
||||
import tempfile
|
||||
|
||||
from buildozer.targets.android import TargetAndroid
|
||||
from buildozer.targets.android import (
|
||||
TargetAndroid, ANDROID_NDK_VERSION, MSG_P4A_RECOMMENDED_NDK_ERROR
|
||||
)
|
||||
|
||||
|
||||
class TestBuildozer(unittest.TestCase):
|
||||
|
@ -200,3 +202,48 @@ class TestBuildozer(unittest.TestCase):
|
|||
assert m_stdout.write.call_args_list == [
|
||||
mock.call(command_output)
|
||||
]
|
||||
|
||||
def test_p4a_best_ndk_version_default_value(self):
|
||||
self.set_specfile_log_level(self.specfile.name, 1)
|
||||
buildozer = Buildozer(self.specfile.name, 'android')
|
||||
assert buildozer.target.p4a_best_ndk_version is None
|
||||
|
||||
def test_p4a_best_android_ndk_error(self):
|
||||
self.set_specfile_log_level(self.specfile.name, 1)
|
||||
buildozer = Buildozer(self.specfile.name, 'android')
|
||||
|
||||
with mock.patch('sys.stdout', new_callable=StringIO) as mock_stdout:
|
||||
ndk_version = buildozer.target.p4a_best_android_ndk
|
||||
assert MSG_P4A_RECOMMENDED_NDK_ERROR in mock_stdout.getvalue()
|
||||
# and we should get the default android's ndk version of buildozer
|
||||
assert ndk_version == ANDROID_NDK_VERSION
|
||||
|
||||
@mock.patch('buildozer.targets.android.os.path.isfile')
|
||||
@mock.patch('buildozer.targets.android.os.path.exists')
|
||||
@mock.patch('buildozer.targets.android.open')
|
||||
def test_p4a_best_android_ndk_found(
|
||||
self, mock_open, mock_exists, mock_isfile
|
||||
):
|
||||
self.set_specfile_log_level(self.specfile.name, 1)
|
||||
buildozer = Buildozer(self.specfile.name, 'android')
|
||||
|
||||
expected_ndk = '19b'
|
||||
mock_open.side_effect = [
|
||||
mock.mock_open(
|
||||
read_data='RECOMMENDED_NDK_VERSION = {expected_ndk}\n'.format(
|
||||
expected_ndk=expected_ndk)
|
||||
).return_value
|
||||
]
|
||||
ndk_version = buildozer.target.p4a_best_android_ndk
|
||||
pa_dir = os.path.join(
|
||||
buildozer.platform_dir, buildozer.target.p4a_directory)
|
||||
mock_open.assert_called_once_with(
|
||||
os.path.join(pa_dir, "pythonforandroid", "recommendations.py"), 'r'
|
||||
)
|
||||
assert ndk_version == expected_ndk
|
||||
|
||||
# now test that we only read one time p4a file, so we call again to
|
||||
# `p4a_best_android_ndk` and we should still have one call to `open`
|
||||
# file, the performed above
|
||||
ndk_version = buildozer.target.p4a_best_android_ndk
|
||||
mock_open.assert_called_once()
|
||||
|
|
Loading…
Reference in a new issue