Skip to content

Repackage go binaries into XCFramework package supporting iOS/macOS (and probably iOS Simulator/Catalyst) #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .github/workflows/build-go-dependency-wrapper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Builds and publishes the wg-go binaries to this repo when run as a GitHub Workflow.
# The binaries in this repo are compiled without modification from upstream (official WireGuard) sources
# However, if you have security requirements beyond my assertion of "trust me bruh", the code/configs/scripts in this
# repo are 100% auditable and you are welcome to fork it and run it yourself to guarantee and grant yourself
# that wonderfully fluttery feeling of diy, security, and privacy. All the scripts should work automagically
# in their own github workflow context, or with a little effort, you can run it yourself offline.

name: Go Dependency Wrapper

on:
workflow_dispatch:
inputs:
update_go_deps:
description: 'Update go dependencies with `go get -u ./...'
required: false
type: boolean
defualt: false
go_update_patch_only:
description: '(only used if `update_go_deps` is `true`) When updating, only update the patch version.'
required: false
type: boolean
default: true
tag:
description: 'Releases can only be created from tags, so a unique tag is required. This will probably get updated to a versioning syntax in the future.'
required: true


jobs:
wg-build:
name: Wireguard Build and Release
runs-on: macos-15

concurrency:
# Only allow a single run of this workflow on each branch, automatically cancelling older runs.
group: wg-${{ github.head_ref }}
cancel-in-progress: true

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Determine Tag
id: tag
run: |
set -x

