Skip to content

Commit 71c237f

Browse files
authored
Introduces pkg_config_location in Prerequisite and use OpenSSLPrerequisite().pkg_config_location in hostpython3, so we can support ssl on hostpython3 just out of the box also on macOS (kivy#2599)
* Introduces pkg_config_location in Prerequisite and use OpenSSLPrerequisite().pkg_config_location in hostpython3, so we can support ssl on hostpython3 just out of the box also on macOS
1 parent fff7013 commit 71c237f

File tree

3 files changed

+92
-9
lines changed

3 files changed

+92
-9
lines changed

pythonforandroid/prerequisites.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
class Prerequisite(object):
1212
name = "Default"
13+
homebrew_formula_name = ""
1314
mandatory = dict(linux=False, darwin=False)
1415
installer_is_supported = dict(linux=False, darwin=False)
1516

@@ -108,6 +109,25 @@ def _darwin_get_brew_formula_location_prefix(self, formula, installed=False):
108109
else:
109110
return _stdout_res.decode("utf-8").strip()
110111

112+
def darwin_pkg_config_location(self):
113+
warning(
114+
f"pkg-config location is not supported on macOS for prerequisite: {self.name}"
115+
)
116+
return ""
117+
118+
def linux_pkg_config_location(self):
119+
warning(
120+
f"pkg-config location is not supported on linux for prerequisite: {self.name}"
121+
)
122+
return ""
123+
124+
@property
125+
def pkg_config_location(self):
126+
if sys.platform == "darwin":
127+
return self.darwin_pkg_config_location()
128+
elif sys.platform == "linux":
129+
return self.linux_pkg_config_location()
130+
111131

112132
class HomebrewPrerequisite(Prerequisite):
113133
name = "homebrew"
@@ -245,19 +265,28 @@ def darwin_installer(self):
245265

246266

247267
class OpenSSLPrerequisite(Prerequisite):
248-
name = "openssl@1.1"
268+
name = "openssl"
269+
homebrew_formula_name = "openssl@1.1"
249270
mandatory = dict(linux=False, darwin=True)
250271
installer_is_supported = dict(linux=False, darwin=True)
251272

252273
def darwin_checker(self):
253274
return (
254-
self._darwin_get_brew_formula_location_prefix("openssl@1.1", installed=True)
275+
self._darwin_get_brew_formula_location_prefix(
276+
self.homebrew_formula_name, installed=True
277+
)
255278
is not None
256279
)
257280

281+
def darwin_pkg_config_location(self):
282+
return os.path.join(
283+
self._darwin_get_brew_formula_location_prefix(self.homebrew_formula_name),
284+
"lib/pkgconfig",
285+
)
286+
258287
def darwin_installer(self):
259288
info("Installing OpenSSL ...")
260-
subprocess.check_output(["brew", "install", "openssl@1.1"])
289+
subprocess.check_output(["brew", "install", self.homebrew_formula_name])
261290

262291

263292
class AutoconfPrerequisite(Prerequisite):

pythonforandroid/recipes/hostpython3/__init__.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import sh
2+
import os
23

34
from multiprocessing import cpu_count
45
from pathlib import Path
@@ -11,6 +12,7 @@
1112
current_directory,
1213
ensure_dir,
1314
)
15+
from pythonforandroid.prerequisites import OpenSSLPrerequisite
1416

1517
HOSTPYTHON_VERSION_UNSET_MESSAGE = (
1618
'The hostpython recipe must have set version'
@@ -60,6 +62,17 @@ def python_exe(self):
6062
'''Returns the full path of the hostpython executable.'''
6163
return join(self.get_path_to_python(), self._exe_name)
6264

65+
def get_recipe_env(self, arch=None):
66+
env = os.environ.copy()
67+
openssl_prereq = OpenSSLPrerequisite()
68+
if env.get("PKG_CONFIG_PATH", ""):
69+
env["PKG_CONFIG_PATH"] = os.pathsep.join(
70+
openssl_prereq.pkg_config_location, env["PKG_CONFIG_PATH"]
71+
)
72+
else:
73+
env["PKG_CONFIG_PATH"] = openssl_prereq.pkg_config_location
74+
return env
75+
6376
def should_build(self, arch):
6477
if Path(self.python_exe).exists():
6578
# no need to build, but we must set hostpython for our Context
@@ -83,6 +96,8 @@ def get_path_to_python(self):
8396
return join(self.get_build_dir(), self.build_subdir)
8497

8598
def build_arch(self, arch):
99+
env = self.get_recipe_env(arch)
100+
86101
recipe_build_dir = self.get_build_dir(arch.arch)
87102

88103
# Create a subdirectory to actually perform the build
@@ -92,7 +107,7 @@ def build_arch(self, arch):
92107
# Configure the build
93108
with current_directory(build_dir):
94109
if not Path('config.status').exists():
95-
shprint(sh.Command(join(recipe_build_dir, 'configure')))
110+
shprint(sh.Command(join(recipe_build_dir, 'configure')), _env=env)
96111

97112
with current_directory(recipe_build_dir):
98113
# Create the Setup file. This copying from Setup.dist is
@@ -110,7 +125,7 @@ def build_arch(self, arch):
110125
SETUP_DIST_NOT_FIND_MESSAGE
111126
)
112127

