merge dev

This commit is contained in:
dranik
2026-05-05 10:20:41 +03:00
103 changed files with 4050 additions and 2119 deletions

View File

@@ -0,0 +1,38 @@
# .github/actions/apple-install-cert/action.yml
name: Setup apple keychain
description: Creates and configures a temporary build keychain
inputs:
keychain-path:
description: Path to the keychain
required: true
keychain-password:
description: Password to the keychain
required: true
cert-base64:
description: Base64-encoded certificate
required: true
cert-password:
description: Certificate password
required: true
runs:
using: composite
steps:
- name: Create keychain
shell: bash
env:
KEYCHAIN_PATH: ${{ inputs.keychain-path }}
KEYCHAIN_PASSWORD: ${{ inputs.keychain-password }}
CERT_BASE64: ${{ inputs.cert-base64 }}
CERT_PASSWORD: ${{ inputs.cert-password }}
run: |
CERT_PATH=$(mktemp /tmp/cert_XXXXXX.p12)
trap "rm -f '$CERT_PATH'" EXIT
echo -n "$CERT_BASE64" | base64 --decode -o "$CERT_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$CERT_PASSWORD" -A -t cert -f pkcs12
security set-key-partition-list -S apple-tool:,apple:,codesign: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"

Binary file not shown.

View File

@@ -0,0 +1,57 @@
# .github/actions/apple-setup-keychain/action.yml
name: Setup apple keychain
description: Creates and configures a temporary build keychain
inputs:
keychain-name:
description: Name of the keychain
required: false
default: "ci-amnezia"
keychain-password:
description: The keychain password
required: true
lock-timeout:
description: A timeout after exceeding which the keychain would be locked
required: false
default: "0"
outputs:
keychain-path:
description: "Full path to the keychain created"
value: ${{ steps.setup.outputs.keychain-path }}
keychain-name:
description: "Actual name of the keychain created"
value: ${{ steps.setup.outputs.keychain-name }}
runs:
using: composite
steps:
- name: Setup keychain
id: setup
shell: bash
env:
KEYCHAIN_NAME: ${{ inputs.keychain-name }}
KEYCHAIN_PASSWORD: ${{ inputs.keychain-password }}
LOCK_TIMEOUT: ${{ inputs.lock-timeout }}
run: |
KEYCHAIN_PATH="$HOME/Library/Keychains/$KEYCHAIN_NAME.keychain-db"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
if [[ "$LOCK_TIMEOUT" == "0" ]]; then
security set-keychain-settings "$KEYCHAIN_PATH"
else
security set-keychain-settings -u -t "$LOCK_TIMEOUT" "$KEYCHAIN_PATH"
fi
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "${{ github.action_path }}/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -A
security import "${{ github.action_path }}/AppleWWDRCAG3.cer" -k "$KEYCHAIN_PATH" -A
security list-keychains -d user -s "$KEYCHAIN_PATH"
security default-keychain -s "$KEYCHAIN_PATH"
echo "keychain-name=$KEYCHAIN_NAME" >> $GITHUB_OUTPUT
echo "keychain-path=$KEYCHAIN_PATH" >> $GITHUB_OUTPUT

View File

@@ -0,0 +1,31 @@
# .github/actions/apple-setup-provisioning-profile/action.yml
name: Setup provisioning profiles
description: Decodes and installs provisioning profiles
inputs:
provisioning_profile_base64:
description: Base64-encoded provisioning profile
required: true
runs:
using: composite
steps:
- name: Setup provisioning profile
shell: bash
run: |
PROFILES_DIR="$HOME/Library/MobileDevice/Provisioning Profiles"
TEMP_FILE=$(mktemp)
echo "${{ inputs.provisioning_profile_base64 }}" | base64 --decode > "$TEMP_FILE"
PROFILE_UUID=$(grep UUID -A1 -a "$TEMP_FILE" | grep -io "[-A-F0-9]\{36\}")
if [[ -z "$PROFILE_UUID" ]]; then
echo "Failed to extract UUID from provisioning profile"
rm -f "$TEMP_FILE"
exit 1
fi
mkdir -p "$PROFILES_DIR"
mv "$TEMP_FILE" "$PROFILES_DIR/$PROFILE_UUID.mobileprovision"
echo "Installed profile: $PROFILE_UUID"

View File

