Android build support (#1136)

This commit is contained in:
QxQ 2020-12-01 16:42:50 +08:00 committed by GitHub
parent 07fc8ce594
commit 098c00ebac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 154 additions and 34 deletions

92
.github/workflows/build-android.yml vendored Normal file
View File

@ -0,0 +1,92 @@
name: Build Android APK
on:
push:
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildtype: [Debug, Release]
arch: [x86, x86_64, arm, arm64]
qt_version: [5.15.0]
include:
- arch: x86
long_arch: x86
short_arch: x86
- arch: x86_64
long_arch: x86_64
short_arch: x64
- arch: arm
long_arch: armeabi-v7a
short_arch: arm
- arch: arm64
long_arch: arm64-v8a
short_arch: arm64
- buildtype: Debug
lowercase_buildtype: debug
- buildtype: Release
lowercase_buildtype: release
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Display Workflow Information
run: |
echo "Build Type: ${{ matrix.buildtype }}, Architecture: ${{ matrix.long_arch }}"
- name: Cache Qt
id: cache-qt
uses: actions/cache@v1
with:
path: ../Qt
key: QtCache-${{ matrix.buildtype }}-${{ matrix.arch }}-${{ matrix.qt_version }}
- name: Installing Qt - ${{ matrix.arch }}
uses: jurplel/install-qt-action@v2
with:
version: ${{ matrix.qt_version }}
target: android
cached: ${{ steps.cache-qt.outputs.cache-hit }}
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r21d
- name: Download Dependencies
run: |
sudo apt install -y ninja-build
cd ./libs
QV2RAY_LIBS=android QV2RAY_LIBS_ARCH="${{ matrix.short_arch }}" ./setup-libs.sh
QV2RAY_LIBS=tools ./setup-libs.sh
- name: Build Qv2ray
run: |
set
mkdir build
cd build
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} \
-DCMAKE_PREFIX_PATH=$Qt5_DIR \
-DCMAKE_FIND_ROOT_PATH=$Qt5_DIR \
-DCMAKE_TOOLCHAIN_FILE=${{ steps.setup-ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake \
-DANDROID_NATIVE_API_LEVEL=23 \
-DANDROID_SDK=$ANDROID_SDK_ROOT \
-DANDROID_NDK=${{ steps.setup-ndk.outputs.ndk-path }} \
-DANDROID_ABI=${{ matrix.long_arch }} \
-DANDROID_STL=c++_shared
cmake --build . --parallel $(nproc)
- name: Build APK
run: |
cd build/
androiddeployqt --output ./android-build/ --input ./android_deployment_settings.json --${{ matrix.lowercase_buildtype }}
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: Qv2ray.${{ github.sha }}.Android-${{ matrix.long_arch }}.qt${{ matrix.qt_version }}-${{ matrix.buildtype }}.zip
path: build/android-build/build/outputs/apk/${{ matrix.lowercase_buildtype }}/

3
.gitmodules vendored
View File

@ -31,3 +31,6 @@
[submodule "3rdparty/QCodeEditor"]
path = 3rdparty/QCodeEditor
url = https://github.com/cpeditor/QCodeEditor
[submodule "3rdparty/android_openssl"]
path = 3rdparty/android_openssl
url = https://github.com/KDAB/android_openssl

1
3rdparty/android_openssl vendored Submodule

@ -0,0 +1 @@
Subproject commit fb472b74cb437fbfd6cbb676a7ba07a27a982688

View File

@ -40,19 +40,19 @@ endif()
if(ANDROID)
set(ANDROID_PACKAGE_SOURCE ${CMAKE_SOURCE_DIR}/assets/android)
set(QT_ANDROID_PACKAGE_SOURCE_DIR "\"android-package-source-directory\":\"${ANDROID_PACKAGE_SOURCE}\",")
message("Configuring for Android, ABI: ${ANDROID_ABI}")
message("Configuring for Android ABI ${CMAKE_ANDROID_ARCH}")
if(NOT ANDROID_SDK)
set(ANDROID_SDK $ENV{ANDROID_SDK_ROOT})
endif()
include(${ANDROID_SDK}/android_openssl/CMakeLists.txt)
set(ANDROID_LIB_ARCH ${CMAKE_ANDROID_ARCH})
if(${ANDROID_LIB_ARCH} STREQUAL "x86_64")
set(ANDROID_LIB_ARCH "x64")
endif()
message("Android SDK: ${ANDROID_SDK}, ${CMAKE_ANDROID_ARCH}")
message("Android SDK: ${ANDROID_SDK}")
set(QV2RAY_PLATFORM_LIBS_BIN_PATH_PREFIX ${CMAKE_SOURCE_DIR}/libs/tools)
set(QV2RAY_PLATFORM_LIBS_PATH_PREFIX ${CMAKE_SOURCE_DIR}/libs/${ANDROID_LIB_ARCH}-android)
include(cmake/platforms/prefixes.cmake)
include(cmake/platforms/android.cmake)
set(APK_PACKAGE_NAME "net.qv2ray.qv2ray")
set(APK_PACKAGE_VERSION "v${QV2RAY_VERSION_STRING}")
set(APK_DISPLAY_NAME "Qv2ray")
@ -337,6 +337,7 @@ endif()
if(QV2RAY_HAS_BUILTIN_SUBSCRIPTION_PLUGIN)
include(src/plugins/subscription-adapters/QvPlugin-BuiltinSubscriptionAdapters.cmake)
endif()
# ==================================================================================
# Qv2ray UI Frontend
# ==================================================================================
@ -396,6 +397,7 @@ QVLOG(QV2RAY_QM_FILES)
QVLOG(QV2RAY_QRC_RESOURCES)
if(ANDROID)
QVLOG(ANDROID_EXTRA_LIBS)
add_library(qv2ray SHARED ${QV2RAY_FULL_SOURCES})
else()
include(cmake/backward-cpp.cmake)

View File

@ -1,5 +1,9 @@
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
find_package(gRPC CONFIG QUIET)
# Debian, for example, cannot find gRPC in a proper way.
# This is used as a fallback searching method
if(NOT gRPC_FOUND)
if(WIN32)
message(FATAL_ERROR "gRPC Not Found")

View File

@ -1,7 +1,10 @@
if(ANDROID)
set(CURL_LIBRARIES -lcurl -lssl -lcrypto -lz)
elseif(WIN32)
if(WIN32)
set(CURL_LIBRARIES libcurl libssl libcrypto zlib)
endif()
find_package(CURL REQUIRED)
if(ANDROID)
find_package(OpenSSL REQUIRED)
set(CURL_LIBRARIES CURL::libcurl OpenSSL::SSL OpenSSL::Crypto)
endif()

View File

@ -0,0 +1,20 @@
macro(add_android_full_lib libname)
message("Adding ${libname}")
list(APPEND ANDROID_EXTRA_LIBS ${libname})
endmacro()
QVLOG(CMAKE_ANDROID_ARCH)
if(CMAKE_BUILD_TYPE EQUAL "DEBUG")
set (SSL_ROOT_PATH "${CMAKE_SOURCE_DIR}/3rdparty/android_openssl/no-asm/latest")
else()
set (SSL_ROOT_PATH "${CMAKE_SOURCE_DIR}/3rdparty/android_openssl/latest")
endif()
add_android_full_lib("${SSL_ROOT_PATH}/arm/libcrypto_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/arm/libssl_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/arm64/libcrypto_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/arm64/libssl_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/x86/libcrypto_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/x86/libssl_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/x86_64/libcrypto_1_1.so")
add_android_full_lib("${SSL_ROOT_PATH}/x86_64/libssl_1_1.so")

View File

@ -2,7 +2,6 @@ if(NOT QV2RAY_PLATFORM_LIBS_BIN_PATH_PREFIX)
set(QV2RAY_PLATFORM_LIBS_BIN_PATH_PREFIX ${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}/tools)
endif()
list(APPEND CMAKE_PROGRAM_PATH
${QV2RAY_PLATFORM_LIBS_BIN_PATH_PREFIX}/grpc/
${QV2RAY_PLATFORM_LIBS_BIN_PATH_PREFIX}/protobuf/
@ -24,8 +23,9 @@ if(NOT DEFINED CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO)
message(STATUS "CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO set to RelWithDebInfo;Release;")
endif()
QVLOG(QV2RAY_PLATFORM_LIBS_PATH_PREFIX)
if(CMAKE_BUILD_TYPE MATCHES "^[Dd][Ee][Bb][Uu][Gg]$" OR NOT DEFINED CMAKE_BUILD_TYPE)
#Debug build: Put Debug paths before Release paths.
# Debug build: Put Debug paths before Release paths.
list(APPEND CMAKE_PREFIX_PATH
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}/debug
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}
@ -39,14 +39,9 @@ if(CMAKE_BUILD_TYPE MATCHES "^[Dd][Ee][Bb][Uu][Gg]$" OR NOT DEFINED CMAKE_BUILD_
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}
)
else()
#Release build: Put Release paths before Debug paths. Debug Paths are required so that CMake generates correct info in autogenerated target files.
list(APPEND CMAKE_PREFIX_PATH
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}
)
link_directories(
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}/lib
)
list(APPEND CMAKE_FIND_ROOT_PATH
${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}
)
# Release build: Put Release paths before Debug paths.
# Debug Paths are required so that CMake generates correct info in autogenerated target files.
list(APPEND CMAKE_PREFIX_PATH ${QV2RAY_PLATFORM_LIBS_PATH_PREFIX})
link_directories(${QV2RAY_PLATFORM_LIBS_PATH_PREFIX}/lib)
list(APPEND CMAKE_FIND_ROOT_PATH ${QV2RAY_PLATFORM_LIBS_PATH_PREFIX})
endif()

