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()
Exemple #2
0
    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
Exemple #3
0
    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),
         ),
     )
Exemple #7
0
 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)
Exemple #8
0
    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])
Exemple #9
0
    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)