Ubuntu20.04安装Anbox安卓模拟器
Ubuntu20.04安装安卓虚拟机anbox
官方链接:https://github.com/anbox/docs
1、添加需要的Anbox内核模块
#下载源码包
wget https://github.com/anbox/anbox-modules.gitsudo cp anbox.conf /etc/modules-load.d/
sudo cp 99-anbox.rules /lib/udev/rules.d/sudo cp -rT ashmem /usr/src/anbox-ashmem-1
sudo cp -rT binder /usr/src/anbox-binder-1#安装相关模块
sudo dkms install anbox-ashmem/1
sudo dkms install anbox-binder/1
#加载内核模块
sudo modprobe ashmem_linux
sudo modprobe binder_linux#验证
[root@ubuntu2004 ~]#lsmod | grep -e ashmem_linux -e binder_linux
binder_linux 184320 0
ashmem_linux 20480 0
[root@ubuntu2004 ~]#ls -alh /dev/binder /dev/ashmem
ls: cannot access '/dev/binder': No such file or directory
crw------- 1 root root 10, 57 Oct 14 12:45 /dev/ashmem
2、编译安装Anbox软件包
2.1 编译安装
#下载源码包
git clone https://github.com/anbox/anbox.git
#在全局 Git 配置中,将你的 Anbox 源码目录添加到“安全目录”列表中
git config --global --add safe.directory /home/baiyin/Downloads/anbox#确保你在 build 目录中
[root@ubuntu2004 ~]#cd anbox/
[root@ubuntu2004 ~/anbox]#mkdir build
[root@ubuntu2004 ~/anbox]#cd build/
#重新运行 CMake 配置
[root@ubuntu2004 ~/anbox/build]# cmake ..
#重新编译
[root@ubuntu2004 ~/anbox/build]# make -j$(nproc)
遇到一下报错
#执行make报错,查看报错信息中有c++ 17报错,尝试升级c++版本
[root@ubuntu2004 ~/anbox/build]#make [ 3%] Built target sdbus-cpp [ 10%] Built target process-cpp [ 13%] Built target emugen [ 14%] Built target OpenglCodecCommon [ 16%] Built target GLESv1_dec [ 18%] Built target GLESv2_dec [ 19%] Building CXX object external/android-emugl/shared/emugl/common/CMakeFiles/emugl_common.dir/mutex_unittest.cpp.o In file included from /usr/local/include/gtest/gtest-message.h:57, from /usr/local/include/gtest/gtest-assertion-result.h:46, from /usr/local/include/gtest/gtest.h:63, from /root/anbox/external/android-emugl/shared/emugl/common/mutex_unittest.cpp:19: /usr/local/include/gtest/internal/gtest-port.h:260:2: error: #error C++ versions less than C++17 are not supported. 260 | #error C++ versions less than C++17 are not supported. | ^~~~~ In file included from /usr/local/include/gtest/gtest-matchers.h:49, from /usr/local/include/gtest/internal/gtest-death-test-internal.h:47, from /usr/local/include/gtest/gtest-death-test.h:43, from /usr/local/include/gtest/gtest.h:64, from /root/anbox/external/android-emugl/shared/emugl/common/mutex_unittest.cpp:19: /usr/local/include/gtest/gtest-printers.h:707:38: error: variable or field ‘PrintStringTo’ declared void 707 | GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os); | ^~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:707:38: error: ‘string_view’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:707:38: note: ‘std::string_view’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:707:67: error: expected primary-expression before ‘*’ token 707 | GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os); | ^ /usr/local/include/gtest/gtest-printers.h:707:69: error: ‘os’ was not declared in this scope 707 | GTEST_API_ void PrintStringTo(::std::string_view s, ::std::ostream* os); | ^~ /usr/local/include/gtest/gtest-printers.h: In function ‘void testing::internal::PrintTo(const string&, std::ostream*)’: /usr/local/include/gtest/gtest-printers.h:709:3: error: ‘PrintStringTo’ was not declared in this scope; did you mean ‘PrintToString’? 709 | PrintStringTo(s, os); | ^~~~~~~~~~~~~ | PrintToString /usr/local/include/gtest/gtest-printers.h: At global scope: /usr/local/include/gtest/gtest-printers.h:711:28: error: variable or field ‘PrintTo’ declared void 711 | inline void PrintTo(::std::string_view s, ::std::ostream* os) { | ^~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:711:28: error: ‘string_view’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:711:28: note: ‘std::string_view’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:711:57: error: expected primary-expression before ‘*’ token 711 | inline void PrintTo(::std::string_view s, ::std::ostream* os) { | ^ /usr/local/include/gtest/gtest-printers.h:711:59: error: ‘os’ was not declared in this scope 711 | inline void PrintTo(::std::string_view s, ::std::ostream* os) { | ^~ /usr/local/include/gtest/gtest-printers.h:727:41: error: variable or field ‘PrintU16StringTo’ declared void 727 | GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os); | ^~~~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:727:41: error: ‘u16string_view’ is not a member of ‘std’; did you mean ‘u16string’? 727 | GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os); | ^~~~~~~~~~~~~~ | u16string /usr/local/include/gtest/gtest-printers.h:727:73: error: expected primary-expression before ‘*’ token 727 | GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os); | ^ /usr/local/include/gtest/gtest-printers.h:727:75: error: ‘os’ was not declared in this scope 727 | GTEST_API_ void PrintU16StringTo(::std::u16string_view s, ::std::ostream* os); | ^~ /usr/local/include/gtest/gtest-printers.h: In function ‘void testing::internal::PrintTo(const u16string&, std::ostream*)’: /usr/local/include/gtest/gtest-printers.h:729:3: error: ‘PrintU16StringTo’ was not declared in this scope; did you mean ‘PrintToString’? 729 | PrintU16StringTo(s, os); | ^~~~~~~~~~~~~~~~ | PrintToString /usr/local/include/gtest/gtest-printers.h: At global scope: /usr/local/include/gtest/gtest-printers.h:731:28: error: variable or field ‘PrintTo’ declared void 731 | inline void PrintTo(::std::u16string_view s, ::std::ostream* os) { | ^~~~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:731:28: error: ‘u16string_view’ is not a member of ‘std’; did you mean ‘u16string’? 731 | inline void PrintTo(::std::u16string_view s, ::std::ostream* os) { | ^~~~~~~~~~~~~~ | u16string /usr/local/include/gtest/gtest-printers.h:731:60: error: expected primary-expression before ‘*’ token 731 | inline void PrintTo(::std::u16string_view s, ::std::ostream* os) { | ^ /usr/local/include/gtest/gtest-printers.h:731:62: error: ‘os’ was not declared in this scope 731 | inline void PrintTo(::std::u16string_view s, ::std::ostream* os) { | ^~ /usr/local/include/gtest/gtest-printers.h:736:41: error: variable or field ‘PrintU32StringTo’ declared void 736 | GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os); | ^~~~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:736:41: error: ‘u32string_view’ is not a member of ‘std’; did you mean ‘u32string’? 736 | GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os); | ^~~~~~~~~~~~~~ | u32string /usr/local/include/gtest/gtest-printers.h:736:73: error: expected primary-expression before ‘*’ token 736 | GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os); | ^ /usr/local/include/gtest/gtest-printers.h:736:75: error: ‘os’ was not declared in this scope 736 | GTEST_API_ void PrintU32StringTo(::std::u32string_view s, ::std::ostream* os); | ^~ /usr/local/include/gtest/gtest-printers.h: In function ‘void testing::internal::PrintTo(const u32string&, std::ostream*)’: /usr/local/include/gtest/gtest-printers.h:738:3: error: ‘PrintU32StringTo’ was not declared in this scope; did you mean ‘PrintToString’? 738 | PrintU32StringTo(s, os); | ^~~~~~~~~~~~~~~~ | PrintToString /usr/local/include/gtest/gtest-printers.h: At global scope: /usr/local/include/gtest/gtest-printers.h:740:28: error: variable or field ‘PrintTo’ declared void 740 | inline void PrintTo(::std::u32string_view s, ::std::ostream* os) { | ^~~~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:740:28: error: ‘u32string_view’ is not a member of ‘std’; did you mean ‘u32string’? 740 | inline void PrintTo(::std::u32string_view s, ::std::ostream* os) { | ^~~~~~~~~~~~~~ | u32string /usr/local/include/gtest/gtest-printers.h:740:60: error: expected primary-expression before ‘*’ token 740 | inline void PrintTo(::std::u32string_view s, ::std::ostream* os) { | ^ /usr/local/include/gtest/gtest-printers.h:740:62: error: ‘os’ was not declared in this scope 740 | inline void PrintTo(::std::u32string_view s, ::std::ostream* os) { | ^~ /usr/local/include/gtest/gtest-printers.h:746:42: error: variable or field ‘PrintWideStringTo’ declared void 746 | GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os); | ^~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:746:42: error: ‘wstring_view’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:746:72: error: expected primary-expression before ‘*’ token 746 | GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os); | ^ /usr/local/include/gtest/gtest-printers.h:746:74: error: ‘os’ was not declared in this scope 746 | GTEST_API_ void PrintWideStringTo(::std::wstring_view s, ::std::ostream* os); | ^~ /usr/local/include/gtest/gtest-printers.h: In function ‘void testing::internal::PrintTo(const wstring&, std::ostream*)’: /usr/local/include/gtest/gtest-printers.h:748:3: error: ‘PrintWideStringTo’ was not declared in this scope; did you mean ‘PrintToString’? 748 | PrintWideStringTo(s, os); | ^~~~~~~~~~~~~~~~~ | PrintToString /usr/local/include/gtest/gtest-printers.h: At global scope: /usr/local/include/gtest/gtest-printers.h:750:28: error: variable or field ‘PrintTo’ declared void 750 | inline void PrintTo(::std::wstring_view s, ::std::ostream* os) { | ^~~~~~~~~~~~ /usr/local/include/gtest/gtest-printers.h:750:28: error: ‘wstring_view’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:750:58: error: expected primary-expression before ‘*’ token 750 | inline void PrintTo(::std::wstring_view s, ::std::ostream* os) { | ^ /usr/local/include/gtest/gtest-printers.h:750:60: error: ‘os’ was not declared in this scope 750 | inline void PrintTo(::std::wstring_view s, ::std::ostream* os) { | ^~ /usr/local/include/gtest/gtest-printers.h:922:29: error: ‘any’ is not a member of ‘std’ 922 | class UniversalPrinter<std::any> { | ^~~ /usr/local/include/gtest/gtest-printers.h:922:29: note: ‘std::any’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:922:29: error: ‘any’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:922:29: note: ‘std::any’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:922:32: error: template argument 1 is invalid 922 | class UniversalPrinter<std::any> { | ^ /usr/local/include/gtest/gtest-printers.h:945:29: error: ‘optional’ is not a member of ‘std’ 945 | class UniversalPrinter<std::optional<T>> { | ^~~~~~~~ /usr/local/include/gtest/gtest-printers.h:945:29: note: ‘std::optional’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:945:29: error: ‘optional’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:945:29: note: ‘std::optional’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:945:38: error: template argument 1 is invalid 945 | class UniversalPrinter<std::optional<T>> { | ^ /usr/local/include/gtest/gtest-printers.h:945:39: error: expected unqualified-id before ‘>’ token 945 | class UniversalPrinter<std::optional<T>> { | ^~ /usr/local/include/gtest/gtest-printers.h:959:29: error: ‘nullopt_t’ is not a member of ‘std’; did you mean ‘nullptr_t’? 959 | class UniversalPrinter<std::nullopt_t> { | ^~~~~~~~~ | nullptr_t /usr/local/include/gtest/gtest-printers.h:959:29: error: ‘nullopt_t’ is not a member of ‘std’; did you mean ‘nullptr_t’? 959 | class UniversalPrinter<std::nullopt_t> { | ^~~~~~~~~ | nullptr_t /usr/local/include/gtest/gtest-printers.h:959:38: error: template argument 1 is invalid 959 | class UniversalPrinter<std::nullopt_t> { | ^ /usr/local/include/gtest/gtest-printers.h:966:29: error: ‘variant’ is not a member of ‘std’ 966 | class UniversalPrinter<std::variant<T...>> { | ^~~~~~~ /usr/local/include/gtest/gtest-printers.h:966:29: note: ‘std::variant’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:966:29: error: ‘variant’ is not a member of ‘std’ /usr/local/include/gtest/gtest-printers.h:966:29: note: ‘std::variant’ is only available from C++17 onwards /usr/local/include/gtest/gtest-printers.h:966:38: error: expected parameter pack before ‘...’ 966 | class UniversalPrinter<std::variant<T...>> { | ^~~ /usr/local/include/gtest/gtest-printers.h:966:38: error: template argument 1 is invalid /usr/local/include/gtest/gtest-printers.h:966:41: error: expected unqualified-id before ‘>’ token 966 | class UniversalPrinter<std::variant<T...>> { | ^~ In file included from /usr/local/include/gtest/gtest.h:67, from /root/anbox/external/android-emugl/shared/emugl/common/mutex_unittest.cpp:19: /usr/local/include/gtest/gtest-param-test.h:483:56: error: missing template arguments before ‘(’ token 483 | typename StdFunction = decltype(std::function(std::declval<Func>()))> | ^ /usr/local/include/gtest/gtest-param-test.h:493:56: error: missing template arguments before ‘(’ token 493 | typename StdFunction = decltype(std::function(std::declval<Func>()))> | ^ make[2]: *** [external/android-emugl/shared/emugl/common/CMakeFiles/emugl_common.dir/build.make:146: external/android-emugl/shared/emugl/common/CMakeFiles/emugl_common.dir/mutex_unittest.cpp.o] Error 1 make[1]: *** [CMakeFiles/Makefile2:1510: external/android-emugl/shared/emugl/common/CMakeFiles/emugl_common.dir/all] Error 2 make: *** [Makefile:146: all] Error 2
2.1 解决思路
#升级c++版本到17
修改项目的 CMakeLists.txt
#
[root@ubuntu2004 ~/anbox/build]#head -n10 ../CMakeLists.txt
project(anbox C CXX)
cmake_minimum_required(VERSION 2.8.2) #添加此行之后
#添加以下三行
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)include(CTest)
include(GNUInstallDirs)#链接阶段没找到 gtest 的库文件(libgtest.a 或 libgtest.so)
sudo apt install libgtest-dev
##Ubuntu 的 libgtest-dev 只包含源码,需要自己编译安装:
cd /usr/src/googletest
sudo cmake .
sudo make
sudo cp lib/*.a /usr/lib
[root@ubuntu2004 /usr/src/googletest]#ls /usr/lib/libgtest*
/usr/lib/libgtest.a /usr/lib/libgtest_main.a#执行之后重新编译
[root@ubuntu2004 ~]# cd ~/anbox/build
[root@ubuntu2004 ~/anbox/build]# make -j$(nproc)
##在 CMake 中手动链接 gtest 库,上面的方式仍然报同样错误,可以直接在测试的 CMakeLists.txt 中显式添加链接指令
[root@ubuntu2004 ~]# vim anbox/tests/anbox/android/CMakeLists.txt
#...
add_executable(intent_tests intent_tests.cpp) #定义测试可执行文件的部分
target_link_libraries(intent_tests gtest gtest_main pthread) #添加此行#再次重新编译
cd ~/anbox/build
make -j$(nproc)#禁用测试模块
##临时禁用
cmake .. -DENABLE_TESTS=OFF
make -j$(nproc)##永久禁用
[root@ubuntu2004 ~/anbox]#vim CMakeLists.txt
#...add_subdirectory(src)
#add_subdirectory(tests) #注释掉此行
add_subdirectory(android)
2.2 再次make编译,并继续执行步骤
root@ubuntu2004 ~/anbox/build]#make -j$(nproc)
#...[ 95%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/daemon.cpp.o
[ 96%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/logger.cpp.o
[ 96%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/not_reachable.cpp.o
[ 97%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/utils.cpp.o
[ 97%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/runtime.cpp.o
[ 97%] Building CXX object src/CMakeFiles/anbox-core.dir/anbox/system_configuration.cpp.o
[ 98%] Linking CXX static library libanbox-core.a
[ 98%] Built target anbox-core
[100%] Building CXX object src/CMakeFiles/anbox.dir/main.cpp.o
[100%] Linking CXX executable anbox
[100%] Built target anbox #显示以上内容表示成功#make install
[root@ubuntu2004 ~/anbox/build]#make install
[ 4%] Built target sdbus-cpp
[ 13%] Built target process-cpp
[ 16%] Built target emugen
[ 17%] Built target OpenglCodecCommon
[ 19%] Built target GLESv1_dec
[ 21%] Built target GLESv2_dec
[ 28%] Built target emugl_common
[ 31%] Built target OpenGLESDispatch
[ 32%] Built target renderControl_dec
[ 34%] Built target xdg
[ 35%] Built target xdg_test
[ 35%] Built target backward_object
[ 36%] Built target backward
[ 39%] Built target anbox-protobuf
[ 40%] Built target utils
[ 41%] Built target cpu_features
[ 98%] Built target anbox-core
[100%] Built target anbox
Install the project...
-- Install configuration: "RelWithDebInfo"
-- Installing: /usr/local/share/anbox/ui/loading-screen.png
-- Installing: /usr/local/include/backward.hpp
-- Installing: /usr/local/lib/backward/BackwardConfig.cmake
-- Installing: /usr/local/bin/anbox
-- Set runtime path of "/usr/local/bin/anbox" to ""[root@ubuntu2004 ~]# anbox -help
the option '--command' is required but missing
NAME:anbox - anboxUSAGE:anbox [command options] [arguments...]COMMANDS:check-features Check that the host system supports all necessary features wait-ready Wait until the Android system has successfully booted system-info Print various information about the system we're running on launch Launch an Activity by sending an intent session-manager Run the the anbox session manager version Print the version of the daemon help Print a short help message