View File

@ -1 +1 @@
6052
6058

View File

@ -8,4 +8,5 @@ QvVPNService::QvVPNService(int &argc, char *argv[]) : QAndroidService(argc, argv
QAndroidBinder *QvVPNService::onBind(const QAndroidIntent &intent)
{
return nullptr;
}

View File

@ -19,13 +19,13 @@ Qv2rayQMLApplication::Qv2rayQMLApplication(int &argc, char *argv[]) : Qv2rayPlat
{
}
void Qv2rayQMLApplication::MessageBoxWarn(QWidget *parent, const QString &title, const QString &text, MessageOpt button)
void Qv2rayQMLApplication::MessageBoxWarn(QWidget *parent, const QString &title, const QString &text)
{
QMessageBox::warning(parent, title, text, MessageBoxButtonMap[button]);
QMessageBox::warning(parent, title, text);
}
void Qv2rayQMLApplication::MessageBoxInfo(QWidget *parent, const QString &title, const QString &text, MessageOpt button)
void Qv2rayQMLApplication::MessageBoxInfo(QWidget *parent, const QString &title, const QString &text)
{
QMessageBox::information(parent, title, text, MessageBoxButtonMap[button]);
QMessageBox::information(parent, title, text);
}
MessageOpt Qv2rayQMLApplication::MessageBoxAsk(QWidget *parent, const QString &title, const QString &text, const QList<MessageOpt> &list)
@ -38,14 +38,13 @@ MessageOpt Qv2rayQMLApplication::MessageBoxAsk(QWidget *parent, const QString &t
return MessageBoxButtonMap.key(QMessageBox::question(parent, title, text, btns));
}
Qv2raySetupStatus Qv2rayQMLApplication::Initialize()
QStringList Qv2rayQMLApplication::checkPrerequisitesInternal()
{
return InitializeInternal();
return {};
}
Qv2rayExitCode Qv2rayQMLApplication::RunQv2ray()
Qv2rayExitReason Qv2rayQMLApplication::runQv2rayInternal()
{
RunInternal();
QQuickStyle::setStyle("Material");
QQmlApplicationEngine engine;
const QUrl url("qrc:/forms/MainWindow.qml");
@ -83,10 +82,10 @@ Qv2rayExitCode Qv2rayQMLApplication::RunQv2ray()
QList<QQmlError> warnings;
node.usePreloadedDocument(applicationDirPath() + "/forms/MainWindow.qml", window, warnings);
#endif
return (Qv2rayExitCode) exec();
return (Qv2rayExitReason) exec();
}
void Qv2rayQMLApplication::TerminateUI()
void Qv2rayQMLApplication::terminateUIInternal()
{
}

View File

@ -11,15 +11,15 @@ namespace Qv2ray
Q_OBJECT
public:
explicit Qv2rayQMLApplication(int &argc, char *argv[]);
void MessageBoxWarn(QWidget *parent, const QString &title, const QString &text, MessageOpt button = OK) override;
void MessageBoxInfo(QWidget *parent, const QString &title, const QString &text, MessageOpt button = OK) override;
void MessageBoxWarn(QWidget *parent, const QString &title, const QString &text) override;
void MessageBoxInfo(QWidget *parent, const QString &title, const QString &text) override;
MessageOpt MessageBoxAsk(QWidget *parent, const QString &title, const QString &text, const QList<MessageOpt> &buttons) override;
Qv2raySetupStatus Initialize() override;
Qv2rayExitCode RunQv2ray() override;
QStringList checkPrerequisitesInternal() override;
Qv2rayExitReason runQv2rayInternal() override;
void terminateUIInternal() override;
void OpenURL(const QString &url) override;
private slots:
void TerminateUI() override;
#ifndef QV2RAY_NO_SINGLEAPPLICATON
void onMessageReceived(quint32, QByteArray) override;
#endif