@@ -9,9 +9,60 @@ env:
QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/ # https://download.qt.io/static/mirrorlist/ QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/ # https://download.qt.io/static/mirrorlist/
jobs: jobs:
Detect-Changes:
runs-on: ubuntu-latest
outputs:
recipes_changed: ${{ steps.filter.outputs.recipes }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
base: ${{ github.event.before }}
filters: |
recipes:
- 'recipes/**'
- 'conanfile.py'
Bake-Prebuilts-Linux:
runs-on: ubuntu-latest
needs: Detect-Changes
if: needs.Detect-Changes.outputs.recipes_changed == 'true'
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- uses: actions/setup-python@v6
with:
python-version: 3.14
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build dependencies'
shell: bash
run: |
for build_type in Release Debug; do
cmake -S . -B build -DPREBUILTS_ONLY=1 "-DCMAKE_BUILD_TYPE=$build_type"
done
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------
Build-Linux-Ubuntu: Build-Linux-Ubuntu:
runs-on: android-runner runs-on: android-runner
needs: Bake-Prebuilts-Linux
if: ${{ always() }}
env: env:
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
QIF_VERSION: 4.7 QIF_VERSION: 4.7
@@ -39,7 +90,18 @@ jobs:
set-env: 'true' set-env: 'true'
aqtversion: '==3.3.0' aqtversion: '==3.3.0'
py7zrversion: '==0.22.*' 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' - name: 'Get sources'
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -47,38 +109,17 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 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' - name: 'Build project'
run: | shell: bash
sudo apt-get install libxkbcommon-x11-0 libsecret-1-dev env:
export QT_BIN_DIR=${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64/bin QT_INSTALL_DIR: ${{ runner.temp }}
export QIF_BIN_DIR=${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin run: deploy/build.sh --generator Ninja --installer all
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
- name: 'Upload installer artifact' - name: 'Upload installer artifact'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip path: deploy/build/AmneziaVPN-*-Linux.run
path: deploy/AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip archive: false
retention-days: 7
- name: 'Upload unpacked artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Linux_unpacked
path: deploy/AppDir
retention-days: 7 retention-days: 7
- name: 'Upload translations artifact' - name: 'Upload translations artifact'
@@ -88,15 +129,48 @@ jobs:
path: client/translations path: client/translations
retention-days: 7 retention-days: 7
# ------------------------------------------------------
Bake-Prebuilts-Windows:
runs-on: windows-latest
needs: Detect-Changes
if: needs.Detect-Changes.outputs.recipes_changed == 'true'
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- uses: actions/setup-python@v6
with:
python-version: 3.14
- uses: ilammy/msvc-dev-cmd@v1
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build dependencies'
run: cmake -S . -B build -G "Visual Studio 17 2022" -DPREBUILTS_ONLY=1
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------ # ------------------------------------------------------
Build-Windows: Build-Windows:
runs-on: windows-latest runs-on: windows-latest
needs: Bake-Prebuilts-Windows
if: ${{ always() }}
env: env:
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
QIF_VERSION: 4.7 QIF_VERSION: 4.7
BUILD_ARCH: 64
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }} PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_S3_ENDPOINT }} FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_S3_ENDPOINT }}
@@ -113,17 +187,6 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 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' - name: 'Install Qt'
uses: jurplel/install-qt-action@v3 uses: jurplel/install-qt-action@v3
with: with:
@@ -160,50 +223,85 @@ jobs:
$wixBinDir = Join-Path $env:USERPROFILE ".dotnet\tools" $wixBinDir = Join-Path $env:USERPROFILE ".dotnet\tools"
echo "WIX_BIN_DIR=$wixBinDir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 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' - name: 'Build project'
shell: cmd shell: cmd
env:
QT_INSTALL_DIR: ${{ runner.temp }}
run: | run: |
set BUILD_ARCH=${{ env.BUILD_ARCH }} set WIX_ROOT_PATH="${{ env.USERPROFILE }}\.dotnet\tools"
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2022_64\\bin" deploy\build.bat --installer all
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
- name: 'Rename Windows installer' - name: 'Upload WIX installer artifact'
shell: cmd uses: actions/upload-artifact@v7
run: |
copy AmneziaVPN_x${{ env.BUILD_ARCH }}.exe AmneziaVPN_%VERSION%_x64.exe
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_${{ env.VERSION }}_x64.exe path: deploy/build/AmneziaVPN-*-win64.msi
path: AmneziaVPN_${{ env.VERSION }}_x64.exe archive: false
retention-days: 7
- name: 'Upload IFW installer artifact'
uses: actions/upload-artifact@v7
with:
path: deploy/build/AmneziaVPN-*-win64.exe
archive: false
retention-days: 7 retention-days: 7
- name: 'Upload MSI installer artifact' # ------------------------------------------------------
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Windows_MSI_installer
path: AmneziaVPN_x${{ env.BUILD_ARCH }}.msi
retention-days: 7
- name: 'Upload unpacked artifact' Bake-Prebuilts-iOS:
uses: actions/upload-artifact@v4 runs-on: macos-latest
needs: Detect-Changes
if: needs.Detect-Changes.outputs.recipes_changed == 'true'
strategy:
matrix:
xcode-version: [26.0]
steps:
- uses: actions/checkout@v4
with: with:
name: AmneziaVPN_Windows_unpacked submodules: 'true'
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release fetch-depth: 10
retention-days: 7
- uses: actions/setup-python@v6
with:
python-version: 3.14
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode-version }}
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build dependencies'
run: cmake -S . -B build -G Xcode -DPREBUILTS_ONLY=1 -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------ # ------------------------------------------------------
Build-iOS: Build-iOS:
runs-on: macos-latest runs-on: macos-latest
needs: Bake-Prebuilts-iOS
if: ${{ always() }}
env: env:
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
CC: cc KEYCHAIN_PASSWORD: ""
CXX: c++
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }} PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_S3_ENDPOINT }} FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_S3_ENDPOINT }}
@@ -214,6 +312,35 @@ jobs:
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }} PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
steps: steps:
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- uses: ./.github/actions/apple-setup-keychain
id: setup-keychain
with:
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
- name: 'Install signing certificate'
uses: ./.github/actions/apple-install-cert
with:
keychain-path: ${{ steps.setup-keychain.outputs.keychain-path }}
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
cert-base64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
cert-password: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
- name: 'Install app provisioning profile'
uses: ./.github/actions/apple-setup-provisioning-profile
with:
provisioning_profile_base64: ${{ secrets.IOS_APP_PROVISIONING_PROFILE }}
- name: 'Install NE provisioning profile'
uses: ./.github/actions/apple-setup-provisioning-profile
with:
provisioning_profile_base64: ${{ secrets.IOS_NE_PROVISIONING_PROFILE }}
- name: 'Setup xcode' - name: 'Setup xcode'
uses: maxim-lobanov/setup-xcode@v1 uses: maxim-lobanov/setup-xcode@v1
with: with:
@@ -243,159 +370,76 @@ jobs:
set-env: 'true' set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}' extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install go' - name: 'Setup python'
uses: actions/setup-go@v5 uses: actions/setup-python@v6
with: with:
go-version: '1.24' python-version: 3.14
cache: false
- name: 'Setup gomobile' - name: 'Install deps'
run: | run: pip install "conan==2.26.2" jsonschema jinja2
export PATH=$PATH:~/go/bin
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
# - name: 'Setup ccache'
# uses: hendrikmuhs/ccache-action@v1.2
- name: 'Install dependencies'
run: pip install jsonschema jinja2
- name: 'Build project' - name: 'Build project'
env:
QT_INSTALL_DIR: ${{ runner.temp }}
APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
run: | run: |
git submodule update --init --recursive sh deploy/build.sh -t ios | \
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/ios/bin"
export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
export PATH=$PATH:~/go/bin
sh deploy/build_ios.sh | \
sed -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/d' | \ sed -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/d' | \
sed -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/d' | \ sed -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/d' | \
sed -e '/-DPROD_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DPROD_AGW_PUBLIC_KEY/d' | \ sed -e '/-DPROD_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DPROD_AGW_PUBLIC_KEY/d' | \
sed -e '/-DDEV_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DDEV_AGW_PUBLIC_KEY/d' sed -e '/-DDEV_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DDEV_AGW_PUBLIC_KEY/d'
env:
IOS_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
IOS_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
IOS_SIGNING_CERT_PASSWORD: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
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: Bake-Prebuilts-MacOS:
runs-on: macos-latest runs-on: macos-latest
env: needs: Detect-Changes
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4 if: needs.Detect-Changes.outputs.recipes_changed == 'true'
QT_VERSION: 6.4.3
MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }} strategy:
matrix:
MAC_APP_CERT_CERT: ${{ secrets.MAC_APP_CERT_CERT }} xcode-version: [16.2, 16.4]
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 }}
FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_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: steps:
- name: 'Setup xcode' - uses: actions/checkout@v4
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: with:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
# - name: 'Setup ccache' - uses: actions/setup-python@v6
# 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: with:
name: AmneziaVPN_MacOS_old_installer python-version: 3.14
path: deploy/build/pkg/AmneziaVPN.pkg
retention-days: 7
- name: 'Upload unpacked artifact' - uses: maxim-lobanov/setup-xcode@v1
uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_MacOS_old_unpacked xcode-version: ${{ matrix.xcode-version }}
path: deploy/build/client/AmneziaVPN.app
retention-days: 7 - name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build dependencies'
run: cmake -S . -B build -G Xcode -DPREBUILTS_ONLY=1
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------ # ------------------------------------------------------
Build-MacOS: Build-MacOS:
runs-on: macos-latest runs-on: macos-latest
needs: Bake-Prebuilts-MacOS
if: ${{ always() }}
env: env:
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
KEYCHAIN_PASSWORD: ""
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_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }} PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
@@ -407,6 +451,31 @@ jobs:
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }} PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
steps: steps:
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- uses: ./.github/actions/apple-setup-keychain
id: setup-keychain
with:
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
- uses: ./.github/actions/apple-install-cert
with:
keychain-path: ${{ steps.setup-keychain.outputs.keychain-path }}
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
cert-base64: ${{ secrets.MAC_APP_CERT_CERT }}
cert-password: ${{ secrets.MAC_APP_CERT_PW }}
- uses: ./.github/actions/apple-install-cert
with:
keychain-path: ${{ steps.setup-keychain.outputs.keychain-path }}
keychain-password: ${{ env.KEYCHAIN_PASSWORD }}
cert-base64: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
cert-password: ${{ secrets.MAC_INSTALL_CERT_PW }}
- name: 'Setup xcode' - name: 'Setup xcode'
uses: maxim-lobanov/setup-xcode@v1 uses: maxim-lobanov/setup-xcode@v1
with: with:
@@ -425,52 +494,79 @@ jobs:
set-env: 'true' set-env: 'true'
aqtversion: '==3.3.0' aqtversion: '==3.3.0'
py7zrversion: '==0.22.*' py7zrversion: '==0.22.*'
extra: '--base ${{ env.QT_MIRROR }}' extra: '--base ${{ env.QT_MIRROR }}'
- name: 'Get sources' - name: 'Setup python'
uses: actions/checkout@v4 uses: actions/setup-python@v6
with:
python-version: 3.14
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build project'
env:
QT_INSTALL_DIR: ${{ runner.temp }}
CODESIGN_SIGNATURE: ${{ secrets.MAC_SIGNER_ID }}
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 --generator Ninja --installer all
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v7
with:
path: deploy/build/AmneziaVPN-*-Darwin.pkg
archive: false
retention-days: 7
# ------------------------------------------------------
Bake-Prebuilts-MacOS-NE:
runs-on: macos-latest
needs: Detect-Changes
if: needs.Detect-Changes.outputs.recipes_changed == 'true'
strategy:
matrix:
xcode-version: [16.2, 16.4]
steps:
- uses: actions/checkout@v4
with: with:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
- name: 'Get version from CMakeLists.txt' - uses: actions/setup-python@v6
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: |
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 ../../..
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_${{ env.VERSION }}_macos.zip python-version: 3.14
path: deploy/AmneziaVPN_${{ env.VERSION }}_macos.zip
retention-days: 7
- name: 'Upload unpacked artifact' - uses: maxim-lobanov/setup-xcode@v1
uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_MacOS_unpacked xcode-version: ${{ matrix.xcode-version }}
path: deploy/build/client/AmneziaVPN.app
retention-days: 7 - name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build dependencies'
run: cmake -S . -B build -G Xcode -DPREBUILTS_ONLY=1 -DMACOS_NE=TRUE
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------
Build-MacOS-NE: Build-MacOS-NE:
runs-on: macos-latest runs-on: macos-latest
needs: Bake-Prebuilts-MacOS-NE
if: ${{ always() }}
env: env:
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
@@ -490,6 +586,14 @@ jobs:
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }} PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
steps: steps:
- uses: ./.github/actions/apple-setup-provisioning-profile
with:
provisioning_profile_base64: ${{ secrets.MAC_APP_PROVISIONING_PROFILE }}
- uses: ./.github/actions/apple-setup-provisioning-profile
with:
provisioning_profile_base64: ${{ secrets.MAC_NE_PROVISIONING_PROFILE }}
- name: 'Setup xcode' - name: 'Setup xcode'
uses: maxim-lobanov/setup-xcode@v1 uses: maxim-lobanov/setup-xcode@v1
with: with:
@@ -525,8 +629,13 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
# - name: 'Setup ccache' - name: 'Setup python'
# uses: hendrikmuhs/ccache-action@v1.2 uses: actions/setup-python@v6
with:
python-version: 3.14
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Build project' - name: 'Build project'
run: | run: |
@@ -540,13 +649,69 @@ jobs:
path: deploy/build/client/AmneziaVPN.app path: deploy/build/client/AmneziaVPN.app
retention-days: 7 retention-days: 7
# ------------------------------------------------------
Bake-Prebuilts-Android:
runs-on: android-runner
needs: Detect-Changes
if: needs.Detect-Changes.outputs.recipes_changed == 'true'
env:
ANDROID_PLATFORM: android-28
NDK_VERSION: 27.0.11718014
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- uses: actions/setup-python@v6
with:
python-version: 3.14
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Setup Android SDK'
uses: android-actions/setup-android@v4
with:
packages: "platforms;${{ env.ANDROID_PLATFORM }} ndk;${{ env.NDK_VERSION }}"
- name: 'Build dependencies'
run: |
CMAKE_ANDROID_NDK="$ANDROID_HOME/ndk/$NDK_VERSION"
args=(
-G Ninja
-DPREBUILTS_ONLY=1
-DCMAKE_SYSTEM_NAME=Android
"-DANDROID_PLATFORM=$ANDROID_PLATFORM"
"-DCMAKE_ANDROID_NDK=$CMAKE_ANDROID_NDK"
)
for abi in arm64-v8a armeabi-v7a x86 x86_64; do
for build_type in Release Debug; do
cmake -S . -B build_${abi//-/_} "${args[@]}" "-DCMAKE_ANDROID_ARCH_ABI=$abi" "-DCMAKE_BUILD_TYPE=$build_type"
done
done
- name: 'Authorize in remote'
run: conan remote login amnezia "${{ secrets.CONAN_USER }}" -p "${{ secrets.CONAN_PASSWORD }}"
- name: 'Upload baked prebuilts'
run: conan upload -r amnezia "*" -c
# ------------------------------------------------------ # ------------------------------------------------------
Build-Android: Build-Android:
runs-on: android-runner runs-on: android-runner
needs: Bake-Prebuilts-Android
if: ${{ always() }}
env: env:
ANDROID_BUILD_PLATFORM: android-36 ANDROID_PLATFORM: android-28
NDK_VERSION: 27.0.11718014
QT_VERSION: 6.10.1 QT_VERSION: 6.10.1
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools' QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }} PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
@@ -559,6 +724,11 @@ jobs:
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }} PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
steps: steps:
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
- name: 'Install desktop Qt' - name: 'Install desktop Qt'
uses: jurplel/install-qt-action@v4 uses: jurplel/install-qt-action@v4
with: with:
@@ -619,38 +789,24 @@ jobs:
py7zrversion: '==0.22.*' py7zrversion: '==0.22.*'
extra: '--base ${{ env.QT_MIRROR }}' extra: '--base ${{ env.QT_MIRROR }}'
- name: 'Grant execute permission for qt-cmake'
shell: bash
run: |
chmod +x ${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/android_x86_64/bin/qt-cmake
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
- 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: 'Setup Java' - name: 'Setup Java'
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '17' java-version: '17'
# cache: 'gradle'
- name: 'Setup Android NDK' - name: 'Setup Android SDK'
id: setup-ndk uses: android-actions/setup-android@v4
uses: nttld/setup-ndk@v1
with: with:
ndk-version: 'r26b' packages: "platforms;${{ env.ANDROID_PLATFORM }} ndk;${{ env.NDK_VERSION }}"
- name: 'Setup python'
uses: actions/setup-python@v6
with:
python-version: 3.14
- name: 'Install conan'
run: pip install "conan==2.26.2"
- name: 'Decode keystore secret to file' - name: 'Decode keystore secret to file'
env: env:
@@ -661,61 +817,64 @@ jobs:
- name: 'Build project' - name: 'Build project'
env: env:
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} QT_INSTALL_DIR: ${{ runner.temp }}
QT_HOST_PATH: ${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/gcc_64 QT_ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android.keystore
ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android.keystore QT_ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_ALIAS }}
ANDROID_KEYSTORE_KEY_ALIAS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_ALIAS }} QT_ANDROID_KEYSTORE_STORE_PASS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_PASS }}
ANDROID_KEYSTORE_KEY_PASS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_PASS }}
shell: bash shell: bash
run: ./deploy/build_android.sh --aab --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }}
- name: 'Rename Android APKs'
run: | run: |
cd deploy/build deploy/build.sh -t android --sign --aab
mv AmneziaVPN-x86_64-release.apk AmneziaVPN_${VERSION}_android9+_x86_64.apk
mv AmneziaVPN-x86-release.apk AmneziaVPN_${VERSION}_android9+_x86.apk
mv AmneziaVPN-arm64-v8a-release.apk AmneziaVPN_${VERSION}_android9+_arm64-v8a.apk
mv AmneziaVPN-armeabi-v7a-release.apk AmneziaVPN_${VERSION}_android9+_armeabi-v7a.apk
cd ../..
- name: 'Upload x86_64 apk' VERSION=$(grep CMAKE_PROJECT_VERSION:STATIC deploy/build/CMakeCache.txt | cut -d= -f2)
uses: actions/upload-artifact@v4
(cd deploy/build/client/android-build && mv AmneziaVPN.apk AmneziaVPN_${VERSION}_android9+_universal.apk)
(cd deploy/build/client/android-build/build/outputs/bundle/release && mv android-build-release.aab AmneziaVPN_${VERSION}.aab)
for abi in arm64-v8a armeabi-v7a x86 x86_64; do
deploy/build.sh -t android --sign --abi ${abi} --build ./deploy/build/${abi}
(cd deploy/build/${abi}/client/android-build && mv AmneziaVPN.apk AmneziaVPN_${VERSION}_android9+_${abi}.apk)
done
- name: 'Upload universal APK'
uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN_${{ env.VERSION }}_android9+_x86_64.apk path: deploy/build/client/android-build/*.apk
path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_x86_64.apk archive: false
compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload x86 apk' - name: 'Upload AAB'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN_${{ env.VERSION }}_android9+_x86.apk path: deploy/build/client/android-build/build/outputs/bundle/release/*.aab
path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_x86.apk archive: false
compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload arm64-v8a apk' - name: 'Upload arm64-v8a APK'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN_${{ env.VERSION }}_android9+_arm64-v8a.apk path: deploy/build/arm64-v8a/client/android-build/*.apk
path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_arm64-v8a.apk archive: false
compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload armeabi-v7a apk' - name: 'Upload armeabi-v7a APK'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN_${{ env.VERSION }}_android9+_armeabi-v7a.apk path: deploy/build/armeabi-v7a/client/android-build/*.apk
path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_armeabi-v7a.apk archive: false
compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload aab' - name: 'Upload x86 APK'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: AmneziaVPN-android path: deploy/build/x86/client/android-build/*.apk
path: deploy/build/AmneziaVPN-release.aab archive: false
compression-level: 0 retention-days: 7
- name: 'Upload x86_64 APK'
uses: actions/upload-artifact@v7
with:
path: deploy/build/x86_64/client/android-build/*.apk
archive: false
retention-days: 7 retention-days: 7
Extra: Extra:

4
.gitmodules vendored
View File

@@ -4,10 +4,6 @@
[submodule "client/3rd/SortFilterProxyModel"] [submodule "client/3rd/SortFilterProxyModel"]
path = client/3rd/SortFilterProxyModel path = client/3rd/SortFilterProxyModel
url = https://github.com/mitchcurtis/SortFilterProxyModel.git url = https://github.com/mitchcurtis/SortFilterProxyModel.git
[submodule "client/3rd-prebuilt"]
path = client/3rd-prebuilt
url = https://github.com/amnezia-vpn/3rd-prebuilt
branch = feature/special-handshake
[submodule "client/3rd/amneziawg-apple"] [submodule "client/3rd/amneziawg-apple"]
path = client/3rd/amneziawg-apple path = client/3rd/amneziawg-apple
url = https://github.com/amnezia-vpn/amneziawg-apple url = https://github.com/amnezia-vpn/amneziawg-apple

View File

@@ -1,13 +1,29 @@
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJECT AmneziaVPN) set(PROJECT AmneziaVPN)
set(AMNEZIAVPN_VERSION 4.8.15.4) set(AMNEZIAVPN_VERSION 4.8.15.4)
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} project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
DESCRIPTION "AmneziaVPN" DESCRIPTION "AmneziaVPN"
HOMEPAGE_URL "https://amnezia.org/" HOMEPAGE_URL "https://amnezia.org/"
) )
if (PREBUILTS_ONLY)
# trigger conan to kick off `conan install`
find_package(OpenSSL REQUIRED)
return()
endif()
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d") string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}") set(RELEASE_DATE "${CURRENT_DATE}")
@@ -29,18 +45,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
endif() endif()
set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON) set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE)
if(IOS)
set(CMAKE_OSX_ARCHITECTURES "arm64")
elseif(MACOS_NE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
else()
set(CMAKE_OSX_ARCHITECTURES "x86_64")
endif()
endif()
if(APPLE AND NOT IOS) if(APPLE AND NOT IOS)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -67,42 +71,8 @@ add_subdirectory(client)
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE) if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
add_subdirectory(service) add_subdirectory(service)
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
endif() endif()
set(AMNEZIA_STAGE_DIR "${CMAKE_BINARY_DIR}/stage") if ((LINUX AND NOT ANDROID) OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (WIN32))
include(${CMAKE_SOURCE_DIR}/cmake/CPack.cmake)
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(AMNEZIA_LICENSE_TXT "${CMAKE_BINARY_DIR}/LICENSE.txt")
configure_file("${CMAKE_SOURCE_DIR}/LICENSE" "${AMNEZIA_LICENSE_TXT}" COPYONLY)
set(CPACK_RESOURCE_FILE_LICENSE "${AMNEZIA_LICENSE_TXT}")
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)
endif() endif()

167
README.md
View File

@@ -53,24 +53,14 @@ AmneziaVPN uses several open-source projects to work:
- [OpenSSL](https://www.openssl.org/) - [OpenSSL](https://www.openssl.org/)
- [OpenVPN](https://openvpn.net/) - [OpenVPN](https://openvpn.net/)
- [Shadowsocks](https://shadowsocks.org/)
- [Qt](https://www.qt.io/) - [Qt](https://www.qt.io/)
- [LibSsh](https://libssh.org) - forked from Qt Creator - [LibSsh](https://libssh.org)
- [WireGuard](https://www.wireguard.com/)
- [Xray-core](https://xtls.github.io/en/)
- [Conan](https://conan.io/)
- and more... - and more...
## Checking out the source code ## Help us with translations
Make sure to pull all submodules after checking out the repo.
```bash
git submodule update --init --recursive
```
## Development
Want to contribute? Welcome!
### Help with translations
Download the most actual translation files. Download the most actual translation files.
@@ -83,99 +73,98 @@ Each *.ts file contains strings for one corresponding language.
Translate or correct some strings in one or multiple *.ts files and commit them back to this repository into the ``client/translations`` folder. Translate or correct some strings in one or multiple *.ts files and commit them back to this repository into the ``client/translations`` folder.
You can do it via a web-interface or any other method you're familiar with. You can do it via a web-interface or any other method you're familiar with.
### Building sources and deployment ## Checking out the source code
Check deploy folder for build scripts. Make sure to pull all submodules after checking out the repo.
### How to build an iOS app from source code on MacOS
1. First, make sure you have [XCode](https://developer.apple.com/xcode/) installed, at least version 14 or higher.
2. We use QT to generate the XCode project. We need QT version 6.6.2. Install QT for MacOS [here](https://doc.qt.io/qt-6/macos.html) or [QT Online Installer](https://www.qt.io/download-open-source). Required modules:
- MacOS
- iOS
- Qt 5 Compatibility Module
- Qt Shader Tools
- Additional Libraries:
- Qt Image Formats
- Qt Multimedia
- Qt Remote Objects
3. Install CMake if required. We recommend CMake version 3.25. You can install CMake [here](https://cmake.org/download/)
4. You also need to install go >= v1.16. If you don't have it installed already,
download go from the [official website](https://golang.org/dl/) or use Homebrew.
The latest version is recommended. Install gomobile
```bash ```bash
export PATH=$PATH:~/go/bin git submodule update --init --recursive
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
``` ```
5. Build the project ## Hacking guide
Want to contribute? Welcome!
### Build requirements
* [`CMake`](https://cmake.org/download/)
* Compiler and underlying build system, depending on the target:
- [Linux] Any of `make` and `gcc`
- [Apple] [`Xcode`](https://developer.apple.com/xcode/) or [`Xcode command line tools`](https://developer.apple.com/xcode/)
- [Windows] [`Visual Studio 2022`](https://aka.ms/vs/17/release/vs_community.exe) or [`VS 2022 Build Tools`](https://aka.ms/vs/17/release/vs_buildtools.exe)
- [Android] [`Android SDK`](#installing-android-sdk) and [`Ninja`](https://ninja-build.org/)
* [`Qt 6.10+`](https://www.qt.io/download-open-source) with the following modules:
- Core module for targeting platform (Desktop/Android/iOS)
- Qt 5 Compatibility module
- Qt Remote Objects
* [`Conan`](https://conan.io/downloads) package manager
- On MacOS is enough just to use `homebrew` or install it in `.venv` in project root
- Other systems must have it in `PATH`
* (Optional) Installer dependencies:
- [Windows/Linux] [`Qt Installer Framework`](https://www.qt.io/download-open-source)
- [Windows] [`WIX toolset`](https://github.com/wixtoolset/wix/releases)
### Building the project using scripts
* Run scripts located in `deploy` directory
* Basically, if dependencies are located in default installation paths, the scripts will find them automatically.
* If they differ, specify them using the following variables:
- `QT_INSTALL_DIR` - Qt root installation folder
- `QT_ROOT_PATH` - Qt framework root directory
- `QIF_ROOT_PATH` - Qt Installer Framework root path
- `ANDROID_HOME` - Path to Android SDK root folder
- and others. Check scripts for more
Unix-like:
```bash ```bash
export QT_BIN_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/ios/bin" # Build executables for the host platform
export QT_MACOS_ROOT_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/macos" deploy/build.sh
export QT_IOS_BIN=$QT_BIN_DIR
export PATH=$PATH:~/go/bin
mkdir build-ios
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
```
Replace PATH-TO-QT-FOLDER and QT-VERSION to your environment
# Or just
deploy/build.sh
If you get `gomobile: command not found` make sure to set PATH to the location # Build executables and installers for the host platform
of the bin folder where gomobile was installed. Usually, it's in `GOPATH`. deploy/build.sh --installer all
```bash
export PATH=$(PATH):/path/to/GOPATH/bin # Build Android APK and AAB
deploy/build.sh -t android --aab
# Call for help
deploy/build.sh -h
``` ```
6. Open the XCode project. You can then run /test/archive/ship the app. Windows:
```batch
:: Build executables for Windows
deploy/build.bat
If the build fails with the following error :: Build executables with IFW installer for Windows
``` deploy/build.bat --installer ifw
make: ***
[$(PROJECTDIR)/client/build/AmneziaVPN.build/Debug-iphoneos/wireguard-go-bridge/goroot/.prepared]
Error 1
```
Add a user-defined variable to both AmneziaVPN and WireGuardNetworkExtension targets' build settings with
key `PATH` and value `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
if the above error persists on your M1 Mac, then most probably you need to install arch based CMake :: Build executables with IFW and WIX installer for Windows
``` deploy/build.bat --installer ifw --installer wix
arch -arm64 brew install cmake
:: Or just
deploy/build.bat --installer all
``` ```
Build might fail with the "source files not found" error the first time you try it, because the modern XCode build system compiles dependencies in parallel, and some dependencies end up being built after the ones that ### Developing the project in IDEs
require them. In this case, simply restart the build.
## How to build the Android app * Basically, you can use any IDE that handles CMake and Qt kits properly to run configure and build steps, and to navigate through the code nicely. For example:
- `Qt Creator`
- `Visual Studio Code` with `Qt Extension Pack`
- and so on
_Tested on Mac OS_ * To use `Xcode`, you have to configure project first by using `cmake`. The easiest way to do it is to use `Qt Creator` for configuration. Then open `AmneziaVPN.xcodeproj` file from the build folder by using `Xcode`. Note that none of the files changed are saved - the files actually getting changed in build directory. Copy them manually if necessary
The Android app has the following requirements: * `Android studio` could be used in the same way - just configure the project by using `cmake` manually or by using `Qt Creator`. Open `<build-dir>/client/android-build` in `Android studio` then. Do not forget to copy the changes - everything you do is saved under the build directory actually.
* JDK 11
* Android platform SDK 33
* CMake 3.25.0
After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly. ### Installing Android SDK
- Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`. * Android SDK could be installed using the following methods:
- Set path to JDK 11 - Using `Qt Creator`. Use `Preferences`->`SDKs`
- Set path to Android SDK (`$ANDROID_HOME`) - Using `Android studio`. By default it installs necessary `SDKs` automatically during the installation
- Manually by using `sdk-manager`. Check [this](https://developer.android.com/tools) page for details
In case you get errors regarding missing SDK or 'SDK manager not running', you cannot fix them by correcting the paths. If you have some spare GBs on your disk, you can let QT Creator install all requirements by choosing an empty folder for `Android SDK location` and clicking on `Set Up SDK`. Be aware: This will install a second Android SDK and NDK on your machine! 
Double-check that the right CMake version is configured:  Click on `QT Creator` -> `Preferences` and click on the side menu on `Kits`. Under the center content view's `Kits` tab, you'll find an entry for `CMake Tool`. If the default selected CMake version is lower than 3.25.0, install on your system CMake >= 3.25.0 and choose `System CMake at <path>` from the drop-down list. If this entry is missing, you either have not installed CMake yet or QT Creator hasn't found the path to it. In that case, click in the preferences window on the side menu item `CMake`, then on the tab `Tools` in the center content view, and finally on the button `Add` to set the path to your installed CMake. 
Please make sure that you have selected Android Platform SDK 33 for your project: click in the main view's side menu on `Projects`, and on the left, you'll see a section `Build & Run` showing different Android build targets. You can select any of them, Amnezia VPN's project setup is designed in a way that all Android targets will be built. Click on the targets submenu item `Build` and scroll in the center content view to `Build Steps`. Click on `Details` at the end of the headline `Build Android APK` (the `Details` button might be hidden in case the QT Creator Window is not running in full screen!). Here we are: Choose `android-33` as `Android Build Platform SDK`.
That's it! You should be ready to compile the project from QT Creator!
### Development flow
After you've hit the build button, QT-Creator copies the whole project to a folder in the repository parent directory. The folder should look something like `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>`.
If you want to develop Amnezia VPNs Android components written in Kotlin, such as components using system APIs, you need to import the generated project in Android Studio with `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>/client/android-build` as the projects root directory. While you should be able to compile the generated project from Android Studio, you cannot work directly in the repository's Android project. So whenever you are confident with your work in the generated project, you'll need to copy and paste the affected files to the corresponding path in the repository's Android project so that you can add and commit your changes!
You may face compiling issues in QT Creator after you've worked in Android Studio on the generated project. Just do a `./gradlew clean` in the generated project's root directory (`<path>/client/android-build/.`) and you should be good to go.
## License ## License

View File

@@ -50,23 +50,14 @@ AmneziaVPN использует несколько проектов с откр
- [OpenSSL](https://www.openssl.org/) - [OpenSSL](https://www.openssl.org/)
- [OpenVPN](https://openvpn.net/) - [OpenVPN](https://openvpn.net/)
- [Shadowsocks](https://shadowsocks.org/)
- [Qt](https://www.qt.io/) - [Qt](https://www.qt.io/)
- [LibSsh](https://libssh.org) - [LibSsh](https://libssh.org)
- [WireGuard](https://www.wireguard.com/)
- [Xray-core](https://xtls.github.io/en/)
- [Conan](https://conan.io/)
- и другие... - и другие...
## Проверка исходного кода ## Помощь с переводами
После клонирования репозитория обязательно загрузите все подмодули.
```bash
git submodule update --init --recursive
```
## Разработка
Хотите внести свой вклад? Добро пожаловать!
### Помощь с переводами
Загрузите самые актуальные файлы перевода. Загрузите самые актуальные файлы перевода.
@@ -76,90 +67,98 @@ git submodule update --init --recursive
Переведите или исправьте строки в одном или нескольких файлах *.ts и загрузите их обратно в этот репозиторий в папку ``client/translations``. Это можно сделать через веб-интерфейс или любым другим знакомым вам способом. Переведите или исправьте строки в одном или нескольких файлах *.ts и загрузите их обратно в этот репозиторий в папку ``client/translations``. Это можно сделать через веб-интерфейс или любым другим знакомым вам способом.
### Сборка исходного кода и деплой ## Проверка исходного кода
Проверьте папку deploy для скриптов сборки.
### Как собрать iOS-приложение из исходного кода на MacOS После клонирования репозитория обязательно загрузите все подмодули.
1. Убедитесь, что у вас установлен Xcode версии 14 или выше.
2. Для генерации проекта Xcode используется QT. Требуется версия QT 6.6.2. Установите QT для MacOS здесь или через QT Online Installer. Необходимые модули:
- MacOS
- iOS
- Модуль совместимости с Qt 5
- Qt Shader Tools
- Дополнительные библиотеки:
- Qt Image Formats
- Qt Multimedia
- Qt Remote Objects
3. Установите CMake, если это необходимо. Рекомендуемая версия — 3.25. Скачать CMake можно здесь.
4. Установите Go версии >= v1.16. Если Go ещё не установлен, скачайте его с [официального сайта](https://golang.org/dl/) или используйте Homebrew. Установите gomobile:
```bash ```bash
export PATH=$PATH:~/go/bin git submodule update --init --recursive
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
``` ```
5. Соберите проект: ## Руководство по разработке
Хотите внести свой вклад? Добро пожаловать!
### Требования для сборки
* [`CMake`](https://cmake.org/download/)
* Компилятор и система сборки, в зависимости от таргета:
- [Linux] Любые `make` и `gcc`
- [Apple] [`Xcode`](https://developer.apple.com/xcode/) или [`Xcode command line tools`](https://developer.apple.com/xcode/)
- [Windows] [`Visual Studio 2022`](https://aka.ms/vs/17/release/vs_community.exe) или [`VS 2022 Build Tools`](https://aka.ms/vs/17/release/vs_buildtools.exe)
- [Android] [`Android SDK`](#установка-android-sdk) и [`Ninja`](https://ninja-build.org/)
* [`Qt 6.10+`](https://www.qt.io/download-open-source) со следующими модулями:
- Основные модули для таргета (Desktop/Android/iOS)
- Qt 5 Compatibility module
- Qt Remote Objects
* Пакетный менеджер [`Conan`](https://conan.io/downloads)
- На MacOS достаточно использовать `homebrew` или установить в `.venv` в корень проекта
- Для остальных систем необходимо прописать пути в `PATH`
* (Необязательно) Заивисимости для установщиков:
- [Windows/Linux] [`Qt Installer Framework`](https://www.qt.io/download-open-source)
- [Windows] [`WIX toolset`](https://github.com/wixtoolset/wix/releases)
### Сборка проекта через скрипты
* Запустите скрипты, находящиеся в папке `deploy`
* Если все зависимости установлены в стандартных локациях, скрипт найдёт их самостоятельно
* Если пути отличаются, их нужно явно указать используя:
- `QT_INSTALL_DIR` - корневая папка установки Qt
- `QT_ROOT_PATH` - корневая папка Qt Framework
- `QIF_ROOT_PATH` - корневая папка Qt Installer Framework
- `ANDROID_HOME` - путь к Android SDK
- и другие. Их можно получить из вышеуказанных скриптов
Unix-like:
```bash ```bash
export QT_BIN_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/ios/bin" # Build executables for the host platform
export QT_MACOS_ROOT_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/macos" deploy/build.sh
export QT_IOS_BIN=$QT_BIN_DIR
export PATH=$PATH:~/go/bin
mkdir build-ios
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
```
Замените <PATH-TO-QT-FOLDER> и <QT-VERSION> на ваши значения.
Если появляется ошибка gomobile: command not found, убедитесь, что PATH настроен на папку bin, где установлен gomobile: # Or just
```bash deploy/build.sh
export PATH=$(PATH):/path/to/GOPATH/bin
# Build executables and installers for the host platform
deploy/build.sh --installer all
# Build Android APK and AAB
deploy/build.sh -t android --aab
# Call for help
deploy/build.sh -h
``` ```
6. Откройте проект в Xcode. Теперь вы можете тестировать, архивировать или публиковать приложение. Windows:
```batch
Если сборка завершится с ошибкой: :: Build executables for Windows
``` deploy/build.bat
make: ***
[$(PROJECTDIR)/client/build/AmneziaVPN.build/Debug-iphoneos/wireguard-go-bridge/goroot/.prepared]
Error 1
```
Добавьте пользовательскую переменную PATH в настройки сборки для целей AmneziaVPN и WireGuardNetworkExtension с ключом `PATH` и значением `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
Если ошибка повторяется на Mac с M1, установите версию CMake для архитектуры ARM: :: Build executables with IFW installer for Windows
``` deploy/build.bat --installer ifw
arch -arm64 brew install cmake
:: Build executables with IFW and WIX installer for Windows
deploy/build.bat --installer ifw --installer wix
:: Or just
deploy/build.bat --installer all
``` ```
При первой попытке сборка может завершиться с ошибкой source files not found. Это происходит из-за параллельной компиляции зависимостей в XCode. Просто перезапустите сборку. ### Разработка в IDE
* Можно использовать любые IDE которые умеют работать с CMake и находить Qt Kits. Например:
- `Qt Creator`
- `Visual Studio Code` with `Qt Extension Pack`
- и так далее
## Как собрать Android-приложение * Для использования `Xcode` нужно сконфигурировать проект с помощью `cmake`. Самый простой способ это сделать - использовать `Qt Creator` для конфигурации. Затем, нужно открыть файл `AmneziaVPN.xcodeproj` из папки сборки с помощью `Xcode`. Учтите, что никакие файлы фактически не сохраняются - они сохраняются в директории сборки. Если требуется, скопируйте файлы вручную
Сборка тестировалась на MacOS. Требования:
- JDK 11
- Android SDK 33
- CMake 3.25.0
Установите QT, QT Creator и Android Studio.
Настройте QT Creator:
- В меню QT Creator перейдите в `QT Creator` -> `Preferences` -> `Devices` ->`Android`. * `Android studio` может быть использована подобным вышеуказанному способу - нужно использовать `cmake` вручную или через `Qt Creator` для конфигурации. Далее, откройте `<build-dir>/client/android-build` в `Android studio`. Не забудьте скопировать изменённые файлы в папку с исходным кодом - все файлы, изменённые в IDE, сохраняются фактически в папке сборки.
- Укажите путь к JDK 11.
- Укажите путь к Android SDK (`$ANDROID_HOME`)
Если вы сталкиваетесь с ошибками, связанными с отсутствием SDK или сообщением «SDK manager not running», их нельзя исправить просто корректировкой путей. Если у вас есть несколько свободных гигабайт на диске, вы можете позволить Qt Creator установить все необходимые компоненты, выбрав пустую папку для расположения Android SDK и нажав кнопку **Set Up SDK**. Учтите: это установит второй Android SDK и NDK на вашем компьютере! ### Установка Android SDK
Убедитесь, что настроена правильная версия CMake: перейдите в **Qt Creator -> Preferences** и в боковом меню выберите пункт **Kits**. В центральной части окна, на вкладке **Kits**, найдите запись для инструмента **CMake Tool**. Если выбранная по умолчанию версия CMake ниже 3.25.0, установите на свою систему CMake версии 3.25.0 или выше, а затем выберите опцию **System CMake at <путь>** из выпадающего списка. Если этот пункт отсутствует, это может означать, что вы еще не установили CMake, или Qt Creator не смог найти путь к нему. В таком случае в окне **Preferences** перейдите в боковое меню **CMake**, затем во вкладку **Tools** в центральной части окна и нажмите кнопку **Add**, чтобы указать путь к установленному CMake.
Убедитесь, что для вашего проекта выбрана Android Platform SDK 33: в главном окне на боковой панели выберите пункт **Projects**, и слева вы увидите раздел **Build & Run**, показывающий различные целевые Android-платформы. Вы можете выбрать любую из них, так как настройка проекта Amnezia VPN разработана таким образом, чтобы все Android-цели могли быть собраны. Перейдите в подраздел **Build** и прокрутите центральную часть окна до раздела **Build Steps**. Нажмите **Details** в заголовке **Build Android APK** (кнопка **Details** может быть скрыта, если окно Qt Creator не запущено в полноэкранном режиме!). Вот здесь выберите **android-33** в качестве Android Build Platform SDK.
### Разработка Android-компонентов
После сборки QT Creator копирует проект в отдельную папку, например, `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>`. Для разработки Android-компонентов откройте сгенерированный проект в Android Studio, указав папку `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>/client/android-build` в качестве корневой.
Изменения в сгенерированном проекте нужно вручную перенести в репозиторий. После этого можно коммитить изменения.
Если возникают проблемы со сборкой в QT Creator после работы в Android Studio, выполните команду `./gradlew clean` в корневой папке сгенерированного проекта (`<path>/client/android-build/.`).
* Android SDK может быть установлен следующими способами:
- Используя `Qt Creator`, через настройки в пунктах `Preferences`->`SDKs`
- Используя `Android studio`. По умолчанию необходимые `SDK` устанавливаются автоматически.
- Вручную, используя `sdk-manager`. Подробности можно найти [здесь](https://developer.android.com/tools)
## Лицензия ## Лицензия

View File

@@ -71,8 +71,6 @@ qt6_add_resources(QRC ${QRC}
) )
# -- i18n begin # -- i18n begin
set(CMAKE_AUTORCC ON)
set(AMNEZIAVPN_TS_FILES set(AMNEZIAVPN_TS_FILES
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ru_RU.ts ${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ru_RU.ts
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_zh_CN.ts ${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_zh_CN.ts
@@ -84,20 +82,10 @@ set(AMNEZIAVPN_TS_FILES
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_hi_IN.ts ${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_hi_IN.ts
) )
file(GLOB_RECURSE AMNEZIAVPN_TS_SOURCES *.qrc *.cpp *.h *.ui) qt6_add_translations(${PROJECT}
list(FILTER AMNEZIAVPN_TS_SOURCES EXCLUDE REGEX "qtgamepad/examples") TS_FILES ${AMNEZIAVPN_TS_FILES}
RESOURCE_PREFIX "/translations"
qt_create_translation(AMNEZIAVPN_QM_FILES ${AMNEZIAVPN_TS_SOURCES} ${AMNEZIAVPN_TS_FILES}) )
set(QM_FILE_LIST "")
foreach(FILE ${AMNEZIAVPN_QM_FILES})
get_filename_component(QM_FILE_NAME ${FILE} NAME)
list(APPEND QM_FILE_LIST "<file>${QM_FILE_NAME}</file>")
endforeach()
string(REPLACE ";" "" QM_FILE_LIST ${QM_FILE_LIST})
configure_file(${CMAKE_CURRENT_LIST_DIR}/translations/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
qt6_add_resources(QRC ${I18NQRC} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
# -- i18n end # -- i18n end
set(IS_CI ${CI}) set(IS_CI ${CI})
@@ -176,6 +164,10 @@ if(APPLE)
set(CMAKE_XCODE_GENERATE_SCHEME FALSE) set(CMAKE_XCODE_GENERATE_SCHEME FALSE)
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM}) set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM})
set(CMAKE_XCODE_ATTRIBUTE_GROUP_ID_IOS ${BUILD_IOS_GROUP_IDENTIFIER}) set(CMAKE_XCODE_ATTRIBUTE_GROUP_ID_IOS ${BUILD_IOS_GROUP_IDENTIFIER})
if (BUILD_VPN_KEYCHAIN)
set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--keychain ${BUILD_VPN_KEYCHAIN}")
endif()
endif() endif()
if(LINUX AND NOT ANDROID) if(LINUX AND NOT ANDROID)
@@ -201,45 +193,15 @@ elseif(APPLE)
include(cmake/macos.cmake) include(cmake/macos.cmake)
endif() 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()
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE) if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
list(APPEND SOURCES ${CMAKE_CURRENT_LIST_DIR}/main.cpp) list(APPEND SOURCES ${CMAKE_CURRENT_LIST_DIR}/main.cpp)
target_link_libraries(${PROJECT} PRIVATE ${LIBS})
target_compile_definitions(${PROJECT} PRIVATE "MZ_$<UPPER_CASE:${MZ_PLATFORM_NAME}>")
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC}) 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). # Finalize the executable so Qt can gather/deploy QML modules and plugins correctly (Android needs this).
@@ -251,3 +213,51 @@ if(COMMAND qt_finalize_executable)
else() else()
qt_finalize_target(${PROJECT}) qt_finalize_target(${PROJECT})
endif() endif()
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
)
if (APPLE AND NOT IOS AND NOT MACOS_NE)
list(APPEND OVPN_SCRIPTS "${CMAKE_SOURCE_DIR}/deploy/data/macos/update-resolv-conf.sh")
endif()
if (LINUX AND NOT ANDROID)
list(APPEND OVPN_SCRIPTS "${CMAKE_SOURCE_DIR}/deploy/data/linux/update-resolv-conf.sh")
endif()
if(OVPN_SCRIPTS)
add_custom_command(TARGET ${PROJECT} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${OVPN_SCRIPTS}
"$<TARGET_FILE_DIR:${PROJECT}>"
)
install(FILES ${OVPN_SCRIPTS}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT AmneziaVPN
PERMISSIONS
OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
)
endif()

View File

@@ -39,6 +39,7 @@ android {
// keeps language resources for only the locales specified below // keeps language resources for only the locales specified below
resourceConfigurations += listOf("en", "ru", "b+zh+Hans") resourceConfigurations += listOf("en", "ru", "b+zh+Hans")
ndk.abiFilters += qtTargetAbiList.split(",")
} }
sourceSets { sourceSets {
@@ -52,50 +53,12 @@ android {
} }
} }
signingConfigs {
register("release") {
storeFile = providers.environmentVariable("ANDROID_KEYSTORE_PATH").orNull?.let { file(it) }
storePassword = providers.environmentVariable("ANDROID_KEYSTORE_KEY_PASS").orNull
keyAlias = providers.environmentVariable("ANDROID_KEYSTORE_KEY_ALIAS").orNull
keyPassword = providers.environmentVariable("ANDROID_KEYSTORE_KEY_PASS").orNull
}
}
buildTypes { buildTypes {
release { release {
// exclude coroutine debug resource from release build // exclude coroutine debug resource from release build
packaging { packaging {
resources.excludes += "DebugProbesKt.bin" resources.excludes += "DebugProbesKt.bin"
} }
signingConfig = signingConfigs["release"]
}
create("fdroid") {
initWith(getByName("release"))
signingConfig = null
matchingFallbacks += "release"
}
}
splits {
abi {
isEnable = true
reset()
include(*qtTargetAbiList.split(',').toTypedArray())
isUniversalApk = false
}
}
// fix for Qt Creator to allow deploying the application to a device
// to enable this fix, add the line outputBaseName=android-build to local.properties
if (outputBaseName.isNotEmpty()) {
applicationVariants.all {
outputs.map { it as BaseVariantOutputImpl }
.forEach { output ->
if (output.outputFileName.endsWith(".apk")) {
output.outputFileName = "$outputBaseName-${buildType.name}.apk"
}
}
} }
} }

View File

@@ -1,11 +1,11 @@
[versions] [versions]
agp = "8.5.2" agp = "8.6.1"
kotlin = "1.9.24" kotlin = "1.9.24"
androidx-core = "1.13.1" androidx-core = "1.13.1"
androidx-activity = "1.9.1" androidx-activity = "1.9.1"
androidx-annotation = "1.8.2" androidx-annotation = "1.8.2"
androidx-biometric = "1.2.0-alpha05" androidx-biometric = "1.2.0-alpha05"
androidx-camera = "1.3.4" androidx-camera = "1.5.3"
androidx-fragment = "1.8.2" androidx-fragment = "1.8.2"
androidx-security-crypto = "1.1.0-alpha06" androidx-security-crypto = "1.1.0-alpha06"
androidx-datastore = "1.1.1" androidx-datastore = "1.1.1"

View File

@@ -26,7 +26,6 @@ plugins {
id("settings-property-delegate") id("settings-property-delegate")
} }
rootProject.name = "AmneziaVPN"
rootProject.buildFileName = "build.gradle.kts" rootProject.buildFileName = "build.gradle.kts"
include(":qt") include(":qt")
@@ -47,15 +46,7 @@ val qtMinSdkVersion: String by gradleProperties
// set default values for all modules // set default values for all modules
configure<SettingsExtension> { configure<SettingsExtension> {
buildToolsVersion = androidBuildToolsVersion buildToolsVersion = androidBuildToolsVersion
compileSdk = androidCompileSdkVersion.substringAfter('-').toInt() compileSdk = androidCompileSdkVersion.split('-')[1].toInt()
minSdk = qtMinSdkVersion.toInt() minSdk = qtMinSdkVersion.toInt()
ndkVersion = androidNdkVersion ndkVersion = androidNdkVersion
} }
// stop Gradle running by androiddeployqt
gradle.taskGraph.whenReady {
if (providers.environmentVariable("ANDROIDDEPLOYQT_RUN").isPresent
&& !providers.systemProperty("explicitRun").isPresent) {
allTasks.forEach { it.enabled = false }
}
}

View File

@@ -214,10 +214,7 @@ class AmneziaActivity : QtActivity() {
private fun loadLibs() { private fun loadLibs() {
listOf( listOf(
"rsapss", "rsapss"
"crypto_3",
"ssl_3",
"ssh"
).forEach { ).forEach {
loadSharedLibrary(this.applicationContext, it) loadSharedLibrary(this.applicationContext, it)
} }

View File

@@ -8,81 +8,11 @@ include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.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}
)
add_compile_definitions(_WINSOCKAPI_) add_compile_definitions(_WINSOCKAPI_)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(BUILD_WITH_QT6 ON) set(BUILD_WITH_QT6 ON)
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain) add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain EXCLUDE_FROM_ALL)
if(ANDROID) if(ANDROID)
# Use qtgamepad from amnezia-vpn/qtgamepad repository # Use qtgamepad from amnezia-vpn/qtgamepad repository
@@ -106,12 +36,13 @@ endif()
set(LIBS ${LIBS} qt6keychain) set(LIBS ${LIBS} qt6keychain)
include_directories( 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/QSimpleCrypto/src/include
${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain ${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain
${CMAKE_CURRENT_BINARY_DIR}/3rd/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)

View File

@@ -42,18 +42,14 @@ set(SOURCES ${SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/core/utils/installedAppsImageProvider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/core/utils/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 find_package(awg-android REQUIRED)
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/android/xray/libXray) 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})

View File

@@ -1,8 +1,6 @@
message("Client iOS build") 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(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
enable_language(OBJC) enable_language(OBJC)
enable_language(OBJCXX) enable_language(OBJCXX)
enable_language(Swift) enable_language(Swift)
@@ -132,17 +130,8 @@ target_sources(${PROJECT} PRIVATE
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
) )
add_subdirectory(ios/networkextension) add_subdirectory(ios/networkextension)
add_dependencies(${PROJECT} 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")

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_SHORT_VERSION_STRING "${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}"
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}" 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} set(HEADERS ${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/ui/utils/macosUtil.h ${CMAKE_CURRENT_SOURCE_DIR}/ui/utils/macosUtil.h

View File

@@ -1,7 +1,6 @@
message("Client ==> MacOS NE build") message("Client ==> MacOS NE build")
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE) 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}) set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
@@ -140,7 +139,6 @@ target_sources(${PROJECT} PRIVATE
) )
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
) )
@@ -153,19 +151,6 @@ message(${QtCore_location})
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE) 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 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: Privacy Technologies OU"
"$<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} COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Signing OpenVPNAdapter framework"
) )

View File

@@ -241,7 +241,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
connData.clientId = Utils::getRandomString(32); connData.clientId = Utils::getRandomString(32);
int ret = 0; int ret = 0;
int nVersion = 1; int nVersion = 0;
QByteArray clientIdUtf8 = connData.clientId.toUtf8(); QByteArray clientIdUtf8 = connData.clientId.toUtf8();

View File

@@ -170,11 +170,6 @@ ErrorCode OpenVpnProtocol::start()
{ {
OpenVpnProtocol::stop(); OpenVpnProtocol::stop();
if (!QFileInfo::exists(Utils::openVpnExecPath())) {
setLastError(ErrorCode::OpenVpnExecutableMissing);
return lastError();
}
if (!QFileInfo::exists(configPath())) { if (!QFileInfo::exists(configPath())) {
setLastError(ErrorCode::OpenVpnConfigMissing); setLastError(ErrorCode::OpenVpnConfigMissing);
return lastError(); return lastError();

View File

@@ -159,15 +159,15 @@ ErrorCode XrayProtocol::startTun2Socks()
m_tun2socksProcess->setArguments({ "-device", QString("tun://%1").arg(tunName), "-proxy", proxyUrl }); m_tun2socksProcess->setArguments({ "-device", QString("tun://%1").arg(tunName), "-proxy", proxyUrl });
connect( connect(
m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this,
[this]() { [this]() {
auto readAllStandardOutput = m_tun2socksProcess->readAllStandardOutput(); auto readAllStandardError = m_tun2socksProcess->readAllStandardError();
if (!readAllStandardOutput.waitForFinished()) { if (!readAllStandardError.waitForFinished()) {
qWarning() << "Failed to read output from tun2socks"; qWarning() << "Failed to read output from tun2socks";
return; return;
} }
const QString line = readAllStandardOutput.returnValue(); const QString line = readAllStandardError.returnValue();
if (!line.contains("[TCP]") && !line.contains("[UDP]")) if (!line.contains("[TCP]") && !line.contains("[UDP]"))
qDebug() << "[tun2socks]:" << line; qDebug() << "[tun2socks]:" << line;

View File

@@ -259,15 +259,7 @@ bool Utils::killProcessByName(const QString &name)
QString Utils::openVpnExecPath() QString Utils::openVpnExecPath()
{ {
#ifdef Q_OS_WIN return Utils::executable("openvpn", true);
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
} }
QString Utils::wireguardExecPath() QString Utils::wireguardExecPath()
@@ -295,15 +287,7 @@ QString Utils::certUtilPath()
QString Utils::tun2socksPath() QString Utils::tun2socksPath()
{ {
#ifdef Q_OS_WIN return Utils::executable("tun2socks", true);
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
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN

View File

@@ -110,21 +110,14 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy ${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 ${CLIENT_ROOT_DIR})
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_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(openvpnadapter REQUIRED)
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework) find_package(awg-apple REQUIRED)
target_link_libraries(networkextension PRIVATE amnezia::awg-apple)
find_package(hev-socks5-tunnel REQUIRED)
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel)

View File

@@ -1,3 +0,0 @@
#ifndef WIREGUARD_GO_VERSION
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
#endif // WIREGUARD_GO_VERSION

View File

@@ -114,25 +114,14 @@ set_property(TARGET AmneziaVPNNetworkExtension APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy ${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 ${CLIENT_ROOT_DIR})
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CMAKE_CURRENT_BINARY_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}) find_package(awg-apple REQUIRED)
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a) target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::awg-apple)
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
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)

View File

@@ -1,3 +0,0 @@
#ifndef WIREGUARD_GO_VERSION
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
#endif // WIREGUARD_GO_VERSION

View File

@@ -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("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("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
return app.exec(); return app.exec();
} }

View File

@@ -80,7 +80,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
QDir appPath(QCoreApplication::applicationDirPath()); QDir appPath(QCoreApplication::applicationDirPath());
QStringList wgArgs = {"-f", "amn0"}; 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)) { if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
logger.error() << "Unable to start tunnel process due to timeout"; logger.error() << "Unable to start tunnel process due to timeout";
m_tunnel.kill(); m_tunnel.kill();

View File

@@ -79,7 +79,7 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
QDir appPath(QCoreApplication::applicationDirPath()); QDir appPath(QCoreApplication::applicationDirPath());
QStringList wgArgs = {"-f", "utun"}; 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)) { if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
logger.error() << "Unable to start tunnel process due to timeout"; logger.error() << "Unable to start tunnel process due to timeout";
m_tunnel.kill(); m_tunnel.kill();

View File

@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/translations">
@QM_FILE_LIST@
</qresource>
</RCC>

91
cmake/CPack.cmake Normal file
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
cmake/CPackOptions.cmake Normal file
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
cmake/conan_provider.cmake Normal file
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)

View File

@@ -0,0 +1,31 @@
if(APPLE)
get_property(generator_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (generator_is_multi_config)
set(CONAN_INSTALL_BUILD_CONFIGURATIONS Release Debug MinSizeRel RelWithDebInfo)
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(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)
set(CMAKE_ANDROID_STL_TYPE "c++_shared" CACHE STRING "")
endif()
if (WIN32 OR APPLE)
set(CMAKE_INSTALL_BINDIR ".")
endif()

View File

@@ -0,0 +1,17 @@
find_program(CONAN_COMMAND "conan" REQUIRED
HINTS
"${CMAKE_SOURCE_DIR}/.venv/bin"
"/opt/homebrew/bin"
)
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()
execute_process(
COMMAND ${CONAN_COMMAND} remote add amnezia "https://artifactory.amnezia.org/artifactory/api/conan/client-prebuilts" --force
)

49
cmake/sign_binaries.cmake Normal file
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
cmake/sign_packages.cmake Normal file
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
cmake/util/codesign.cmake Normal file
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()

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
cmake/util/signtool.cmake Normal file
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()

47
conanfile.py Normal file
View File

@@ -0,0 +1,47 @@
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 == "iOS" 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")
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")
# expicitly use libssh@amnezia to prevent it from being downloaded from conan-center
self.requires("libssh/0.11.3@amnezia")
self.requires("openssl/3.6.1")
self.requires("zlib/1.3.2")

147
deploy/build.bat Normal file
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%" "-DCMAKE_VS_GLOBALS=UseMultiToolTask=true;EnforceProcessCountAcrossBuilds=true" || goto :fail
cmake --build "%BUILD_DIR%" --config Release -- /m || 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

221
deploy/build.sh Executable file
View File

@@ -0,0 +1,221 @@
#!/bin/bash
set -o errexit
set +o xtrace
run_traced() {
PS4='\033[1;34m+ \033[0m'
set -o xtrace
"$@"
{ set +o xtrace; } 2>/dev/null
}
all_abis_set="arm64-v8a armeabi-v7a x86_64 x86"
get_abi_folder() {
case $1 in
arm64-v8a) echo "android_arm64_v8a" ;;
armeabi-v7a) echo "android_armv7" ;;
x86) echo "android_x86" ;;
all|x86_64) echo "android_x86_64" ;;
*) echo "" ;;
esac
}
abis=()
installers=()
while [[ $# -gt 0 ]]; do
case "$1" in
-b|--build) : ${BUILD_PATH:="$2"}; shift 2 ;;
-s|--source) : ${SOURCE_PATH:="$2"}; shift 2 ;;
-t|--target) TARGET="$2"; shift 2 ;;
-f|--force) : ${FORCE=true}; shift ;;
-g|--generator) : ${CMAKE_GENERATOR=$2}; shift 2 ;;
--installer) installers+=("$2"); shift 2 ;;
--abi) abis+=("$2"); shift 2 ;;
--sign) : ${SIGN:=true}; shift ;;
--aab) : ${BUILD_AAB=true}; shift ;;
--help|-h|?)
echo "Usage: $0 [options]"
echo " Options:"
echo " -b|--build <path> - specify build folder"
echo " -s|--source <path> - specify path to amnezia-client root folder"
echo " -t|--target <name> - specify build target"
echo " -f|--force - force removal of build folder prior cmake configuration"
echo " -g|--generator <name> - use specified generator for CMake"
echo " --installer <name|all> - specify an installer(s) to build. allowed to be used multiple times"
echo " --abi - specify Android ABIs for target to build for. all by default"
echo " --sign - whether to sign the resulting files. only appicable to Android"
echo " --aab - whether to build AAB. only applicable to Android"
exit 0
;;
*) echo "Unknown arg \"$1\". Use $0 -h to get help"; exit 1 ;;
esac
done
: ${SOURCE_PATH:=$(pwd)}
: ${BUILD_PATH:="$SOURCE_PATH/deploy/build"}
: ${INSTALLERS:="${installers[@]}"}
: ${ABIS:="${abis[@]}"}
: ${ABIS:="all"}
: ${HOST:="$(uname -s)"}
: ${TARGET:="$HOST"}
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')
TARGET=$(echo "$TARGET" | tr '[:upper:]' '[:lower:]')
bases=(~/Qt /opt/Qt)
[ -n "${QT_INSTALL_DIR}" ] && bases=("${QT_INSTALL_DIR}/Qt" "${bases[@]}")
# seek for Qt installation in bases folders
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[@]}" | awk -F'/' '{print $NF, $0}' | sort -V | tail -1 | awk '{print $2}')}
: ${QIF_ROOT_PATH:=$(printf '%s\n' "${qif_folders[@]}" | awk -F'/' '{print $NF, $0}' | sort -V | tail -1 | awk '{print $2}')}
if [[ -z "$QT_ROOT_PATH" ]]; then
echo "* Qt not found in standard paths and in QT_INSTALL_DIR"
echo " Please install the suitable version of Qt"
echo " or specify it by using QT_ROOT_PATH/QT_INSTALL_DIR variables"
exit 1
fi
# add host options
case "$HOST" in
linux) [[ "$HOST" != "$TARGET" ]] && [[ -n "${QT_ROOT_PATH}" ]] && : ${QT_HOST_PATH:="$QT_ROOT_PATH/gcc_64"} ;;
darwin) [[ "$HOST" != "$TARGET" ]] && [[ -n "${QT_ROOT_PATH}" ]] && : ${QT_HOST_PATH:="$QT_ROOT_PATH/macos"} ;;
*) echo "Unsupported host \"$HOST\""; exit 1 ;;
esac
# add custom per-target options
case "$TARGET" in
linux)
[ "$INSTALLERS" = "all" ] && INSTALLERS="IFW"
: ${CMAKE_GENERATOR:="Unix Makefiles"}
: ${CMAKE_PREFIX_PATH:="$QT_ROOT_PATH"/gcc_64}
;;
darwin|macos)
[ "$INSTALLERS" = "all" ] && INSTALLERS="productbuild"
: ${CMAKE_GENERATOR:="Unix Makefiles"}
: ${CMAKE_PREFIX_PATH:="$QT_ROOT_PATH"/macos}
;;
macos-ne)
MACOS_NE=TRUE
DEPLOY=1
no_installers=1
: ${CMAKE_GENERATOR:="Xcode"}
: ${CMAKE_PREFIX_PATH:="$QT_ROOT_PATH"/macos}
;;
ios)
DEPLOY=1
no_installers=1
: ${CMAKE_GENERATOR:="Xcode"}
: ${CMAKE_OSX_SYSROOT=iphoneos}
: ${CMAKE_TOOLCHAIN_FILE:="$QT_ROOT_PATH/ios/lib/cmake/Qt6/qt.toolchain.cmake"}
;;
android)
no_installers=1
: ${CMAKE_GENERATOR:="Ninja"}
: ${ANDROID_PLATFORM:="android-28"}
if [[ -n "$SIGN" ]]; then
QT_ANDROID_SIGN_APK=TRUE
QT_ANDROID_SIGN_AAB=TRUE
fi
[[ "$ABIS" == "all" ]] && ABIS="$all_abis_set"
toolchain_abi=""
for abi in $ABIS; do
abi_exists=$(get_abi_folder "$abi")
if [[ -z "$abi_exists" ]]; then
echo "Unsupported ABI \"${abi}\""
exit 1
fi
: ${toolchain_abi:="$abi"}
done
if [[ "$ABIS" == "$all_abis_set" ]]; then
QT_ANDROID_BUILD_ALL_ABIS=TRUE
else
QT_ANDROID_ABIS="${ABIS// /;}"
fi
toolchain_dir=$(get_abi_folder "$toolchain_abi")
: ${CMAKE_PREFIX_PATH:="$QT_ROOT_PATH/$toolchain_dir/lib/cmake/Qt6/qt.toolchain.cmake"}
: ${CMAKE_TOOLCHAIN_FILE:="$QT_ROOT_PATH/$toolchain_dir/lib/cmake/Qt6/qt.toolchain.cmake"}
;;
*) echo "Unsupported target \"$TARGET\""; exit 1 ;;
esac
if [[ "$INSTALLERS" =~ IFW ]] && [[ -z "$QIF_ROOT_PATH" ]]; then
echo "* Qt Installer Framework not found in standard paths and in QT_INSTALL_DIR"
echo " Please install the suitable version of Qt Installer Framework"
echo " or specify it by using QIF_ROOT_PATH/QT_INSTALL_DIR variables"
exit 1
fi
# search for Android SDK and NDK
if [[ "$TARGET" == "android" ]]; then
bases=()
case "$HOST" in
linux) bases=(~/Android/sdk) ;;
darwin) bases=(~/Library/Android/sdk) ;;
esac
[[ -n "$ANDROID_HOME" ]] && bases=("$ANDROID_HOME" "${bases[@]}")
ndk_dirs=()
for base in "${bases[@]}"; do
for ndk_dir in "$base"/ndk/${ANDROID_NDK_VERSION:-*}; do
[[ -d "$ndk_dir" ]] && ndk_dirs+=("$ndk_dir")
done
done
: ${ANDROID_NDK_ROOT:=$(printf '%s\n' "${ndk_dirs[@]}" | awk -F'/' '{print $NF, $0}' | sort -V | tail -1 | awk '{print $2}')}
: ${ANDROID_SDK_ROOT:="$ANDROID_NDK_ROOT/../.."}
fi
: ${CMAKE_BUILD_TYPE:=Release}
args=()
[[ -n "$CMAKE_GENERATOR" ]] && args+=("-G" "$CMAKE_GENERATOR")
[[ -n "$CMAKE_BUILD_TYPE" ]] && args+=("-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE")
[[ -n "$CMAKE_PREFIX_PATH" ]] && args+=("-DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH")
[[ -n "$CMAKE_TOOLCHAIN_FILE" ]] && args+=("-DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE")
[[ -n "$QT_HOST_PATH" ]] && args+=("-DQT_HOST_PATH=$QT_HOST_PATH")
[[ -n "$CMAKE_OSX_SYSROOT" ]] && args+=("-DCMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT")
[[ -n "$MACOS_NE" ]] && args+=("-DMACOS_NE=$MACOS_NE")
[[ -n "$DEPLOY" ]] && args+=("-DDEPLOY=$DEPLOY")
[[ -n "$ANDROID_ABI" ]] && args+=("-DANDROID_ABI=$ANDROID_ABI")
[[ -n "$ANDROID_SDK_ROOT" ]] && args+=("-DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT")
[[ -n "$ANDROID_NDK_ROOT" ]] && args+=("-DANDROID_NDK_ROOT=$ANDROID_NDK_ROOT")
[[ -n "$ANDROID_PLATFORM" ]] && args+=("-DANDROID_PLATFORM=$ANDROID_PLATFORM")
[[ -n "$QT_ANDROID_SIGN_APK" ]] && args+=("-DQT_ANDROID_SIGN_APK=$QT_ANDROID_SIGN_APK")
[[ -n "$QT_ANDROID_SIGN_AAB" ]] && args+=("-DQT_ANDROID_SIGN_AAB=$QT_ANDROID_SIGN_AAB")
[[ -n "$QT_ANDROID_ABIS" ]] && args+=("-DQT_ANDROID_ABIS=$QT_ANDROID_ABIS")
[[ -n "$QT_ANDROID_BUILD_ALL_ABIS" ]] && args+=("-DQT_ANDROID_BUILD_ALL_ABIS=$QT_ANDROID_BUILD_ALL_ABIS")
if [[ -n "$FORCE" ]]; then
run_traced rm -rf "$BUILD_PATH"
fi
run_traced cmake -S "$SOURCE_PATH" -B "$BUILD_PATH" "${args[@]}"
run_traced cmake --build "$BUILD_PATH" --config "$CMAKE_BUILD_TYPE"
[[ -n "$BUILD_AAB" ]] && run_traced cmake --build "$BUILD_PATH" --config "$CMAKE_BUILD_TYPE" -t "aab"
if [ -z "$no_installers" ]; then
for installer in $INSTALLERS; do
args=()
[[ "$installer" == IFW ]] && args+=(-D "QTIFWDIR=$QIF_ROOT_PATH")
(cd "$BUILD_PATH" && run_traced cpack -G "$installer" "${args[@]}")
done
fi

View File

@@ -1,188 +0,0 @@
#!/bin/bash
# shellcheck disable=SC2086
set -o errexit -o nounset
usage() {
cat <<EOT
Usage:
build_android [options] <artifact_types>
Build AmneziaVPN android client.
Artifact types:
-u, --aab Build Android App Bundle (AAB)
-a, --apk (<abi_list> | all) Build APKs for the specified ABIs or for all available ABIs
Available ABIs: 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
<abi_list> - list of ABIs delimited by ';'
Options:
-d, --debug Build debug version
-b, --build-platform <platform> The SDK platform used for building the Java code of the application
By default, the latest available platform is used
-m, --move Move the build result to the root of the build directory
-f, --fdroid Build for F-Droid
-h, --help Display this help
EOT
}
BUILD_TYPE="release"
opts=$(getopt -l debug,aab,apk:,build-platform:,move,fdroid,help -o "dua:b:mfh" -- "$@")
eval set -- "$opts"
while true; do
case "$1" in
-d | --debug) BUILD_TYPE="debug"; shift;;
-u | --aab) AAB=1; shift;;
-a | --apk) ABIS=$2; shift 2;;
-b | --build-platform) ANDROID_BUILD_PLATFORM=$2; shift 2;;
-m | --move) MOVE_RESULT=1; shift;;
-f | --fdroid) FDROID=1; shift;;
-h | --help) usage; exit 0;;
--) shift; break;;
esac
done
# Validate ABIS parameter
if [[ -v ABIS && \
! "$ABIS" = "all" && \
! "$ABIS" =~ ^((x86|x86_64|armeabi-v7a|arm64-v8a);)*(x86|x86_64|armeabi-v7a|arm64-v8a)$ ]]; then
echo "The 'apk' option must be a list of ['x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a']" \
"delimited by ';' or 'all', but is '$ABIS'"
exit 1
fi
# At least one artifact type must be specified
if [[ ! (-v AAB || -v ABIS) ]]; then
usage; exit 0
fi
echo "Build script started..."
PROJECT_DIR=$(pwd)
DEPLOY_DIR=$PROJECT_DIR/deploy
mkdir -p $DEPLOY_DIR/build
BUILD_DIR=$DEPLOY_DIR/build
OUT_APP_DIR=$BUILD_DIR/client
echo "Project dir: $PROJECT_DIR"
echo "Build dir: $BUILD_DIR"
# Determine path to qt bin folder with qt-cmake
if [[ -v AAB || "$ABIS" = "all" ]]; then
qt_bin_dir_suffix="x86_64"
else
if [[ $ABIS = *";"* ]]; then
oneOf=$(echo $ABIS | cut -d';' -f 1)
else
oneOf=$ABIS
fi
case $oneOf in
"armeabi-v7a") qt_bin_dir_suffix="armv7";;
"arm64-v8a") qt_bin_dir_suffix="arm64_v8a";;
*) qt_bin_dir_suffix=$oneOf;;
esac
fi
# get real path
# calls on paths containing '..' may result in a 'Permission denied'
QT_BIN_DIR=$(cd $QT_HOST_PATH/../android_$qt_bin_dir_suffix/bin && pwd)
echo "Building App..."
echo "Qt host: $QT_HOST_PATH"
echo "Using Qt in $QT_BIN_DIR"
echo "Using Android SDK in $ANDROID_SDK_ROOT"
echo "Using Android NDK in $ANDROID_NDK_ROOT"
# Run qt-cmake to configure build
qt_cmake_opts=()
if [[ -v AAB || "$ABIS" = "all" ]]; then
qt_cmake_opts+=(-DQT_ANDROID_BUILD_ALL_ABIS=ON)
else
qt_cmake_opts+=(-DQT_ANDROID_ABIS="$ABIS")
fi
# QT_NO_GLOBAL_APK_TARGET_PART_OF_ALL=ON - Skip building apks as part of the default 'ALL' target
# We'll build apks during androiddeployqt
$QT_BIN_DIR/qt-cmake -S $PROJECT_DIR -B $BUILD_DIR \
-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL=ON \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
"${qt_cmake_opts[@]}"
# Build app
cmake --build $BUILD_DIR --config $BUILD_TYPE
# Build and package APK or AAB
echo "Building APK/AAB..."
deployqt_opts=()
if [ -v AAB ]; then
deployqt_opts+=(--aab)
fi
if [ -v ANDROID_BUILD_PLATFORM ]; then
deployqt_opts+=(--android-platform "$ANDROID_BUILD_PLATFORM")
fi
if [ "$BUILD_TYPE" = "release" ]; then
deployqt_opts+=(--release)
fi
# for gradle to skip all tasks when it is executed by androiddeployqt
# gradle is started later explicitly
export ANDROIDDEPLOYQT_RUN=1
$QT_HOST_PATH/bin/androiddeployqt \
--input $OUT_APP_DIR/android-AmneziaVPN-deployment-settings.json \
--output $OUT_APP_DIR/android-build \
"${deployqt_opts[@]}"
# run gradle
gradle_opts=()
if [ -v FDROID ]; then
BUILD_TYPE="fdroid"
fi
if [ -v AAB ]; then
gradle_opts+=(bundle"${BUILD_TYPE^}")
fi
if [ -v ABIS ]; then
gradle_opts+=(assemble"${BUILD_TYPE^}")
fi
$OUT_APP_DIR/android-build/gradlew \
--project-dir $OUT_APP_DIR/android-build \
-DexplicitRun=1 \
"${gradle_opts[@]}"
if [[ -v CI || -v MOVE_RESULT ]]; then
echo "Moving APK/AAB..."
if [ -v AAB ]; then
mv -u $OUT_APP_DIR/android-build/build/outputs/bundle/$BUILD_TYPE/AmneziaVPN-$BUILD_TYPE.aab \
$PROJECT_DIR/deploy/build/
fi
if [ -v ABIS ]; then
if [ "$ABIS" = "all" ]; then
ABIS="x86;x86_64;armeabi-v7a;arm64-v8a"
fi
suffix=$BUILD_TYPE
if [ -v FDROID ]; then
suffix+="-unsigned"
fi
IFS=';' read -r -a abi_array <<< "$ABIS"
for ABI in "${abi_array[@]}"
do
mv -u $OUT_APP_DIR/android-build/build/outputs/apk/$BUILD_TYPE/AmneziaVPN-$ABI-$suffix.apk \
$PROJECT_DIR/deploy/build/
done
fi
fi

View File

@@ -1,99 +0,0 @@
#!/bin/bash
echo "Build script started ..."
set -o errexit -o nounset
# Hold on to current directory
PROJECT_DIR=$(pwd)
BUILD_DIR=$PROJECT_DIR/build-ios
mkdir -p $BUILD_DIR
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
# Search Qt
if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=6.6.2;
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/ios/bin
fi
echo "Using Qt in $QT_BIN_DIR"
# Checking env
$QT_BIN_DIR/qt-cmake --version
cmake --version
clang -v
# Generate XCodeProj
$QT_BIN_DIR/qt-cmake . -B $BUILD_DIR -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR -DDEPLOY=ON
KEYCHAIN=amnezia.build.ios.keychain
KEYCHAIN_FILE=$HOME/Library/Keychains/${KEYCHAIN}-db
# Setup keychain
if [ "${IOS_SIGNING_CERT_BASE64+x}" ]; then
echo "Import certificate"
TRUST_CERT_CER=$BUILD_DIR/trust-cert.cer
SIGNING_CERT_P12=$BUILD_DIR/signing-cert.p12
echo $IOS_TRUST_CERT_BASE64 | base64 --decode > $TRUST_CERT_CER
echo $IOS_SIGNING_CERT_BASE64 | base64 --decode > $SIGNING_CERT_P12
shasum -a 256 $TRUST_CERT_CER
shasum -a 256 $SIGNING_CERT_P12
KEYCHAIN_PASS=$IOS_SIGNING_CERT_PASSWORD
security create-keychain -p $KEYCHAIN_PASS $KEYCHAIN || true
security default-keychain -s $KEYCHAIN
security unlock-keychain -p $KEYCHAIN_PASS $KEYCHAIN
security default-keychain
security list-keychains
security import $TRUST_CERT_CER -k $KEYCHAIN -P "" -T /usr/bin/codesign
security import $SIGNING_CERT_P12 -k $KEYCHAIN -P $IOS_SIGNING_CERT_PASSWORD -T /usr/bin/codesign
security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k $KEYCHAIN_PASS $KEYCHAIN
security find-identity -p codesigning
security set-keychain-settings $KEYCHAIN_FILE
security set-keychain-settings -t 3600 $KEYCHAIN_FILE
security unlock-keychain -p $KEYCHAIN_PASS $KEYCHAIN_FILE
# Copy provisioning prifiles
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles/"
echo $IOS_APP_PROVISIONING_PROFILE | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision
echo $IOS_NE_PROVISIONING_PROFILE | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision
shasum -a 256 ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision
shasum -a 256 ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision
profile_uuid=`grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision | grep -io "[-A-F0-9]\{36\}"`
profile_ne_uuid=`grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision | grep -io "[-A-F0-9]\{36\}"`
mv ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$profile_uuid.mobileprovision
mv ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$profile_ne_uuid.mobileprovision
else
echo "Failed to import certificate, aborting..."
exit 1
fi
# Build project
xcodebuild \
"OTHER_CODE_SIGN_FLAGS=--keychain '$KEYCHAIN_FILE'" \
-configuration Release \
-scheme AmneziaVPN \
-destination "generic/platform=iOS,name=Any iOS'" \
-project $BUILD_DIR/AmneziaVPN.xcodeproj
# restore keychain
security default-keychain -s login.keychain

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

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"

View File

@@ -1,122 +0,0 @@
#!/bin/bash
echo "Build script for macOS Network Extension 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-macos
BUILD_DIR=$DEPLOY_DIR/build-macos
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_DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/deploy-prebuilt/macos
DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/macos
INSTALLER_DATA_DIR=$BUILD_DIR/installer/packages/$APP_DOMAIN/data
INSTALLER_BUNDLE_DIR=$BUILD_DIR/installer/$APP_FILENAME
DMG_FILENAME=$PROJECT_DIR/${APP_NAME}.dmg
echo "Import certificate"
TRUST_CERT_CER=$BUILD_DIR/trust-cert.cer
SIGNING_CERT_P12=$BUILD_DIR/signing-cert.p12
echo $MAC_TRUST_CERT_BASE64 | base64 --decode > $TRUST_CERT_CER
echo $MAC_SIGNING_CERT_BASE64 | base64 --decode > $SIGNING_CERT_P12
shasum -a 256 $TRUST_CERT_CER
shasum -a 256 $SIGNING_CERT_P12
KEYCHAIN_PASS=$MAC_SIGNING_CERT_PASSWORD
# Keychain setup
KEYCHAIN=amnezia.build.macos.keychain
TEMP_PASS=tmp_pass
KEYCHAIN_FILE=$HOME/Library/Keychains/$KEYCHAIN-db
security create-keychain -p $TEMP_PASS $KEYCHAIN || true
security default-keychain -s $KEYCHAIN
security unlock-keychain -p $TEMP_PASS $KEYCHAIN
security default-keychain
security list-keychains
# Import certificates into keychain
security import $TRUST_CERT_CER -k $KEYCHAIN -P "" -T /usr/bin/codesign || true
security import $SIGNING_CERT_P12 -k $KEYCHAIN -P $MAC_SIGNING_CERT_PASSWORD -T /usr/bin/codesign || true
# Configure keychain settings
security set-key-partition-list -S apple-tool:,apple: -k $TEMP_PASS $KEYCHAIN
security find-identity -p codesigning
# Setup provisioning profiles for main app and NE
echo "Setting up provisioning profiles..."
# Copy provisioning prifiles
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles/"
echo $MAC_APP_PROVISIONING_PROFILE | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision
echo $MAC_NE_PROVISIONING_PROFILE | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision
shasum -a 256 ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision
shasum -a 256 ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision
profile_uuid=`grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision | grep -io "[-A-F0-9]\{36\}"`
echo $profile_uuid
profile_ne_uuid=`grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision | grep -io "[-A-F0-9]\{36\}"`
echo $profile_ne_uuid
mv ~/Library/MobileDevice/Provisioning\ Profiles/app.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$profile_uuid.mobileprovision
mv ~/Library/MobileDevice/Provisioning\ Profiles/ne.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$profile_ne_uuid.mobileprovision
# setup environment
QT_MACOS_BIN=$QT_BIN_DIR
export PATH=$PATH:~/go/bin
echo "QT_BIN_DIR: $QT_BIN_DIR"
# Build the Network Extension app
echo "Building MAC Network Extension App..."
mkdir -p build-macos
$QT_MACOS_BIN/qt-cmake . -B build-macos -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR -DMACOS_NE=TRUE -DCMAKE_BUILD_TYPE=Release -DDEPLOY=ON
# Build and run tests here
echo "____________________________________"
echo "............Deploying..............."
echo "____________________________________"
echo "Deploying MAC Network Extension App..."
echo "xcode build"
xcodebuild \
"OTHER_CODE_SIGN_FLAGS=--keychain '$KEYCHAIN_FILE'" \
-configuration Release \
-scheme AmneziaVPN \
-destination "platform=macOS" \
-project $PROJECT_DIR/build-macos/AmneziaVPN.xcodeproj
# Restore keychain to default
echo "Restoring default keychain..."
security default-keychain -s "/Users/runner/Library/Keychains/login.keychain-db"
echo "Build and signing process completed successfully!"

View File

@@ -1,151 +0,0 @@
@ECHO OFF
CHCP 1252
REM %VAR:"=% mean dequoted %VAR%
set PATH=%QT_BIN_DIR:"=%;%PATH%
echo "Using Qt in %QT_BIN_DIR%"
echo "Using QIF in %QIF_BIN_DIR%"
echo "Using WiX in %WIX_BIN_DIR%"
if "%WIX_BIN_DIR%"=="" (
echo "WIX_BIN_DIR is not set"
exit /b 1
)
set WIX_BIN_DIR_UNQUOTED=%WIX_BIN_DIR:"=%
set WIX_CLI=%WIX_BIN_DIR_UNQUOTED%\wix.exe
if not exist "%WIX_CLI%" (
echo "WiX CLI (wix.exe) was not found in %WIX_BIN_DIR%"
exit /b 1
)
REM Hold on to current directory
set PROJECT_DIR=%cd%
set SCRIPT_DIR=%PROJECT_DIR:"=%\deploy
set WORK_DIR=%SCRIPT_DIR:"=%\build_%BUILD_ARCH:"=%
set APP_NAME=AmneziaVPN
set APP_FILENAME=%APP_NAME:"=%.exe
set SERVICE_FILENAME=%APP_NAME:"=%-service.exe
set APP_DOMAIN=org.amneziavpn.package
set OUT_APP_DIR=%WORK_DIR:"=%\client\release
set PREBILT_DEPLOY_DATA_DIR=%PROJECT_DIR:"=%\client\3rd-prebuilt\deploy-prebuilt\windows\x%BUILD_ARCH:"=%
set DEPLOY_DATA_DIR=%SCRIPT_DIR:"=%\data\windows\x%BUILD_ARCH:"=%
set INSTALLER_DATA_DIR=%WORK_DIR:"=%\installer\packages\%APP_DOMAIN:"=%\data
set TARGET_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%_x%BUILD_ARCH:"=%.exe
set TARGET_MSI_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%_x%BUILD_ARCH:"=%.msi
set STAGE_DIR=%WORK_DIR:"=%\stage
echo "Environment:"
echo "WORK_DIR: %WORK_DIR%"
echo "APP_FILENAME: %APP_FILENAME%"
echo "SERVICE_FILENAME: %SERVICE_FILENAME%"
echo "PROJECT_DIR: %PROJECT_DIR%"
echo "SCRIPT_DIR: %SCRIPT_DIR%"
echo "OUT_APP_DIR: %OUT_APP_DIR%"
echo "DEPLOY_DATA_DIR: %DEPLOY_DATA_DIR%"
echo "INSTALLER_DATA_DIR: %INSTALLER_DATA_DIR%"
echo "TARGET_FILENAME: %TARGET_FILENAME%"
echo "TARGET_MSI_FILENAME: %TARGET_MSI_FILENAME%"
echo "STAGE_DIR: %STAGE_DIR%"
echo "Cleanup..."
rmdir /Q /S %WORK_DIR%
del %TARGET_FILENAME%
del %TARGET_MSI_FILENAME%
rmdir /Q /S "%STAGE_DIR%"
mkdir %WORK_DIR%
call "%QT_BIN_DIR:"=%\qt-cmake" --version
"%QT_BIN_DIR:"=%\windeployqt" -v
cmake --version
cd %PROJECT_DIR%
call cmake . -B %WORK_DIR% "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_PREFIX_PATH:PATH=%QT_BIN_DIR%"
cd %WORK_DIR%
cmake --build . --config release -- /p:UseMultiToolTask=true /m
if %errorlevel% neq 0 exit /b %errorlevel%
echo "Deploying..."
mkdir "%OUT_APP_DIR%"
copy "%WORK_DIR%\service\server\release\%SERVICE_FILENAME%" "%OUT_APP_DIR%"
rem copy "%WORK_DIR%\client\%APP_FILENAME%" "%OUT_APP_DIR%"
copy /Y "%PROJECT_DIR%\client\images\app.ico" "%OUT_APP_DIR%\AmneziaVPN.ico" >nul
echo "Signing exe"
cd %OUT_APP_DIR%
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe
"%QT_BIN_DIR:"=%\windeployqt" --release --qmldir "%PROJECT_DIR:"=%\client" --force --no-translations --force-openssl "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%"
"%QT_BIN_DIR:"=%\windeployqt" --release "%OUT_APP_DIR:"=%\%SERVICE_FILENAME:"=%"
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll
echo "Copying deploy data..."
xcopy %DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f
xcopy %PREBILT_DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f
cd %SCRIPT_DIR%
xcopy %SCRIPT_DIR:"=%\installer %WORK_DIR:"=%\installer /s /e /y /i /f
mkdir %INSTALLER_DATA_DIR%
echo "Deploy finished, content:"
dir %OUT_APP_DIR%
cd %OUT_APP_DIR%
echo "Compressing data..."
"%QIF_BIN_DIR:"=%\archivegen" -c 9 %INSTALLER_DATA_DIR:"=%\%APP_NAME:"=%.7z .
cd "%WORK_DIR:"=%\installer"
echo "Creating installer..."
"%QIF_BIN_DIR:"=%\binarycreator" --offline-only -v -c config\windows.xml -p packages -f %TARGET_FILENAME%
timeout 5
cd %PROJECT_DIR%
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%"
echo "Preparing staging directory for MSI..."
rmdir /Q /S "%STAGE_DIR%"
mkdir "%STAGE_DIR%"
xcopy "%OUT_APP_DIR%" "%STAGE_DIR%" /s /e /y /i /f >nul
echo "Building MSI via CPack..."
rmdir /Q /S "%WORK_DIR%\_CPack_Packages"
cd %WORK_DIR%
cpack -G WIX -C Release --config "%WORK_DIR%\CPackConfig.cmake"
if exist "%WORK_DIR%\_CPack_Packages\win64\WIX\wix.log" (
echo ---------------------------------------------
echo Contents of wix.log:
type "%WORK_DIR%\_CPack_Packages\win64\WIX\wix.log"
echo ---------------------------------------------
)
if %errorlevel% neq 0 exit /b %errorlevel%
set GENERATED_MSI=
for /f "delims=" %%i in ('dir /b /a:-d /o:-d "%WORK_DIR%\*.msi"') do (
if not defined GENERATED_MSI set GENERATED_MSI=%WORK_DIR%\%%i
)
if "%GENERATED_MSI%"=="" (
echo "Failed to locate generated MSI package"
exit /b 1
)
copy /Y "%GENERATED_MSI%" "%TARGET_MSI_FILENAME%"
if %errorlevel% neq 0 exit /b %errorlevel%
cd %PROJECT_DIR%
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_MSI_FILENAME%"
echo "Finished, see %TARGET_FILENAME% and %TARGET_MSI_FILENAME%"
exit 0

1
deploy/data/LICENSE.txt Symbolic link
View File

@@ -0,0 +1 @@
../../LICENSE

View File

@@ -1 +0,0 @@
../../client/3rd-prebuilt/deploy-prebuilt/

View File

@@ -7,8 +7,7 @@ StartLimitIntervalSec=0
Type=simple Type=simple
Restart=always Restart=always
RestartSec=1 RestartSec=1
ExecStart=/opt/AmneziaVPN/service/AmneziaVPN-service.sh ExecStart=/opt/AmneziaVPN/bin/AmneziaVPN-service
Environment=LD_LIBRARY_PATH=/opt/AmneziaVPN/client/lib
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

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" "$@"

View File

@@ -1,7 +0,0 @@
[Paths]
Prefix= ./../
Libraries= ./lib/
Plugins= ./plugins/
Imports= ./qml/
Translations= ./translations/
Qml2Imports= ./qml/

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 start $APP_NAME >> $LOG_FILE
sudo systemctl enable $APP_NAME >> $LOG_FILE sudo systemctl enable $APP_NAME >> $LOG_FILE
sudo chmod 555 $APP_PATH/client/$APP_NAME.sh >> $LOG_FILE sudo ln -sf $APP_PATH/bin/$APP_NAME /usr/local/sbin/$APP_NAME >> $LOG_FILE
sudo ln -s $APP_PATH/client/$APP_NAME.sh /usr/local/sbin/$APP_NAME >> $LOG_FILE sudo ln -sf $APP_PATH/bin/$APP_NAME /usr/local/bin/$APP_NAME >> $LOG_FILE
sudo ln -s $APP_PATH/client/$APP_NAME.sh /usr/local/bin/$APP_NAME >> $LOG_FILE
echo "user desktop creation loop started" >> $LOG_FILE echo "user desktop creation loop started" >> $LOG_FILE
sudo cp $APP_PATH/$APP_NAME.desktop /usr/share/applications/ >> $LOG_FILE sudo cp $APP_PATH/$APP_NAME.desktop /usr/share/applications/ >> $LOG_FILE

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-service.sh"
export QT_QPA_PLATFORM_PLUGIN_PATH="$BASE_DIR"/plugins//platforms:$QT_QPA_PLATFORM_PLUGIN_PATH
"$BASE_DIR/bin/AmneziaVPN-service" "$@"

View File

@@ -1,7 +0,0 @@
[Paths]
Prefix= ./../
Libraries= ./lib/
Plugins= ./plugins/
Imports= ./qml/
Translations= ./translations/
Qml2Imports= ./qml/

View File

@@ -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>

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

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

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>

View File

@@ -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>

View File

@@ -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>

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>

View File

@@ -1,32 +1,32 @@
set AmneziaPath=%~dp0 set AmneziaPath=%~dp0
echo %AmneziaPath% echo %AmneziaPath%
rem Define directories for logs rem Define directories for logs
set "ORG_DIR=%AppData%\AmneziaVPN.ORG" set "ORG_DIR=%AppData%\AmneziaVPN.ORG"
set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN" set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN"
set "USER_LOG_DIR=%USER_APP_DIR%\log" set "USER_LOG_DIR=%USER_APP_DIR%\log"
set "SYS_APP_DIR=%ProgramData%\AmneziaVPN" set "SYS_APP_DIR=%ProgramData%\AmneziaVPN"
set "SYS_LOG_DIR=%SYS_APP_DIR%\log" set "SYS_LOG_DIR=%SYS_APP_DIR%\log"
set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log" set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log"
timeout /t 1 timeout /t 1
sc stop AmneziaVPN-service sc stop AmneziaVPN-service
sc delete AmneziaVPN-service sc delete AmneziaVPN-service
sc stop AmneziaWGTunnel$AmneziaVPN sc stop AmneziaWGTunnel$AmneziaVPN
sc delete AmneziaWGTunnel$AmneziaVPN sc delete AmneziaWGTunnel$AmneziaVPN
taskkill /IM "AmneziaVPN-service.exe" /F taskkill /IM "AmneziaVPN-service.exe" /F
taskkill /IM "AmneziaVPN.exe" /F taskkill /IM "AmneziaVPN.exe" /F
rem Delete the service log file under ProgramData rem Delete the service log file under ProgramData
if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%" if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%"
if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%" if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%"
rem Try to remove application dir if empty rem Try to remove application dir if empty
rd "%SYS_APP_DIR%" 2>nul rd "%SYS_APP_DIR%" 2>nul
rem Delete client logs under current user's AppData\Roaming (Organization\Application) rem Delete client logs under current user's AppData\Roaming (Organization\Application)
if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%" if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%"
rem Try to remove app and org directories if empty rem Try to remove app and org directories if empty
rd "%USER_APP_DIR%" 2>nul rd "%USER_APP_DIR%" 2>nul
rd "%ORG_DIR%" 2>nul rd "%ORG_DIR%" 2>nul
exit /b 0 exit /b 0

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

View File

@@ -1,32 +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
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

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
)

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>

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>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>AmneziaVPN</DisplayName>
<Description>Installation package for AmneziaVPN</Description>
<Version>@CMAKE_PROJECT_VERSION@</Version>
<ReleaseDate>@RELEASE_DATE@</ReleaseDate>
<Default>true</Default>
<ForcedInstallation>true</ForcedInstallation>
<RequiresAdminRights>true</RequiresAdminRights>
<Script>componentscript.js</Script>
</Package>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CPackWiXPatch> <CPackWiXPatch>
<CPackWiXFragment Id="CM_CP_AmneziaVPN_service.exe"> <CPackWiXFragment Id="CM_CP_AmneziaVPN.AmneziaVPN_service.exe">
<ServiceInstall <ServiceInstall
Id="AmneziaServiceInstall" Id="AmneziaServiceInstall"
Name="AmneziaVPN-service" Name="AmneziaVPN-service"
@@ -21,4 +21,4 @@
Remove="uninstall" Remove="uninstall"
Wait="yes" /> Wait="yes" />
</CPackWiXFragment> </CPackWiXFragment>
</CPackWiXPatch> </CPackWiXPatch>

View File

@@ -0,0 +1,62 @@
from conan import ConanFile
from conan.tools.files import get, copy
from conan.tools.layout import basic_layout
from conan.errors import ConanInvalidConfiguration
from conan.tools.env import VirtualBuildEnv, Environment
import os
import stat
from pathlib import Path
class AmneziaLibxray(ConanFile):
name = "amnezia-libxray"
version = "1.0.0"
settings = "os", "arch", "compiler"
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
def layout(self):
basic_layout(self, build_folder=".")
def build_requirements(self):
self.tool_requires("go/1.26.0")
def validate(self):
if self.settings.os != "Android":
raise ConanInvalidConfiguration(f"{self.name} v{self.version} does not support {self.settings.os}")
def source(self):
get(self, "https://github.com/amnezia-vpn/amnezia-libxray/archive/refs/tags/v1.0.0.zip",
sha256="0c50c5acd5063a9fc3cfbb5b3e11481d30cfa3762b3cb1d72130248ff498e9df", strip_root=True
)
def generate(self):
VirtualBuildEnv(self).generate()
env = Environment()
ndk_path_str = self.conf.get("tools.android:ndk_path")
if ndk_path_str:
ndk_path = Path(ndk_path_str)
if len(ndk_path.parts) > 2:
sdk_path = ndk_path.parents[1]
env.define("ANDROID_HOME", str(sdk_path))
env.vars(self).save_script("conan_provide_androidhome")
def _patch_sources(self):
build_path = os.path.join(self.build_folder, "build.sh")
build_stat = os.stat(build_path)
os.chmod(build_path, build_stat.st_mode | stat.S_IEXEC)
def build(self):
self._patch_sources()
self.run("./build.sh android")
def package(self):
copy(self, "libxray.aar", src=self.build_folder, dst=os.path.join(self.package_folder, "aar"))
def package_info(self):
self.cpp_info.set_property("cmake_extra_variables", {
"AMNEZIA_LIBXRAY_PATH": os.path.join(self.package_folder, "aar", "libxray.aar"),
})

View File

@@ -0,0 +1,110 @@
from conan import ConanFile
from conan.tools.files import get, copy, collect_libs, chdir, rename
from conan.tools.layout import basic_layout
from conan.errors import ConanInvalidConfiguration
from conan.tools.gnu import Autotools, AutotoolsToolchain
import os
class AmneziaXrayBindings(ConanFile):
name = "amnezia-xray-bindings"
version = "1.1.0"
settings = "os", "arch", "compiler"
@property
def _goos(self):
return {
"Linux": "linux",
"iOS": "ios",
"Macos": "darwin",
"Windows": "windows"
}.get(str(self.settings.os))
@property
def _goarch(self):
return {
"x86": "386",
"x86_64": "amd64",
"armv8": "arm64"
}.get(str(self.settings.arch))
@property
def _is_windows(self):
return str(self.settings.os).startswith("Windows")
def config_options(self):
self.package_type = "shared-library" if self._is_windows else "static-library"
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
if self._is_windows:
# mingw-builds is being used on Windows
del self.settings.compiler
def layout(self):
basic_layout(self)
def build_requirements(self):
self.tool_requires("go/1.26.0")
if self._is_windows:
self.win_bash = True
if not self.conf.get("tools.microsoft.bash:path", check_type=str):
self.tool_requires("msys2/cci.latest")
self.tool_requires("mingw-builds/15.1.0")
def validate(self):
if not self._goos or not self._goarch:
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
)
def source(self):
get(self, "https://github.com/amnezia-vpn/amnezia-xray-bindings/archive/v1.1.0.zip",
sha256="6ea768ec7002cedd422a39aea17704b888acaf794432aa5937cfc92fb6d80eb5", strip_root=True)
def generate(self):
tc = AutotoolsToolchain(self)
tc.make_args = [
"LIB_ARC=libamnezia_xray.a"
]
env = tc.environment()
env.define("ARCH", self._goarch)
env.define("GOARCH", self._goarch)
env.define("GOOS", self._goos)
env.define("CGO_LDFLAGS", tc.ldflags)
env.define("CGO_CFLAGS", tc.cflags)
if self._is_windows:
env.define("OS", "windows")
tc.generate(env)
def build(self):
with chdir(self, self.source_folder):
autotools = Autotools(self)
autotools.make()
def _rename_header(self):
if not self._is_windows:
rename(self, os.path.join(self.package_folder, "include", "libamnezia_xray.h"),
os.path.join(self.package_folder, "include", "amnezia_xray.h"))
def _rename_libs(self):
# workaround of bad naming strategy in amnezia-xray-bindings
# TODO: change it and kick out the code below
lib_dir = os.path.join(self.package_folder, "lib")
for fname in os.listdir(lib_dir):
if not fname.startswith("lib"):
src = os.path.join(lib_dir, fname)
dst = os.path.join(lib_dir, "lib" + fname)
os.rename(src, dst)
def package(self):
copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
copy(self, "*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"))
self._rename_header()
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "amnezia::xray-bindings")
self.cpp_info.libs = collect_libs(self)

View File

@@ -0,0 +1,86 @@
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
from conan.tools.files import copy, replace_in_file
from conan.errors import ConanInvalidConfiguration
from conan.tools.scm import Git
import os
import platform
class AwgAndroid(ConanFile):
name = "awg-android"
version = "1.1.7"
settings = "os", "arch", "build_type", "compiler"
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
def layout(self):
cmake_layout(self)
def build_requirements(self):
self.tool_requires("cmake/[>=3.4.1 <4]")
def validate(self):
if self.settings.os != "Android":
raise ConanInvalidConfiguration(f"{self.name} v{self.version} does not support {self.settings.os}")
def source(self):
git = Git(self)
git.clone(
url="https://github.com/amnezia-vpn/amneziawg-android.git",
target=".",
args=["--recurse-submodules", "--branch", f"v{self.version}"]
)
def generate(self):
tc = CMakeToolchain(self)
tc.variables["GRADLE_USER_HOME"] = os.path.join(self.build_folder, "gradle_user_home")
tc.variables["CMAKE_LIBRARY_OUTPUT_DIRECTORY"] = os.path.join(self.build_folder, "out")
# not to warn in case of strtok() usage
tc.extra_cflags = ["-Wno-deprecated-declarations"]
tc.generate()
def _patch_sources(self):
if platform.system() == 'Darwin':
replace_in_file(self,
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
'flock "$@.lock" -c \' \\\n',
"",
)
replace_in_file(self,
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
'mv "$@.tmp" "$@"\'',
'mv "$@.tmp" "$@"',
)
replace_in_file(self,
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
'touch "$@"\'',
'touch "$@"',
)
replace_in_file(self,
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
'sha256sum -c',
'shasum -a 256 -c'
)
def build(self):
self._patch_sources()
cmake = CMake(self)
cmake.configure(build_script_folder=os.path.join(self.source_folder, "tunnel", "tools"))
cmake.build(target=["libwg-go.so", "libwg.so", "libwg-quick.so"])
def package(self):
copy(self, "libwg-go.h", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "include"))
copy(self, "libwg-go.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "libwg.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "bin"))
copy(self, "libwg-quick.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "bin"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-android")
self.cpp_info.libs = [ "wg-go" ]
self.cpp_info.set_property("cmake_extra_variables", {
"AMNEZIA_ANDROID_LIBWG_PATH": os.path.join(self.package_folder, "bin", "libwg.so"),
"AMNEZIA_ANDROID_LIBWG_QUICK_PATH": os.path.join(self.package_folder, "bin", "libwg-quick.so"),
})

View File

@@ -0,0 +1,66 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.layout import basic_layout
from conan.tools.files import get, copy, collect_libs
from conan.tools.apple import is_apple_os
from conan.tools.gnu import AutotoolsToolchain, Autotools
import os
class AwgApple(ConanFile):
name = "awg-apple"
version = "2.0.1"
settings = "os", "arch", "compiler"
@property
def _goarch(self):
arch_map = {
"armv8": "arm64",
"x86_64": "x86_64",
}
archs = str(self.settings.arch).split("|")
return " ".join(arch_map.get(arch, arch) for arch in archs)
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
def layout(self):
basic_layout(self, build_folder=os.path.join(self.folders.source, "Sources/WireGuardKitGo"))
def build_requirements(self):
self.tool_requires("go/1.26.0")
def validate(self):
if not is_apple_os(self):
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.os}"
)
def source(self):
get(self, f"https://github.com/amnezia-vpn/amneziawg-apple/archive/refs/tags/v{self.version}.zip",
sha256="9fe4f8cfbb6a751558b54b7979db3a5ea46e49731912aae99f093e84a1433e97", strip_root=True
)
def generate(self):
tc = AutotoolsToolchain(self)
sdk = self.settings.get_safe("os.sdk", "macosx")
tc.make_args = [
f"ARCHS={self._goarch}",
f"PLATFORM_NAME={sdk}"
]
tc.generate()
def build(self):
autotools = Autotools(self)
autotools.make()
autotools.make("version-header")
def package(self):
copy(self, "wireguard.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
copy(self, "*.h", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "include"))
copy(self, "*.a", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "lib"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-apple")
self.cpp_info.libs = collect_libs(self)

View File

@@ -0,0 +1,67 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.layout import basic_layout
from conan.tools.files import get, copy
from conan.tools.gnu import Autotools, AutotoolsToolchain
import os
class AwgGo(ConanFile):
name = "awg-go"
version = "0.2.16"
package_type = "application"
settings = "os", "arch"
@property
def _goos(self):
return {
"Linux": "linux",
"Macos": "darwin",
"Windows": "windows"
}.get(str(self.settings.os))
@property
def _goarch(self):
return {
"x86": "386",
"x86_64": "amd64",
"armv8": "arm64"
}.get(str(self.settings.arch))
def layout(self):
basic_layout(self, build_folder=".")
def build_requirements(self):
self.tool_requires("go/1.26.0")
def validate(self):
if not self._goos or not self._goarch:
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
)
def source(self):
get(self, f"https://github.com/amnezia-vpn/amneziawg-go/archive/refs/tags/v{self.version}.zip",
sha256="34da7d4189f215f3930de441548bc2a0c89d54d347a4fb85cb9c715fce6413aa", strip_root=True
)
def generate(self):
tc = AutotoolsToolchain(self)
env = tc.environment()
env.define("GOOS", self._goos)
env.define("GOARCH", self._goarch)
env.define("CGO_LDFLAGS", tc.ldflags)
env.define("CGO_CFLAGS", tc.cflags)
tc.generate(env)
def build(self):
at = Autotools(self)
at.make()
def package(self):
copy(self, "amneziawg-go", src=self.build_folder, dst=self.package_folder)
def package_info(self):
self.cpp_info.exe = True
self.cpp_info.location = os.path.join(self.package_folder, "amneziawg-go")
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-go")

View File

@@ -0,0 +1,102 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.errors import ConanInvalidConfiguration
from conan.tools.files import get, copy, chdir
from conan.tools.gnu import AutotoolsToolchain
import os
class AwgWindows(ConanFile):
name = "awg-windows"
version = "0.1.8"
settings = "os", "arch"
@property
def _goarm(self):
return {
"armv5el": "5",
"armv5hf": "5",
"armv6": "6",
"armv7": "7",
"armv7hf": "7",
"armv7s": "7",
"armv7k": "7",
}.get(str(self.settings.arch))
@property
def _goarch(self):
return {
"x86": "386",
"x86_64": "amd64",
"armv5el": "arm",
"armv5hf": "arm",
"armv6": "arm",
"armv7": "arm",
"armv7hf": "arm",
"armv7s": "arm",
"armv7k": "arm",
"armv8": "arm64",
"armv8_32": "arm64",
"armv8.3": "arm64",
"arm64ec": "arm64"
}.get(str(self.settings.arch))
def layout(self):
basic_layout(self)
def validate(self):
if not str(self.settings.os).startswith("Windows"):
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} is to be used on Windows only!"
)
if not self._goarch:
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.arch} architecture"
)
def build_requirements(self):
self.tool_requires("mingw-builds/15.1.0")
self.tool_requires("go/1.26.0")
def requirements(self):
self.requires("wintun/[*]")
def source(self):
get(self, f"https://github.com/amnezia-vpn/amneziawg-windows/archive/refs/tags/v{self.version}.zip",
sha256="1de472832b332515c96cdf14ea887edde42ed7ad173675280c51baa9a3ef62f2", strip_root=True)
def generate(self):
tc = AutotoolsToolchain(self)
tc.extra_cflags = [
"-Wall",
"-Wno-unused-function",
"-Wno-switch",
"-DWINVER=0x0601"
]
tc.extra_ldflags = [
"-Wl,--dynamicbase",
"-Wl,--nxcompat",
"-Wl,--export-all-symbols",
"-Wl,--high-entropy-va"
]
env = tc.environment()
env.define("GOOS", "windows")
if self._goarm:
env.define("GOARM", self._goarm)
env.define("GOARCH", self._goarch)
env.define("CGO_ENABLED", "1")
env.define("CGO_LDFLAGS", tc.ldflags)
env.define("CGO_CFLAGS", tc.cflags)
tc.generate(env)
def build(self):
with chdir(self, self.source_folder):
self.run(f'go build -buildmode c-shared -ldflags="-w -s" -trimpath -v -o "{os.path.join(self.build_folder, "tunnel.dll")}"')
def package(self):
copy(self, "tunnel.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"))
def package_info(self):
self.cpp_info.exe = True
self.cpp_info.location = os.path.join(self.package_folder, "bin", "tunnel.dll")
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-windows")

26
recipes/go/conandata.yml Normal file
View File

@@ -0,0 +1,26 @@
sources:
"1.26.0":
Macos:
x86_64:
url: "https://go.dev/dl/go1.26.0.darwin-amd64.tar.gz"
sha256: "1ca28b7703cbea05a65b2a1d92d6b308610ef92f8824578a0874f2e60c9d5a22"
armv8:
url: "https://go.dev/dl/go1.26.0.darwin-arm64.tar.gz"
sha256: "b1640525dfe68f066d56f200bef7bf4dce955a1a893bd061de6754c211431023"
Linux:
x86:
url: "https://go.dev/dl/go1.26.0.linux-386.tar.gz"
sha256: "35e2ec7a7ae6905a1fae5459197b70e3fcbc5e0a786a7d6ba8e49bcd38ad2e26"
x86_64:
url: "https://go.dev/dl/go1.26.0.linux-amd64.tar.gz"
sha256: "aac1b08a0fb0c4e0a7c1555beb7b59180b05dfc5a3d62e40e9de90cd42f88235"
armv8:
url: "https://go.dev/dl/go1.26.0.linux-arm64.tar.gz"
sha256: "bd03b743eb6eb4193ea3c3fd3956546bf0e3ca5b7076c8226334afe6b75704cd"
Windows:
x86:
url: "https://go.dev/dl/go1.26.0.windows-386.zip"
sha256: "50674f3d6a071fa1a4c1d76dc37fafa0330df87d84087a262fee020da5396b6b"
x86_64:
url: "https://go.dev/dl/go1.26.0.windows-amd64.zip"
sha256: "9bbe0fc64236b2b51f6255c05c4232532b8ecc0e6d2e00950bd3021d8a4d07d4"

23
recipes/go/conanfile.py Normal file
View File

@@ -0,0 +1,23 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.files import get, copy
import os
class Golang(ConanFile):
name = "go"
version = "1.26.0"
settings = "os", "arch"
def layout(self):
basic_layout(self)
def build(self):
get(self, **self.conan_data["sources"][str(self.version)][str(self.settings.os)][str(self.settings.arch)], strip_root=True, destination="go")
def package(self):
copy(self, "*", src=os.path.join(self.build_folder, "go"), dst=self.package_folder)
def package_info(self):
self.cpp_info.bindirs = ["bin"]

View File

@@ -0,0 +1,100 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.scm import Git
from conan.tools.files import copy, collect_libs
from conan.internal.model.pkg_type import PackageType
from conan.tools.gnu import AutotoolsToolchain, Autotools
from conan.tools.apple import is_apple_os
import os
import shutil
required_conan_version = ">=2.26"
class HevSocks5Tunnel(ConanFile):
name = "hev-socks5-tunnel"
version = "2.14.4"
settings = "os", "arch", "compiler"
options = {
"shared": [True, False],
"as_framework": [True, False],
}
default_options = {
"shared": False,
"as_framework": False
}
def config_options(self):
if not is_apple_os(self):
del self.options.as_framework
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
if self.options.get_safe("as_framework"):
self.options.shared = False
def layout(self):
basic_layout(self, build_folder=".")
def source(self):
git = Git(self)
git.clone(
url="https://github.com/heiher/hev-socks5-tunnel.git",
target=".",
args=["--recurse-submodules", "--branch", self.version]
)
def generate(self):
tc = AutotoolsToolchain(self)
tc.generate()
def build(self):
autotools = Autotools(self)
autotools.make("shared" if self.options.shared else "static")
if self.options.get_safe("as_framework"):
lib_path = os.path.join(self.build_folder, "bin", "libhev-socks5-tunnel.a")
self.run(
f"libtool -static -o {lib_path}"
f" {lib_path}"
f" {os.path.join(self.build_folder, "third-part", "lwip", "bin", "liblwip.a")}"
f" {os.path.join(self.build_folder, "third-part", "yaml", "bin", "libyaml.a")}"
f" {os.path.join(self.build_folder, "third-part", "hev-task-system", "bin", "libhev-task-system.a")}"
)
include_dir = os.path.join(self.build_folder, "framework_include")
copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=include_dir)
copy(self, "module.modulemap", src=os.path.join(self.source_folder), dst=include_dir)
self.run('xcodebuild -create-xcframework'
f' -library {lib_path}'
f' -headers {include_dir}'
f' -output {os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework")}'
)
def package(self):
if self.options.get_safe("as_framework"):
shutil.copytree(src=os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework"),
dst=os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework"))
else:
copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=os.path.join(self.package_folder, "include"))
copy(self, "*.a", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.so", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib"))
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "heiher::hev-socks5-tunnel")
if self.options.get_safe("as_framework"):
self.cpp_info.type = PackageType.STATIC
self.cpp_info.package_framework = True
self.cpp_info.location = os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework")
else:
self.cpp_info.libraries = collect_libs(self)

View File

@@ -0,0 +1,57 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.files import get, collect_libs
from conan.tools.gnu import Autotools, AutotoolsToolchain, PkgConfigDeps, AutotoolsDeps
from conan.errors import ConanInvalidConfiguration
from pathlib import Path
class LibcapNg(ConanFile):
name = "libcap-ng"
version = "0.9.2"
settings = "build_type", "compiler", "os", "arch"
options = {
"shared": [True, False]
}
default_options = {
"shared": False
}
def layout(self):
basic_layout(self, src_folder="src")
def validate(self):
if self.settings.os != "Linux":
ConanInvalidConfiguration(f"{self.name} v{self.version} is available only on Linux")
def requirements(self):
self.tool_requires("automake/1.16.5")
self.tool_requires("libtool/2.4.7")
self.tool_requires("pkgconf/2.5.1")
def source(self):
get(self, f"https://github.com/stevegrubb/libcap-ng/archive/refs/tags/v{self.version}.zip",
sha256="9c8847f9732f8ee161faf5bebad44cc6f614a8199f3d8dcb2014290b4acedc18", strip_root=True)
def generate(self):
pkgconf = PkgConfigDeps(self)
pkgconf.generate()
tc = AutotoolsToolchain(self)
tc.configure_args += ["--without-python3", "--disable-cap-audit"]
tc.generate()
deps = AutotoolsDeps(self)
deps.generate()
def build(self):
Path(self.source_folder, "NEWS").touch(exist_ok=True)
autotools = Autotools(self)
autotools.autoreconf()
autotools.configure()
autotools.make()
def package(self):
autotools = Autotools(self)
autotools.install()
def package_info(self):
self.cpp_info.libs = collect_libs(self)

134
recipes/libssh/conanfile.py Normal file
View File

@@ -0,0 +1,134 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.files import copy, get, rmdir
from conan.tools.microsoft import is_msvc_static_runtime, is_msvc
from conan.tools.scm import Version
import os
required_conan_version = ">=2.21"
class LibSSHRecipe(ConanFile):
name = "libssh"
version = "0.11.3"
user = "amnezia"
license = "LGPL-2.1"
homepage = "https://www.libssh.org/"
description = "multiplatform C library implementing the SSHv2 protocol on client and server side"
topics = ("ssh", "shell", "ssh2", "connection")
package_type = "library"
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_zlib": [True, False],
"crypto_backend": ["openssl", "gcrypt", "mbedtls"],
"with_symbol_versioning": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"with_zlib": True,
"crypto_backend": "openssl",
"with_symbol_versioning": True,
}
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
del self.options.with_symbol_versioning
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
def layout(self):
cmake_layout(self, src_folder="src")
def requirements(self):
if self.options.with_zlib:
self.requires("zlib/[>=1.2.11 <2]")
if self.options.crypto_backend =="openssl":
self.requires("openssl/[>=1.1 <4]")
elif self.options.crypto_backend == "gcrypt":
self.requires("libgcrypt/[>=1.8.4 <2]")
elif self.options.crypto_backend == "mbedtls":
self.requires("mbedtls/3.6.0")
def validate(self):
if self.options.crypto_backend == "mbedtls" and not self.dependencies["mbedtls"].options.enable_threading:
raise ConanInvalidConfiguration(f"{self.ref} requires '-o mbedtls/*:enable_threading=True' when using '-o libssh/*:crypto_backend=mbedtls'")
def source(self):
get(self, "https://www.libssh.org/files/0.11/libssh-0.11.3.tar.xz",
sha256="7d8a1361bb094ec3f511964e78a5a4dba689b5986e112afabe4f4d0d6c6125c3", strip_root=True
)
def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["CLIENT_TESTING"] = False
tc.cache_variables["SERVER_TESTING"] = False
tc.cache_variables["WITH_EXAMPLES"] = False
tc.cache_variables["WITH_GCRYPT"] = self.options.crypto_backend == "gcrypt"
tc.cache_variables["WITH_GSSAPI"] = False
tc.cache_variables["WITH_MBEDTLS"] = self.options.crypto_backend == "mbedtls"
tc.cache_variables["WITH_NACL"] = False
tc.cache_variables["WITH_SYMBOL_VERSIONING"] = self.options.get_safe("with_symbol_versioning", True)
tc.variables["WITH_ZLIB"] = self.options.with_zlib
if is_msvc(self):
tc.cache_variables["USE_MSVC_RUNTIME_LIBRARY_DLL"] = not is_msvc_static_runtime(self)
tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW"
tc.cache_variables["CMAKE_TRY_COMPILE_CONFIGURATION"] = str(self.settings.build_type)
if self.settings.os == "Android":
if Version(self.settings.get_safe("os.api_level")) < 24:
tc.cache_variables["HAVE_IFADDRS_H"] = False
tc.cache_variables["HAVE_GLOB_H"] = False
tc.preprocessor_definitions["S_IWRITE"] = "S_IRUSR"
tc.preprocessor_definitions["S_IWRITE"] = "S_IWUSR"
tc.preprocessor_definitions["S_IEXEC"] = "S_IXUSR"
tc.generate()
deps = CMakeDeps(self)
deps.set_property("libgcrypt", "cmake_file_name", "GCrypt")
deps.set_property("libgcrypt", "cmake_additional_variables_prefixes", ["GCRYPT"])
deps.set_property("libgcrypt", "cmake_extra_variables", {"GCRYPT_FOUND": "TRUE"})
deps.set_property("mbedtls", "cmake_additional_variables_prefixes", ["MBEDTLS"])
deps.set_property("mbedtls", "cmake_extra_variables", {"MBEDTLS_FOUND": "TRUE"})
deps.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
copy(self, pattern="COPYING", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
cmake = CMake(self)
cmake.install()
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
def package_info(self):
self.cpp_info.libs = ["ssh"]
if not self.options.shared:
self.cpp_info.defines.append("LIBSSH_STATIC=ON")
if self.settings.os == "Windows":
self.cpp_info.system_libs.extend(["ws2_32", "iphlpapi"])
self.cpp_info.set_property("cmake_file_name", "libssh")
# target and alias names defined at:
# ssh https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n351
# ssh::ssh https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n371
# ssh-static https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n413
# ssh::static https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n428
self.cpp_info.set_property("cmake_target_name", "ssh::ssh")
self.cpp_info.set_property(
"cmake_target_aliases",
["ssh"] if self.options.shared else ["ssh", "ssh-static", "ssh::static"],
)
# pkg-config defined at https://git.libssh.org/projects/libssh.git/tree/CMakeLists.txt?h=libssh-0.10.6#n124
self.cpp_info.set_property("pkg_config_name", "libssh")

View File

@@ -0,0 +1,3 @@
patches:
"1.0.0":
- patch_file: "patches/0001-fix-cloak-go-build.patch"

View File

@@ -0,0 +1,57 @@
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
from conan.tools.files import copy, apply_conandata_patches, export_conandata_patches
from conan.tools.scm import Git
from conan.errors import ConanInvalidConfiguration
import os
class OpenvpnPtAndroid(ConanFile):
name = "openvpn-pt-android"
version = "1.0.0"
package_type = "shared-library"
settings = "os", "arch", "build_type", "compiler"
def export_sources(self):
export_conandata_patches(self)
def layout(self):
cmake_layout(self, src_folder="src")
def build_requirements(self):
self.tool_requires("swig/4.1.1")
self.tool_requires("go/1.26.0")
self.tool_requires("cmake/[>=3.4.1 <4]")
def validate(self):
if self.settings.os != "Android":
raise ConanInvalidConfiguration(f"{self.name} only supports Android, got {self.settings.os}")
def source(self):
git = Git(self)
git.clone(
url="https://github.com/amnezia-vpn/openvpn-pt-android.git",
target=".",
args=["--recurse-submodules", "--branch", "update-ovpn3"]
)
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
apply_conandata_patches(self)
cmake = CMake(self)
cmake.configure()
cmake.build(target=["ck_ovpn_plugin_go", "ovpn3", "ovpnutil", "rsapss"])
def package(self):
copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
copy(self, "*.so", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "amnezia::openvpn-pt-android")
self.cpp_info.libs = [ "ovpn3", "ovpnutil", "rsapss" ]
self.cpp_info.set_property("cmake_extra_variables", {
"OPENVPN_PT_ANDROID_LIBCK_OVPN_PLUGIN_PATH": os.path.join(self.package_folder, "lib", "libck-ovpn-plugin.so")
})

View File

@@ -0,0 +1,65 @@
From 5a96e1a9a5116917969afdd7adebfa895ff42617 Mon Sep 17 00:00:00 2001
From: Yaroslav Gurov <ygurov@proton.me>
Date: Mon, 30 Mar 2026 17:38:11 +0200
Subject: [PATCH] fix cloak go build
---
cloak.cmake | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/cloak.cmake b/cloak.cmake
index 8199ebc..d8ef1cb 100644
--- a/cloak.cmake
+++ b/cloak.cmake
@@ -9,36 +9,32 @@ list(APPEND CMAKE_PROGRAM_PATH "/usr/local/go/bin")
find_program(GO_EXEC go)
set(BUILD_CMD_ARGS build)
-list(APPEND BUILD_CMD_ARGS -buildmode=c-shared -o ${CMAKE_CURRENT_BINARY_DIR}/${CLOAK_LIB} ${CMAKE_GO_FLAGS} ./...)
-
-set(PREPARE_ENV_ARGS env)
-list(APPEND PREPARE_ENV_ARGS -w CGO_ENABLED=1 GOOS=android)
-
+list(APPEND BUILD_CMD_ARGS -buildmode=c-shared -v -o ${CMAKE_CURRENT_BINARY_DIR}/${CLOAK_LIB} ./...)
string(REGEX MATCH "[0-9]+$" ANDROID_API_LEVEL ${ANDROID_PLATFORM})
message(WARNING "build cloak plugin abi=${ANDROID_ABI}, ANDROID_API_LEVEL=${ANDROID_API_LEVEL}")
+list(APPEND GO_ENV CGO_ENABLED=1 GOOS=android)
+list(APPEND GO_ENV "CC=${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
if ("${ANDROID_ABI}" STREQUAL "x86")
- list(APPEND PREPARE_ENV_ARGS GOARCH=386)
- list(APPEND PREPARE_ENV_ARGS CC=${ANDROID_TOOLCHAIN_ROOT}/bin/i686-linux-android${ANDROID_API_LEVEL}-clang)
+ list(APPEND GO_ENV GOARCH=386)
elseif ("${ANDROID_ABI}" STREQUAL "x86_64")
- list(APPEND PREPARE_ENV_ARGS GOARCH=amd64)
- list(APPEND PREPARE_ENV_ARGS CC=${ANDROID_TOOLCHAIN_ROOT}/bin/x86_64-linux-android${ANDROID_API_LEVEL}-clang)
+ list(APPEND GO_ENV GOARCH=amd64)
elseif ("${ANDROID_ABI}" STREQUAL "arm64-v8a")
- list(APPEND PREPARE_ENV_ARGS GOARCH=arm64)
- list(APPEND PREPARE_ENV_ARGS CC=${ANDROID_TOOLCHAIN_ROOT}/bin/aarch64-linux-android${ANDROID_API_LEVEL}-clang)
+ list(APPEND GO_ENV GOARCH=arm64)
elseif ("${ANDROID_ABI}" STREQUAL "armeabi-v7a")
- list(APPEND PREPARE_ENV_ARGS GOARCH=arm)
- list(APPEND PREPARE_ENV_ARGS GOARM=7)
- list(APPEND PREPARE_ENV_ARGS CC=${ANDROID_TOOLCHAIN_ROOT}/bin/armv7a-linux-androideabi${ANDROID_API_LEVEL}-clang)
+ list(APPEND GO_ENV GOARCH=arm)
+ list(APPEND GO_ENV GOARM=7)
endif ()
+string(REPLACE -mthumb -marm GO_C_FLAGS ${CMAKE_C_FLAGS})
+list(APPEND GO_ENV "CGO_CFLAGS=${GO_C_FLAGS}")
+list(APPEND GO_ENV "CGO_LDFLAGS=${GO_C_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CLOAK_LIB}
DEPENDS ${CLOAK_SRCS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cloak/cmd/ck-ovpn-plugin
- COMMAND ${GO_EXEC} ${PREPARE_ENV_ARGS}
- COMMAND ${GO_EXEC} ${BUILD_CMD_ARGS}
+ COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV} ${GO_EXEC} ${BUILD_CMD_ARGS}
COMMENT "Building Go library")
add_custom_target(${TARGET} DEPENDS ${CLOAK_LIB} ${HEADER})
--
2.50.1 (Apple Git-155)

View File

@@ -0,0 +1,107 @@
from conan import ConanFile
from conan.tools.files import get, copy, replace_in_file
from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps, PkgConfigDeps
from conan.tools.layout import basic_layout
from conan.tools.cmake import cmake_layout, CMakeToolchain, CMake, CMakeDeps
import os
class Openvpn(ConanFile):
name = "openvpn"
version = "2.7.0"
package_type = "application"
settings = "os", "build_type", "arch", "compiler"
@property
def _is_windows(self):
return str(self.settings.os).startswith("Windows")
def export_sources(self):
copy(self, "*applink.c", src=self.recipe_folder, dst=self.export_sources_folder)
def layout(self):
if self._is_windows:
cmake_layout(self)
else:
basic_layout(self)
def build_requirements(self):
if self._is_windows:
self.tool_requires("cmake/[>=3.14 <4]")
else:
self.tool_requires("libtool/2.4.7")
self.tool_requires("automake/1.16.5")
if self.settings.os == "Linux" or self._is_windows:
self.tool_requires("pkgconf/2.5.1")
def requirements(self):
self.requires("openssl/3.6.1", visible=False)
self.requires("lz4/1.10.0", visible=False)
self.requires("lzo/2.10", visible=False)
if self.settings.os == "Linux":
self.requires("libnl/3.9.0", visible=False)
self.requires("libcap-ng/0.9.2", visible=False)
if self._is_windows:
self.requires("tap-windows6/[*]")
def source(self):
get(self, f"https://github.com/OpenVPN/openvpn/archive/refs/tags/v{self.version}.zip",
sha256="1a65d8587f932c13d55b1f175ff2e1d61d795d9092788662e888054854d4ee3d", strip_root=True
)
def _patch_sources(self):
replace_in_file(self,
os.path.join(self.source_folder, "CMakeLists.txt"),
"/Qspectre",
""
)
def generate(self):
self._patch_sources()
if self.settings.os == "Linux" or self._is_windows:
pkgconf = PkgConfigDeps(self)
pkgconf.generate()
if self._is_windows:
tc = CMakeToolchain(self)
applink_include_path = os.path.join(self.export_sources_folder, "include").replace("\\", "/")
tap_include_path = (self.dependencies["tap-windows6"].cpp_info.aggregated_components().includedirs[0]).replace("\\", "/")
tc.extra_cflags = [ f"-I{tap_include_path}", f"-I{applink_include_path}" ]
tc.extra_cxxflags = [ f"-I{tap_include_path}", f"-I{applink_include_path}" ]
tc.cache_variables["BUILD_TESTING"] = False
tc.cache_variables["ENABLE_PKCS11"] = False
tc.generate()
deps = CMakeDeps(self)
deps.generate()
else:
tc = AutotoolsToolchain(self)
tc.configure_args.extend(["--disable-shared", "--enable-static"])
tc.configure_args.append("--disable-plugins")
tc.generate()
deps = AutotoolsDeps(self)
deps.generate()
def build(self):
if self._is_windows:
cmake = CMake(self)
cmake.configure()
cmake.build()
else:
at = Autotools(self)
at.autoreconf()
at.configure()
at.make()
def package(self):
if self._is_windows:
copy(self, "*openvpn.exe", src=self.build_folder, dst=self.package_folder, keep_path=False)
else:
copy(self, "openvpn", src=os.path.join(self.build_folder, "src", "openvpn"), dst=self.package_folder)
def package_info(self):
self.cpp_info.exe = True
ext = ".exe" if self._is_windows else ""
self.cpp_info.location = os.path.join(self.package_folder, f"openvpn{ext}")

View File

@@ -0,0 +1,151 @@
/*
* Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#define APPLINK_STDIN 1
#define APPLINK_STDOUT 2
#define APPLINK_STDERR 3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS 5
#define APPLINK_FREAD 6
#define APPLINK_FWRITE 7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF 9
#define APPLINK_FCLOSE 10 /* should not be used */
#define APPLINK_FOPEN 11 /* solely for completeness */
#define APPLINK_FSEEK 12
#define APPLINK_FTELL 13
#define APPLINK_FFLUSH 14
#define APPLINK_FERROR 15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO 17 /* to be used with below */
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
#define APPLINK_READ 19
#define APPLINK_WRITE 20
#define APPLINK_LSEEK 21
#define APPLINK_CLOSE 22
#define APPLINK_MAX 22 /* always same as last macro */
#ifndef APPMACROS_ONLY
/*
* Normally, do not define APPLINK_NO_INCLUDES. Define it if you are using
* symbol preprocessing and do not want the preprocessing to affect the
* following included header files. You will need to put these
* include lines somewhere in the file that is including applink.c.
*/
#ifndef APPLINK_NO_INCLUDES
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#endif
#ifdef __BORLANDC__
/* _lseek in <io.h> is a function-like macro so we can't take its address */
#undef _lseek
#define _lseek lseek
#endif
static void *app_stdin(void)
{
return stdin;
}
static void *app_stdout(void)
{
return stdout;
}
static void *app_stderr(void)
{
return stderr;
}
static int app_feof(FILE *fp)
{
return feof(fp);
}
static int app_ferror(FILE *fp)
{
return ferror(fp);
}
static void app_clearerr(FILE *fp)
{
clearerr(fp);
}
static int app_fileno(FILE *fp)
{
return _fileno(fp);
}
static int app_fsetmod(FILE *fp, char mod)
{
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void **
#if defined(__BORLANDC__)
/*
* __stdcall appears to be the only way to get the name
* decoration right with Borland C. Otherwise it works
* purely incidentally, as we pass no parameters.
*/
__stdcall
#else
__cdecl
#endif
OPENSSL_Applink(void)
{
static int once = 1;
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] = { (void *)APPLINK_MAX };
if (once) {
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
once = 0;
}
return OPENSSL_ApplinkTable;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,72 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.apple import is_apple_os
from conan.errors import ConanInvalidConfiguration
from conan.tools.scm import Git
from conan.internal.model.pkg_type import PackageType
from conan.tools.files import chdir
import os
import shutil
class OpenVPNAdapter(ConanFile):
name = "openvpnadapter"
version = "1.0.0"
settings = "os", "build_type"
@property
def _sdk(self):
return str(self.settings.get_safe("os.sdk", "macosx"))
@property
def _platform(self):
return {
"macosx": "macOS",
"iphoneos": "iOS",
"iphonesimulator": "iOS Simulator"
}.get(self._sdk)
@property
def _configuration(self):
return "Debug" if self.settings.get_safe("build_type") == "Debug" else "Release"
def layout(self):
basic_layout(self)
def validate(self):
if not is_apple_os(self):
raise ConanInvalidConfiguration(
f"There is absolutely no point building Apple framework for {self.settings.os}"
)
def source(self):
git = Git(self)
git.clone(
url="https://github.com/amnezia-vpn/OpenVPNAdapter.git",
target=".",
args=["--recurse-submodules", "--branch", "master-amnezia"]
)
def build(self):
with chdir(self, self.source_folder):
self.run("xcrun xcodebuild"
" -project OpenVPNAdapter.xcodeproj"
" -scheme OpenVPNAdapter"
" -configuration Release"
f" -destination 'generic/platform={self._platform}'"
f" -sdk {self._sdk}"
f' "CONFIGURATION_BUILD_DIR={self.build_folder}"'
f' "BUILT_PRODUCTS_DIR={self.build_folder}"'
" BUILD_LIBRARY_FOR_DISTRIBUTION=YES"
" CODE_SIGNING_ALLOWED=NO"
)
def package(self):
shutil.copytree(os.path.join(self.build_folder, "OpenVPNAdapter.framework"),
os.path.join(self.package_folder, "OpenVPNAdapter.framework"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "amnezia::openvpnadapter")
self.cpp_info.type = PackageType.STATIC
self.cpp_info.package_framework = True
self.cpp_info.location = os.path.join(self.package_folder, "OpenVPNAdapter.framework")

View File

@@ -0,0 +1,47 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.errors import ConanInvalidConfiguration
from conan.tools.files import get, copy
import os
class TapWindows6(ConanFile):
name = "tap-windows6"
version = "9.27.0"
settings = "os", "arch"
@property
def _arch(self):
return {
"x86": "i386",
"x86_64": "amd64",
"armv8": "arm64"
}.get(str(self.settings.arch))
def layout(self):
basic_layout(self)
def validate(self):
if not str(self.settings.os).startswith("Windows"):
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does only support Windows"
)
if not self._arch:
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.arch}"
)
def source(self):
get(self, f"https://github.com/OpenVPN/tap-windows6/releases/download/{self.version}/dist.win10.zip",
sha256="36e2609b7ceefedcb978ce5c48caf9e0e5af83423717c4e2e3c1d7ebca8f62a5", strip_root=True)
def package(self):
copy(self, "*.h", src=os.path.join(self.source_folder, "include"), dst=os.path.join(self.package_folder, "include"))
copy(self, "*", src=os.path.join(self.source_folder, self._arch), dst=os.path.join(self.package_folder, "bin"))
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "openvpn::tap-windows6")
self.cpp_info.set_property("cmake_extra_variables", {
"TAP_WINDOWS6_BIN": os.path.join(self.package_folder, "bin").replace("\\", "/")
})

