mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-02 08:33:38 +02:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fa72d8de43 | |||
| e43973f8ad | |||
| 8d28beacd8 | |||
| 495d59da07 | |||
| 528015d17e | |||
| 55237f951e | |||
| 1b4f3d5872 | |||
| 8eefe7d26b | |||
| fd34bf08f1 | |||
| a7734d6093 | |||
| 526a7cad89 | |||
| 13955dd36b | |||
| d81c1e5c1a | |||
| 3ad6a7a46d | |||
| de5e2635e3 | |||
| b08154671e | |||
| af2ade1d20 | |||
| f456db5392 | |||
| ea71e9b87d | |||
| 7f3a4aaa14 | |||
| 7c455591f6 | |||
| f8e229ff7b | |||
| b033fefa31 | |||
| aab0927242 | |||
| ca8164fde4 | |||
| 7efb532bc9 | |||
| 98915b3cf2 | |||
| fa5076dff0 | |||
| dbb918b68c | |||
| 5078d1a2ca | |||
| 6907886c44 | |||
| 2f01aac483 | |||
| b94cddcb1c | |||
| 2b5c2cb021 | |||
| 729d6ee6d3 | |||
| cd87253844 | |||
| 8cdaa0c2ee | |||
| d563d66b28 | |||
| 37327e30d3 | |||
| e0af63ce1c | |||
| 041d0fcab5 | |||
| 2a6960a4fb | |||
| 8481367fb6 | |||
| 70d6f9996d | |||
| 616d58e901 | |||
| 0bfbd82536 | |||
| 544ad4ba6e |
@@ -0,0 +1,56 @@
|
||||
# .github/actions/setup-keychain/action.yml
|
||||
name: Setup apple keychain
|
||||
description: Creates and configures a temporary build keychain
|
||||
|
||||
inputs:
|
||||
keychain-path:
|
||||
description: Name of the keychain
|
||||
required: true
|
||||
keychain-password:
|
||||
description: Temporary keychain password
|
||||
required: true
|
||||
app-cert-base64:
|
||||
description: Base64-encoded P12 app certificate
|
||||
required: true
|
||||
app-cert-password:
|
||||
description: Application certificate password
|
||||
required: true
|
||||
installer-cert-base64:
|
||||
description: Base64-encoded P12 installer certificate
|
||||
required: true
|
||||
installer-cert-password:
|
||||
description: Installer certificate password
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Create keychain
|
||||
shell: bash
|
||||
env:
|
||||
KEYCHAIN_PATH: ${{ inputs.keychain-path }}
|
||||
KEYCHAIN_PASSWORD: ${{ inputs.keychain-password }}
|
||||
APP_CERT_BASE64: ${{ inputs.app-cert-base64 }}
|
||||
APP_CERT_PASSWORD: ${{ inputs.app-cert-password }}
|
||||
INSTALLER_CERT_BASE64: ${{ inputs.installer-cert-base64 }}
|
||||
INSTALLER_CERT_PASSWORD: ${{ inputs.installer-cert-password }}
|
||||
run: |
|
||||
set -e
|
||||
|
||||
APP_CERT_PATH=$RUNNER_TEMP/DeveloperIdApplicationCertificate.p12
|
||||
INSTALLER_CERT_PATH=$RUNNER_TEMP/DeveloperIdInstallerCertificate.p12
|
||||
|
||||
echo -n "$APP_CERT_BASE64" | base64 --decode -o "$APP_CERT_PATH"
|
||||
echo -n "$INSTALLER_CERT_BASE64" | base64 --decode -o "$INSTALLER_CERT_PATH"
|
||||
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security default-keychain -s "$KEYCHAIN_PATH"
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
|
||||
security import "${{ github.action_path }}/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -A
|
||||
security import "$APP_CERT_PATH" -k "$KEYCHAIN_PATH" -P "$APP_CERT_PASSWORD" -A -t cert -f pkcs12
|
||||
security import "$INSTALLER_CERT_PATH" -k "$KEYCHAIN_PATH" -P "$INSTALLER_CERT_PASSWORD" -A -t cert -f pkcs12
|
||||
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
||||
+95
-202
@@ -38,7 +38,18 @@ jobs:
|
||||
set-env: 'true'
|
||||
aqtversion: '==3.3.0'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install conan'
|
||||
run: pip install "conan==2.26.2"
|
||||
|
||||
- name: 'Install system packages'
|
||||
run: sudo apt-get install libxkbcommon-x11-0 libsecret-1-dev
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
@@ -46,38 +57,17 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Get version from CMakeLists.txt'
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
sudo apt-get install libxkbcommon-x11-0 libsecret-1-dev
|
||||
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64/bin
|
||||
export QIF_BIN_DIR=${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin
|
||||
bash deploy/build_linux.sh
|
||||
|
||||
- name: 'Pack installer'
|
||||
run: cd deploy && tar -cf AmneziaVPN_Linux_Installer.tar AmneziaVPN_Linux_Installer.bin && zip AmneziaVPN_${VERSION}_linux_x64.tar.zip AmneziaVPN_Linux_Installer.tar
|
||||
shell: bash
|
||||
env:
|
||||
QT_INSTALL_DIR: ${{ runner.temp }}
|
||||
run: ./deploy/build.sh
|
||||
|
||||
- name: 'Upload installer artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip
|
||||
path: deploy/AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload unpacked artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_Linux_unpacked
|
||||
path: deploy/AppDir
|
||||
path: deploy/build/AmneziaVPN-*-Linux.run
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload translations artifact'
|
||||
@@ -95,7 +85,6 @@ jobs:
|
||||
env:
|
||||
QT_VERSION: 6.10.1
|
||||
QIF_VERSION: 4.7
|
||||
BUILD_ARCH: 64
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||
@@ -111,17 +100,6 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Get version from CMakeLists.txt'
|
||||
id: get_version
|
||||
shell: bash
|
||||
run: |
|
||||
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Install Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
@@ -158,39 +136,34 @@ jobs:
|
||||
$wixBinDir = Join-Path $env:USERPROFILE ".dotnet\tools"
|
||||
echo "WIX_BIN_DIR=$wixBinDir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install conan'
|
||||
run: pip install "conan==2.26.2"
|
||||
|
||||
- name: 'Build project'
|
||||
shell: cmd
|
||||
env:
|
||||
QT_INSTALL_DIR: ${{ runner.temp }}
|
||||
run: |
|
||||
set BUILD_ARCH=${{ env.BUILD_ARCH }}
|
||||
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2022_64\\bin"
|
||||
set QIF_BIN_DIR="${{ runner.temp }}\\Qt\\Tools\\QtInstallerFramework\\${{ env.QIF_VERSION }}\\bin"
|
||||
set WIX_BIN_DIR=%USERPROFILE%\.dotnet\tools
|
||||
call deploy\\build_windows.bat
|
||||
set WIX_ROOT_PATH="${{ env.USERPROFILE }}\.dotnet\tools"
|
||||
deploy\build.bat --installer all
|
||||
|
||||
- name: 'Rename Windows installer'
|
||||
shell: cmd
|
||||
run: |
|
||||
copy AmneziaVPN_x${{ env.BUILD_ARCH }}.exe AmneziaVPN_%VERSION%_x64.exe
|
||||
|
||||
- name: 'Upload installer artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: 'Upload WIX installer artifact'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: AmneziaVPN_${{ env.VERSION }}_x64.exe
|
||||
path: AmneziaVPN_${{ env.VERSION }}_x64.exe
|
||||
path: deploy/build/AmneziaVPN-*-win64.msi
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload MSI installer artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
- name: 'Upload IFW installer artifact'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: AmneziaVPN_Windows_MSI_installer
|
||||
path: AmneziaVPN_x${{ env.BUILD_ARCH }}.msi
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload unpacked artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_Windows_unpacked
|
||||
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release
|
||||
path: deploy/build/AmneziaVPN-*-win64.exe
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
@@ -258,11 +231,13 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: pip install jsonschema jinja2
|
||||
- name: 'Install deps'
|
||||
run: pip install "conan==2.26.2" jsonschema jinja2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -285,93 +260,6 @@ jobs:
|
||||
IOS_APP_PROVISIONING_PROFILE: ${{ secrets.IOS_APP_PROVISIONING_PROFILE }}
|
||||
IOS_NE_PROVISIONING_PROFILE: ${{ secrets.IOS_NE_PROVISIONING_PROFILE }}
|
||||
|
||||
# - name: 'Upload appstore .ipa and dSYMs to artifacts'
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: app-store ipa & dsyms
|
||||
# path: |
|
||||
# ${{ github.workspace }}/AmneziaVPN-iOS.ipa
|
||||
# ${{ github.workspace }}/*.app.dSYM.zip
|
||||
# retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-MacOS-old:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
|
||||
QT_VERSION: 6.4.3
|
||||
|
||||
MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
|
||||
|
||||
MAC_APP_CERT_CERT: ${{ secrets.MAC_APP_CERT_CERT }}
|
||||
MAC_SIGNER_ID: ${{ secrets.MAC_SIGNER_ID }}
|
||||
MAC_APP_CERT_PW: ${{ secrets.MAC_APP_CERT_PW }}
|
||||
|
||||
MAC_INSTALLER_SIGNER_CERT: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
|
||||
MAC_INSTALLER_SIGNER_ID: ${{ secrets.MAC_INSTALLER_SIGNER_ID }}
|
||||
MAC_INSTALL_CERT_PW: ${{ secrets.MAC_INSTALL_CERT_PW }}
|
||||
|
||||
APPLE_DEV_EMAIL: ${{ secrets.APPLE_DEV_EMAIL }}
|
||||
APPLE_DEV_PASSWORD: ${{ secrets.APPLE_DEV_PASSWORD }}
|
||||
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup xcode'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '15.4.0'
|
||||
|
||||
- name: 'Install Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
host: 'mac'
|
||||
target: 'desktop'
|
||||
arch: 'clang_64'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||
dir: ${{ runner.temp }}
|
||||
setup-python: 'true'
|
||||
set-env: 'true'
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||
bash deploy/build_macos.sh -n
|
||||
|
||||
- name: 'Upload installer artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_MacOS_old_installer
|
||||
path: deploy/build/pkg/AmneziaVPN.pkg
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload unpacked artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_MacOS_old_unpacked
|
||||
path: deploy/build/client/AmneziaVPN.app
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-MacOS:
|
||||
@@ -379,19 +267,8 @@ jobs:
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.10.1
|
||||
|
||||
MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
|
||||
|
||||
MAC_APP_CERT_CERT: ${{ secrets.MAC_APP_CERT_CERT }}
|
||||
MAC_SIGNER_ID: ${{ secrets.MAC_SIGNER_ID }}
|
||||
MAC_APP_CERT_PW: ${{ secrets.MAC_APP_CERT_PW }}
|
||||
|
||||
MAC_INSTALLER_SIGNER_CERT: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
|
||||
MAC_INSTALLER_SIGNER_ID: ${{ secrets.MAC_INSTALLER_SIGNER_ID }}
|
||||
MAC_INSTALL_CERT_PW: ${{ secrets.MAC_INSTALL_CERT_PW }}
|
||||
|
||||
APPLE_DEV_EMAIL: ${{ secrets.APPLE_DEV_EMAIL }}
|
||||
APPLE_DEV_PASSWORD: ${{ secrets.APPLE_DEV_PASSWORD }}
|
||||
KEYCHAIN_NAME: "build.keychain"
|
||||
KEYCHAIN_PASSWORD: ""
|
||||
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||
@@ -420,7 +297,15 @@ jobs:
|
||||
set-env: 'true'
|
||||
aqtversion: '==3.3.0'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install conan'
|
||||
run: pip install "conan==2.26.2"
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
@@ -428,39 +313,34 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Get version from CMakeLists.txt'
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: 'Install certs'
|
||||
uses: ./.github/actions/setup-keychain
|
||||
with:
|
||||
keychain-path: ${{ env.KEYCHAIN_NAME }}
|
||||
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
|
||||
app-cert-base64: ${{ secrets.MAC_APP_CERT_CERT }}
|
||||
app-cert-password: ${{ secrets.MAC_APP_CERT_PW }}
|
||||
installer-cert-base64: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
|
||||
installer-cert-password: ${{ secrets.MAC_INSTALL_CERT_PW }}
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||
bash deploy/build_macos.sh -n
|
||||
|
||||
- name: 'Pack macOS installer'
|
||||
run: |
|
||||
cd deploy/build/pkg
|
||||
zip -r ../../AmneziaVPN_${VERSION}_macos.zip AmneziaVPN.pkg
|
||||
cd ../../..
|
||||
env:
|
||||
QT_INSTALL_DIR: ${{ runner.temp }}
|
||||
CODESIGN_KEYCHAIN: ${{ env.KEYCHAIN_NAME }}
|
||||
CODESIGN_SIGNATURE: ${{ secrets.MAC_SIGNER_ID }}
|
||||
CODESIGN_INSTALLER_KEYCHAIN: ${{ env.KEYCHAIN_NAME }}
|
||||
CODESIGN_INSTALLER_SIGNATURE: ${{ secrets.MAC_INSTALLER_SIGNER_ID }}
|
||||
NOTARYTOOL_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
|
||||
NOTARYTOOL_EMAIL: ${{ secrets.APPLE_DEV_EMAIL }}
|
||||
NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_DEV_PASSWORD }}
|
||||
shell: bash
|
||||
run: deploy/build.sh
|
||||
|
||||
- name: 'Upload installer artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: AmneziaVPN_${{ env.VERSION }}_macos.zip
|
||||
path: deploy/AmneziaVPN_${{ env.VERSION }}_macos.zip
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload unpacked artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_MacOS_unpacked
|
||||
path: deploy/build/client/AmneziaVPN.app
|
||||
path: deploy/build/AmneziaVPN-*-Darwin.pkg
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
Build-MacOS-NE:
|
||||
@@ -519,8 +399,13 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install conan'
|
||||
run: pip install "conan==2.26.2"
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -652,6 +537,14 @@ jobs:
|
||||
run: |
|
||||
echo $KEYSTORE_BASE64 | base64 --decode > android.keystore
|
||||
|
||||
- name: 'Setup python'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: 'Install conan'
|
||||
run: pip install "conan==2.26.2"
|
||||
|
||||
- name: 'Build project'
|
||||
env:
|
||||
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
+13
-36
@@ -3,6 +3,13 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
set(PROJECT AmneziaVPN)
|
||||
set(AMNEZIAVPN_VERSION 4.8.13.1)
|
||||
|
||||
set(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP ON CACHE BOOL "" FORCE)
|
||||
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
|
||||
${CMAKE_SOURCE_DIR}/cmake/platform_settings.cmake
|
||||
${CMAKE_SOURCE_DIR}/cmake/recipes_bootstrap.cmake
|
||||
${CMAKE_SOURCE_DIR}/cmake/conan_provider.cmake
|
||||
CACHE STRING "" FORCE)
|
||||
|
||||
project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
@@ -24,6 +31,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
|
||||
set(MZ_PLATFORM_NAME "android")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
|
||||
set(MZ_PLATFORM_NAME "ios")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
||||
set(MZ_PLATFORM_NAME "ios")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
|
||||
set(MZ_PLATFORM_NAME "wasm")
|
||||
endif()
|
||||
@@ -33,7 +42,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(APPLE)
|
||||
if(IOS)
|
||||
if(IOS OR CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
elseif(MACOS_NE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
|
||||
@@ -44,42 +53,10 @@ endif()
|
||||
|
||||
add_subdirectory(client)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
add_subdirectory(service)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
|
||||
endif()
|
||||
|
||||
set(AMNEZIA_STAGE_DIR "${CMAKE_BINARY_DIR}/stage")
|
||||
|
||||
if(WIN32 AND NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
file(TO_CMAKE_PATH "${AMNEZIA_STAGE_DIR}" AMNEZIA_STAGE_DIR_CMAKE)
|
||||
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_WIX_VERSION 4)
|
||||
set(CPACK_PACKAGE_NAME "AmneziaVPN")
|
||||
set(CPACK_PACKAGE_VENDOR "AmneziaVPN")
|
||||
set(CPACK_PACKAGE_VERSION ${AMNEZIAVPN_VERSION})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "AmneziaVPN client")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "AmneziaVPN")
|
||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "AmneziaVPN" "AmneziaVPN")
|
||||
set(CPACK_WIX_UPGRADE_GUID "{2D55AC62-96D6-4692-8C05-0D85BBF95485}")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/client/images/app.ico")
|
||||
|
||||
# WiX patches
|
||||
set(_AMNEZIA_WIX_PATCH_SERVICE "${CMAKE_SOURCE_DIR}/deploy/installer/wix/service_install_patch.xml")
|
||||
set(_AMNEZIA_WIX_PATCH_CLOSE_APP "${CMAKE_SOURCE_DIR}/deploy/installer/wix/close_client_patch.xml")
|
||||
file(TO_CMAKE_PATH "${_AMNEZIA_WIX_PATCH_SERVICE}" _AMNEZIA_WIX_PATCH_SERVICE_CMAKE)
|
||||
file(TO_CMAKE_PATH "${_AMNEZIA_WIX_PATCH_CLOSE_APP}" _AMNEZIA_WIX_PATCH_CLOSE_APP_CMAKE)
|
||||
set(CPACK_WIX_PATCH_FILE "${_AMNEZIA_WIX_PATCH_SERVICE_CMAKE};${_AMNEZIA_WIX_PATCH_CLOSE_APP_CMAKE}")
|
||||
|
||||
# WiX v4 Util extension for CloseApplication + namespace for util
|
||||
set(CPACK_WIX_EXTENSIONS "${CPACK_WIX_EXTENSIONS};WixToolset.Util.wixext")
|
||||
set(CPACK_WIX_CUSTOM_XMLNS "util=http://wixtoolset.org/schemas/v4/wxs/util")
|
||||
|
||||
set(CPACK_INSTALLED_DIRECTORIES "${AMNEZIA_STAGE_DIR_CMAKE};/")
|
||||
|
||||
include(CPack)
|
||||
if ((LINUX AND NOT ANDROID) OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (WIN32))
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/CPack.cmake)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
# AmneziaVPN Apple TV Build
|
||||
|
||||
This document describes how to build the current branch for Apple TV from the repository root.
|
||||
|
||||
The pipeline is:
|
||||
|
||||
1. Use a separately built static Qt 6.9.2 for `tvOS`.
|
||||
2. Let Conan build/provide C/C++ dependencies.
|
||||
3. Generate an Xcode project with `qt-cmake`.
|
||||
4. Build the `.app` and embedded Network Extension with `xcodebuild`.
|
||||
|
||||
Important:
|
||||
|
||||
- Run the project commands from the repository root.
|
||||
- This is a device build for `appletvos`, not a simulator build.
|
||||
- `xcodebuild build` produces `.app`.
|
||||
- `.ipa` is produced later via `archive` and `-exportArchive`.
|
||||
- The current tvOS Network Extension scope is WireGuard-only.
|
||||
- The temporary tvOS WireGuard bridge prebuilt is opt-in. The Conan recipe does not contain machine-specific fallback paths.
|
||||
- Do not initialize or update submodules just for this build. If a clean checkout has empty `client/3rd` folders, pass `AMNEZIA_THIRDPARTY_ROOT` to an already initialized read-only `client/3rd` tree.
|
||||
|
||||
## 1. Environment
|
||||
|
||||
Set these paths for your machine:
|
||||
|
||||
```bash
|
||||
export REPO_ROOT="$PWD"
|
||||
export QT_DESKTOP_PREFIX="$HOME/Qt/6.9.2/macos"
|
||||
export QT_TVOS_SRC="$HOME/Qt_tv/qt-6.9.2-tvos-src"
|
||||
export QT_TVOS_PREFIX="$HOME/Qt_tv/6.9.2/tvos-device"
|
||||
export BUILD_DIR="$REPO_ROOT/build-tvos-device-conan"
|
||||
```
|
||||
|
||||
If this checkout does not have initialized `client/3rd` sources, point CMake at an initialized tree:
|
||||
|
||||
```bash
|
||||
export AMNEZIA_THIRDPARTY_ROOT="/path/to/initialized/amnezia/client/3rd"
|
||||
```
|
||||
|
||||
If you are using a temporary prebuilt tvOS WireGuard bridge, point Conan at it explicitly:
|
||||
|
||||
```bash
|
||||
export AMNEZIA_TVOS_AWG_PREBUILT_DIR="/path/to/WireGuardKitGo-appletvos"
|
||||
export AMNEZIA_TVOS_AWG_VERSION_HEADER_DIR="/path/to/directory/with/wireguard-go-version.h"
|
||||
```
|
||||
|
||||
`AMNEZIA_TVOS_AWG_PREBUILT_DIR` must contain `libwg-go.a`.
|
||||
|
||||
`AMNEZIA_TVOS_AWG_VERSION_HEADER_DIR` is optional when `wireguard-go-version.h` lives in the same directory as `libwg-go.a`.
|
||||
|
||||
If the env vars are not set, the recipe uses the normal source build path. Rebuilding and publishing the tvOS WireGuard bridge through the registry is a separate task.
|
||||
|
||||
## 2. Required Local Tools
|
||||
|
||||
Conan must be available:
|
||||
|
||||
```bash
|
||||
uv tool install conan
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
conan --version
|
||||
```
|
||||
|
||||
Validated version:
|
||||
|
||||
```text
|
||||
Conan version 2.27.1
|
||||
```
|
||||
|
||||
The build uses Xcode's AppleTVOS SDK:
|
||||
|
||||
```bash
|
||||
xcrun --sdk appletvos --show-sdk-path
|
||||
```
|
||||
|
||||
## 3. Prepare Qt Sources
|
||||
|
||||
Do not edit the installed Qt sources in place. Copy them into a separate tvOS fork:
|
||||
|
||||
```bash
|
||||
mkdir -p "$HOME/Qt_tv"
|
||||
rsync -a "$HOME/Qt/6.9.2/Src/" "$QT_TVOS_SRC/"
|
||||
```
|
||||
|
||||
Recommended for reproducibility:
|
||||
|
||||
```bash
|
||||
cd "$QT_TVOS_SRC"
|
||||
git init
|
||||
git add .
|
||||
git commit -m "Qt 6.9.2 source snapshot"
|
||||
```
|
||||
|
||||
## 4. Apply the Qt tvOS Patchset
|
||||
|
||||
Apply the local Qt tvOS patchset to `$QT_TVOS_SRC`.
|
||||
|
||||
If you need to recreate the patchset from a fresh copy, compare these files against `$HOME/Qt/6.9.2/Src` and reapply the same changes:
|
||||
|
||||
- `qtbase/cmake/QtBaseGlobalTargets.cmake`
|
||||
- `qtbase/cmake/QtBaseHelpers.cmake`
|
||||
- `qtbase/cmake/QtBuildPathsHelpers.cmake`
|
||||
- `qtbase/cmake/QtMkspecHelpers.cmake`
|
||||
- `qtbase/cmake/QtConfig.cmake.in`
|
||||
- `qtbase/mkspecs/unsupported/macx-tvos-clang/qplatformdefs.h`
|
||||
- `qtbase/src/corelib/CMakeLists.txt`
|
||||
- `qtbase/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm`
|
||||
- `qtbase/src/gui/CMakeLists.txt`
|
||||
- `qtbase/src/widgets/CMakeLists.txt`
|
||||
- `qtbase/src/network/kernel/qnetworkproxy_darwin.cpp`
|
||||
- `qtbase/src/testlib/qtestcrashhandler.cpp`
|
||||
- `qtbase/src/plugins/platforms/ios/qiosapplicationdelegate.mm`
|
||||
- `qtbase/src/plugins/platforms/ios/qiosscreen.mm`
|
||||
- `qtbase/src/plugins/platforms/ios/qiostheme.mm`
|
||||
- `qtbase/src/plugins/platforms/ios/quiview.mm`
|
||||
- `qtbase/src/plugins/platforms/ios/qiosclipboard.mm`
|
||||
|
||||
Recommended after patching:
|
||||
|
||||
```bash
|
||||
git -C "$QT_TVOS_SRC" diff > "$HOME/Qt_tv/qt-6.9.2-tvos.patch"
|
||||
```
|
||||
|
||||
Do not use `QT_APPLE_SDK=appletvos`. The working path is `CMAKE_SYSTEM_NAME=tvOS` with `CMAKE_OSX_SYSROOT=appletvos`.
|
||||
|
||||
## 5. Build Qt 6.9.2 for Apple TV
|
||||
|
||||
Only the modules required by this project are built.
|
||||
|
||||
```bash
|
||||
mkdir -p /private/tmp/qt6.9.2-tvos-device-build
|
||||
cd /private/tmp/qt6.9.2-tvos-device-build
|
||||
|
||||
"$QT_TVOS_SRC/configure" \
|
||||
-release -static -appstore-compliant \
|
||||
-nomake tests -nomake examples \
|
||||
-submodules qtbase,qtdeclarative,qtshadertools,qtremoteobjects,qtsvg,qt5compat,qttools \
|
||||
-qt-host-path "$QT_DESKTOP_PREFIX" \
|
||||
-prefix "$QT_TVOS_PREFIX" \
|
||||
-- \
|
||||
-G Ninja \
|
||||
-DQT_QMAKE_TARGET_MKSPEC=macx-tvos-clang \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_SYSROOT=appletvos \
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=17.0 \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DQT_NO_APPLE_SDK_MAX_VERSION_CHECK=ON
|
||||
|
||||
cmake --build . --parallel 8
|
||||
cmake --install .
|
||||
```
|
||||
|
||||
Sanity checks:
|
||||
|
||||
```bash
|
||||
"$QT_TVOS_PREFIX/bin/qt-cmake" --version
|
||||
"$QT_TVOS_PREFIX/bin/qmake" -query QMAKE_XSPEC
|
||||
```
|
||||
|
||||
Expected `QMAKE_XSPEC`:
|
||||
|
||||
```text
|
||||
macx-tvos-clang
|
||||
```
|
||||
|
||||
Return to the repository root after building Qt:
|
||||
|
||||
```bash
|
||||
cd "$REPO_ROOT"
|
||||
```
|
||||
|
||||
## 6. Conan Dependency Behavior
|
||||
|
||||
For `CMAKE_SYSTEM_NAME=tvOS`, the project-level Conan graph is intentionally reduced:
|
||||
|
||||
- included: `awg-apple/2.0.1`
|
||||
- included: `libssh/0.11.3@amnezia`
|
||||
- included: `openssl/3.6.1` with `no_apps=True`
|
||||
- excluded: `openvpnadapter`
|
||||
- excluded: `hev-socks5-tunnel`
|
||||
|
||||
This keeps the current Apple TV target in the same practical scope as before: app plus WireGuard-only Network Extension.
|
||||
|
||||
`libssh` is built with `WITH_EXEC=OFF` on tvOS because tvOS does not provide `fork()` or `execv()`.
|
||||
|
||||
## 7. Configure the Project
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
"$QT_TVOS_PREFIX/bin/qt-cmake" \
|
||||
-B"$BUILD_DIR" \
|
||||
-GXcode \
|
||||
-DQT_HOST_PATH="$QT_DESKTOP_PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_SYSROOT=appletvos
|
||||
```
|
||||
|
||||
If you need to provide an external initialized `client/3rd` tree:
|
||||
|
||||
```bash
|
||||
"$QT_TVOS_PREFIX/bin/qt-cmake" \
|
||||
-B"$BUILD_DIR" \
|
||||
-GXcode \
|
||||
-DQT_HOST_PATH="$QT_DESKTOP_PREFIX" \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_SYSROOT=appletvos \
|
||||
-DAMNEZIA_THIRDPARTY_ROOT="$AMNEZIA_THIRDPARTY_ROOT"
|
||||
```
|
||||
|
||||
Expected non-fatal configure warnings:
|
||||
|
||||
```text
|
||||
Warning: plug-in QIOSIntegrationPlugin is not known to the current Qt installation.
|
||||
Warning: plug-in QJpegPlugin is not known to the current Qt installation.
|
||||
...
|
||||
```
|
||||
|
||||
In this repo those warnings are tolerated because `client/cmake/ios.cmake` also links the static plugin targets explicitly when available.
|
||||
|
||||
## 8. Build the Apple TV App
|
||||
|
||||
```bash
|
||||
xcodebuild -quiet \
|
||||
-project "$BUILD_DIR/AmneziaVPN.xcodeproj" \
|
||||
-scheme AmneziaVPN \
|
||||
-configuration RelWithDebInfo \
|
||||
-sdk appletvos \
|
||||
CODE_SIGNING_ALLOWED=NO \
|
||||
build
|
||||
```
|
||||
|
||||
Outputs:
|
||||
|
||||
- `$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app`
|
||||
- `$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/PlugIns/AmneziaVPNNetworkExtension.appex`
|
||||
|
||||
Verification:
|
||||
|
||||
```bash
|
||||
file "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/AmneziaVPN"
|
||||
file "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/PlugIns/AmneziaVPNNetworkExtension.appex/AmneziaVPNNetworkExtension"
|
||||
lipo -info "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/AmneziaVPN"
|
||||
lipo -info "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/PlugIns/AmneziaVPNNetworkExtension.appex/AmneziaVPNNetworkExtension"
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
```text
|
||||
Mach-O 64-bit executable arm64
|
||||
Non-fat file: ... is architecture: arm64
|
||||
```
|
||||
|
||||
Useful plist checks:
|
||||
|
||||
```bash
|
||||
plutil -p "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/Info.plist" | rg 'CFBundleIdentifier|DTPlatformName|UIDeviceFamily|MinimumOSVersion' -C 1
|
||||
plutil -p "$BUILD_DIR/client/RelWithDebInfo-appletvos/AmneziaVPN.app/PlugIns/AmneziaVPNNetworkExtension.appex/Info.plist" | rg 'CFBundleIdentifier|NSExtension|DTPlatformName|MinimumOSVersion' -C 1
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `DTPlatformName => appletvos`
|
||||
- `UIDeviceFamily => 3`
|
||||
- `MinimumOSVersion => 17.0`
|
||||
- extension point `com.apple.networkextension.packet-tunnel`
|
||||
|
||||
## 9. `.app` vs `.ipa`
|
||||
|
||||
This is the normal sequence:
|
||||
|
||||
1. `xcodebuild build` -> `.app`
|
||||
2. `xcodebuild archive` -> `.xcarchive`
|
||||
3. `xcodebuild -exportArchive` -> `.ipa`
|
||||
|
||||
So seeing `.app` after a successful `build` is correct.
|
||||
|
||||
## 10. Optional Archive and Export
|
||||
|
||||
The commands below are the next step for packaging, but signing and provisioning must be configured first.
|
||||
|
||||
Archive:
|
||||
|
||||
```bash
|
||||
xcodebuild \
|
||||
-project "$BUILD_DIR/AmneziaVPN.xcodeproj" \
|
||||
-scheme AmneziaVPN \
|
||||
-configuration RelWithDebInfo \
|
||||
-sdk appletvos \
|
||||
-archivePath "$BUILD_DIR/AmneziaVPN-tvos.xcarchive" \
|
||||
archive
|
||||
```
|
||||
|
||||
Export:
|
||||
|
||||
```bash
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "$BUILD_DIR/AmneziaVPN-tvos.xcarchive" \
|
||||
-exportPath "$BUILD_DIR/export-tvos" \
|
||||
-exportOptionsPlist /absolute/path/to/ExportOptions.plist
|
||||
```
|
||||
|
||||
The resulting `.ipa` should appear under:
|
||||
|
||||
```text
|
||||
$BUILD_DIR/export-tvos
|
||||
```
|
||||
|
||||
## 11. Known Non-Fatal Warnings
|
||||
|
||||
The validated `xcodebuild` still prints warnings that do not break the build:
|
||||
|
||||
- missing Swift search path under the active Xcode Metal toolchain
|
||||
- `SDKROOT[sdk=...]` target-level warnings generated by Xcode project export
|
||||
- Swift conditional compilation flag warnings such as `GROUP_ID="..."`
|
||||
- asset catalog warnings because the current icon set is still iOS-shaped, not a full tvOS Top Shelf asset set
|
||||
- Go/WireGuard umbrella-header warnings from the temporary local `libwg-go.a` bridge
|
||||
- deprecated libssh SCP API warnings in existing app code
|
||||
- `qt_import_plugins()` warnings shown during configure
|
||||
|
||||
If the static platform plugin is not linked correctly, the typical failure is:
|
||||
|
||||
- `_OBJC_CLASS_$_QIOSApplicationDelegate`
|
||||
- `_qt_main_wrapper`
|
||||
|
||||
Those are cleanup tasks, not blockers for the current build proof.
|
||||
|
||||
## 12. Fast Rebuild Checklist
|
||||
|
||||
If everything is already built once:
|
||||
|
||||
1. Reuse `$QT_TVOS_PREFIX`
|
||||
2. Reuse Conan cache under `$HOME/.conan2`
|
||||
3. Reuse or pass an initialized `AMNEZIA_THIRDPARTY_ROOT`
|
||||
4. Re-run `qt-cmake` into `$BUILD_DIR`
|
||||
5. Re-run `xcodebuild -quiet ... build`
|
||||
+36
-35
@@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
set(PROJECT AmneziaVPN)
|
||||
project(${PROJECT})
|
||||
|
||||
set(AMNEZIA_THIRDPARTY_ROOT "${CMAKE_CURRENT_LIST_DIR}/3rd" CACHE PATH "Path to Amnezia client/3rd sources")
|
||||
get_filename_component(AMNEZIA_THIRDPARTY_CLIENT_ROOT "${AMNEZIA_THIRDPARTY_ROOT}/.." ABSOLUTE)
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER "Autogen")
|
||||
set_property(GLOBAL PROPERTY AUTOMOC_TARGETS_FOLDER "Autogen")
|
||||
@@ -33,7 +36,7 @@ add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
||||
add_definitions(-DFREE_V2_ENDPOINT="$ENV{FREE_V2_ENDPOINT}")
|
||||
add_definitions(-DPREM_V1_ENDPOINT="$ENV{PREM_V1_ENDPOINT}")
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
set(PACKAGES ${PACKAGES} Widgets)
|
||||
endif()
|
||||
|
||||
@@ -46,7 +49,7 @@ set(LIBS ${LIBS}
|
||||
Qt6::Core5Compat Qt6::Concurrent
|
||||
)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
set(LIBS ${LIBS} Qt6::Widgets)
|
||||
endif()
|
||||
|
||||
@@ -56,7 +59,7 @@ target_include_directories(${PROJECT} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
|
||||
endif()
|
||||
@@ -108,6 +111,7 @@ include_directories(
|
||||
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${AMNEZIA_THIRDPARTY_CLIENT_ROOT}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
@@ -175,7 +179,7 @@ if(LINUX AND NOT ANDROID)
|
||||
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
endif()
|
||||
|
||||
@@ -183,7 +187,8 @@ if(ANDROID)
|
||||
include(cmake/android.cmake)
|
||||
endif()
|
||||
|
||||
if(IOS)
|
||||
if(IOS OR CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
option(AMNEZIA_IOS_ENABLE_APPLETV_TARGET "Enable Apple TV target settings for iOS/Xcode projects" OFF)
|
||||
include(cmake/ios.cmake)
|
||||
include(cmake/ios-arch-fixup.cmake)
|
||||
elseif(APPLE AND MACOS_NE)
|
||||
@@ -196,36 +201,6 @@ endif()
|
||||
target_link_libraries(${PROJECT} PRIVATE ${LIBS})
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_$<UPPER_CASE:${MZ_PLATFORM_NAME}>")
|
||||
|
||||
# deploy artifacts required to run the application to the debug build folder
|
||||
if(WIN32)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(DEPLOY_PLATFORM_PATH "windows/x64")
|
||||
else()
|
||||
set(DEPLOY_PLATFORM_PATH "windows/x32")
|
||||
endif()
|
||||
elseif(LINUX)
|
||||
set(DEPLOY_PLATFORM_PATH "linux/client")
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(DEPLOY_PLATFORM_PATH "macos")
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_PLATFORM_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
${CMAKE_SOURCE_DIR}/client/3rd-prebuilt/deploy-prebuilt/${DEPLOY_PLATFORM_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC})
|
||||
|
||||
# Finalize the executable so Qt can gather/deploy QML modules and plugins correctly (Android needs this).
|
||||
@@ -237,3 +212,29 @@ if(COMMAND qt_finalize_executable)
|
||||
else()
|
||||
qt_finalize_target(${PROJECT})
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
install(TARGETS ${PROJECT}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
install(FILES $<TARGET_RUNTIME_DLLS:${PROJECT}>
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
|
||||
set(deploy_tool_options "")
|
||||
if(WIN32)
|
||||
set(deploy_tool_options "--force-openssl --force")
|
||||
endif()
|
||||
|
||||
qt_generate_deploy_qml_app_script(
|
||||
TARGET ${PROJECT}
|
||||
OUTPUT_SCRIPT QT_DEPLOY_SCRIPT
|
||||
NO_UNSUPPORTED_PLATFORM_ERROR
|
||||
DEPLOY_TOOL_OPTIONS ${deploy_tool_options}
|
||||
)
|
||||
install(SCRIPT ${QT_DEPLOY_SCRIPT}
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -250,7 +250,7 @@ bool AmneziaApplication::parseCommands()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
void AmneziaApplication::startLocalServer() {
|
||||
const QString serverName("AmneziaVPNInstance");
|
||||
QLocalServer::removeServer(serverName);
|
||||
@@ -271,7 +271,7 @@ void AmneziaApplication::startLocalServer() {
|
||||
bool AmneziaApplication::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Close) {
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
quit();
|
||||
#else
|
||||
if (m_forceQuit) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include <QThread>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#define AMNEZIA_BASE_CLASS QGuiApplication
|
||||
#else
|
||||
#define AMNEZIA_BASE_CLASS QApplication
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
void loadFonts();
|
||||
bool parseCommands();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
void startLocalServer();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[versions]
|
||||
agp = "8.5.2"
|
||||
agp = "8.6.1"
|
||||
kotlin = "1.9.24"
|
||||
androidx-core = "1.13.1"
|
||||
androidx-activity = "1.9.1"
|
||||
androidx-annotation = "1.8.2"
|
||||
androidx-biometric = "1.2.0-alpha05"
|
||||
androidx-camera = "1.3.4"
|
||||
androidx-camera = "1.5.3"
|
||||
androidx-fragment = "1.8.2"
|
||||
androidx-security-crypto = "1.1.0-alpha06"
|
||||
androidx-datastore = "1.1.1"
|
||||
|
||||
@@ -203,10 +203,7 @@ class AmneziaActivity : QtActivity() {
|
||||
|
||||
private fun loadLibs() {
|
||||
listOf(
|
||||
"rsapss",
|
||||
"crypto_3",
|
||||
"ssl_3",
|
||||
"ssh"
|
||||
"rsapss"
|
||||
).forEach {
|
||||
loadSharedLibrary(this.applicationContext, it)
|
||||
}
|
||||
|
||||
+12
-80
@@ -1,88 +1,19 @@
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
set(AMNEZIA_THIRDPARTY_ROOT "${CLIENT_ROOT_DIR}/3rd" CACHE PATH "Path to Amnezia client/3rd sources")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules;${CMAKE_MODULE_PATH}")
|
||||
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/SortFilterProxyModel)
|
||||
add_subdirectory(${AMNEZIA_THIRDPARTY_ROOT}/SortFilterProxyModel ${CMAKE_CURRENT_BINARY_DIR}/3rd/SortFilterProxyModel)
|
||||
set(LIBS ${LIBS} SortFilterProxyModel)
|
||||
include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
|
||||
|
||||
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.cmake)
|
||||
|
||||
set(LIBSSH_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/")
|
||||
set(OPENSSL_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/")
|
||||
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
|
||||
if(WIN32)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86_64/ssh.lib")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86_64")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
|
||||
else()
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86/ssh.lib")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
if(MACOS_NE)
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libz.a")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/macos/universal2")
|
||||
else()
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/x86_64/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/x86_64/libz.a")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/macos/x86_64")
|
||||
endif()
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libcrypto.a")
|
||||
elseif(IOS)
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/ios/arm64")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/ios/arm64/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/ios/arm64/libz.a")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/ios/iphone/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/ios/iphone/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/ios/iphone/lib/libcrypto.a")
|
||||
elseif(ANDROID)
|
||||
set(abi ${CMAKE_ANDROID_ARCH_ABI})
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/android/${abi}")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/android/${abi}/libssh.so")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/android/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/android/${abi}/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/android/${abi}/libcrypto.a")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/android/${abi}")
|
||||
elseif(LINUX)
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/linux/x86_64")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/linux/x86_64/libz.a")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/linux/x86_64/libssh.a")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/linux/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libcrypto.a")
|
||||
endif()
|
||||
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${LIBSSH_LIB_PATH}
|
||||
${ZLIB_LIB_PATH}
|
||||
)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${OPENSSL_LIB_SSL_PATH}
|
||||
${OPENSSL_LIB_CRYPTO_PATH}
|
||||
)
|
||||
include(${AMNEZIA_THIRDPARTY_ROOT}/qrcodegen/qrcodegen.cmake)
|
||||
|
||||
add_compile_definitions(_WINSOCKAPI_)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
set(BUILD_WITH_QT6 ON)
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain)
|
||||
add_subdirectory(${AMNEZIA_THIRDPARTY_ROOT}/qtkeychain ${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain EXCLUDE_FROM_ALL)
|
||||
|
||||
if(ANDROID)
|
||||
# Use qtgamepad from amnezia-vpn/qtgamepad repository
|
||||
@@ -106,12 +37,13 @@ endif()
|
||||
set(LIBS ${LIBS} qt6keychain)
|
||||
|
||||
include_directories(
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${LIBSSH_INCLUDE_DIR}/include
|
||||
${LIBSSH_ROOT_DIR}/include
|
||||
${CLIENT_ROOT_DIR}/3rd/libssh/include
|
||||
${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src/include
|
||||
${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain
|
||||
${AMNEZIA_THIRDPARTY_ROOT}/QSimpleCrypto/src/include
|
||||
${AMNEZIA_THIRDPARTY_ROOT}/qtkeychain/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
|
||||
)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
list(APPEND LIBS OpenSSL::SSL OpenSSL::Crypto)
|
||||
|
||||
find_package(libssh REQUIRED)
|
||||
list(APPEND LIBS ssh::ssh)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
set(QSIMPLECRYPTO_DIR ${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src)
|
||||
set(AMNEZIA_THIRDPARTY_ROOT "${CLIENT_ROOT_DIR}/3rd" CACHE PATH "Path to Amnezia client/3rd sources")
|
||||
set(QSIMPLECRYPTO_DIR ${AMNEZIA_THIRDPARTY_ROOT}/QSimpleCrypto/src)
|
||||
|
||||
include_directories(${QSIMPLECRYPTO_DIR})
|
||||
|
||||
|
||||
+10
-14
@@ -42,18 +42,14 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/core/installedAppsImageProvider.cpp
|
||||
)
|
||||
|
||||
foreach(abi IN ITEMS ${QT_ANDROID_ABIS})
|
||||
set_property(TARGET ${PROJECT} PROPERTY QT_ANDROID_EXTRA_LIBS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/amneziawg/android/${abi}/libwg-go.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libck-ovpn-plugin.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpn3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpnutil.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/librsapss.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libcrypto_3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libssl_3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/android/${abi}/libssh.so
|
||||
)
|
||||
endforeach()
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/xray/android/libxray.aar
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/android/xray/libXray)
|
||||
find_package(awg-android REQUIRED)
|
||||
set(LIBS ${LIBS} amnezia::awg-android)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${AMNEZIA_ANDROID_LIBWG_PATH} ${AMNEZIA_ANDROID_LIBWG_QUICK_PATH})
|
||||
|
||||
find_package(amnezia-libxray REQUIRED)
|
||||
file(COPY ${AMNEZIA_LIBXRAY_PATH} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/android/xray/libXray)
|
||||
|
||||
find_package(openvpn-pt-android REQUIRED)
|
||||
set(LIBS ${LIBS} amnezia::openvpn-pt-android)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${OPENVPN_PT_ANDROID_LIBCK_OVPN_PLUGIN_PATH})
|
||||
|
||||
@@ -39,5 +39,7 @@ while(IOS_TARGETS)
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "arm64"
|
||||
)
|
||||
endwhile()
|
||||
endwhile()
|
||||
|
||||
+136
-31
@@ -1,7 +1,19 @@
|
||||
message("Client iOS build")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0)
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
message("Apple TV target mode is ON")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 17.0)
|
||||
set(QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN TRUE)
|
||||
set(QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE TRUE)
|
||||
set(IOS_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info-tvOS.plist.in)
|
||||
set(IOS_LAUNCHSCREEN_STORYBOARD ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/tvOS/AmneziaVPNLaunchScreen.storyboard)
|
||||
else()
|
||||
message("Apple TV target mode is OFF")
|
||||
set(IOS_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info.plist.in)
|
||||
set(IOS_LAUNCHSCREEN_STORYBOARD ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard)
|
||||
endif()
|
||||
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
@@ -10,13 +22,23 @@ enable_language(Swift)
|
||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_UIKIT UIKit)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
# Use framework linker flags directly for tvOS to avoid iPhoneOS SDK absolute paths.
|
||||
set(FW_AUTHENTICATIONSERVICES "-framework AuthenticationServices")
|
||||
set(FW_UIKIT "-framework UIKit")
|
||||
set(FW_AVFOUNDATION "-framework AVFoundation")
|
||||
set(FW_FOUNDATION "-framework Foundation")
|
||||
set(FW_STOREKIT "-framework StoreKit")
|
||||
set(FW_USERNOTIFICATIONS "-framework UserNotifications")
|
||||
else()
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_UIKIT UIKit)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
endif()
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${FW_AUTHENTICATIONSERVICES}
|
||||
@@ -25,9 +47,12 @@ set(LIBS ${LIBS}
|
||||
${FW_FOUNDATION}
|
||||
${FW_STOREKIT}
|
||||
${FW_USERNOTIFICATIONS}
|
||||
${FW_NETWORKEXTENSION}
|
||||
)
|
||||
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
set(LIBS ${LIBS} ${FW_NETWORKEXTENSION})
|
||||
endif()
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h
|
||||
@@ -57,7 +82,7 @@ target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info.plist.in
|
||||
MACOSX_BUNDLE_INFO_PLIST ${IOS_INFO_PLIST}
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
@@ -66,7 +91,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
@@ -74,13 +98,36 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
|
||||
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
XCODE_ATTRIBUTE_SDKROOT "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_LIBRARY_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/usr/lib/swift"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_FRAMEWORK_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
QT_IOS_PERMISSIONS ""
|
||||
)
|
||||
else()
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEFINED DEPLOY)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
@@ -111,7 +158,61 @@ target_compile_options(${PROJECT} PRIVATE
|
||||
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
||||
)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/amneziawg-apple/Sources)
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
# qscnetworkreachability plugin links IOKit, which is unavailable on tvOS.
|
||||
qt_import_plugins(${PROJECT}
|
||||
NO_DEFAULT
|
||||
INCLUDE
|
||||
QIOSIntegrationPlugin
|
||||
QJpegPlugin
|
||||
QSvgPlugin
|
||||
QGifPlugin
|
||||
QICOPlugin
|
||||
QSvgIconPlugin
|
||||
QSecureTransportBackendPlugin
|
||||
EXCLUDE
|
||||
QSCNetworkReachabilityNetworkInformationPlugin
|
||||
QDarwinCameraPermissionPlugin
|
||||
)
|
||||
|
||||
# Static tvOS Qt build doesn't auto-link these plugin archives into the
|
||||
# Xcode target, but the app entry point lives in QIOSIntegrationPlugin.
|
||||
set(_amnezia_tvos_static_plugins
|
||||
Qt6::QIOSIntegrationPlugin
|
||||
Qt6::QIOSIntegrationPlugin_init
|
||||
Qt6::QJpegPlugin
|
||||
Qt6::QJpegPlugin_init
|
||||
Qt6::QSvgPlugin
|
||||
Qt6::QSvgPlugin_init
|
||||
Qt6::QGifPlugin
|
||||
Qt6::QGifPlugin_init
|
||||
Qt6::QICOPlugin
|
||||
Qt6::QICOPlugin_init
|
||||
Qt6::QSvgIconPlugin
|
||||
Qt6::QSvgIconPlugin_init
|
||||
Qt6::QSecureTransportBackendPlugin
|
||||
Qt6::QSecureTransportBackendPlugin_init
|
||||
)
|
||||
foreach(_amnezia_tvos_static_plugin IN LISTS _amnezia_tvos_static_plugins)
|
||||
if(TARGET ${_amnezia_tvos_static_plugin})
|
||||
target_link_libraries(${PROJECT} PRIVATE ${_amnezia_tvos_static_plugin})
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_amnezia_tvos_static_plugin)
|
||||
unset(_amnezia_tvos_static_plugins)
|
||||
|
||||
# Qt 6.9.2 iOS package links IOKit via Qt6::Core interface, but tvOS SDK
|
||||
# does not provide IOKit. Strip this single framework for Apple TV builds.
|
||||
get_target_property(_qtcore_iface_libs Qt6::Core INTERFACE_LINK_LIBRARIES)
|
||||
if(_qtcore_iface_libs)
|
||||
string(REPLACE "-framework IOKit;" "" _qtcore_iface_libs "${_qtcore_iface_libs}")
|
||||
string(REPLACE ";-framework IOKit" "" _qtcore_iface_libs "${_qtcore_iface_libs}")
|
||||
set_property(TARGET Qt6::Core PROPERTY INTERFACE_LINK_LIBRARIES "${_qtcore_iface_libs}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(AMNEZIA_THIRDPARTY_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/3rd" CACHE PATH "Path to Amnezia client/3rd sources")
|
||||
set(WG_APPLE_SOURCE_DIR ${AMNEZIA_THIRDPARTY_ROOT}/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosvpnprotocol.swift
|
||||
@@ -123,25 +224,29 @@ target_sources(${PROJECT} PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
if(IOS_LAUNCHSCREEN_STORYBOARD)
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${IOS_LAUNCHSCREEN_STORYBOARD}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${IOS_LAUNCHSCREEN_STORYBOARD}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
else()
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework")
|
||||
|
||||
|
||||
@@ -23,9 +23,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ui/macos_util.h
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
message("Client ==> MacOS NE build")
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
|
||||
@@ -152,19 +151,6 @@ message(${QtCore_location})
|
||||
|
||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos)
|
||||
target_link_libraries("AmneziaVPNNetworkExtension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks
|
||||
COMMAND /usr/bin/find "$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework" -name "*.sha256" -delete
|
||||
COMMAND /usr/bin/codesign --force --sign "Apple Distribution"
|
||||
"$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework/Versions/Current/OpenVPNAdapter"
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Signing OpenVPNAdapter framework"
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/mozilla/controllerimpl.h
|
||||
)
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||
)
|
||||
@@ -89,14 +89,14 @@ set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/mozilla/shared/leakdetector.cpp
|
||||
)
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Include native macOS platform helpers (dock/status-item)
|
||||
if(APPLE AND NOT IOS)
|
||||
if(APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
list(APPEND HEADERS
|
||||
${CLIENT_ROOT_DIR}/platforms/macos/macosutils.h
|
||||
${CLIENT_ROOT_DIR}/platforms/macos/macosstatusicon.h
|
||||
@@ -175,7 +175,7 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
message("Client desktop build")
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#include "openvpn_configurator.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTemporaryFile>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/networkUtilities.h"
|
||||
#include "containers/containers_defs.h"
|
||||
@@ -165,7 +161,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
||||
QString dnsConf = QString("\nscript-security 2\n"
|
||||
"up %1/update-resolv-conf.sh\n"
|
||||
"down %1/update-resolv-conf.sh\n")
|
||||
.arg(qApp->applicationDirPath());
|
||||
.arg(QCoreApplication::applicationDirPath());
|
||||
|
||||
config.append(dnsConf);
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ssh_configurator.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
@@ -8,11 +9,6 @@
|
||||
#include <QTemporaryFile>
|
||||
#include <QThread>
|
||||
#include <qtimer.h>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/server_defs.h"
|
||||
#include "utilities.h"
|
||||
@@ -24,7 +20,7 @@ SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, const QShar
|
||||
|
||||
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||
{
|
||||
#if !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
@@ -70,13 +66,13 @@ QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||
// DEAD CODE.
|
||||
void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
||||
{
|
||||
#if !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QProcess *p = new QProcess();
|
||||
p->setProcessChannelMode(QProcess::SeparateChannels);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
p->setProcessEnvironment(prepareEnv());
|
||||
p->setProgram(qApp->applicationDirPath() + "\\cygwin\\putty.exe");
|
||||
p->setProgram(QCoreApplication::applicationDirPath() + "\\cygwin\\putty.exe");
|
||||
|
||||
if (credentials.secretData.contains("PRIVATE KEY")) {
|
||||
// todo: connect by key
|
||||
@@ -100,10 +96,10 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
pathEnvVar.clear();
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "\\openvpn;");
|
||||
#elif defined(Q_OS_MACX) && !defined(MACOS_NE)
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
@@ -196,7 +196,7 @@ void CoreController::initAndroidController()
|
||||
|
||||
void CoreController::initAppleController()
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
IosController::Instance()->initialize();
|
||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
|
||||
emit m_pageController->goToPageHome();
|
||||
@@ -233,7 +233,7 @@ void CoreController::initSignalHandlers()
|
||||
|
||||
void CoreController::initNotificationHandler()
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||
|
||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
||||
@@ -248,7 +248,7 @@ void CoreController::initNotificationHandler()
|
||||
|
||||
auto* trayHandler = qobject_cast<SystemTrayNotificationHandler*>(m_notificationHandler.get());
|
||||
connect(this, &CoreController::websiteUrlChanged, trayHandler, &SystemTrayNotificationHandler::updateWebsiteUrl);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void CoreController::updateTranslator(const QLocale &locale)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QQmlContext>
|
||||
#include <QThread>
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include "ui/systemtray_notificationhandler.h"
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "ui/models/sites_model.h"
|
||||
#include "ui/models/newsModel.h"
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include "ui/notificationhandler.h"
|
||||
#endif
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||
QSharedPointer<QTranslator> m_translator;
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
QScopedPointer<NotificationHandler> m_notificationHandler;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -404,7 +404,7 @@ QPair<QString, QNetworkInterface> NetworkUtilities::getGatewayAndIface()
|
||||
close(sock);
|
||||
return { gateway_address, QNetworkInterface::interfaceFromName(interface) };
|
||||
#endif
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QString gateway;
|
||||
int index = -1;
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>AmneziaVPNLaunchScreen</string>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,6 +1,14 @@
|
||||
enable_language(Swift)
|
||||
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
set(AMNEZIA_THIRDPARTY_ROOT "${CLIENT_ROOT_DIR}/3rd" CACHE PATH "Path to Amnezia client/3rd sources")
|
||||
set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
message("Network Extension tvOS mode is ON")
|
||||
else()
|
||||
message("Network Extension tvOS mode is OFF")
|
||||
endif()
|
||||
|
||||
add_executable(networkextension)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
@@ -28,6 +36,23 @@ set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
|
||||
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
XCODE_ATTRIBUTE_SDKROOT "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_LIBRARY_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/usr/lib/swift"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_FRAMEWORK_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks"
|
||||
LINKER_LANGUAGE Swift
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEPLOY)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
@@ -45,38 +70,49 @@ endif()
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
)
|
||||
|
||||
set_target_properties("networkextension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
find_library(FW_MOBILE_CORE MobileCoreServices)
|
||||
find_library(FW_UI_KIT UIKit)
|
||||
find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${FW_ASSETS_LIBRARY})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_MOBILE_CORE})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
else()
|
||||
target_link_libraries(networkextension PRIVATE -lresolv)
|
||||
endif()
|
||||
|
||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
set(WG_APPLE_SOURCE_DIR ${AMNEZIA_THIRDPARTY_ROOT}/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
set(NE_COMMON_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
)
|
||||
|
||||
set(NE_WIREGUARD_SOURCES
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
|
||||
@@ -84,24 +120,50 @@ target_sources(networkextension PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||
)
|
||||
|
||||
set(NE_XRAY_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
)
|
||||
|
||||
set(NE_OPENVPN_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
)
|
||||
|
||||
set(NE_APPLE_GLUE_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
list(APPEND NE_APPLE_GLUE_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/tvos_cgo_stubs.c
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(networkextension PRIVATE ${NE_COMMON_SOURCES})
|
||||
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
target_sources(networkextension PRIVATE
|
||||
${NE_WIREGUARD_SOURCES}
|
||||
${NE_OPENVPN_SOURCES}
|
||||
${NE_XRAY_SOURCES}
|
||||
${NE_APPLE_GLUE_SOURCES}
|
||||
)
|
||||
else()
|
||||
target_sources(networkextension PRIVATE
|
||||
${NE_WIREGUARD_SOURCES}
|
||||
${NE_APPLE_GLUE_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
@@ -110,21 +172,16 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64/libwg-go.a)
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::awg-apple)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework)
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel)
|
||||
endif()
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
@@ -114,25 +114,14 @@ set_property(TARGET AmneziaVPNNetworkExtension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/universal2/libwg-go.a)
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
message(${CLIENT_ROOT_DIR})
|
||||
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::awg-apple)
|
||||
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers)
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE heiher::hev-socks5-tunnel)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
+3
-4
@@ -12,11 +12,11 @@
|
||||
#include "Windows.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
||||
#endif
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
bool isAnotherInstanceRunning()
|
||||
{
|
||||
QLocalSocket socket;
|
||||
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
|
||||
AmneziaApplication app(argc, argv);
|
||||
OsSignalHandler::setup();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
if (isAnotherInstanceRunning()) {
|
||||
QTimer::singleShot(1000, &app, [&]() { app.quit(); });
|
||||
return app.exec();
|
||||
@@ -75,7 +75,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
||||
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ import NetworkExtension
|
||||
import Network
|
||||
import os
|
||||
import Darwin
|
||||
#if !os(tvOS)
|
||||
import OpenVPNAdapter
|
||||
#endif
|
||||
|
||||
enum TunnelProtoType: String {
|
||||
case wireguard, openvpn, xray
|
||||
@@ -38,8 +40,10 @@ struct Constants {
|
||||
|
||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
var wgAdapter: WireGuardAdapter?
|
||||
#if !os(tvOS)
|
||||
var ovpnAdapter: OpenVPNAdapter?
|
||||
private lazy var openVPNPacketFlowAdapter = PacketTunnelFlowAdapter(flow: packetFlow)
|
||||
#endif
|
||||
private let pathMonitorQueue = DispatchQueue(label: Constants.processQueueName + ".path-monitor")
|
||||
private let pathMonitor = NWPathMonitor()
|
||||
private var didReceiveInitialPathUpdate = false
|
||||
@@ -49,7 +53,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
var splitTunnelType: Int?
|
||||
var splitTunnelSites: [String]?
|
||||
|
||||
#if !os(tvOS)
|
||||
let vpnReachability = OpenVPNReachability()
|
||||
#endif
|
||||
|
||||
var startHandler: ((Error?) -> Void)?
|
||||
var stopHandler: (() -> Void)?
|
||||
@@ -57,9 +63,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
var activeIfaceIdx: UInt32 = 0
|
||||
|
||||
#if !os(tvOS)
|
||||
func openVPNPacketFlow() -> OpenVPNAdapterPacketFlow {
|
||||
openVPNPacketFlowAdapter
|
||||
}
|
||||
#endif
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
@@ -206,9 +214,21 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
errorNotifier: errorNotifier,
|
||||
completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if os(tvOS)
|
||||
completionHandler(NSError(domain: "org.amnezia.ne",
|
||||
code: -1002,
|
||||
userInfo: [NSLocalizedDescriptionKey: "OpenVPN backend is not available for tvOS in this build"]))
|
||||
#else
|
||||
startOpenVPN(completionHandler: completionHandler)
|
||||
#endif
|
||||
case .xray:
|
||||
#if os(tvOS)
|
||||
completionHandler(NSError(domain: "org.amnezia.ne",
|
||||
code: -1003,
|
||||
userInfo: [NSLocalizedDescriptionKey: "Xray backend is not available for tvOS in this build"]))
|
||||
#else
|
||||
startXray(completionHandler: completionHandler)
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -225,10 +245,18 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
stopWireguard(with: reason,
|
||||
completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if os(tvOS)
|
||||
completionHandler()
|
||||
#else
|
||||
stopOpenVPN(with: reason,
|
||||
completionHandler: completionHandler)
|
||||
#endif
|
||||
case .xray:
|
||||
#if os(tvOS)
|
||||
completionHandler()
|
||||
#else
|
||||
stopXray(completionHandler: completionHandler)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +270,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
case .wireguard:
|
||||
handleWireguardStatusMessage(messageData, completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if !os(tvOS)
|
||||
handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler)
|
||||
#else
|
||||
completionHandler?(nil)
|
||||
#endif
|
||||
case .xray:
|
||||
break;
|
||||
}
|
||||
@@ -260,7 +292,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
private func handle(networkChange changePath: Network.NWPath, completion: @escaping (Error?) -> Void) {
|
||||
updateActiveInterfaceIndex(for: changePath)
|
||||
wg_log(.info, message: "Tunnel restarted.")
|
||||
neLog(.info, message: "Tunnel restarted.")
|
||||
startTunnel(options: nil, completionHandler: completion)
|
||||
}
|
||||
}
|
||||
@@ -311,16 +343,17 @@ private extension PacketTunnelProvider {
|
||||
}
|
||||
|
||||
extension WireGuardLogLevel {
|
||||
var osLogLevel: OSLogType {
|
||||
switch self {
|
||||
case .verbose:
|
||||
return .debug
|
||||
case .error:
|
||||
return .error
|
||||
var osLogLevel: OSLogType {
|
||||
switch self {
|
||||
case .verbose:
|
||||
return .debug
|
||||
case .error:
|
||||
return .error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
|
||||
private let flow: NEPacketTunnelFlow
|
||||
|
||||
@@ -339,6 +372,7 @@ final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
|
||||
flow.writePackets(packets, withProtocols: protocols)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extension NEProviderStopReason {
|
||||
var amneziaDescription: String {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -959,6 +959,10 @@ void IosController::sendVpnExtensionMessage(NSDictionary* message, std::function
|
||||
}
|
||||
|
||||
bool IosController::shareText(const QStringList& filesToSend) {
|
||||
#if defined(Q_OS_TVOS)
|
||||
Q_UNUSED(filesToSend)
|
||||
return false;
|
||||
#else
|
||||
NSMutableArray *sharingItems = [NSMutableArray new];
|
||||
|
||||
for (int i = 0; i < filesToSend.size(); i++) {
|
||||
@@ -967,7 +971,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
}
|
||||
#if !MACOS_NE
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
if (!qtController) return false;
|
||||
|
||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||
#endif
|
||||
@@ -991,23 +995,25 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
wait.exec();
|
||||
|
||||
return isAccepted;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString IosController::openFile() {
|
||||
#if !MACOS_NE
|
||||
#if defined(Q_OS_TVOS)
|
||||
return QString();
|
||||
#elif !MACOS_NE
|
||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
||||
|
||||
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
||||
documentPicker.delegate = documentPickerDelegate;
|
||||
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
if (!qtController) return QString();
|
||||
|
||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||
|
||||
#endif
|
||||
__block QString filePath;
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !defined(Q_OS_TVOS)
|
||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||
if (path) {
|
||||
filePath = QString::fromUtf8(path.UTF8String);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <NetworkExtension/NETunnelProviderSession.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#include <UIKit/UIKit.h>
|
||||
@@ -21,7 +22,7 @@ class IosController;
|
||||
@end
|
||||
|
||||
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||
|
||||
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
@end
|
||||
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
@implementation DocumentPickerDelegate
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
||||
|
||||
@@ -7,6 +7,24 @@
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if defined(Q_OS_TVOS)
|
||||
|
||||
IOSNotificationHandler::IOSNotificationHandler(QObject* parent) : NotificationHandler(parent) {}
|
||||
|
||||
IOSNotificationHandler::~IOSNotificationHandler() {}
|
||||
|
||||
void IOSNotificationHandler::notify(NotificationHandler::Message type,
|
||||
const QString& title,
|
||||
const QString& message,
|
||||
int timerMsec) {
|
||||
Q_UNUSED(type)
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(message)
|
||||
Q_UNUSED(timerMsec)
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -172,3 +190,5 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // Q_OS_TVOS
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* tvOS does not export these iOS runtime helpers used by Go cgo archives.
|
||||
* WireGuardKitGo references them indirectly; provide no-op stubs for tvOS.
|
||||
*/
|
||||
void darwin_arm_init_mach_exception_handler(void) {}
|
||||
void darwin_arm_init_thread_exception_port(void) {}
|
||||
@@ -80,7 +80,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||
|
||||
QDir appPath(QCoreApplication::applicationDirPath());
|
||||
QStringList wgArgs = {"-f", "amn0"};
|
||||
m_tunnel.start(appPath.filePath("../../client/bin/wireguard-go"), wgArgs);
|
||||
m_tunnel.start(appPath.filePath("amneziawg-go"), wgArgs);
|
||||
if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "Unable to start tunnel process due to timeout";
|
||||
m_tunnel.kill();
|
||||
|
||||
@@ -79,7 +79,7 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||
|
||||
QDir appPath(QCoreApplication::applicationDirPath());
|
||||
QStringList wgArgs = {"-f", "utun"};
|
||||
m_tunnel.start(appPath.filePath("wireguard-go"), wgArgs);
|
||||
m_tunnel.start(appPath.filePath("amneziawg-go"), wgArgs);
|
||||
if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "Unable to start tunnel process due to timeout";
|
||||
m_tunnel.kill();
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace amnezia
|
||||
|
||||
constexpr char defaultPort[] = "51820";
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
constexpr char defaultMtu[] = "1280";
|
||||
#else
|
||||
constexpr char defaultMtu[] = "1376";
|
||||
@@ -210,7 +210,7 @@ namespace amnezia
|
||||
namespace awg
|
||||
{
|
||||
constexpr char defaultPort[] = "55424";
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
constexpr char defaultMtu[] = "1280";
|
||||
#else
|
||||
constexpr char defaultMtu[] = "1376";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || (defined(Q_OS_MACX) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#include "openvpnovercloakprotocol.h"
|
||||
#include "openvpnprotocol.h"
|
||||
#include "shadowsocksvpnprotocol.h"
|
||||
@@ -114,7 +114,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || (defined(Q_OS_MACX) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||
|
||||
@@ -124,14 +124,14 @@ ErrorCode XrayProtocol::startTun2Socks()
|
||||
m_tun2socksProcess->setProgram(PermittedProcess::Tun2Socks);
|
||||
m_tun2socksProcess->setArguments({"-device", QString("tun://%1").arg(tunName), "-proxy", "socks5://127.0.0.1:10808" });
|
||||
|
||||
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() {
|
||||
auto readAllStandardOutput = m_tun2socksProcess->readAllStandardOutput();
|
||||
if (!readAllStandardOutput.waitForFinished()) {
|
||||
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this, [this]() {
|
||||
auto readAllStandardError = m_tun2socksProcess->readAllStandardError();
|
||||
if (!readAllStandardError.waitForFinished()) {
|
||||
qWarning() << "Failed to read output from tun2socks";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString line = readAllStandardOutput.returnValue();
|
||||
const QString line = readAllStandardError.returnValue();
|
||||
|
||||
if (!line.contains("[TCP]") && !line.contains("[UDP]"))
|
||||
qDebug() << "[tun2socks]:" << line;
|
||||
|
||||
+1388
-841
File diff suppressed because it is too large
Load Diff
+1402
-867
File diff suppressed because it is too large
Load Diff
+1388
-841
File diff suppressed because it is too large
Load Diff
+1391
-840
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1408
-865
File diff suppressed because it is too large
Load Diff
+1396
-853
File diff suppressed because it is too large
Load Diff
+1402
-875
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,5 @@
|
||||
#include "connectionController.h"
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "utilities.h"
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "version.h"
|
||||
@@ -33,7 +27,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||
|
||||
void ConnectionController::openConnection()
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||
{
|
||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
@@ -604,14 +604,14 @@ bool ImportController::decodeQrCode(const QString &code)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void ImportController::startDecodingQr()
|
||||
{
|
||||
m_qrCodeChunks.clear();
|
||||
m_totalQrCodeChunksCount = 0;
|
||||
m_receivedQrCodeChunksCount = 0;
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
m_isQrCodeProcessed = true;
|
||||
#endif
|
||||
#if defined Q_OS_ANDROID
|
||||
|
||||
@@ -38,7 +38,7 @@ public slots:
|
||||
QString getConfigFileName();
|
||||
QString getMaliciousWarningText();
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void startDecodingQr();
|
||||
bool parseQrCodeChunk(const QString &code);
|
||||
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
|
||||
void processAmneziaConfig(QJsonObject &config);
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void stopDecodingQr();
|
||||
#endif
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
ConfigTypes m_configType;
|
||||
QString m_maliciousWarningText;
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
QMap<int, QByteArray> m_qrCodeChunks;
|
||||
bool m_isQrCodeProcessed;
|
||||
int m_totalQrCodeChunksCount;
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#define INSTALLCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include <QProcess>
|
||||
#endif
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/defs.h"
|
||||
@@ -111,7 +113,7 @@ private:
|
||||
|
||||
QString m_privateKeyPassphrase;
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
QList<QSharedPointer<QProcess>> m_sftpMountProcesses;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "pageController.h"
|
||||
#include "utils/converter.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include <QCoreApplication>
|
||||
#if defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
@@ -14,7 +15,7 @@
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
#if defined Q_OS_MAC
|
||||
#if defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
#include "ui/macos_util.h"
|
||||
#endif
|
||||
|
||||
@@ -27,7 +28,7 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
||||
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_MACX
|
||||
#if defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
connect(this, &PageController::raiseMainWindow, []() {
|
||||
setDockIconVisible(true);
|
||||
});
|
||||
@@ -64,7 +65,7 @@ QString PageController::getPagePath(PageLoader::PageEnum page)
|
||||
void PageController::closeWindow()
|
||||
{
|
||||
// On mobile platforms, quit app on close; on desktop, just hide window
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
qApp->quit();
|
||||
#else
|
||||
emit hideMainWindow();
|
||||
@@ -118,7 +119,7 @@ void PageController::showOnStartup()
|
||||
} else {
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
emit hideMainWindow();
|
||||
#elif defined(Q_OS_MACX)
|
||||
#elif defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
setDockIconVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,8 @@ QString getPlatformName()
|
||||
return "Windows";
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
return "Android";
|
||||
#elif defined(Q_OS_TVOS)
|
||||
return "tvOS";
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return "Linux";
|
||||
#elif defined(Q_OS_MACX)
|
||||
@@ -109,7 +111,7 @@ bool SettingsController::isLoggingEnabled()
|
||||
void SettingsController::toggleLogging(bool enable)
|
||||
{
|
||||
m_settings->setSaveLogs(enable);
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
AmneziaVPN::toggleLogging(enable);
|
||||
#endif
|
||||
if (enable == true) {
|
||||
@@ -158,7 +160,6 @@ void SettingsController::clearLogs()
|
||||
|
||||
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
||||
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
|
||||
}
|
||||
|
||||
void SettingsController::backupAppConfig(const QString &fileName)
|
||||
@@ -193,7 +194,7 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||
if (ok) {
|
||||
QJsonObject newConfigData = QJsonDocument::fromJson(data).object();
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MACX)
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || (defined(Q_OS_MACX) && !defined(Q_OS_TVOS))
|
||||
bool autoStart = false;
|
||||
if (newConfigData.contains("Conf/autoStart")) {
|
||||
autoStart = newConfigData["Conf/autoStart"].toBool();
|
||||
@@ -230,7 +231,7 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||
m_sitesModel->setRouteMode(siteSplitTunnelingRouteMode);
|
||||
m_sitesModel->toggleSplitTunneling(siteSplittunnelingEnabled);
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
m_settings->setAutoConnect(false);
|
||||
m_settings->setStartMinimized(false);
|
||||
m_settings->setKillSwitchEnabled(false);
|
||||
@@ -269,7 +270,7 @@ void SettingsController::clearSettings()
|
||||
|
||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
AmneziaVPN::clearSettings();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
@@ -31,7 +31,7 @@ void SystemController::saveFile(const QString &fileName, const QString &data)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
QUrl fileUrl = QDir::tempPath() + "/" + fileName;
|
||||
QFile file(fileUrl.toString());
|
||||
#else
|
||||
@@ -43,7 +43,7 @@ void SystemController::saveFile(const QString &fileName, const QString &data)
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
QStringList filesToSend;
|
||||
filesToSend.append(fileUrl.toString());
|
||||
// todo check if save successful
|
||||
@@ -98,7 +98,7 @@ QString SystemController::getFileName(const QString &acceptLabel, const QString
|
||||
return AndroidController::instance()->openFile(nameFilter);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
|
||||
fileName = IosController::Instance()->openFile();
|
||||
if (fileName.isEmpty()) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QDebug>
|
||||
#include "notificationhandler.h"
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
# include "platforms/ios/iosnotificationhandler.h"
|
||||
#else
|
||||
# include "systemtray_notificationhandler.h"
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
// static
|
||||
NotificationHandler* NotificationHandler::create(QObject* parent) {
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
return new IOSNotificationHandler(parent);
|
||||
#else
|
||||
return new SystemTrayNotificationHandler(parent);
|
||||
|
||||
@@ -58,7 +58,7 @@ QString Autostart::appPath() {
|
||||
return QCoreApplication::applicationFilePath() + " --autostart";
|
||||
}
|
||||
|
||||
#elif defined Q_OS_MACX
|
||||
#elif defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
|
||||
bool Autostart::isAutostart() {
|
||||
QProcess process;
|
||||
|
||||
+4
-20
@@ -190,7 +190,7 @@ bool Utils::processIsRunning(const QString &fileName, const bool fullFlag)
|
||||
CloseHandle(hSnapshot);
|
||||
return false;
|
||||
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(MACOS_NE)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(Q_OS_ANDROID) || defined(MACOS_NE)
|
||||
return false;
|
||||
#else
|
||||
QProcess process;
|
||||
@@ -250,7 +250,7 @@ bool Utils::killProcessByName(const QString &name)
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
return success;
|
||||
#elif defined Q_OS_IOS || defined(Q_OS_ANDROID)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(Q_OS_ANDROID)
|
||||
return false;
|
||||
#else
|
||||
return QProcess::execute("pkill", { name }) == 0;
|
||||
@@ -259,15 +259,7 @@ bool Utils::killProcessByName(const QString &name)
|
||||
|
||||
QString Utils::openVpnExecPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return Utils::executable("openvpn/openvpn", true);
|
||||
#elif defined Q_OS_LINUX
|
||||
// We have service that runs OpenVPN on Linux. We need to make same
|
||||
// path for client and service.
|
||||
return Utils::executable("../../client/bin/openvpn", true);
|
||||
#else
|
||||
return Utils::executable("/openvpn", true);
|
||||
#endif
|
||||
return Utils::executable("openvpn", true);
|
||||
}
|
||||
|
||||
QString Utils::wireguardExecPath()
|
||||
@@ -295,15 +287,7 @@ QString Utils::certUtilPath()
|
||||
|
||||
QString Utils::tun2socksPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return Utils::executable("xray/tun2socks", true);
|
||||
#elif defined Q_OS_LINUX
|
||||
// We have service that runs OpenVPN on Linux. We need to make same
|
||||
// path for client and service.
|
||||
return Utils::executable("../../client/bin/tun2socks", true);
|
||||
#else
|
||||
return Utils::executable("/tun2socks", true);
|
||||
#endif
|
||||
return Utils::executable("tun2socks", true);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
m_checkTimer.setInterval(1000);
|
||||
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
|
||||
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
@@ -127,7 +127,7 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
if (state == Vpn::ConnectionState::Connected ||
|
||||
state == Vpn::ConnectionState::Connecting ||
|
||||
state == Vpn::ConnectionState::Reconnecting) {
|
||||
@@ -243,7 +243,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
||||
|
||||
appendSplitTunnelingConfig();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
||||
if (!m_vpnProtocol) {
|
||||
setConnectionState(Vpn::ConnectionState::Error);
|
||||
@@ -255,7 +255,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
||||
createAndroidConnections();
|
||||
|
||||
m_vpnProtocol.reset(androidVpnProtocol);
|
||||
#elif defined Q_OS_IOS || defined(MACOS_NE)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
IosController::Instance()->connectVpn(proto, m_vpnConfiguration);
|
||||
connect(&m_checkTimer, &QTimer::timeout, IosController::Instance(), &IosController::checkStatus);
|
||||
@@ -446,7 +446,7 @@ void VpnConnection::reconnectToVpn() {
|
||||
|
||||
void VpnConnection::disconnectFromVpn()
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
// iOS/macOS NE use IosController directly; m_vpnProtocol is not set there.
|
||||
IosController::Instance()->disconnectVpn();
|
||||
disconnect(&m_checkTimer, &QTimer::timeout, IosController::Instance(), &IosController::checkStatus);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
set(CPACK_PACKAGE_VENDOR AmneziaVPN)
|
||||
set(CPACK_PACKAGE_VERSION ${AMNEZIAVPN_VERSION})
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY AmneziaVPN)
|
||||
set(CPACK_PACKAGE_EXECUTABLES AmneziaVPN AmneziaVPN)
|
||||
set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_CURRENT_LIST_DIR}/sign_binaries.cmake)
|
||||
set(CPACK_POST_BUILD_SCRIPTS ${CMAKE_CURRENT_LIST_DIR}/sign_packages.cmake)
|
||||
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_CURRENT_LIST_DIR}/CPackOptions.cmake)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/deploy/data/LICENSE.txt)
|
||||
|
||||
list(PREPEND CPACK_COMPONENTS_ALL AmneziaVPN)
|
||||
|
||||
if(APPLE)
|
||||
set(CPACK_GENERATOR productbuild)
|
||||
else()
|
||||
set(CPACK_GENERATOR IFW)
|
||||
endif()
|
||||
|
||||
# === CPack IFW generator settings ===
|
||||
set(CPACK_IFW_PACKAGE_NAME AmneziaVPN)
|
||||
set(CPACK_IFW_PACKAGE_TITLE AmneziaVPN)
|
||||
set(CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH 600)
|
||||
set(CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT 380)
|
||||
set(CPACK_IFW_PACKAGE_WIZARD_STYLE Modern)
|
||||
set(CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR ON)
|
||||
set(CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH ON)
|
||||
set(CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS ON)
|
||||
set(CPACK_IFW_PACKAGE_CONTROL_SCRIPT ${CMAKE_SOURCE_DIR}/deploy/installer/qif/controlscript.js)
|
||||
|
||||
# === CPack WIX generator settings ===
|
||||
set(CPACK_WIX_VERSION 4)
|
||||
set(CPACK_WIX_UPGRADE_GUID "{2D55AC62-96D6-4692-8C05-0D85BBF95485}")
|
||||
set(CPACK_WIX_PRODUCT_ICON ${CMAKE_SOURCE_DIR}/client/images/app.ico)
|
||||
set(CPACK_WIX_CUSTOM_XMLNS "util=http://wixtoolset.org/schemas/v4/wxs/util")
|
||||
set(_AMNEZIA_WIX_PATCH_SERVICE ${CMAKE_SOURCE_DIR}/deploy/installer/wix/service_install_patch.xml)
|
||||
set(_AMNEZIA_WIX_PATCH_CLOSE_APP ${CMAKE_SOURCE_DIR}/deploy/installer/wix/close_client_patch.xml)
|
||||
file(TO_CMAKE_PATH "${_AMNEZIA_WIX_PATCH_SERVICE}" _AMNEZIA_WIX_PATCH_SERVICE_CMAKE)
|
||||
file(TO_CMAKE_PATH "${_AMNEZIA_WIX_PATCH_CLOSE_APP}" _AMNEZIA_WIX_PATCH_CLOSE_APP_CMAKE)
|
||||
list(APPEND CPACK_WIX_PATCH_FILE "${_AMNEZIA_WIX_PATCH_SERVICE_CMAKE}" "${_AMNEZIA_WIX_PATCH_CLOSE_APP_CMAKE}")
|
||||
list(APPEND CPACK_WIX_EXTENSIONS "WixToolset.Util.wixext")
|
||||
|
||||
# === CPack productbuild generator settings ===
|
||||
set(CPACK_PRODUCTBUILD_IDENTIFIER org.amneziavpn)
|
||||
set(CPACK_PREFLIGHT_AMNEZIAVPN_SCRIPT ${CMAKE_SOURCE_DIR}/deploy/data/macos/post_uninstall.sh)
|
||||
set(CPACK_POSTFLIGHT_AMNEZIAVPN_SCRIPT ${CMAKE_SOURCE_DIR}/deploy/data/macos/post_install.sh)
|
||||
set(CPACK_POSTFLIGHT_UNINSTALL_SCRIPT ${CMAKE_SOURCE_DIR}/deploy/data/macos/post_uninstall.sh)
|
||||
# provide custom CPack.distribution.dist.in
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/deploy/data/macos)
|
||||
|
||||
if(LINUX AND NOT ANDROID)
|
||||
install(FILES
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/linux/AmneziaVPN.service
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/linux/AmneziaVPN.png
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/linux/AmneziaVPN.desktop
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/linux/post_install.sh
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/linux/post_uninstall.sh
|
||||
DESTINATION "."
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
install(FILES
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/windows/post_install.cmd
|
||||
${CMAKE_SOURCE_DIR}/deploy/data/windows/post_uninstall.cmd
|
||||
DESTINATION "."
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
endif()
|
||||
|
||||
if (APPLE AND NOT IOS AND NOT MACOS_NE)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/deploy/data/macos/AmneziaVPN.plist
|
||||
DESTINATION "AmneziaVPN.app/Contents/Resources"
|
||||
COMPONENT AmneziaVPN
|
||||
)
|
||||
endif()
|
||||
|
||||
include(CPackIFW)
|
||||
cpack_ifw_configure_component(AmneziaVPN
|
||||
VERSION ${AMNEZIAVPN_VERSION}
|
||||
RELEASE_DATE ${RELEASE_DATE}
|
||||
REQUIRES_ADMIN_RIGHTS
|
||||
FORCED_INSTALLATION
|
||||
SCRIPT ${CMAKE_SOURCE_DIR}/deploy/installer/qif/componentscript.js
|
||||
)
|
||||
|
||||
include(CPack)
|
||||
cpack_add_component(Uninstall
|
||||
DISPLAY_NAME "Uninstall AmneziaVPN"
|
||||
REQUIRES_ADMIN_RIGHTS
|
||||
DISABLED
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
set(CPACK_COMPONENTS_ALL AmneziaVPN)
|
||||
|
||||
if (CPACK_GENERATOR STREQUAL productbuild)
|
||||
list(APPEND CPACK_COMPONENTS_ALL Uninstall)
|
||||
endif()
|
||||
|
||||
if(NOT CODESIGN_INSTALLER_SIGNATURE)
|
||||
set(CODESIGN_INSTALLER_SIGNATURE "$ENV{CODESIGN_INSTALLER_SIGNATURE}")
|
||||
endif()
|
||||
set(CPACK_PRODUCTBUILD_IDENTITY_NAME "${CODESIGN_INSTALLER_SIGNATURE}")
|
||||
set(CPACK_PKGBUILD_IDENTITY_NAME "${CODESIGN_INSTALLER_SIGNATURE}")
|
||||
|
||||
if(NOT CODESIGN_INSTALLER_KEYCHAIN)
|
||||
set(CODESIGN_INSTALLER_KEYCHAIN "$ENV{CODESIGN_INSTALLER_KEYCHAIN}")
|
||||
endif()
|
||||
set(CPACK_PRODUCTBUILD_KEYCHAIN_PATH "${CODESIGN_INSTALLER_KEYCHAIN}")
|
||||
set(CPACK_PKGBUILD_KEYCHAIN_PATH "${CODESIGN_INSTALLER_KEYCHAIN}")
|
||||
@@ -0,0 +1,722 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2024 JFrog
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
set(CONAN_MINIMUM_VERSION 2.0.5)
|
||||
|
||||
# Create a new policy scope and set the minimum required cmake version so the
|
||||
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
|
||||
# even if the parent project does not specify a minimum cmake version or a minimum
|
||||
# version less than this module requires (e.g. 3.0) before the first project() call.
|
||||
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
|
||||
#
|
||||
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
|
||||
# affects the current policy scope, i.e. between the PUSH and POP in this case.
|
||||
#
|
||||
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
|
||||
cmake_policy(PUSH)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
|
||||
function(detect_os os os_api_level os_sdk os_subsystem os_version)
|
||||
# it could be cross compilation
|
||||
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
|
||||
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(${os} Macos PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
||||
set(${os} Neutrino PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
|
||||
set(${os} Windows PARENT_SCOPE)
|
||||
set(${os_subsystem} cygwin PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
|
||||
set(${os} Windows PARENT_SCOPE)
|
||||
set(${os_subsystem} msys2 PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L17C1-L17C34
|
||||
set(${os} Emscripten PARENT_SCOPE)
|
||||
else()
|
||||
set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
if(DEFINED ANDROID_PLATFORM)
|
||||
string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM})
|
||||
elseif(DEFINED CMAKE_SYSTEM_VERSION)
|
||||
set(_os_api_level ${CMAKE_SYSTEM_VERSION})
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: android api level=${_os_api_level}")
|
||||
set(${os_api_level} ${_os_api_level} PARENT_SCOPE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
|
||||
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
|
||||
# generators, but just has the original input string for Xcode.
|
||||
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
|
||||
set(_os_sdk ${CMAKE_OSX_SYSROOT})
|
||||
else()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
|
||||
set(apple_platform_suffix simulator)
|
||||
else()
|
||||
set(apple_platform_suffix os)
|
||||
endif()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
|
||||
set(_os_sdk "appletv${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
|
||||
set(_os_sdk "iphone${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
|
||||
set(_os_sdk "watch${apple_platform_suffix}")
|
||||
endif()
|
||||
endif()
|
||||
if(DEFINED os_sdk)
|
||||
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
|
||||
set(${os_sdk} ${_os_sdk} PARENT_SCOPE)
|
||||
endif()
|
||||
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_arch arch)
|
||||
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
|
||||
# Therefore this code only finds one. If the recipes support multiple architectures, the
|
||||
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
|
||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
|
||||
list(LENGTH apple_arch_list apple_arch_count)
|
||||
if(apple_arch_count GREATER 1)
|
||||
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
elseif(MSVC)
|
||||
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
|
||||
else()
|
||||
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
if(host_arch MATCHES "aarch64|arm64|ARM64")
|
||||
list(APPEND _arch armv8)
|
||||
endif()
|
||||
if(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
|
||||
list(APPEND _arch armv7)
|
||||
endif()
|
||||
if(host_arch MATCHES armv7s)
|
||||
list(APPEND _arch armv7s)
|
||||
endif()
|
||||
if(host_arch MATCHES "i686|i386|X86")
|
||||
list(APPEND _arch x86)
|
||||
endif()
|
||||
if(host_arch MATCHES "AMD64|amd64|x86_64|x64")
|
||||
list(APPEND _arch x86_64)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L294C1-L294C80
|
||||
list(APPEND _arch wasm)
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: cmake_system_processor=${_arch}")
|
||||
list(JOIN _arch "|" _arch)
|
||||
set(${arch} ${_arch} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_cxx_standard compiler cxx_standard)
|
||||
set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
|
||||
if(CMAKE_CXX_EXTENSIONS)
|
||||
if(compiler STREQUAL "msvc")
|
||||
set(${cxx_standard} "${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(detect_gnu_libstdcxx)
|
||||
# _conan_is_gnu_libstdcxx true if GNU libstdc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _conan_is_gnu_libstdcxx)
|
||||
|
||||
# _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI
|
||||
check_cxx_source_compiles("
|
||||
#include <string>
|
||||
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
|
||||
int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
|
||||
set(_conan_gnu_libstdcxx_suffix "")
|
||||
if(_conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
set(_conan_gnu_libstdcxx_suffix "11")
|
||||
endif()
|
||||
unset (_conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(detect_libcxx)
|
||||
# _conan_is_libcxx true if LLVM libc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _conan_is_libcxx)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_lib_cxx lib_cxx)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
|
||||
set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
detect_gnu_libstdcxx()
|
||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
# Check for libc++
|
||||
detect_libcxx()
|
||||
if(_conan_is_libcxx)
|
||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check for libstdc++
|
||||
detect_gnu_libstdcxx()
|
||||
if(_conan_is_gnu_libstdcxx)
|
||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO: it would be an error if we reach this point
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
# Do nothing - compiler.runtime and compiler.runtime_type
|
||||
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
|
||||
return()
|
||||
else()
|
||||
# TODO: unable to determine, ask user to provide a full profile file instead
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type)
|
||||
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
||||
set(_compiler ${CMAKE_CXX_COMPILER_ID})
|
||||
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
|
||||
else()
|
||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
||||
message(FATAL_ERROR "C or C++ compiler not defined")
|
||||
endif()
|
||||
set(_compiler ${CMAKE_C_COMPILER_ID})
|
||||
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: CMake compiler=${_compiler}")
|
||||
message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}")
|
||||
|
||||
if(_compiler MATCHES MSVC)
|
||||
set(_compiler "msvc")
|
||||
string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version)
|
||||
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
|
||||
if(CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
|
||||
else()
|
||||
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
|
||||
endif()
|
||||
|
||||
set(_KNOWN_MSVC_RUNTIME_VALUES "")
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
|
||||
|
||||
# only accept the 6 possible values, otherwise we don't don't know to map this
|
||||
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
|
||||
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
|
||||
endif()
|
||||
|
||||
# Runtime is "dynamic" in all cases if it ends in DLL
|
||||
if(_msvc_runtime_library MATCHES ".*DLL$")
|
||||
set(_compiler_runtime "dynamic")
|
||||
else()
|
||||
set(_compiler_runtime "static")
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}")
|
||||
|
||||
# Only define compiler.runtime_type when explicitly requested
|
||||
# If a generator expression is used, let Conan handle it conditional on build_type
|
||||
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
|
||||
if(_msvc_runtime_library MATCHES "Debug")
|
||||
set(_compiler_runtime_type "Debug")
|
||||
else()
|
||||
set(_compiler_runtime_type "Release")
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}")
|
||||
endif()
|
||||
|
||||
unset(_KNOWN_MSVC_RUNTIME_VALUES)
|
||||
|
||||
elseif(_compiler MATCHES AppleClang)
|
||||
set(_compiler "apple-clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
elseif(_compiler MATCHES Clang)
|
||||
set(_compiler "clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
elseif(_compiler MATCHES GNU)
|
||||
set(_compiler "gcc")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: [settings] compiler=${_compiler}")
|
||||
message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}")
|
||||
if (_compiler_runtime)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}")
|
||||
endif()
|
||||
if (_compiler_runtime_type)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}")
|
||||
endif()
|
||||
|
||||
set(${compiler} ${_compiler} PARENT_SCOPE)
|
||||
set(${compiler_version} ${_compiler_version} PARENT_SCOPE)
|
||||
set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE)
|
||||
set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_build_type build_type)
|
||||
get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT multiconfig_generator)
|
||||
# Only set when we know we are in a single-configuration generator
|
||||
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
|
||||
set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(set_conan_compiler_if_appleclang lang command output_variable)
|
||||
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
|
||||
execute_process(COMMAND xcrun --find ${command}
|
||||
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
|
||||
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
|
||||
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
|
||||
set(${output_variable} "")
|
||||
endif()
|
||||
unset(_xcrun_out)
|
||||
unset(_xcrun_toolchain_path)
|
||||
unset(_compiler_parent_path)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(append_compiler_executables_configuration)
|
||||
set(_conan_c_compiler "")
|
||||
set(_conan_cpp_compiler "")
|
||||
set(_conan_rc_compiler "")
|
||||
set(_conan_compilers_list "")
|
||||
if(CMAKE_C_COMPILER)
|
||||
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"")
|
||||
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
|
||||
list(APPEND _conan_compilers_list ${_conan_c_compiler})
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C compiler is not defined. "
|
||||
"Please define CMAKE_C_COMPILER or enable the C language.")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER)
|
||||
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
|
||||
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
|
||||
list(APPEND _conan_compilers_list ${_conan_cpp_compiler})
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
|
||||
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
|
||||
endif()
|
||||
if(CMAKE_RC_COMPILER)
|
||||
set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"")
|
||||
list(APPEND _conan_compilers_list ${_conan_rc_compiler})
|
||||
# Not necessary to warn if RC not defined
|
||||
endif()
|
||||
if(NOT "x${_conan_compilers_list}" STREQUAL "x")
|
||||
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}")
|
||||
string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n")
|
||||
endif()
|
||||
endif()
|
||||
unset(_conan_c_compiler)
|
||||
unset(_conan_cpp_compiler)
|
||||
unset(_conan_rc_compiler)
|
||||
unset(_conan_compilers_list)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_host_profile output_file)
|
||||
detect_os(os os_api_level os_sdk os_subsystem os_version)
|
||||
detect_arch(arch)
|
||||
detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type)
|
||||
detect_cxx_standard(${compiler} compiler_cppstd)
|
||||
detect_lib_cxx(compiler_libcxx)
|
||||
detect_build_type(build_type)
|
||||
|
||||
set(profile "")
|
||||
string(APPEND profile "[settings]\n")
|
||||
if(arch)
|
||||
string(APPEND profile arch=${arch} "\n")
|
||||
endif()
|
||||
if(os)
|
||||
string(APPEND profile os=${os} "\n")
|
||||
endif()
|
||||
if(os_api_level)
|
||||
string(APPEND profile os.api_level=${os_api_level} "\n")
|
||||
endif()
|
||||
if(os_version)
|
||||
string(APPEND profile os.version=${os_version} "\n")
|
||||
endif()
|
||||
if(os_sdk)
|
||||
string(APPEND profile os.sdk=${os_sdk} "\n")
|
||||
endif()
|
||||
if(os_subsystem)
|
||||
string(APPEND profile os.subsystem=${os_subsystem} "\n")
|
||||
endif()
|
||||
if(compiler)
|
||||
string(APPEND profile compiler=${compiler} "\n")
|
||||
endif()
|
||||
if(compiler_version)
|
||||
string(APPEND profile compiler.version=${compiler_version} "\n")
|
||||
endif()
|
||||
if(compiler_runtime)
|
||||
string(APPEND profile compiler.runtime=${compiler_runtime} "\n")
|
||||
endif()
|
||||
if(compiler_runtime_type)
|
||||
string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n")
|
||||
endif()
|
||||
if(compiler_cppstd)
|
||||
string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n")
|
||||
endif()
|
||||
if(compiler_libcxx)
|
||||
string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n")
|
||||
endif()
|
||||
if(build_type)
|
||||
string(APPEND profile "build_type=${build_type}\n")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED output_file)
|
||||
set(file_name "${CMAKE_BINARY_DIR}/profile")
|
||||
else()
|
||||
set(file_name ${output_file})
|
||||
endif()
|
||||
|
||||
string(APPEND profile "[conf]\n")
|
||||
string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
|
||||
|
||||
# propagate compilers via profile
|
||||
append_compiler_executables_configuration()
|
||||
|
||||
if(os STREQUAL "Android")
|
||||
string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: Creating profile ${file_name}")
|
||||
file(WRITE ${file_name} ${profile})
|
||||
message(STATUS "CMake-Conan: Profile: \n${profile}")
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_profile_detect_default)
|
||||
message(STATUS "CMake-Conan: Checking if a default profile exists")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile path default
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(NOT ${return_code} EQUAL "0")
|
||||
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile detect
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_install)
|
||||
set(conan_output_folder ${CMAKE_BINARY_DIR}/conan)
|
||||
# Invoke "conan install" with the provided arguments
|
||||
set(conan_args -of=${conan_output_folder})
|
||||
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}")
|
||||
|
||||
|
||||
# In case there was not a valid cmake executable in the PATH, we inject the
|
||||
# same we used to invoke the provider to the PATH
|
||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
||||
set(old_path $ENV{PATH})
|
||||
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
||||
set(ENV{PATH} "${old_path}")
|
||||
endif()
|
||||
|
||||
if(NOT "${return_code}" STREQUAL "0")
|
||||
message(FATAL_ERROR "Conan install failed='${return_code}'")
|
||||
endif()
|
||||
|
||||
# the files are generated in a folder that depends on the layout used, if
|
||||
# one is specified, but we don't know a priori where this is.
|
||||
# TODO: this can be made more robust if Conan can provide this in the json output
|
||||
string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder)
|
||||
cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder)
|
||||
|
||||
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}")
|
||||
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}")
|
||||
# reconfigure on conanfile changes
|
||||
string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label)
|
||||
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}")
|
||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}")
|
||||
# success
|
||||
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
|
||||
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_get_version conan_command conan_current_version)
|
||||
execute_process(
|
||||
COMMAND ${conan_command} --version
|
||||
OUTPUT_VARIABLE conan_output
|
||||
RESULT_VARIABLE conan_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(conan_result)
|
||||
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
|
||||
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_version_check)
|
||||
set(options )
|
||||
set(one_value_args MINIMUM CURRENT)
|
||||
set(multi_value_args )
|
||||
cmake_parse_arguments(conan_version_check
|
||||
"${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||
|
||||
if(NOT conan_version_check_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
|
||||
endif()
|
||||
if(NOT conan_version_check_CURRENT)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
|
||||
endif()
|
||||
|
||||
if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(construct_profile_argument argument_variable profile_list)
|
||||
set(${argument_variable} "")
|
||||
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
|
||||
set(_arg_flag "--profile:host=")
|
||||
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
|
||||
set(_arg_flag "--profile:build=")
|
||||
endif()
|
||||
|
||||
set(_profile_list "${${profile_list}}")
|
||||
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
|
||||
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
|
||||
set(${argument_variable} ${_profile_list})
|
||||
|
||||
unset(_arg_flag)
|
||||
unset(_profile_list)
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_provide_dependency method package_name)
|
||||
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
|
||||
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
|
||||
if(NOT _conan_install_success)
|
||||
find_program(CONAN_COMMAND "conan" REQUIRED)
|
||||
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
|
||||
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
|
||||
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
|
||||
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
|
||||
conan_profile_detect_default()
|
||||
endif()
|
||||
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
|
||||
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
|
||||
endif()
|
||||
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
|
||||
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
|
||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
|
||||
if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*")
|
||||
message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile")
|
||||
endif()
|
||||
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
|
||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
|
||||
if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*")
|
||||
message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
if(DEFINED CONAN_INSTALL_BUILD_CONFIGURATIONS)
|
||||
# Configurations are specified by the project or user
|
||||
set(_build_configs "${CONAN_INSTALL_BUILD_CONFIGURATIONS}")
|
||||
list(LENGTH _build_configs _build_configs_length)
|
||||
if(NOT _multiconfig_generator AND _build_configs_length GREATER 1)
|
||||
message(FATAL_ERROR "cmake-conan: when using a single-config CMake generator, "
|
||||
"please only specify a single configuration in CONAN_INSTALL_BUILD_CONFIGURATIONS")
|
||||
endif()
|
||||
unset(_build_configs_length)
|
||||
else()
|
||||
# No configuration overrides, provide sensible defaults
|
||||
if(_multiconfig_generator)
|
||||
set(_build_configs Release Debug)
|
||||
else()
|
||||
set(_build_configs ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
list(JOIN _build_configs ", " _build_configs_msg)
|
||||
message(STATUS "CMake-Conan: Installing configuration(s): ${_build_configs_msg}")
|
||||
foreach(_build_config IN LISTS _build_configs)
|
||||
set(_self_build_config "")
|
||||
if(NOT _multiconfig_generator AND NOT _build_config STREQUAL "${CMAKE_BUILD_TYPE}")
|
||||
set(_self_build_config -s &:build_type=${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=${_build_config} ${_self_build_config} ${CONAN_INSTALL_ARGS})
|
||||
endforeach()
|
||||
|
||||
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
||||
if(EXISTS "${_conan_generators_folder}/conan_cmakedeps_paths.cmake")
|
||||
message(STATUS "CMake-Conan: Loading conan_cmakedeps_paths.cmake file")
|
||||
include(${_conan_generators_folder}/conan_cmakedeps_paths.cmake)
|
||||
endif()
|
||||
|
||||
unset(_self_build_config)
|
||||
unset(_multiconfig_generator)
|
||||
unset(_build_configs)
|
||||
unset(_build_configs_msg)
|
||||
unset(_host_profile_flags)
|
||||
unset(_build_profile_flags)
|
||||
unset(_conan_install_success)
|
||||
else()
|
||||
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
|
||||
unset(_conan_install_success)
|
||||
endif()
|
||||
|
||||
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
||||
|
||||
# Ensure that we consider Conan-provided packages ahead of any other,
|
||||
# irrespective of other settings that modify the search order or search paths
|
||||
# This follows the guidelines from the find_package documentation
|
||||
# (https://cmake.org/cmake/help/latest/command/find_package.html):
|
||||
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
|
||||
# find_package (<PackageName>)
|
||||
|
||||
# Filter out `REQUIRED` from the argument list, as the first call may fail
|
||||
set(_find_args_${package_name} "${ARGN}")
|
||||
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
|
||||
if(NOT "MODULE" IN_LIST _find_args_${package_name})
|
||||
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
unset(_find_args_${package_name})
|
||||
endif()
|
||||
|
||||
# Invoke find_package a second time - if the first call succeeded,
|
||||
# this will simply reuse the result. If not, fall back to CMake default search
|
||||
# behaviour, also allowing modules to be searched.
|
||||
if(NOT ${package_name}_FOUND)
|
||||
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
|
||||
if(_index EQUAL -1)
|
||||
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
||||
endif()
|
||||
unset(_index)
|
||||
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
|
||||
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
cmake_language(
|
||||
SET_DEPENDENCY_PROVIDER conan_provide_dependency
|
||||
SUPPORTED_METHODS FIND_PACKAGE
|
||||
)
|
||||
|
||||
|
||||
macro(conan_provide_dependency_check)
|
||||
set(_conan_provide_dependency_invoked FALSE)
|
||||
get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
||||
if(NOT _conan_provide_dependency_invoked)
|
||||
message(WARNING "Conan is correctly configured as dependency provider, "
|
||||
"but Conan has not been invoked. Please add at least one "
|
||||
"call to `find_package()`.")
|
||||
if(DEFINED CONAN_COMMAND)
|
||||
# supress warning in case `CONAN_COMMAND` was specified but unused.
|
||||
set(_conan_command ${CONAN_COMMAND})
|
||||
unset(_conan_command)
|
||||
endif()
|
||||
endif()
|
||||
unset(_conan_provide_dependency_invoked)
|
||||
endmacro()
|
||||
|
||||
|
||||
# Add a deferred call at the end of processing the top-level directory
|
||||
# to check if the dependency provider was invoked at all.
|
||||
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
|
||||
|
||||
# Configurable variables for Conan profiles
|
||||
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
|
||||
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
|
||||
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
|
||||
|
||||
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
if(NOT _cmake_program)
|
||||
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
|
||||
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
|
||||
endif()
|
||||
|
||||
cmake_policy(POP)
|
||||
@@ -0,0 +1,40 @@
|
||||
if(APPLE)
|
||||
get_property(generator_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if (generator_is_multi_config)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(CONAN_INSTALL_BUILD_CONFIGURATIONS RelWithDebInfo)
|
||||
else()
|
||||
set(CONAN_INSTALL_BUILD_CONFIGURATIONS Release Debug MinSizeRel RelWithDebInfo)
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(CONAN_INSTALL_ARGS "--build=missing;-o;openssl/3.6.1:no_apps=True" CACHE STRING "" FORCE)
|
||||
set(AMNEZIA_IOS_ENABLE_APPLETV_TARGET ON CACHE BOOL "" FORCE)
|
||||
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "17.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE)
|
||||
elseif(MACOS_NE)
|
||||
set(CONAN_INSTALL_ARGS "--build=missing;-o=&:macos_ne=True" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
set(CONAN_INSTALL_ARGS
|
||||
"--build=missing"
|
||||
"-c=tools.android:cmake_legacy_toolchain=false"
|
||||
"-c=tools.build:sharedlinkflags=['-Wl,-z,max-page-size=16384']"
|
||||
"-c=tools.build:exelinkflags=['-Wl,-z,max-page-size=16384']"
|
||||
CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
endif()
|
||||
@@ -0,0 +1,9 @@
|
||||
find_program(CONAN_COMMAND "conan" REQUIRED)
|
||||
|
||||
file(GLOB_RECURSE LOCAL_RECIPES "${CMAKE_SOURCE_DIR}/recipes/*/conanfile.py")
|
||||
foreach(RECIPE ${LOCAL_RECIPES})
|
||||
get_filename_component(RECIPE_DIR ${RECIPE} DIRECTORY)
|
||||
execute_process(
|
||||
COMMAND ${CONAN_COMMAND} export ${RECIPE_DIR}
|
||||
)
|
||||
endforeach()
|
||||
@@ -0,0 +1,49 @@
|
||||
if(NOT DEFINED SIGNTOOL_SUBJECT_NAME)
|
||||
set(SIGNTOOL_SUBJECT_NAME "$ENV{SIGNTOOL_SUBJECT_NAME}")
|
||||
endif()
|
||||
if(NOT DEFINED CODESIGN_SIGNATURE)
|
||||
set(CODESIGN_SIGNATURE "$ENV{CODESIGN_SIGNATURE}")
|
||||
endif()
|
||||
if(NOT DEFINED CODESIGN_KEYCHAIN)
|
||||
set(CODESIGN_KEYCHAIN "$ENV{CODESIGN_KEYCHAIN}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
file(GLOB_RECURSE BINARIES
|
||||
"${CPACK_TEMPORARY_DIRECTORY}/*.dll"
|
||||
"${CPACK_TEMPORARY_DIRECTORY}/*.exe"
|
||||
)
|
||||
|
||||
if(BINARIES AND SIGNTOOL_SUBJECT_NAME)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/util/signtool.cmake)
|
||||
signtool_sign_files("${BINARIES}" "${SIGNTOOL_SUBJECT_NAME}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
file(GLOB_RECURSE all_subdirs LIST_DIRECTORIES true "${CPACK_TEMPORARY_DIRECTORY}/*")
|
||||
|
||||
set(frameworks ${all_subdirs})
|
||||
list(FILTER frameworks INCLUDE REGEX [[.*\.framework$]])
|
||||
|
||||
file(GLOB_RECURSE dylibs "${CPACK_TEMPORARY_DIRECTORY}/*.dylib")
|
||||
|
||||
set(bundle ${all_subdirs})
|
||||
list(FILTER bundle INCLUDE REGEX [[.*\.app$]])
|
||||
list(GET bundle 0 bundle)
|
||||
|
||||
file(GLOB_RECURSE execs "${bundle}/Contents/MacOS/*")
|
||||
set(client_exec ${execs})
|
||||
list(FILTER client_exec INCLUDE REGEX [[AmneziaVPN$]])
|
||||
set(service_exec ${execs})
|
||||
list(FILTER service_exec INCLUDE REGEX [[AmneziaVPN-service$]])
|
||||
set(other_execs ${execs})
|
||||
list(FILTER other_execs EXCLUDE REGEX [[AmneziaVPN$|AmneziaVPN-service$]])
|
||||
|
||||
list(APPEND files "${frameworks}" "${dylibs}" "${other_execs}" "${service_exec}" "${client_exec}" "${bundle}")
|
||||
|
||||
if (files AND CODESIGN_SIGNATURE)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/util/codesign.cmake)
|
||||
codesign_sign_files("${files}" "${CODESIGN_SIGNATURE}" "${CODESIGN_KEYCHAIN}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,30 @@
|
||||
if(NOT DEFINED SIGNTOOL_SUBJECT_NAME)
|
||||
set(SIGNTOOL_SUBJECT_NAME "$ENV{SIGNTOOL_SUBJECT_NAME}")
|
||||
endif()
|
||||
if(NOT DEFINED NOTARYTOOL_EMAIL)
|
||||
set(NOTARYTOOL_EMAIL "$ENV{NOTARYTOOL_EMAIL}")
|
||||
endif()
|
||||
if(NOT DEFINED NOTARYTOOL_TEAM_ID)
|
||||
set(NOTARYTOOL_TEAM_ID "$ENV{NOTARYTOOL_TEAM_ID}")
|
||||
endif()
|
||||
if(NOT DEFINED NOTARYTOOL_PASSWORD)
|
||||
set(NOTARYTOOL_PASSWORD "$ENV{NOTARYTOOL_PASSWORD}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if (SIGNTOOL_SUBJECT_NAME)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/util/signtool.cmake)
|
||||
foreach(PACKAGE_FILE IN LISTS CPACK_PACKAGE_FILES)
|
||||
signtool_sign_files("${PACKAGE_FILE}" "${SIGNTOOL_SUBJECT_NAME}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(NOTARYTOOL_EMAIL AND NOTARYTOOL_TEAM_ID AND NOTARYTOOL_PASSWORD)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/util/notarytool.cmake)
|
||||
foreach(file IN LISTS CPACK_PACKAGE_FILES)
|
||||
notarize_and_staple_file("${file}" "${NOTARYTOOL_EMAIL}" "${NOTARYTOOL_TEAM_ID}" "${NOTARYTOOL_PASSWORD}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,36 @@
|
||||
find_program(CODESIGN_COMMAND codesign REQUIRED)
|
||||
|
||||
function(codesign_sign_files files signature keychain)
|
||||
if (NOT signature)
|
||||
message(FATAL_ERROR "codesign failed: signature is required")
|
||||
endif()
|
||||
|
||||
set(args
|
||||
--force
|
||||
--verbose
|
||||
--timestamp
|
||||
--options runtime
|
||||
--sign "${signature}"
|
||||
)
|
||||
|
||||
if(keychain)
|
||||
list(APPEND args --keychain "${keychain}")
|
||||
endif()
|
||||
|
||||
foreach(file IN LISTS files)
|
||||
set(cmd ${CODESIGN_COMMAND} ${args} "${file}")
|
||||
|
||||
list(JOIN cmd " " cmd_str)
|
||||
message(STATUS "${cmd_str}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${cmd}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE error
|
||||
)
|
||||
if(NOT result EQUAL 0)
|
||||
string(REPLACE "\n" "\n " error " ${error}")
|
||||
message(FATAL_ERROR "codesign failed:\n${error}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
@@ -0,0 +1,46 @@
|
||||
find_program(XCRUN_COMMAND xcrun REQUIRED)
|
||||
|
||||
function(notarize_file file email team_id password)
|
||||
set(args
|
||||
--apple-id ${email}
|
||||
--team-id ${team_id}
|
||||
--password ${password}
|
||||
--wait
|
||||
)
|
||||
|
||||
set(cmd ${XCRUN_COMMAND} notarytool submit ${args} ${file})
|
||||
|
||||
list(JOIN cmd " " cmd_str)
|
||||
message(STATUS ${cmd_str})
|
||||
|
||||
execute_process(COMMAND ${cmd}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE error
|
||||
)
|
||||
if(NOT result EQUAL 0)
|
||||
string(REPLACE "\n" "\n " error " ${error}")
|
||||
message(FATAL_ERROR "notarytool failed:\n${error}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(staple_file file)
|
||||
set(cmd ${XCRUN_COMMAND} stapler staple ${file})
|
||||
|
||||
list(JOIN cmd " " cmd_str)
|
||||
message(STATUS ${cmd_str})
|
||||
|
||||
execute_process(COMMAND ${cmd}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE error
|
||||
)
|
||||
if(NOT result EQUAL 0)
|
||||
string(REPLACE "\n" "\n " error " ${error}")
|
||||
message(FATAL_ERROR "stapler failed:\n${error}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(notarize_and_staple_file file email team_id password)
|
||||
notarize_file("${file}" "${email}" "${team_id}" "${password}")
|
||||
staple_file("${file}")
|
||||
endfunction()
|
||||
@@ -0,0 +1,38 @@
|
||||
find_program(SIGNTOOL_COMMAND signtool REQUIRED)
|
||||
|
||||
function(signtool_sign_files PACKAGE_FILES SUBJECT_NAME)
|
||||
if(NOT SUBJECT_NAME)
|
||||
set(SUBJECT_NAME "Privacy Technologies OU")
|
||||
endif()
|
||||
|
||||
if(PACKAGE_FILES)
|
||||
set(args sign
|
||||
/n ${SUBJECT_NAME}
|
||||
/fd sha256
|
||||
/td sha256
|
||||
/tr http://timestamp.comodoca.com/?td=sha256
|
||||
)
|
||||
|
||||
foreach(file IN LISTS PACKAGE_FILES)
|
||||
set(local_args ${args})
|
||||
if (NOT "${file}" MATCHES "\\.msi$")
|
||||
list(APPEND local_args /as)
|
||||
endif()
|
||||
|
||||
set(cmd ${SIGNTOOL_COMMAND} ${local_args} ${file})
|
||||
|
||||
list(JOIN cmd " " cmd_str)
|
||||
message(STATUS "${cmd_str}")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${cmd}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE error
|
||||
)
|
||||
if(NOT result EQUAL 0)
|
||||
string(REPLACE "\n" "\n " error " ${error}")
|
||||
message(FATAL_ERROR "signtool failed:\n${error}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,46 @@
|
||||
from conan import ConanFile
|
||||
|
||||
class AmneziaVPN(ConanFile):
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "VirtualBuildEnv", "CMakeConfigDeps"
|
||||
|
||||
options = {
|
||||
"macos_ne": [True, False]
|
||||
}
|
||||
default_options = {
|
||||
"macos_ne": False
|
||||
}
|
||||
|
||||
def requirements(self):
|
||||
os = str(self.settings.os)
|
||||
|
||||
has_ne = os in ["iOS", "tvOS"] or (os == "Macos" and self.options.macos_ne)
|
||||
has_service = os == "Windows" or os == "Linux" or (os == "Macos" and not has_ne)
|
||||
|
||||
if has_service:
|
||||
if os == "Windows":
|
||||
self.requires("awg-windows/0.1.8")
|
||||
self.requires("tap-windows6/9.27.0")
|
||||
self.requires("win-split-tunnel/1.2.5.0")
|
||||
self.requires("wintun/0.14.1")
|
||||
else:
|
||||
self.requires("awg-go/0.2.16")
|
||||
|
||||
self.requires("amnezia-xray-bindings/1.1.0")
|
||||
self.requires("tun2socks/2.6.0")
|
||||
self.requires("openvpn/2.7.0")
|
||||
self.requires("v2ray-rules-dat/202603162227")
|
||||
|
||||
if has_ne:
|
||||
self.requires("awg-apple/2.0.1")
|
||||
if os != "tvOS":
|
||||
self.requires("hev-socks5-tunnel/2.14.4", options={"as_framework": True})
|
||||
self.requires("openvpnadapter/1.0.0")
|
||||
|
||||
if os == "Android":
|
||||
self.requires("amnezia-libxray/1.0.0")
|
||||
self.requires("awg-android/1.1.7")
|
||||
self.requires("openvpn-pt-android/1.0.0")
|
||||
|
||||
self.requires("libssh/0.11.3@amnezia")
|
||||
self.requires("openssl/3.6.1", options={"no_apps": os == "tvOS"}, force=os == "tvOS")
|
||||
@@ -0,0 +1,147 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
set "PROJECT_DIR=%cd%"
|
||||
set "BUILD_DIR=%PROJECT_DIR%\deploy\build"
|
||||
|
||||
:parse_args
|
||||
if "%~1"=="" goto :done_args
|
||||
if /i "%~1" == "-i" set "ARG_BUILD_INSTALLERS=!ARG_BUILD_INSTALLERS! %~2" & shift
|
||||
if /i "%~1" == "--installer" set "ARG_BUILD_INSTALLERS=!ARG_BUILD_INSTALLERS! %~2" & shift
|
||||
if /i "%~1" == "-arch" set "ARCH=%~2" & shift
|
||||
if /i "%~1" == "--architecture" set "ARCH=%~2" & shift
|
||||
shift
|
||||
goto :parse_args
|
||||
:done_args
|
||||
|
||||
if defined ARG_BUILD_INSTALLERS set "ARG_BUILD_INSTALLERS=%ARG_BUILD_INSTALLERS:all=ifw wix%"
|
||||
|
||||
:: understand toolchain arch (host_target) and Qt prefix path
|
||||
if not defined ARCH set "ARCH=%PROCESSOR_ARCHITECTURE%"
|
||||
if /i "%ARCH%" == "x64" set "ARCH=amd64"
|
||||
if /i "%ARCH%" == "amd64" (
|
||||
if /i "%PROCESSOR_ARCHITECTURE%" == "AMD64" set "_vcvars_arg=amd64"
|
||||
if /i "%PROCESSOR_ARCHITECTURE%" == "x86" set "_vcvars_arg=x86_amd64"
|
||||
set "_qt_postfix_arg=64"
|
||||
)
|
||||
if /i "%ARCH%" == "arm64" (
|
||||
if /i "%PROCESSOR_ARCHITECTURE%" == "AMD64" set "_vcvars_arg=amd64_arm64"
|
||||
if /i "%PROCESSOR_ARCHITECTURE%" == "x86" set "_vcvars_arg=x86_arm64"
|
||||
set "_qt_postfix_arg=arm64"
|
||||
)
|
||||
if not defined _vcvars_arg (
|
||||
echo ERROR: Unsupported architecture "%ARCH%"
|
||||
goto :fail
|
||||
)
|
||||
|
||||
if not defined QT_VERSION set "QT_VERSION=6.*"
|
||||
if not defined QIF_VERSION set "QIF_VERSION=*"
|
||||
|
||||
set "_qt_bases=%USERPROFILE%\Qt C:\Qt"
|
||||
if defined QT_INSTALL_DIR set "_qt_bases=%QT_INSTALL_DIR%\Qt %_qt_bases%"
|
||||
|
||||
:: search over Qt dirs to find framework and tools paths
|
||||
for %%B in (%_qt_bases%) do (
|
||||
if exist "%%~B" (
|
||||
for /d %%D in (%%~B\%QT_VERSION%) do (
|
||||
if not defined _qt_root_path (
|
||||
set "_qt_root_path=%%D"
|
||||
) else (
|
||||
for %%I in (!_qt_root_path!) do call :compare_versions "%%~nxI" "%%~nxD"
|
||||
if errorlevel 1 set "_qt_root_path=%%D"
|
||||
)
|
||||
)
|
||||
|
||||
for /d %%D in (%%~B\Tools\QtInstallerFramework\%QIF_VERSION%) do (
|
||||
if not defined _qif_root_path (
|
||||
set "_qif_root_path=%%D"
|
||||
) else (
|
||||
for %%I in (!_qif_root_path!) do call :compare_versions "%%~nxI" "%%~nxD"
|
||||
if errorlevel 1 set "_qif_root_path=%%D"
|
||||
)
|
||||
)
|
||||
|
||||
if exist "%%~B\Tools\Ninja" set "PATH=%PATH%;%%~B\Tools\Ninja"
|
||||
)
|
||||
)
|
||||
|
||||
if not defined QT_ROOT_PATH set "QT_ROOT_PATH=%_qt_root_path%"
|
||||
if not defined QIF_ROOT_PATH set "QIF_ROOT_PATH=%_qif_root_path%"
|
||||
|
||||
:: use vswhere to find path to vcvarsall.bat
|
||||
if not defined VCINSTALLDIR (
|
||||
if not defined VS_INSTALLER_PATH set "VS_INSTALLER_PATH=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
if exist "%VS_INSTALLER_PATH%" (
|
||||
if defined "%VS_INSTALLATION_VERSION%" (
|
||||
set "_version=-version [%VS_INSTALLATION_VERSION%]"
|
||||
) else (
|
||||
set "_version=-latest"
|
||||
)
|
||||
for /f "usebackq tokens=*" %%I in (
|
||||
`"%VS_INSTALLER_PATH%" -products * %_version% -property resolvedInstallationPath`
|
||||
) do (
|
||||
if not defined VCVARS_PATH set "VCVARS_PATH=%%I\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
:: setup MSVC toolchain using vsvarsall.bat
|
||||
if exist "%VCVARS_PATH%" (
|
||||
@echo on
|
||||
call "%VCVARS_PATH%" %_vcvars_arg%
|
||||
@echo off
|
||||
if errorlevel 1 goto :fail
|
||||
)
|
||||
|
||||
:: build project and installers
|
||||
@echo on
|
||||
cmake -S "%PROJECT_DIR%" -B "%BUILD_DIR%" -DCMAKE_BUILD_TYPE=Release "-DCMAKE_PREFIX_PATH=%QT_ROOT_PATH%\msvc2022_%_qt_postfix_arg%" || goto :fail
|
||||
cmake --build "%BUILD_DIR%" --config Release || goto :fail
|
||||
@echo off
|
||||
for %%I in (%ARG_BUILD_INSTALLERS%) do (
|
||||
if /i "%%I" == "ifw" call :do_ifw
|
||||
if /i "%%I" == "wix" call :do_wix
|
||||
if errorlevel 1 goto :fail
|
||||
)
|
||||
goto :eof
|
||||
|
||||
:: bakes IFW installer
|
||||
:do_ifw
|
||||
@echo on
|
||||
cd "%BUILD_DIR%" && cpack -G IFW -D "QTIFWDIR=%QIF_ROOT_PATH%" || goto :fail
|
||||
@echo off
|
||||
goto :eof
|
||||
|
||||
:: bakes WIX installer
|
||||
:do_wix
|
||||
@echo on
|
||||
cd "%BUILD_DIR%" && cpack -G WIX -D "WIX_BIN_DIR=%WIX_ROOT_PATH%" || goto :fail
|
||||
@echo off
|
||||
goto :eof
|
||||
|
||||
:fail
|
||||
exit /b 1
|
||||
|
||||
:: compares any two versions
|
||||
:compare_versions
|
||||
set "_left=%~1"
|
||||
set "_right=%~2"
|
||||
|
||||
set "_left_temp=%_left%"
|
||||
set "_right_temp=%_right%"
|
||||
|
||||
:seg_loop
|
||||
set "_ls=0"
|
||||
for /f "tokens=1* delims=." %%A in ("%_left_temp%") do (
|
||||
set "_ls=%%A" & set "_left_temp=%%B"
|
||||
)
|
||||
set "_rs=0"
|
||||
for /f "tokens=1* delims=." %%A in ("%_right_temp%") do (
|
||||
set "_rs=%%A" & set "_right_temp=%%B"
|
||||
)
|
||||
|
||||
if %_rs% GTR %_ls% exit /b 1
|
||||
if %_rs% LSS %_ls% exit /b -1
|
||||
if defined _left_temp goto :seg_loop
|
||||
if defined _right_temp goto :seg_loop
|
||||
exit /b 0
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
|
||||
PROJECT_DIR=$(pwd)
|
||||
BUILD_DIR="$PROJECT_DIR/deploy/build"
|
||||
|
||||
bases=(~/Qt /opt/Qt)
|
||||
[ -n "${QT_INSTALL_DIR}" ] && bases+=("${QT_INSTALL_DIR}/Qt")
|
||||
|
||||
qt_folders=()
|
||||
qif_folders=()
|
||||
for base in "${bases[@]}"; do
|
||||
for dir in "$base"/${QT_VERSION:-6.*}; do
|
||||
[ -d "$dir" ] && qt_folders+=("$dir")
|
||||
done
|
||||
for dir in "$base"/Tools/QtInstallerFramework/${QIF_VERSION:-*}; do
|
||||
[ -d "$dir" ] && qif_folders+=("$dir")
|
||||
done
|
||||
done
|
||||
|
||||
: ${QT_ROOT_PATH:=$(printf '%s\n' "${qt_folders[@]}" | sort -V | tail -1)}
|
||||
: ${QIF_ROOT_PATH:=$(printf '%s\n' "${qif_folders[@]}" | sort -V | tail -1)}
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux)
|
||||
: ${QT_PREFIX_PATH:="$QT_ROOT_PATH"/gcc_64}
|
||||
;;
|
||||
Darwin)
|
||||
: ${QT_PREFIX_PATH:="$QT_ROOT_PATH"/macos}
|
||||
;;
|
||||
esac
|
||||
|
||||
args=()
|
||||
if [ -n "${QT_PREFIX_PATH}" ]; then
|
||||
args+=("-DCMAKE_PREFIX_PATH=$QT_PREFIX_PATH")
|
||||
fi
|
||||
|
||||
set -o xtrace
|
||||
|
||||
cmake -S "$PROJECT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release "${args[@]}"
|
||||
cmake --build "$BUILD_DIR" --target all
|
||||
(cd "$BUILD_DIR" && cpack -D QTIFWDIR="$QIF_ROOT_PATH")
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo "Build script started ..."
|
||||
|
||||
set -o errexit -o nounset
|
||||
|
||||
|
||||
# Hold on to current directory
|
||||
PROJECT_DIR=$(pwd)
|
||||
DEPLOY_DIR=$PROJECT_DIR/deploy
|
||||
|
||||
mkdir -p $DEPLOY_DIR/build
|
||||
BUILD_DIR=$DEPLOY_DIR/build
|
||||
|
||||
APP_DIR=$DEPLOY_DIR/AppDir
|
||||
mkdir -p $APP_DIR
|
||||
|
||||
TOOLS_DIR=$DEPLOY_DIR/Tools
|
||||
mkdir -p $TOOLS_DIR
|
||||
|
||||
CQTDEPLOYER_DIR=$TOOLS_DIR/cqtdeployer
|
||||
mkdir -p $CQTDEPLOYER_DIR
|
||||
|
||||
echo "Project dir: ${PROJECT_DIR}"
|
||||
echo "Build dir: ${BUILD_DIR}"
|
||||
|
||||
APP_NAME=AmneziaVPN
|
||||
APP_FILENAME=$APP_NAME.app
|
||||
APP_DOMAIN=org.amneziavpn.package
|
||||
|
||||
DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/linux
|
||||
PREBUILT_DEPLOY_DATA_DIR=$PROJECT_DIR/client/3rd-prebuilt/deploy-prebuilt/linux/client/bin
|
||||
INSTALLER_DATA_DIR=$PROJECT_DIR/deploy/installer/packages/$APP_DOMAIN/data
|
||||
|
||||
PRO_FILE_PATH=$PROJECT_DIR/$APP_NAME.pro
|
||||
QMAKE_STASH_FILE=$PROJECT_DIR/.qmake_stash
|
||||
|
||||
# Search Qt
|
||||
if [ -z "${QT_VERSION+x}" ]; then
|
||||
QT_VERSION=6.6.2
|
||||
if [ -f /opt/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then
|
||||
QT_BIN_DIR=/opt/Qt/$QT_VERSION/gcc_64/bin
|
||||
elif [ -f $HOME/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then
|
||||
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/gcc_64/bin
|
||||
elif [ -f /usr/lib/qt6/bin/qmake ]; then
|
||||
QT_BIN_DIR=/usr/lib/qt6/bin
|
||||
elif [ -f /usr/lib/x86_64-linux-gnu/qt6/bin/qmake ]; then
|
||||
QT_BIN_DIR=/usr/lib/x86_64-linux-gnu/qt6/bin
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Using Qt in $QT_BIN_DIR"
|
||||
|
||||
|
||||
# Checking env
|
||||
$QT_BIN_DIR/qt-cmake --version
|
||||
gcc -v
|
||||
|
||||
# Build App
|
||||
echo "Building App..."
|
||||
cd $BUILD_DIR
|
||||
|
||||
$QT_BIN_DIR/qt-cmake -S $PROJECT_DIR
|
||||
cmake --build . -j --config release
|
||||
|
||||
# Build and run tests here
|
||||
|
||||
#echo "............Deploy.................."
|
||||
|
||||
cp -r $DEPLOY_DATA_DIR/* $APP_DIR
|
||||
cp -r $PREBUILT_DEPLOY_DATA_DIR $APP_DIR/client
|
||||
|
||||
if [ ! -f $CQTDEPLOYER_DIR/cqtdeployer.sh ]; then
|
||||
wget -O $TOOLS_DIR/CQtDeployer.zip https://github.com/QuasarApp/CQtDeployer/releases/download/v1.5.4.17/CQtDeployer_1.5.4.17_Linux_x86_64.zip
|
||||
unzip -o $TOOLS_DIR/CQtDeployer.zip -d $CQTDEPLOYER_DIR/
|
||||
chmod +x -R $CQTDEPLOYER_DIR
|
||||
fi
|
||||
|
||||
|
||||
$CQTDEPLOYER_DIR/cqtdeployer.sh -bin $BUILD_DIR/client/AmneziaVPN -qmake $QT_BIN_DIR/qmake -qmlDir $PROJECT_DIR/client/ui/qml/ -targetDir $APP_DIR/client/
|
||||
$CQTDEPLOYER_DIR/cqtdeployer.sh -bin $BUILD_DIR/service/server/AmneziaVPN-service -qmake $QT_BIN_DIR/qmake -targetDir $APP_DIR/service/
|
||||
|
||||
rm -f $INSTALLER_DATA_DIR/data.7z
|
||||
|
||||
7z a $INSTALLER_DATA_DIR/data.7z $APP_DIR/*
|
||||
|
||||
ldd $CQTDEPLOYER_DIR/bin/binarycreator
|
||||
|
||||
cp -r $PROJECT_DIR/deploy/installer $BUILD_DIR
|
||||
|
||||
$CQTDEPLOYER_DIR/binarycreator.sh --offline-only -v -c $BUILD_DIR/installer/config/linux.xml -p $BUILD_DIR/installer/packages -f $PROJECT_DIR/deploy/AmneziaVPN_Linux_Installer.bin
|
||||
@@ -1,287 +0,0 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# Usage:
|
||||
# Export the required signing credentials before running this script, e.g.:
|
||||
# export MAC_APP_CERT_PW='pw-for-DeveloperID-Application'
|
||||
# export MAC_INSTALL_CERT_PW='pw-for-DeveloperID-Installer'
|
||||
# export MAC_SIGNER_ID='Developer ID Application: Some Company Name (XXXXXXXXXX)'
|
||||
# export MAC_INSTALLER_SIGNER_ID='Developer ID Installer: Some Company Name (XXXXXXXXXX)'
|
||||
# export APPLE_DEV_EMAIL='your@email.com'
|
||||
# export APPLE_DEV_PASSWORD='<your-password>'
|
||||
# bash deploy/build_macos.sh [-n]
|
||||
# -----------------------------------------------------------------------------
|
||||
echo "Build script started ..."
|
||||
|
||||
set -o errexit -o nounset
|
||||
|
||||
while getopts n flag
|
||||
do
|
||||
case "${flag}" in
|
||||
n) NOTARIZE_APP=1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Hold on to current directory
|
||||
PROJECT_DIR=$(pwd)
|
||||
DEPLOY_DIR=$PROJECT_DIR/deploy
|
||||
|
||||
mkdir -p "$DEPLOY_DIR/build"
|
||||
BUILD_DIR="$DEPLOY_DIR/build"
|
||||
|
||||
echo "Project dir: ${PROJECT_DIR}"
|
||||
echo "Build dir: ${BUILD_DIR}"
|
||||
|
||||
APP_NAME=AmneziaVPN
|
||||
APP_FILENAME=$APP_NAME.app
|
||||
APP_DOMAIN=org.amneziavpn.package
|
||||
PLIST_NAME=$APP_NAME.plist
|
||||
|
||||
OUT_APP_DIR=$BUILD_DIR/client
|
||||
BUNDLE_DIR=$OUT_APP_DIR/$APP_FILENAME
|
||||
|
||||
# Prebuilt deployment assets are available via the symlink under deploy/data
|
||||
PREBUILT_DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/deploy-prebuilt/macos
|
||||
DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/macos
|
||||
|
||||
|
||||
# Search Qt
|
||||
if [ -z "${QT_VERSION+x}" ]; then
|
||||
QT_VERSION=6.8.3;
|
||||
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/macos/bin
|
||||
fi
|
||||
|
||||
echo "Using Qt in $QT_BIN_DIR"
|
||||
|
||||
|
||||
# Checking env
|
||||
"$QT_BIN_DIR/qt-cmake" --version
|
||||
cmake --version
|
||||
clang -v
|
||||
|
||||
# Build App
|
||||
echo "Building App..."
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
"$QT_BIN_DIR/qt-cmake" -S "$PROJECT_DIR" -B "$BUILD_DIR"
|
||||
cmake --build . --config release --target all
|
||||
|
||||
# Build and run tests here
|
||||
|
||||
# Create a temporary keychain and import certificates
|
||||
KEYCHAIN_PATH="$PROJECT_DIR/mac_sign.keychain"
|
||||
trap 'echo "Cleaning up mac_sign.keychain..."; security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true; rm -f "$KEYCHAIN_PATH" 2>/dev/null || true' EXIT
|
||||
KEYCHAIN=$(security default-keychain -d user | tr -d '"[:space:]"')
|
||||
|
||||
# Build a clean list of the *existing* user key-chains. The raw output of
|
||||
# security list-keychains -d user
|
||||
# looks roughly like:
|
||||
# " \"/Users/foo/Library/Keychains/login.keychain-db\"\n \"/Library/Keychains/System.keychain\""
|
||||
# Every entry is surrounded by quotes and indented with a few blanks. Feeding
|
||||
# that verbatim back to `security list-keychains -s` inside a single quoted
|
||||
# argument leads to one long, invalid path on some systems. We therefore strip
|
||||
# the quotes and rely on the shell to split the string on whitespace so that
|
||||
# each path becomes its own argument.
|
||||
|
||||
read -ra EXISTING_KEYCHAINS <<< "$(security list-keychains -d user | tr -d '"')"
|
||||
|
||||
security list-keychains -d user -s "$KEYCHAIN_PATH" "$KEYCHAIN" "${EXISTING_KEYCHAINS[@]}"
|
||||
KEYCHAIN_PWD="" # Empty password keeps things simple for CI jobs
|
||||
# Create, unlock and configure the temporary key-chain so that `codesign` can
|
||||
# access the imported identities without triggering interactive prompts.
|
||||
security create-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
|
||||
# Keep the key-chain unlocked for the duration of the job (6 hours is plenty).
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
||||
security unlock-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
|
||||
|
||||
# Import the signing certificates only when the corresponding passwords are
|
||||
# available in the environment. This allows the script to run in environments
|
||||
# where code-signing is intentionally turned off (e.g. CI jobs that just build
|
||||
# the artefacts without releasing them).
|
||||
|
||||
if [ -n "${MAC_APP_CERT_PW-}" ]; then
|
||||
# If the certificate is provided via environment variable, decode it.
|
||||
if [ -n "${MAC_APP_CERT_CERT-}" ]; then
|
||||
echo "$MAC_APP_CERT_CERT" | base64 -d > "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12"
|
||||
fi
|
||||
security import "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12" \
|
||||
-k "$KEYCHAIN_PATH" -P "$MAC_APP_CERT_PW" -A
|
||||
fi
|
||||
|
||||
if [ -n "${MAC_INSTALL_CERT_PW-}" ]; then
|
||||
# Same logic for the installer certificate.
|
||||
if [ -n "${MAC_INSTALLER_SIGNER_CERT-}" ]; then
|
||||
echo "$MAC_INSTALLER_SIGNER_CERT" | base64 -d > "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12"
|
||||
fi
|
||||
security import "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12" \
|
||||
-k "$KEYCHAIN_PATH" -P "$MAC_INSTALL_CERT_PW" -A
|
||||
fi
|
||||
|
||||
# This certificate has no password.
|
||||
security import "$DEPLOY_DIR/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign
|
||||
|
||||
security list-keychains -d user -s "$KEYCHAIN_PATH"
|
||||
|
||||
echo "____________________________________"
|
||||
echo "............Deploy.................."
|
||||
echo "____________________________________"
|
||||
|
||||
# Package
|
||||
echo "Packaging ..."
|
||||
|
||||
|
||||
cp -Rv "$PREBUILT_DEPLOY_DATA_DIR"/* "$BUNDLE_DIR/Contents/macOS"
|
||||
"$QT_BIN_DIR/macdeployqt" "$OUT_APP_DIR/$APP_FILENAME" -always-overwrite -qmldir="$PROJECT_DIR"
|
||||
cp -av "$BUILD_DIR/service/server/$APP_NAME-service" "$BUNDLE_DIR/Contents/macOS"
|
||||
rsync -av --exclude="$PLIST_NAME" --exclude=post_install.sh --exclude=post_uninstall.sh "$DEPLOY_DATA_DIR/" "$BUNDLE_DIR/Contents/macOS/"
|
||||
|
||||
if [ "${MAC_APP_CERT_PW+x}" ]; then
|
||||
|
||||
# Path to the p12 that contains the Developer ID *Application* certificate
|
||||
CERTIFICATE_P12=$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12
|
||||
|
||||
# Ensure launchd plist is bundled, but place it inside Resources so that
|
||||
# the bundle keeps a valid structure (nothing but `Contents` at the root).
|
||||
mkdir -p "$BUNDLE_DIR/Contents/Resources"
|
||||
cp "$DEPLOY_DATA_DIR/$PLIST_NAME" "$BUNDLE_DIR/Contents/Resources/$PLIST_NAME"
|
||||
|
||||
# Show available signing identities (useful for debugging)
|
||||
security find-identity -p codesigning || true
|
||||
|
||||
echo "Signing App bundle..."
|
||||
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$BUNDLE_DIR"
|
||||
/usr/bin/codesign --verify -vvvv "$BUNDLE_DIR" || true
|
||||
spctl -a -vvvv "$BUNDLE_DIR" || true
|
||||
|
||||
fi
|
||||
|
||||
echo "Packaging installer..."
|
||||
PKG_DIR=$BUILD_DIR/pkg
|
||||
# Remove any stale packaging data from previous runs
|
||||
rm -rf "$PKG_DIR"
|
||||
PKG_ROOT=$PKG_DIR/root
|
||||
SCRIPTS_DIR=$PKG_DIR/scripts
|
||||
RESOURCES_DIR=$PKG_DIR/resources
|
||||
INSTALL_PKG=$PKG_DIR/${APP_NAME}_install.pkg
|
||||
UNINSTALL_PKG=$PKG_DIR/${APP_NAME}_uninstall.pkg
|
||||
FINAL_PKG=$PKG_DIR/${APP_NAME}.pkg
|
||||
UNINSTALL_SCRIPTS_DIR=$PKG_DIR/uninstall_scripts
|
||||
|
||||
mkdir -p "$PKG_ROOT/Applications" "$SCRIPTS_DIR" "$RESOURCES_DIR" "$UNINSTALL_SCRIPTS_DIR"
|
||||
|
||||
cp -R "$BUNDLE_DIR" "$PKG_ROOT/Applications"
|
||||
# launchd plist is already inside the bundle; no need to add it again after signing
|
||||
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$PKG_ROOT/Applications/$APP_FILENAME"
|
||||
/usr/bin/codesign --verify --deep --strict --verbose=4 "$PKG_ROOT/Applications/$APP_FILENAME" || true
|
||||
cp "$DEPLOY_DATA_DIR/post_install.sh" "$SCRIPTS_DIR/post_install.sh"
|
||||
cp "$DEPLOY_DATA_DIR/post_uninstall.sh" "$UNINSTALL_SCRIPTS_DIR/postinstall"
|
||||
mkdir -p "$RESOURCES_DIR/scripts"
|
||||
cp "$DEPLOY_DATA_DIR/check_install.sh" "$RESOURCES_DIR/scripts/check_install.sh"
|
||||
cp "$DEPLOY_DATA_DIR/check_uninstall.sh" "$RESOURCES_DIR/scripts/check_uninstall.sh"
|
||||
|
||||
cat > "$SCRIPTS_DIR/postinstall" <<'EOS'
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(dirname "$0")"
|
||||
bash "$SCRIPT_DIR/post_install.sh"
|
||||
exit 0
|
||||
EOS
|
||||
|
||||
chmod +x "$SCRIPTS_DIR"/*
|
||||
chmod +x "$UNINSTALL_SCRIPTS_DIR"/*
|
||||
chmod +x "$RESOURCES_DIR/scripts"/*
|
||||
cp "$PROJECT_DIR/LICENSE" "$RESOURCES_DIR/LICENSE"
|
||||
|
||||
APP_VERSION=$(grep -m1 -E 'project\(' "$PROJECT_DIR/CMakeLists.txt" | sed -E 's/.*VERSION ([0-9.]+).*/\1/')
|
||||
echo "Building component package $INSTALL_PKG ..."
|
||||
|
||||
# Disable bundle relocation so the app always ends up in /Applications even if
|
||||
# another copy is lying around somewhere. We do this by letting pkgbuild
|
||||
# analyse the contents, flipping the BundleIsRelocatable flag to false for every
|
||||
# bundle it discovers and then feeding that plist back to pkgbuild.
|
||||
|
||||
COMPONENT_PLIST="$PKG_DIR/component.plist"
|
||||
# Create the component description plist first
|
||||
pkgbuild --analyze --root "$PKG_ROOT" "$COMPONENT_PLIST"
|
||||
|
||||
# Turn all `BundleIsRelocatable` keys to false (PlistBuddy is available on all
|
||||
# macOS systems). We first convert to xml1 to ensure predictable formatting.
|
||||
|
||||
# Turn relocation off for every bundle entry in the plist. PlistBuddy cannot
|
||||
# address keys that contain slashes without quoting, so we iterate through the
|
||||
# top-level keys it prints.
|
||||
plutil -convert xml1 "$COMPONENT_PLIST"
|
||||
for bundle_key in $(/usr/libexec/PlistBuddy -c "Print" "$COMPONENT_PLIST" | awk '/^[ \t]*[A-Za-z0-9].*\.app/ {print $1}'); do
|
||||
/usr/libexec/PlistBuddy -c "Set :'${bundle_key}':BundleIsRelocatable false" "$COMPONENT_PLIST" || true
|
||||
done
|
||||
|
||||
# Now build the real payload package with the edited plist so that the final
|
||||
# PackageInfo contains relocatable="false".
|
||||
pkgbuild --root "$PKG_ROOT" \
|
||||
--identifier "$APP_DOMAIN" \
|
||||
--version "$APP_VERSION" \
|
||||
--install-location "/" \
|
||||
--scripts "$SCRIPTS_DIR" \
|
||||
--component-plist "$COMPONENT_PLIST" \
|
||||
--sign "$MAC_INSTALLER_SIGNER_ID" \
|
||||
"$INSTALL_PKG"
|
||||
|
||||
# Build uninstaller component package
|
||||
UNINSTALL_COMPONENT_PKG=$PKG_DIR/${APP_NAME}_uninstall_component.pkg
|
||||
echo "Building uninstaller component package $UNINSTALL_COMPONENT_PKG ..."
|
||||
pkgbuild --nopayload \
|
||||
--identifier "$APP_DOMAIN.uninstall" \
|
||||
--version "$APP_VERSION" \
|
||||
--scripts "$UNINSTALL_SCRIPTS_DIR" \
|
||||
--sign "$MAC_INSTALLER_SIGNER_ID" \
|
||||
"$UNINSTALL_COMPONENT_PKG"
|
||||
|
||||
# Wrap uninstaller component in a distribution package for clearer UI
|
||||
echo "Building uninstaller distribution package $UNINSTALL_PKG ..."
|
||||
UNINSTALL_RESOURCES=$PKG_DIR/uninstall_resources
|
||||
rm -rf "$UNINSTALL_RESOURCES"
|
||||
mkdir -p "$UNINSTALL_RESOURCES"
|
||||
cp "$DEPLOY_DATA_DIR/uninstall_welcome.html" "$UNINSTALL_RESOURCES"
|
||||
cp "$DEPLOY_DATA_DIR/uninstall_conclusion.html" "$UNINSTALL_RESOURCES"
|
||||
productbuild \
|
||||
--distribution "$DEPLOY_DATA_DIR/distribution_uninstall.xml" \
|
||||
--package-path "$PKG_DIR" \
|
||||
--resources "$UNINSTALL_RESOURCES" \
|
||||
--sign "$MAC_INSTALLER_SIGNER_ID" \
|
||||
"$UNINSTALL_PKG"
|
||||
|
||||
cp "$PROJECT_DIR/deploy/data/macos/distribution.xml" "$PKG_DIR/distribution.xml"
|
||||
|
||||
echo "Creating final installer $FINAL_PKG ..."
|
||||
productbuild --distribution "$PKG_DIR/distribution.xml" \
|
||||
--package-path "$PKG_DIR" \
|
||||
--resources "$RESOURCES_DIR" \
|
||||
--sign "$MAC_INSTALLER_SIGNER_ID" \
|
||||
"$FINAL_PKG"
|
||||
|
||||
if [ "${MAC_INSTALL_CERT_PW+x}" ] && [ "${NOTARIZE_APP+x}" ]; then
|
||||
echo "Notarizing installer package..."
|
||||
xcrun notarytool submit "$FINAL_PKG" \
|
||||
--apple-id "$APPLE_DEV_EMAIL" \
|
||||
--team-id "$MAC_TEAM_ID" \
|
||||
--password "$APPLE_DEV_PASSWORD" \
|
||||
--wait
|
||||
|
||||
echo "Stapling ticket..."
|
||||
xcrun stapler staple "$FINAL_PKG"
|
||||
xcrun stapler validate "$FINAL_PKG"
|
||||
fi
|
||||
|
||||
if [ "${MAC_INSTALL_CERT_PW+x}" ]; then
|
||||
/usr/bin/codesign --verify -vvvv "$FINAL_PKG" || true
|
||||
spctl -a -vvvv "$FINAL_PKG" || true
|
||||
fi
|
||||
|
||||
# Sign app bundle
|
||||
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --keychain "$KEYCHAIN_PATH" --sign "$MAC_SIGNER_ID" "$BUNDLE_DIR"
|
||||
spctl -a -vvvv "$BUNDLE_DIR" || true
|
||||
|
||||
# Restore login keychain as the only user keychain and delete the temporary keychain
|
||||
KEYCHAIN="$HOME/Library/Keychains/login.keychain-db"
|
||||
security list-keychains -d user -s "$KEYCHAIN"
|
||||
security delete-keychain "$KEYCHAIN_PATH"
|
||||
|
||||
echo "Finished, artifact is $FINAL_PKG"
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../LICENSE
|
||||
@@ -1 +0,0 @@
|
||||
../../client/3rd-prebuilt/deploy-prebuilt/
|
||||
@@ -7,8 +7,7 @@ StartLimitIntervalSec=0
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
ExecStart=/opt/AmneziaVPN/service/AmneziaVPN-service.sh
|
||||
Environment=LD_LIBRARY_PATH=/opt/AmneziaVPN/client/lib
|
||||
ExecStart=/opt/AmneziaVPN/bin/AmneziaVPN-service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This is default bat run script of The CQtDeployer project.
|
||||
# This file contains key word that will replaced after deploy project.
|
||||
#
|
||||
# ####################################################################
|
||||
#
|
||||
# LIB_PATH - are relative path to libraries of a deployed distribution.
|
||||
# QML_PATH - are relative path to qml libraries of a deployed distribution.
|
||||
# PLUGIN_PATH - are relative path to qt plugins of a deployed distribution.
|
||||
# BIN_PATH - are relative path to targets of a deployed distribution.
|
||||
|
||||
# SYSTEM_LIB_PATH - are relative path to system libraries of a deployed distribution.
|
||||
# BASE_NAME - are base name of the executable that will be launched after run this script.
|
||||
# CUSTOM_SCRIPT_BLOCK - This is code from the customScript option
|
||||
# RUN_COMMAND - This is command for run application. Required BASE_DIR variable.
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
BASE_DIR=$(dirname "$(readlink -f "$0")")
|
||||
export LD_LIBRARY_PATH="$BASE_DIR"/lib/:"$BASE_DIR":$LD_LIBRARY_PATH
|
||||
export QML_IMPORT_PATH="$BASE_DIR"/qml/:$QML_IMPORT_PATH
|
||||
export QML2_IMPORT_PATH="$BASE_DIR"/qml/:$QML2_IMPORT_PATH
|
||||
export QT_PLUGIN_PATH="$BASE_DIR"/plugins/:$QT_PLUGIN_PATH
|
||||
export QTWEBENGINEPROCESS_PATH="$BASE_DIR"/bin//QtWebEngineProcess
|
||||
export QTDIR="$BASE_DIR"
|
||||
export CQT_PKG_ROOT="$BASE_DIR"
|
||||
export CQT_RUN_FILE="$BASE_DIR/AmneziaVPN.sh"
|
||||
|
||||
export QT_QPA_PLATFORM_PLUGIN_PATH="$BASE_DIR"/plugins//platforms:$QT_QPA_PLATFORM_PLUGIN_PATH
|
||||
|
||||
|
||||
|
||||
"$BASE_DIR/bin/AmneziaVPN" "$@"
|
||||
@@ -1,7 +0,0 @@
|
||||
[Paths]
|
||||
Prefix= ./../
|
||||
Libraries= ./lib/
|
||||
Plugins= ./plugins/
|
||||
Imports= ./qml/
|
||||
Translations= ./translations/
|
||||
Qml2Imports= ./qml/
|
||||
@@ -36,9 +36,8 @@ sudo cp $APP_PATH/$APP_NAME.service /etc/systemd/system/ >> $LOG_FILE
|
||||
|
||||
sudo systemctl start $APP_NAME >> $LOG_FILE
|
||||
sudo systemctl enable $APP_NAME >> $LOG_FILE
|
||||
sudo chmod 555 $APP_PATH/client/$APP_NAME.sh >> $LOG_FILE
|
||||
sudo ln -s $APP_PATH/client/$APP_NAME.sh /usr/local/sbin/$APP_NAME >> $LOG_FILE
|
||||
sudo ln -s $APP_PATH/client/$APP_NAME.sh /usr/local/bin/$APP_NAME >> $LOG_FILE
|
||||
sudo ln -sf $APP_PATH/bin/$APP_NAME /usr/local/sbin/$APP_NAME >> $LOG_FILE
|
||||
sudo ln -sf $APP_PATH/bin/$APP_NAME /usr/local/bin/$APP_NAME >> $LOG_FILE
|
||||
|
||||
echo "user desktop creation loop started" >> $LOG_FILE
|
||||
sudo cp $APP_PATH/$APP_NAME.desktop /usr/share/applications/ >> $LOG_FILE
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This is default bat run script of The CQtDeployer project.
|
||||
# This file contains key word that will replaced after deploy project.
|
||||
#
|
||||
# ####################################################################
|
||||
#
|
||||
# LIB_PATH - are relative path to libraries of a deployed distribution.
|
||||
# QML_PATH - are relative path to qml libraries of a deployed distribution.
|
||||
# PLUGIN_PATH - are relative path to qt plugins of a deployed distribution.
|
||||
# BIN_PATH - are relative path to targets of a deployed distribution.
|
||||
|
||||
# SYSTEM_LIB_PATH - are relative path to system libraries of a deployed distribution.
|
||||
# BASE_NAME - are base name of the executable that will be launched after run this script.
|
||||
# CUSTOM_SCRIPT_BLOCK - This is code from the customScript option
|
||||
# RUN_COMMAND - This is command for run application. Required BASE_DIR variable.
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
BASE_DIR=$(dirname "$(readlink -f "$0")")
|
||||
export LD_LIBRARY_PATH="$BASE_DIR"/lib/:"$BASE_DIR":$LD_LIBRARY_PATH
|
||||
export QML_IMPORT_PATH="$BASE_DIR"/qml/:$QML_IMPORT_PATH
|
||||
export QML2_IMPORT_PATH="$BASE_DIR"/qml/:$QML2_IMPORT_PATH
|
||||
export QT_PLUGIN_PATH="$BASE_DIR"/plugins/:$QT_PLUGIN_PATH
|
||||
export QTWEBENGINEPROCESS_PATH="$BASE_DIR"/bin//QtWebEngineProcess
|
||||
export QTDIR="$BASE_DIR"
|
||||
export CQT_PKG_ROOT="$BASE_DIR"
|
||||
export CQT_RUN_FILE="$BASE_DIR/AmneziaVPN-service.sh"
|
||||
|
||||
export QT_QPA_PLATFORM_PLUGIN_PATH="$BASE_DIR"/plugins//platforms:$QT_QPA_PLATFORM_PLUGIN_PATH
|
||||
|
||||
|
||||
|
||||
"$BASE_DIR/bin/AmneziaVPN-service" "$@"
|
||||
@@ -1,7 +0,0 @@
|
||||
[Paths]
|
||||
Prefix= ./../
|
||||
Libraries= ./lib/
|
||||
Plugins= ./plugins/
|
||||
Imports= ./qml/
|
||||
Translations= ./translations/
|
||||
Qml2Imports= ./qml/
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<installer-gui-script minSpecVersion="1.0">
|
||||
<title>@CPACK_PACKAGE_NAME@</title>
|
||||
<license file="@CPACK_RESOURCE_FILE_LICENSE_NOPATH@"/>
|
||||
@CPACK_APPLE_PKG_INSTALLER_CONTENT@
|
||||
</installer-gui-script>
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>AmneziaVPN Installer</title>
|
||||
<license file="LICENSE"/>
|
||||
<choices-outline>
|
||||
<line choice="install"/>
|
||||
<line choice="uninstall"/>
|
||||
</choices-outline>
|
||||
<choice id="install" title="Install AmneziaVPN" start_selected="true">
|
||||
<pkg-ref id="org.amneziavpn.package"/>
|
||||
</choice>
|
||||
<choice id="uninstall" title="Uninstall AmneziaVPN" start_selected="false">
|
||||
<pkg-ref id="org.amneziavpn.uninstall"/>
|
||||
</choice>
|
||||
<pkg-ref id="org.amneziavpn.package" auth="Root" install-check="scripts/check_install.sh">AmneziaVPN_install.pkg</pkg-ref>
|
||||
<pkg-ref id="org.amneziavpn.uninstall" auth="Root" install-check="scripts/check_uninstall.sh">AmneziaVPN_uninstall_component.pkg</pkg-ref>
|
||||
</installer-gui-script>
|
||||
@@ -1,13 +0,0 @@
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>Uninstall AmneziaVPN</title>
|
||||
<options customize-install-button="always"/>
|
||||
<welcome file="uninstall_welcome.html"/>
|
||||
<conclusion file="uninstall_conclusion.html"/>
|
||||
<choices-outline>
|
||||
<line choice="uninstall"/>
|
||||
</choices-outline>
|
||||
<choice id="uninstall" title="Uninstall AmneziaVPN" start_selected="true">
|
||||
<pkg-ref id="org.amneziavpn.uninstall"/>
|
||||
</choice>
|
||||
<pkg-ref id="org.amneziavpn.uninstall" auth="Root">AmneziaVPN_uninstall_component.pkg</pkg-ref>
|
||||
</installer-gui-script>
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<head><title>Uninstall Complete</title></head>
|
||||
<body>
|
||||
<h1>AmneziaVPN has been uninstalled</h1>
|
||||
<p>Thank you for using AmneziaVPN. The application and its components have been removed.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<head><title>Uninstall AmneziaVPN</title></head>
|
||||
<body>
|
||||
<h1>Uninstall AmneziaVPN</h1>
|
||||
<p>This process will remove AmneziaVPN from your system. Click Continue to proceed.</p>
|
||||
</body>
|
||||
</html>
|
||||
+34
-34
@@ -1,34 +1,34 @@
|
||||
set AmneziaPath=%~dp0
|
||||
echo %AmneziaPath%
|
||||
|
||||
rem Define directories for logs
|
||||
set "ORG_DIR=%AppData%\AmneziaVPN.ORG"
|
||||
set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN"
|
||||
set "USER_LOG_DIR=%USER_APP_DIR%\log"
|
||||
set "SYS_APP_DIR=%ProgramData%\AmneziaVPN"
|
||||
set "SYS_LOG_DIR=%SYS_APP_DIR%\log"
|
||||
set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log"
|
||||
|
||||
timeout /t 1
|
||||
sc stop AmneziaVPN-service
|
||||
sc delete AmneziaVPN-service
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
sc stop AmneziaVPNSplitTunnel
|
||||
sc delete AmneziaVPNSplitTunnel
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
|
||||
rem Delete the service log file under ProgramData
|
||||
if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%"
|
||||
if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%"
|
||||
rem Try to remove application dir if empty
|
||||
rd "%SYS_APP_DIR%" 2>nul
|
||||
|
||||
rem Delete client logs under current user's AppData\Roaming (Organization\Application)
|
||||
if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%"
|
||||
rem Try to remove app and org directories if empty
|
||||
rd "%USER_APP_DIR%" 2>nul
|
||||
rd "%ORG_DIR%" 2>nul
|
||||
|
||||
exit /b 0
|
||||
set AmneziaPath=%~dp0
|
||||
echo %AmneziaPath%
|
||||
|
||||
rem Define directories for logs
|
||||
set "ORG_DIR=%AppData%\AmneziaVPN.ORG"
|
||||
set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN"
|
||||
set "USER_LOG_DIR=%USER_APP_DIR%\log"
|
||||
set "SYS_APP_DIR=%ProgramData%\AmneziaVPN"
|
||||
set "SYS_LOG_DIR=%SYS_APP_DIR%\log"
|
||||
set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log"
|
||||
|
||||
timeout /t 1
|
||||
sc stop AmneziaVPN-service
|
||||
sc delete AmneziaVPN-service
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
sc stop AmneziaVPNSplitTunnel
|
||||
sc delete AmneziaVPNSplitTunnel
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
|
||||
rem Delete the service log file under ProgramData
|
||||
if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%"
|
||||
if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%"
|
||||
rem Try to remove application dir if empty
|
||||
rd "%SYS_APP_DIR%" 2>nul
|
||||
|
||||
rem Delete client logs under current user's AppData\Roaming (Organization\Application)
|
||||
if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%"
|
||||
rem Try to remove app and org directories if empty
|
||||
rd "%USER_APP_DIR%" 2>nul
|
||||
rd "%ORG_DIR%" 2>nul
|
||||
|
||||
exit /b 0
|
||||
@@ -1,5 +0,0 @@
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
exit /b 0
|
||||
@@ -1,34 +0,0 @@
|
||||
set AmneziaPath=%~dp0
|
||||
echo %AmneziaPath%
|
||||
|
||||
rem Define directories for logs
|
||||
set "ORG_DIR=%AppData%\AmneziaVPN.ORG"
|
||||
set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN"
|
||||
set "USER_LOG_DIR=%USER_APP_DIR%\log"
|
||||
set "SYS_APP_DIR=%ProgramData%\AmneziaVPN"
|
||||
set "SYS_LOG_DIR=%SYS_APP_DIR%\log"
|
||||
set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log"
|
||||
|
||||
timeout /t 1
|
||||
sc stop AmneziaVPN-service
|
||||
sc delete AmneziaVPN-service
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
sc stop AmneziaVPNSplitTunnel
|
||||
sc delete AmneziaVPNSplitTunnel
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
|
||||
rem Delete the service log file under ProgramData
|
||||
if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%"
|
||||
if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%"
|
||||
rem Try to remove application dir if empty
|
||||
rd "%SYS_APP_DIR%" 2>nul
|
||||
|
||||
rem Delete client logs under current user's AppData\Roaming (Organization\Application)
|
||||
if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%"
|
||||
rem Try to remove app and org directories if empty
|
||||
rd "%USER_APP_DIR%" 2>nul
|
||||
rd "%ORG_DIR%" 2>nul
|
||||
|
||||
exit /b 0
|
||||
@@ -1,23 +0,0 @@
|
||||
if(WIN32)
|
||||
set(RootDir "@RootDir@")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/windows.xml.in
|
||||
${CMAKE_BINARY_DIR}/installer/config/windows.xml
|
||||
)
|
||||
elseif(LINUX)
|
||||
set(ApplicationsDir "@ApplicationsDir@")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/linux.xml.in
|
||||
${CMAKE_BINARY_DIR}/installer/config/linux.xml
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/AmneziaVPN.desktop.in
|
||||
${CMAKE_BINARY_DIR}/../AppDir/AmneziaVPN.desktop
|
||||
)
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/packages/org.amneziavpn.package/meta/package.xml.in
|
||||
${CMAKE_BINARY_DIR}/installer/packages/org.amneziavpn.package/meta/package.xml
|
||||
)
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Installer>
|
||||
<Name>AmneziaVPN</Name>
|
||||
<Version>@CMAKE_PROJECT_VERSION@</Version>
|
||||
<Title>AmneziaVPN</Title>
|
||||
<Publisher>AmneziaVPN</Publisher>
|
||||
<StartMenuDir>AmneziaVPN</StartMenuDir>
|
||||
<TargetDir>@ApplicationsDir@/AmneziaVPN</TargetDir>
|
||||
<WizardDefaultWidth>600</WizardDefaultWidth>
|
||||
<WizardDefaultHeight>380</WizardDefaultHeight>
|
||||
<WizardStyle>Modern</WizardStyle>
|
||||
<RemoveTargetDir>true</RemoveTargetDir>
|
||||
<AllowSpaceInPath>true</AllowSpaceInPath>
|
||||
<AllowNonAsciiCharacters>false</AllowNonAsciiCharacters>
|
||||
<ControlScript>controlscript.js</ControlScript>
|
||||
<RepositorySettingsPageVisible>false</RepositorySettingsPageVisible>
|
||||
<DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary>
|
||||
<SupportsModify>false</SupportsModify>
|
||||
<DisableAuthorizationFallback>true</DisableAuthorizationFallback>
|
||||
<RemoteRepositories>
|
||||
<Repository>
|
||||
<Url>https://amneziavpn.org/updates/linux</Url>
|
||||
<Enabled>true</Enabled>
|
||||
<DisplayName>AmneziaVPN - repository for Linux</DisplayName>
|
||||
</Repository>
|
||||
</RemoteRepositories>
|
||||
</Installer>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Installer>
|
||||
<Name>AmneziaVPN</Name>
|
||||
<Version>@CMAKE_PROJECT_VERSION@</Version>
|
||||
<Title>AmneziaVPN</Title>
|
||||
<Publisher>AmneziaVPN</Publisher>
|
||||
<StartMenuDir>AmneziaVPN</StartMenuDir>
|
||||
<TargetDir>@RootDir@/Program Files/AmneziaVPN</TargetDir>
|
||||
<WizardDefaultWidth>600</WizardDefaultWidth>
|
||||
<WizardDefaultHeight>380</WizardDefaultHeight>
|
||||
<WizardStyle>Modern</WizardStyle>
|
||||
<RemoveTargetDir>true</RemoveTargetDir>
|
||||
<AllowSpaceInPath>true</AllowSpaceInPath>
|
||||
<AllowNonAsciiCharacters>false</AllowNonAsciiCharacters>
|
||||
<ControlScript>controlscript.js</ControlScript>
|
||||
<RepositorySettingsPageVisible>false</RepositorySettingsPageVisible>
|
||||
<DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary>
|
||||
<SupportsModify>false</SupportsModify>
|
||||
<DisableAuthorizationFallback>true</DisableAuthorizationFallback>
|
||||
</Installer>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user