RAW_TAG="${{ github.event.inputs.tag }}"
TAG=$(echo "$RAW_TAG" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/[-]+/-/g' )

echo "RAW_TAG=${RAW_TAG}" >> "$GITHUB_OUTPUT"
echo "TAG=${TAG}" >> "$GITHUB_OUTPUT"
env:
RAW_TAG: ${{ github.event.inputs.tag }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_BASE_BRANCH: ${{ github.base_ref }}
GITHUB_REF: ${{ github.ref }}

- name: Select Xcode
run: |
sudo xcode-select -s /Applications/Xcode_16.4.app

- name: Install Dependencies
run: |
brew install go

- name: Handle Inputs
run: |
set -xoe

pushd WireGuardGoFoundationSource

if [[ "$RUN_UPDATES" == "true" ]]; then
UPDATE_COMMAND=("go")
UPDATE_COMMAND+=("get")

if [[ "$PATCH_ONLY_UPDATES" == "true" ]]; then
UPDATE_COMMAND+=("-u=patch")
else
UPDATE_COMMAND+=("-u")
fi

UPDATE_COMMAND+=("./...")
fi

"${UPDATE_COMMAND[@]}"

popd

git add WireGuardGoFoundationSource/.
env:
RUN_UPDATES: ${{ github.event.inputs.update_go_deps }}
PATCH_ONLY_UPDATES: ${{ github.event.inputs.go_update_patch_only }}

- name: Build XCFramework
run: |
set -xoe

pushd WireGuardGoFoundationSource
make build-xcframework

zip -ry WireGuardGoFoundation.xcframework.zip WireGuardGoFoundation.xcframework
popd
mv WireGuardGoFoundationSource/WireGuardGoFoundation.xcframework.zip .

- name: Update Package
run: |
set -xoe

CHECKSUM=$(swift package compute-checksum WireGuardGoFoundation.xcframework.zip)
NEW_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/WireGuardGoFoundation.xcframework.zip"

sed -i "" "s|let url = \".*\"|let url = \"$NEW_URL\"|" Package.swift
sed -i "" "s|let checksum = \".*\"|let checksum = \"$CHECKSUM\"|" Package.swift

git add Package.swift
git commit -m "Release ${TAG}"
git push origin HEAD:master
git tag ${TAG}
git push origin ${TAG}
env:
TAG: ${{ steps.tag.outputs.TAG }}

- name: Release
uses: softprops/action-gh-release@v2
with:
files: WireGuardGoFoundation.xcframework.zip
make_latest: true
tag_name: ${{ steps.tag.outputs.TAG }}
19 changes: 19 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## MIT License

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.
25 changes: 8 additions & 17 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// swift-tools-version:5.3
// swift-tools-version:5.10
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let url = "https://github.com/ridgelineinternational/wireguard-apple-xcframework/releases/download/0.0.4/WireGuardGoFoundation.xcframework.zip"
let checksum = "167f19a1584e25cd64e2b8cb23d44c6dc7d890435db78da0da50120503ffa492"

let package = Package(
name: "WireGuardKit",
platforms: [
.macOS(.v12),
.iOS(.v15)
.macOS(.v13),
.iOS(.v16)
],
products: [
.library(name: "WireGuardKit", targets: ["WireGuardKit"])
Expand All @@ -16,25 +19,13 @@ let package = Package(
targets: [
.target(
name: "WireGuardKit",
dependencies: ["WireGuardKitGo", "WireGuardKitC"]
dependencies: ["WireGuardGoFoundation", "WireGuardKitC"]
),
.target(
name: "WireGuardKitC",
dependencies: [],
publicHeadersPath: "."
),
.target(
name: "WireGuardKitGo",
dependencies: [],
exclude: [
"goruntime-boottime-over-monotonic.diff",
"go.mod",
"go.sum",
"api-apple.go",
"Makefile"
],
publicHeadersPath: ".",
linkerSettings: [.linkedLibrary("wg-go")]
)
.binaryTarget(name: "WireGuardGoFoundation", url: url, checksum: checksum)
]
)
87 changes: 22 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# [WireGuard](https://www.wireguard.com/) for iOS and macOS
# [WireGuard](https://www.wireguard.com/) for iOS and macOS (with XCFramework universal build)

This project contains an application for iOS and for macOS, as well as many components shared between the two of them. You may toggle between the two platforms by selecting the target from within Xcode.
This project contains an application for iOS and for macOS, as well as many components shared between the two of them. The xcframework library is compatible with iOS, macOS, and should at least link with the simulator (there may be network extension limitations, but minimal simulator dev should be possible).

## Building

(This section has not been updated since the xcframework introduction. These instructions will likely change - the project probably needs updating for pointing to the right spm project version and since the package is pre built, there's no need to install `go`)

- Clone this repo:

```
Expand Down Expand Up @@ -34,66 +36,21 @@ $ open WireGuard.xcodeproj

## WireGuardKit integration

1. Open your Xcode project and add the Swift package with the following URL:

```
https://git.zx2c4.com/wireguard-apple
```

2. `WireGuardKit` links against `wireguard-go-bridge` library, but it cannot build it automatically
due to Swift package manager limitations. So it needs a little help from a developer.
Please follow the instructions below to create a build target(s) for `wireguard-go-bridge`.

- In Xcode, click File -> New -> Target. Switch to "Other" tab and choose "External Build
System".
- Type in `WireGuardGoBridge<PLATFORM>` under the "Product name", replacing the `<PLATFORM>`
placeholder with the name of the platform. For example, when targeting macOS use `macOS`, or
when targeting iOS use `iOS`.
Make sure the build tool is set to: `/usr/bin/make` (default).
- In the appeared "Info" tab of a newly created target, type in the "Directory" path under
the "External Build Tool Configuration":

```
${BUILD_DIR%Build/*}SourcePackages/checkouts/wireguard-apple/Sources/WireGuardKitGo
```

- Switch to "Build Settings" and find `SDKROOT`.
Type in `macosx` if you target macOS, or type in `iphoneos` if you target iOS.

3. Go to Xcode project settings and locate your network extension target and switch to
"Build Phases" tab.

- Locate "Dependencies" section and hit "+" to add `WireGuardGoBridge<PLATFORM>` replacing
the `<PLATFORM>` placeholder with the name of platform matching the network extension
deployment target (i.e macOS or iOS).

- Locate the "Link with binary libraries" section and hit "+" to add `WireGuardKit`.

4. In Xcode project settings, locate your main bundle app and switch to "Build Phases" tab.
Locate the "Link with binary libraries" section and hit "+" to add `WireGuardKit`.

5. iOS only: Locate Bitcode settings under your application target, Build settings -> Enable Bitcode,
change the corresponding value to "No".

Note that if you ship your app for both iOS and macOS, make sure to repeat the steps 2-4 twice,
once per platform.

## MIT License

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.
It should now be as simple as adding this SPM package as a dependency. The magic behind this is that the package is pre-built as an xcframework, now, however. If you cannot trust a third party binary, you're welcome to build it yourself.

To do so

(Building with GitHub Actions)
1. Fork this project
1. In your fork, go to Actions
1. Choose the "Go Dependency Wrapper" action
1. On the right side of the screen, you should see `Run workflow` - do that.
1. The option to run `go get -u` as part of the build process is presented (this will update the build to use the latest wireguard go upstream code)
1. Provide a name for the tag. Semantic versioning is suggested, but not required.
1. Press `Run Workflow`
1. In a couple minutes, you'll have a new release on your fork that is freshly built.
1. You can now reference your fork with your release tag version in your own iOS/macOS project.

While this might not strictly feel quite the same as building locally, you are completely capable of instpecting the code as this entire repo is transparent.

And if you want to build locally, that's also an option. If you need assistance, the best path forward would be to inspect the workflow yaml file and replicate the steps on your local Mac.
2 changes: 1 addition & 1 deletion Sources/WireGuardKit/WireGuardAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation
import NetworkExtension

#if SWIFT_PACKAGE
import WireGuardKitGo
import WireGuardGoFoundation
import WireGuardKitC
#endif

Expand Down
1 change: 1 addition & 0 deletions Sources/WireGuardKitC/WireGuardKitC.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "key.h"
#include "x25519.h"
#include <sys/types.h>

/* From <sys/kern_control.h> */
#define CTLIOCGINFO 0xc0644e03UL
Expand Down
60 changes: 0 additions & 60 deletions Sources/WireGuardKitGo/Makefile

This file was deleted.

1 change: 0 additions & 1 deletion Sources/WireGuardKitGo/dummy.c

This file was deleted.

14 changes: 0 additions & 14 deletions Sources/WireGuardKitGo/go.mod

This file was deleted.

5 changes: 0 additions & 5 deletions Sources/WireGuardKitGo/module.modulemap

This file was deleted.

Loading