def test_install_stl_lib( self, mock_ensure_dir, mock_isfile, mock_install_lib ): """ Test that :meth:`~pythonforandroid.recipe.STLRecipe.install_stl_lib`, calls the method :meth:`~pythonforandroid.recipe.Recipe.install_libs` with the proper arguments: a subclass of :class:`~pythonforandroid.archs.Arch` and our stl lib (:attr:`~pythonforandroid.recipe.STLRecipe.stl_lib_name`) """ mock_isfile.return_value = False arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('icu', self.ctx) recipe.ctx = self.ctx assert recipe.need_stl_shared, True recipe.install_stl_lib(arch) mock_install_lib.assert_called_once_with( arch, '{ndk_dir}/sources/cxx-stl/llvm-libc++/' 'libs/{arch}/lib{stl_lib}.so'.format( ndk_dir=self.ctx.ndk_dir, arch=arch.arch, stl_lib=recipe.stl_lib_name, ), ) mock_ensure_dir.assert_called()
def __init__(self): super(Context, self).__init__() self.include_dirs = [] self._build_env_prepared = False self._sdk_dir = None self._ndk_dir = None self._android_api = None self._ndk_api = None self.ndk = None self.toolchain_prefix = None self.toolchain_version = None self.local_recipes = None self.copy_libs = False # this list should contain all Archs, it is pruned later self.archs = ( ArchARM(self), ArchARMv7_a(self), Archx86(self), Archx86_64(self), ArchAarch_64(self), ) self.root_dir = realpath(dirname(__file__)) # remove the most obvious flags that can break the compilation self.env.pop("LDFLAGS", None) self.env.pop("ARCHFLAGS", None) self.env.pop("CFLAGS", None) self.python_recipe = None # Set by TargetPythonRecipe
def test_should_build(self, mock_exists): arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('openssl', self.ctx) recipe.ctx = self.ctx self.assertFalse(recipe.should_build(arch)) mock_exists.return_value = False self.assertTrue(recipe.should_build(arch))
def test_should_build(self, mock_exists): # avoid trying to find the recipe in a non-existing storage directory self.ctx.storage_dir = None arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('openssl', self.ctx) recipe.ctx = self.ctx self.assertFalse(recipe.should_build(arch)) mock_exists.return_value = False self.assertTrue(recipe.should_build(arch))
def test_get_recipe_env_with( self, mock_ensure_dir, mock_find_executable, mock_glob ): """ Test that :meth:`~pythonforandroid.recipe.STLRecipe.get_recipe_env` returns some expected keys and values. .. note:: We don't check all the env variables, only those one specific of :class:`~pythonforandroid.recipe.STLRecipe`, the others should be tested in the proper test. """ expected_compiler = ( f"/opt/android/android-ndk/toolchains/" f"llvm/prebuilt/{system().lower()}-x86_64/bin/clang" ) mock_find_executable.return_value = expected_compiler mock_glob.return_value = ["llvm"] arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('icu', self.ctx) assert recipe.need_stl_shared, True env = recipe.get_recipe_env(arch) # check that the mocks have been called mock_glob.assert_called() mock_ensure_dir.assert_called() mock_find_executable.assert_called_once_with( expected_compiler, path=os.environ['PATH'] ) self.assertIsInstance(env, dict) # check `CPPFLAGS` expected_cppflags = { '-I{stl_include}'.format(stl_include=recipe.stl_include_dir) } self.assertIn('CPPFLAGS', env) for flags in expected_cppflags: self.assertIn(flags, env['CPPFLAGS']) # check `LIBS` self.assertIn('LDFLAGS', env) self.assertIn('-L' + recipe.get_stl_lib_dir(arch), env['LDFLAGS']) self.assertIn('LIBS', env) self.assertIn('-lc++_shared', env['LIBS']) # check `CXXFLAGS` and `CXX` for flag in {'CXXFLAGS', 'CXX'}: self.assertIn(flag, env) self.assertIn('-frtti -fexceptions', env[flag])
def test_get_stl_lib_dir(self): """ Test that :meth:`~pythonforandroid.recipe.STLRecipe.get_stl_lib_dir` returns the expected path for the stl library """ arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('icu', self.ctx) self.assertTrue(recipe.need_stl_shared) self.assertEqual( recipe.get_stl_lib_dir(arch), os.path.join( self.ctx.ndk_dir, 'sources/cxx-stl/llvm-libc++/libs/{arch}'.format( arch=arch.arch), ), )
def test_install_libraries(self, mock_install_libs, mock_get_libraries): mock_get_libraries.return_value = { '/build_lib/libsample1.so', '/build_lib/libsample2.so', } self.ctx.recipe_build_order = [ "hostpython3", "openssl", "python3", "sdl2", "kivy", ] arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('openssl', self.ctx) recipe.install_libraries(arch) mock_install_libs.assert_called_once_with( arch, *mock_get_libraries.return_value)
def test_arch_aarch_64(self, mock_ensure_dir, mock_find_executable, mock_glob): """ Test that class :class:`~pythonforandroid.archs.ArchAarch_64` returns some expected attributes and environment variables. .. note:: Here we mock the same functions than :meth:`TestArchARM.test_arch_arm` plus `glob`, so we make sure that the glob result is the expected even if the folder doesn't exist, which is probably the case. This has to be done because here we tests the `get_env` with clang """ mock_find_executable.return_value = self.expected_compiler mock_ensure_dir.return_value = True mock_glob.return_value = ["llvm"] arch = ArchAarch_64(self.ctx) self.assertEqual(arch.arch, "arm64-v8a") self.assertEqual(arch.__str__(), "arm64-v8a") self.assertEqual(arch.toolchain_prefix, "aarch64-linux-android") self.assertEqual(arch.command_prefix, "aarch64-linux-android") self.assertEqual(arch.target, "aarch64-linux-android21") self.assertEqual(arch.platform_dir, "arch-arm64") env = arch.get_env() # check glob and find_executable calls self.assertEqual(mock_glob.call_count, 4) for glob_call, kw in mock_glob.call_args_list: self.assertEqual( glob_call[0], "{ndk_dir}/toolchains/llvm*".format(ndk_dir=self.ctx._ndk_dir), ) mock_find_executable.assert_called_once_with(self.expected_compiler, path=environ["PATH"]) # For x86_64 we expect to find an extra key in`environment` for flag in {"CFLAGS", "CXXFLAGS", "CC", "CXX"}: self.assertIn("-march=armv8-a", env[flag])
def __init__(self): super(Context, self).__init__() self.include_dirs = [] self._build_env_prepared = False self._sdk_dir = None self._ndk_dir = None self._android_api = None self._ndk_ver = None self.ndk = None self.toolchain_prefix = None self.toolchain_version = None self.local_recipes = None self.copy_libs = False # root of the toolchain self.setup_dirs() # this list should contain all Archs, it is pruned later self.archs = ( ArchARM(self), ArchARMv7_a(self), Archx86(self), ArchAarch_64(self), ) ensure_dir(join(self.build_dir, 'bootstrap_builds')) ensure_dir(join(self.build_dir, 'other_builds')) # other_builds: where everything else is built # remove the most obvious flags that can break the compilation self.env.pop("LDFLAGS", None) self.env.pop("ARCHFLAGS", None) self.env.pop("CFLAGS", None) self.python_recipe = None # Set by TargetPythonRecipe
def test_arch_aarch_64(self, mock_ensure_dir, mock_find_executable): """ Test that class :class:`~pythonforandroid.archs.ArchAarch_64` returns some expected attributes and environment variables. .. note:: Here we mock the same functions than :meth:`TestArchARM.test_arch_arm` """ mock_find_executable.return_value = "arm-linux-androideabi-gcc" mock_ensure_dir.return_value = True arch = ArchAarch_64(self.ctx) self.assertEqual(arch.arch, "arm64-v8a") self.assertEqual(arch.__str__(), "arm64-v8a") self.assertEqual(arch.toolchain_prefix, "aarch64-linux-android") self.assertEqual(arch.command_prefix, "aarch64-linux-android") self.assertEqual(arch.target, "aarch64-none-linux-android") self.assertEqual(arch.platform_dir, "arch-arm64") # For x86_64 we expect to find an extra key in`environment` env = arch.get_env() self.assertIn("EXTRA_CFLAGS", env.keys())
def test_postarch_build(self, mock_install_stl_lib): arch = ArchAarch_64(self.ctx) recipe = Recipe.get_recipe('icu', self.ctx) assert recipe.need_stl_shared, True recipe.postbuild_arch(arch) mock_install_stl_lib.assert_called_once_with(arch)