View File

@@ -0,0 +1,90 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.files import get, copy, chdir
from conan.errors import ConanInvalidConfiguration
from conan.tools.gnu import Autotools, AutotoolsToolchain
from conan.tools.env import Environment
import os
class Tun2Socks(ConanFile):
name = "tun2socks"
version = "2.6.0"
package_type = "application"
settings = "os", "arch"
@property
def _goos(self):
return {
"Linux": "linux",
"Macos": "darwin",
"Windows": "windows"
}.get(str(self.settings.os))
@property
def _goarch(self):
return {
"x86": "386",
"x86_64": "amd64",
"armv8": "arm64"
}.get(str(self.settings.arch))
@property
def _is_windows(self):
return str(self.settings.get_safe("os")).startswith("Windows")
@property
def _ext(self):
return ".exe" if self._is_windows else ""
def layout(self):
basic_layout(self)
def validate(self):
if not self._goos or not self._goarch:
raise ConanInvalidConfiguration(
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
)
def build_requirements(self):
self.tool_requires("go/1.26.0")
if self._is_windows:
self.win_bash = True
if not self.conf.get("tools.microsoft.bash:path", check_type=str):
self.tool_requires("msys2/cci.latest")
self.tool_requires("mingw-builds/15.1.0")
def requirements(self):
if self._is_windows:
self.requires("wintun/[*]")
def source(self):
get(self, f"https://github.com/xjasonlyu/tun2socks/archive/refs/tags/v{self.version}.zip",
sha256="a7ef9cec1c30dfe9971af89a8aac767fd3d2a4df833e92b635642c2f0204c701", strip_root=True
)
def generate(self):
tc = AutotoolsToolchain(self)
env = tc.environment()
env.define("LDFLAGS", "")
env.define("CGO_LDFLAGS", tc.ldflags)
env.define("CGO_CFLAGS", tc.cflags)
env.define("GOOS", self._goos)
env.define("GOARCH", self._goarch)
tc.generate(env)
def build(self):
with chdir(self, self.source_folder):
at = Autotools(self)
at.make("tun2socks")
def package(self):
copy(self, "tun2socks", src=self.build_folder, dst=self.package_folder)
if self._is_windows:
with chdir(self, self.package_folder):
os.rename(src="tun2socks", dst="tun2socks.exe")
def package_info(self):
self.cpp_info.exe = True
self.cpp_info.location = os.path.join(self.package_folder, f"tun2socks{self._ext}")
self.cpp_info.set_property("cmake_target_name", "xjasonlyu::tun2socks")

