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.
|
# does.
|
||||||
DEFAULT_SDK_TAG = '4333796'
|
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):
|
class TargetAndroid(Target):
|
||||||
targetname = 'android'
|
targetname = 'android'
|
||||||
|
@ -54,6 +60,7 @@ class TargetAndroid(Target):
|
||||||
p4a_fork = 'kivy'
|
p4a_fork = 'kivy'
|
||||||
p4a_branch = 'master'
|
p4a_branch = 'master'
|
||||||
p4a_apk_cmd = "apk --debug --bootstrap="
|
p4a_apk_cmd = "apk --debug --bootstrap="
|
||||||
|
p4a_best_ndk_version = None
|
||||||
extra_p4a_args = ''
|
extra_p4a_args = ''
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -97,6 +104,47 @@ class TargetAndroid(Target):
|
||||||
kwargs.setdefault('cwd', self.pa_dir)
|
kwargs.setdefault('cwd', self.pa_dir)
|
||||||
return self.buildozer.cmd(self._p4a_cmd + cmd + self.extra_p4a_args, **kwargs)
|
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):
|
def _sdkmanager(self, *args, **kwargs):
|
||||||
"""Call the sdkmanager in our Android SDK with the given arguments."""
|
"""Call the sdkmanager in our Android SDK with the given arguments."""
|
||||||
# Use the android-sdk dir as cwd by default
|
# Use the android-sdk dir as cwd by default
|
||||||
|
@ -112,7 +160,7 @@ class TargetAndroid(Target):
|
||||||
@property
|
@property
|
||||||
def android_ndk_version(self):
|
def android_ndk_version(self):
|
||||||
return self.buildozer.config.getdefault('app', 'android.ndk',
|
return self.buildozer.config.getdefault('app', 'android.ndk',
|
||||||
ANDROID_NDK_VERSION)
|
self.p4a_best_android_ndk)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def android_api(self):
|
def android_api(self):
|
||||||
|
|
|
@ -8,7 +8,9 @@ from buildozer import Buildozer, IS_PY3
|
||||||
from six import StringIO
|
from six import StringIO
|
||||||
import tempfile
|
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):
|
class TestBuildozer(unittest.TestCase):
|
||||||
|
@ -200,3 +202,48 @@ class TestBuildozer(unittest.TestCase):
|
||||||
assert m_stdout.write.call_args_list == [
|
assert m_stdout.write.call_args_list == [
|
||||||
mock.call(command_output)
|
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…
Add table
Reference in a new issue