Compare commits

...

47 Commits

Author SHA1 Message Date
spectrum fa72d8de43 build: make conan tvOS pipeline build
build: make tvOS awg prebuilt explicit

docs: make Apple TV build manual portable
2026-04-27 21:49:00 +03:00
spectrum e43973f8ad feat: add support for tvOS platform 2026-04-25 22:33:27 +03:00
spectrum 8d28beacd8 refactor: separate network extension sources for different protocols and platforms 2026-04-25 22:30:51 +03:00
spectrum 495d59da07 feat: add Apple TV support for network extension and refactor ios cmake scripts 2026-04-25 22:30:07 +03:00
spectrum 528015d17e feat: add support for Apple TV target settings for iOS/Xcode projects 2026-04-25 22:28:06 +03:00
Yaroslav Gurov 55237f951e feat: add conan to all mobile and NE builds 2026-04-21 01:59:18 +02:00
Yaroslav Gurov 1b4f3d5872 chore: remove MacOS-old from build targets 2026-04-21 01:57:47 +02:00
Yaroslav Gurov 8eefe7d26b fix: windows artifact upload 2026-04-20 21:33:59 +02:00
Yaroslav Gurov fd34bf08f1 fix: windows rework CI/CD 2026-04-20 20:40:40 +02:00
Yaroslav Gurov a7734d6093 fix: CI/CD correct QT paths 2026-04-16 16:11:02 +02:00
Yaroslav Gurov 526a7cad89 fix: libncap automake args 2026-04-16 15:31:28 +02:00
Yaroslav Gurov 13955dd36b feat: rework CI/CD for Linux 2026-04-16 14:31:31 +02:00
Yaroslav Gurov d81c1e5c1a feat: rework CI/CD for macos 2026-04-16 01:57:25 +02:00
Yaroslav Gurov 3ad6a7a46d feat: productbuild cpack support 2026-04-13 02:56:18 +02:00
Yaroslav Gurov de5e2635e3 feat: cpack windows full-featured build 2026-04-05 06:18:18 +02:00
Yaroslav Gurov b08154671e feat: linux cpack support 2026-04-03 00:44:35 +02:00
Yaroslav Gurov af2ade1d20 feat: linux initial packaging support 2026-04-02 12:15:41 +02:00
Yaroslav Gurov f456db5392 feat: linux <-> conan features 2026-04-02 12:12:51 +02:00
Yaroslav Gurov ea71e9b87d chore: remove redundant hint from conan find 2026-03-31 14:46:48 +02:00
Yaroslav Gurov 7f3a4aaa14 feat(conan): patch cloak to properly provide env for golang 2026-03-30 17:53:16 +02:00
Yaroslav Gurov 7c455591f6 chore: bump android deps for 16kb support 2026-03-29 03:53:58 +02:00
Yaroslav Gurov f8e229ff7b fix: provide flags for cloak plugin for openvpn-pt-android 2026-03-29 03:53:18 +02:00
Yaroslav Gurov b033fefa31 fix: install for apple systems 2026-03-28 13:41:09 +01:00
Yaroslav Gurov aab0927242 chore: exclude qtkeychain from the target build 2026-03-28 03:08:26 +01:00
Yaroslav Gurov ca8164fde4 feat: support full-featured cmake install 2026-03-28 02:41:49 +01:00
Yaroslav Gurov 7efb532bc9 feat: support of drivers for windows 2026-03-28 02:40:45 +01:00
Yaroslav Gurov 98915b3cf2 chore(conan): recipes cleanup 2026-03-27 00:22:09 +01:00
Yaroslav Gurov fa5076dff0 feat: 16kb support for Android 2026-03-26 23:44:21 +01:00
Yaroslav Gurov dbb918b68c feat: conan and platform bootstrap rework in cmake 2026-03-26 23:43:19 +01:00
Yaroslav Gurov 5078d1a2ca conan: fix version for v2ray-rules-dat 2026-03-26 13:56:53 +01:00
Yaroslav Gurov 6907886c44 conan: make awg-windows and wintun be interpret as exes 2026-03-23 23:37:01 +01:00
Yaroslav Gurov 2f01aac483 conan: windows initial support 2026-03-21 02:03:29 +01:00
Yaroslav Gurov b94cddcb1c conan: address lack of SONAME of libck-ovpn-plugin.so correctly 2026-03-17 21:58:03 +01:00
Yaroslav Gurov 2b5c2cb021 conan: use lib linking instead of QT_EXTRA_LIBS for OVPN 2026-03-17 20:16:36 +01:00
Yaroslav Gurov 729d6ee6d3 conan: add geosite.dat and geoip.dat 2026-03-17 15:22:22 +01:00
Yaroslav Gurov cd87253844 conan: beautify makefile-based recipes 2026-03-17 01:26:00 +01:00
Yaroslav Gurov 8cdaa0c2ee chore: get rid of manual deploy recursive copying 2026-03-17 01:24:24 +01:00
Yaroslav Gurov d563d66b28 chore: bump min macos version 2026-03-17 01:23:14 +01:00
Yaroslav Gurov 37327e30d3 conan: apple full-featured support 2026-03-16 13:24:02 +01:00
NickVs2015 e0af63ce1c fix: awg android connection establish 2026-03-10 00:43:10 +03:00
NickVs2015 041d0fcab5 feat: openvpn add support android 2026-03-09 22:55:05 +03:00
Yaroslav Gurov 2a6960a4fb conan: android additional recipes and fixes 2026-03-09 14:02:47 +01:00
Yaroslav Gurov 8481367fb6 fix: android libssh fixes 2026-03-06 13:29:53 +01:00
Yaroslav Gurov 70d6f9996d feat: conan android initial support 2026-03-06 12:39:46 +01:00
Yaroslav Gurov 616d58e901 feat: macos full feature conan build, except ss and cloak 2026-03-03 01:29:03 +01:00
Yaroslav Gurov 0bfbd82536 feat: add awg-go and awg-apple recipes 2026-02-24 11:51:18 +01:00
Yaroslav Gurov 544ad4ba6e feat: initial conan support 2026-02-23 00:55:11 +01:00
127 changed files with 14164 additions and 7603 deletions
+56
View File
@@ -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
View File
@@ -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
View File
@@ -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()
+340
View File
@@ -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
View File
@@ -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()
+2 -2
View File
@@ -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) {
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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)
+2 -1
View File
@@ -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
View File
@@ -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})
+3 -1
View File
@@ -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
View File
@@ -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")
-3
View File
@@ -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
-14
View File
@@ -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"
)
+4 -4
View File
@@ -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
+7 -11
View File
@@ -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);
+4 -4
View File
@@ -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)
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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;
+54
View File
@@ -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>
+89 -32
View File
@@ -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
+6 -17
View File
@@ -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
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
#if !MACOS_NE
#if !MACOS_NE && !TARGET_OS_TV
#include "QRCodeReaderBase.h"
#import <UIKit/UIKit.h>
+11 -5
View File
@@ -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
+6
View File
@@ -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();
+2 -2
View File
@@ -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";
+2 -2
View File
@@ -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);
+4 -4
View File
@@ -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;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
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);
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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;
+4 -2
View File
@@ -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
};
+6 -5
View File
@@ -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
}
+7 -6
View File
@@ -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
}
+4 -4
View File
@@ -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()) {
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
+6 -6
View File
@@ -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);
+91
View File
@@ -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
)
+17
View File
@@ -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}")
+722
View File
@@ -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)
+40
View File
@@ -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()
+9
View File
@@ -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()
+49
View File
@@ -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()
+30
View File
@@ -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()
+36
View File
@@ -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()
+46
View File
@@ -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()
+38
View File
@@ -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()
+46
View File
@@ -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")
+147
View File
@@ -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
+42
View File
@@ -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")
-90
View File
@@ -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
-287
View File
@@ -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"
+1
View File
@@ -0,0 +1 @@
../../LICENSE
-1
View File
@@ -1 +0,0 @@
../../client/3rd-prebuilt/deploy-prebuilt/
+1 -2
View File
@@ -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
-34
View 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.sh"
export QT_QPA_PLATFORM_PLUGIN_PATH="$BASE_DIR"/plugins//platforms:$QT_QPA_PLATFORM_PLUGIN_PATH
"$BASE_DIR/bin/AmneziaVPN" "$@"
-7
View File
@@ -1,7 +0,0 @@
[Paths]
Prefix= ./../
Libraries= ./lib/
Plugins= ./plugins/
Imports= ./qml/
Translations= ./translations/
Qml2Imports= ./qml/
+2 -3
View File
@@ -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" "$@"
-7
View File
@@ -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>
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then
exit 1
fi
exit 0
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
if [ -d "/Applications/AmneziaVPN.app" ] || pgrep -x "AmneziaVPN-service" >/dev/null; then
exit 0
fi
exit 1
-17
View File
@@ -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>
-7
View File
@@ -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>
@@ -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
-5
View File
@@ -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
-23
View File
@@ -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
)
-27
View File
@@ -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>
-20
View File
@@ -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