View File

@@ -0,0 +1,29 @@
from conan import ConanFile
from conan.tools.layout import basic_layout
from conan.tools.files import download, copy
import os
class V2rayRulesDat(ConanFile):
name = "v2ray-rules-dat"
version = "202603162227"
def layout(self):
basic_layout(self, build_folder=".")
def source(self):
# TODO(ygurov): build from source instead of plain copying
download(self, filename="geoip.dat", url=f"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/{self.version}/geoip.dat",
sha256="e48b925d985d7bf33cfee76f309241af0f1779699963b69363dec2c4740041d1")
download(self, filename="geosite.dat", url=f"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/{self.version}/geosite.dat",
sha256="a2f83e25b8be3f089cfdd9423fc7b6eda5a0d4060919917902711d65acac1e0c")
def package(self):
copy(self, "*.dat", src=self.build_folder, dst=self.package_folder)
def package_info(self):
self.cpp_info.set_property("cmake_target_name", "Loyalsoldier::v2ray-rules-dat")
self.cpp_info.set_property("cmake_extra_variables", {
"GEOSITE_DAT_PATH": os.path.join(self.package_folder, "geosite.dat").replace("\\", "/"),
"GEOIP_DAT_PATH": os.path.join(self.package_folder, "geoip.dat").replace("\\", "/")
})

Some files were not shown because too many files have changed in this diff Show More