113-
shprint(sh.make, '-j', str(cpu_count()), '-C', build_dir)
128+
shprint(sh.make, '-j', str(cpu_count()), '-C', build_dir, _env=env)
114129

115130
# make a copy of the python executable giving it the name we want,
116131
# because we got different python's executable names depending on

tests/test_prerequisites.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import unittest
2-
from unittest import mock
2+
from unittest import mock, skipIf
3+
4+
import sys
35

46
from pythonforandroid.prerequisites import (
57
JDKPrerequisite,
@@ -18,6 +20,7 @@ class PrerequisiteSetUpBaseClass:
1820
def setUp(self):
1921
self.mandatory = dict(linux=False, darwin=False)
2022
self.installer_is_supported = dict(linux=False, darwin=False)
23+
self.expected_homebrew_formula_name = ""
2124

2225
def test_is_mandatory_on_darwin(self):
2326
assert self.prerequisite.mandatory["darwin"] == self.mandatory["darwin"]
@@ -37,6 +40,26 @@ def test_installer_is_supported_on_linux(self):
3740
== self.installer_is_supported["linux"]
3841
)
3942

43+
def test_darwin_pkg_config_location(self):
44+
self.assertEqual(self.prerequisite.darwin_pkg_config_location(), "")
45+
46+
def test_linux_pkg_config_location(self):
47+
self.assertEqual(self.prerequisite.linux_pkg_config_location(), "")
48+
49+
@skipIf(sys.platform != "darwin", "Only run on macOS")
50+
def test_pkg_config_location_property__darwin(self):
51+
self.assertEqual(
52+
self.prerequisite.pkg_config_location,
53+
self.prerequisite.darwin_pkg_config_location(),
54+
)
55+
56+
@skipIf(sys.platform != "linux", "Only run on Linux")
57+
def test_pkg_config_location_property__linux(self):
58+
self.assertEqual(
59+
self.prerequisite.pkg_config_location,
60+
self.prerequisite.linux_pkg_config_location(),
61+
)
62+
4063

4164
class TestJDKPrerequisite(PrerequisiteSetUpBaseClass, unittest.TestCase):
4265
def setUp(self):
@@ -76,6 +99,8 @@ def setUp(self):
7699
self.mandatory = dict(linux=False, darwin=True)
77100
self.installer_is_supported = dict(linux=False, darwin=True)
78101
self.prerequisite = OpenSSLPrerequisite()
102+
self.expected_homebrew_formula_name = "openssl@1.1"
103+
self.expected_homebrew_location_prefix = "/opt/homebrew/opt/openssl@1.1"
79104

80105
@mock.patch(
81106
"pythonforandroid.prerequisites.Prerequisite._darwin_get_brew_formula_location_prefix"
@@ -84,17 +109,31 @@ def test_darwin_checker(self, _darwin_get_brew_formula_location_prefix):
84109
_darwin_get_brew_formula_location_prefix.return_value = None
85110
self.assertFalse(self.prerequisite.darwin_checker())
86111
_darwin_get_brew_formula_location_prefix.return_value = (
87-
"/opt/homebrew/opt/openssl@1.1"
112+
self.expected_homebrew_location_prefix
88113
)
89114
self.assertTrue(self.prerequisite.darwin_checker())
90115
_darwin_get_brew_formula_location_prefix.assert_called_with(
91-
"openssl@1.1", installed=True
116+
self.expected_homebrew_formula_name, installed=True
92117
)
93118

94119
@mock.patch("pythonforandroid.prerequisites.subprocess.check_output")
95120
def test_darwin_installer(self, check_output):
96121
self.prerequisite.darwin_installer()
97-
check_output.assert_called_once_with(["brew", "install", "openssl@1.1"])
122+
check_output.assert_called_once_with(
123+
["brew", "install", self.expected_homebrew_formula_name]
124+
)
125+
126+
@mock.patch(
127+
"pythonforandroid.prerequisites.Prerequisite._darwin_get_brew_formula_location_prefix"
128+
)
129+
def test_darwin_pkg_config_location(self, _darwin_get_brew_formula_location_prefix):
130+
_darwin_get_brew_formula_location_prefix.return_value = (
131+
self.expected_homebrew_location_prefix
132+
)
133+
self.assertEqual(
134+
self.prerequisite.darwin_pkg_config_location(),
135+
f"{self.expected_homebrew_location_prefix}/lib/pkgconfig",
136+
)
98137

99138

100139
class TestAutoconfPrerequisite(PrerequisiteSetUpBaseClass, unittest.TestCase):

0 commit comments

Comments
 (0)