-
CMake 3.15 or later (3.21 or later to use the macOS/iOS presets in
CMakePresets.json) -
A build tool like Ninja, GNU Make or Visual Studio
-
A C++17-compliant compiler, such as:
- GCC 7.3 or later
- Clang 3.3 or later
- Visual Studio 2017 or later
(The library's own code only needs C++11, but protobuf 22 and later require C++17 of everything that includes their headers.)
-
One of the following crypto solutions:
-
Google protobuf 2.6.1+. protobuf 22 and later also pull in Abseil. The
protoccompiler and thelibprotobufruntime you link against must be the same version; the build prints a warning if it can tell that they aren't. -
Google webrtc is used for NAT piercing (ICE) for P2P connections. The relevant code is linked in as a git submodule. You'll need to initialize that submodule to compile.
- The build may have link errors when building with LLVM 10+: LLVM bug #46313. As a workaround, consider building the library with GCC instead.
Just use the appropriate package manager.
Ubuntu/debian:
# apt install libssl-dev
# apt install libprotobuf-dev protobuf-compiler
Arch Linux:
# pacman -S openssl
# pacman -S protobuf
Using CMake (preferred):
$ mkdir build
$ cd build
$ cmake -G Ninja ..
$ ninja
If you are using vcpkg and are OK with the latest release and default configuration (OpenSSL for the crypto backend, P2P disabled), then you do not need to sync any of this code or build gamenetworkingsockets explicitly. You can install it directly from the vcpkg registry:
vcpkg install gamenetworkingsockets
Then include the headers in your project as, e.g.:
#include <steam/steamnetworkingsockets.h>See this example for more.
To build gamenetworkingsockets on Windows, it's recommended to obtain the dependencies by using vcpkg in "manifest mode". The following instructions assume that you will follow the vcpkg recommendations and install vcpkg as a subfolder. If you want to use "classic mode" or install vcpkg somewhere else, you're on your own.
If you don't want to use vcpkg, try the manual instructions.
First, bootstrap vcpkg. From the root folder of your GameNetworkingSockets workspace:
> git clone https://github.com/microsoft/vcpkg
> .\vcpkg\bootstrap-vcpkg.bat
For the following commands, it's important to run them from a Visual Studio command prompt so that the compiler can be located.
You can obtain the dependent packages into your local vcpkg folder as an explicit step. This is optional because the cmake command line below will also do it for you, but doing it as a separate step can help isolate any problems.
> .\vcpkg\vcpkg install --triplet=x64-windows
If you want to use the libsodium backend, install the libsodium dependencies by adding --x-feature=libsodium.
Now run cmake to create the project files. Assuming you have vcpkg in the recommended location as shown above, the vcpkg toolchain will automatically be used, so you do not need to explicitly set CMAKE_TOOLCHAIN_FILE. A minimal command line might look like this:
> cmake -S . -B build -G Ninja
To build all the examples and tests and add P2P/ICE support via the WebRTC submodule, use something like this:
> cmake -S . -B build -G Ninja -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON -DUSE_STEAMWEBRTC=ON
Finally, build the projects:
> cd build
> ninja
Everything the build needs is available from Homebrew:
$ brew install cmake ninja openssl@3 protobuf
What each of those is for:
| Formula | Used for |
|---|---|
openssl@3 |
libcrypto, the default crypto backend (AES-GCM, SHA-256, ed25519/curve25519) |
protobuf |
the protoc compiler and the libprotobuf runtime |
abseil |
not installed directly -- Homebrew's protobuf depends on it, and libprotobuf links against it, so it ends up in your link line too |
cmake, ninja |
build tooling |
Additionally, python3 is needed only if you want to run the tests, and perl
(the one in /usr/bin is fine) only if you build dependencies from source for
iOS.
Do not try to use the OpenSSL that ships with macOS. /usr/lib/libcrypto.dylib
is LibreSSL, Apple ships no headers for it, and it is not a drop-in substitute.
$ cmake -S . -B build -G Ninja
$ cmake --build build
CMake finds the Homebrew OpenSSL and protobuf on its own, because CMake searches
the Homebrew prefix by default -- /opt/homebrew on Apple Silicon, /usr/local
on Intel. If you have more than one OpenSSL around and it picks the wrong one,
point it at the right one explicitly:
$ cmake -S . -B build -G Ninja -DOPENSSL_ROOT_DIR=$(brew --prefix openssl@3)
There is also a preset that does the same thing with a shorter command line:
$ cmake --preset macos
$ cmake --build --preset macos
$ git submodule update --init src/external/vjson # needed by the cert tool
$ cmake -S . -B build -G Ninja -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON -DBUILD_TOOLS=ON
$ cmake --build build
$ ctest --test-dir build
Set CMAKE_OSX_DEPLOYMENT_TARGET to control the minimum supported macOS
version. A universal (arm64 + x86_64) build needs universal dependencies,
which Homebrew does not provide -- its bottles are single-architecture. To get
a universal static library, build each architecture against its own
dependencies and lipo the results; cmake/apple/make-xcframework.sh --macos does
exactly that.
CMake has built-in support for cross-compiling to iOS, so no third-party
toolchain file is required. What you do need is a set of dependencies built
for iOS -- Homebrew only ships macOS binaries -- and a protoc that runs on
the host to generate the protobuf sources.
-
Xcode with the iOS SDK.
xcodebuild -showsdksshould list an iOS SDK and an iOS Simulator SDK. If you only have the Command Line Tools installed, pointxcode-selectat the full Xcode:$ sudo xcode-select -s /Applications/Xcode.app -
Homebrew:
brew install cmake ninja protobufOnly the host tools come from Homebrew here.
protocruns on your Mac to generate the.pb.ccsources; thelibprotobufyou link into the iOS binary has to be built separately (see below) and must be the same version as thatprotoc. The dependency script pins it to whateverprotoc --versionreports, and the CMake build warns you if the two ever diverge.You do not need
openssl@3for an iOS build -- that formula is macOS-only, and OpenSSL for iOS is built from source by the script below. -
Perl -- used by OpenSSL's
Configure. The system/usr/bin/perlis fine.
$ ./cmake/apple/make-xcframework.sh --with-deps
That builds OpenSSL and protobuf/Abseil for iOS device and simulator, builds
GameNetworkingSockets against them, and packages the result as
build/GameNetworkingSockets.xcframework with an ios-arm64 slice and a fat
ios-arm64_x86_64-simulator slice.
The dependencies are folded into the archives, so the xcframework is
self-contained. In Xcode, add it to Frameworks, Libraries, and Embedded
Content, and also link CoreFoundation (Abseil's time-zone code needs it) and
the C++ standard library. The first run takes a while -- it builds OpenSSL and
protobuf three times, once per architecture -- but the results are cached under
build/apple-deps/, so later runs only rebuild GameNetworkingSockets itself.
Useful options:
$ ./cmake/apple/make-xcframework.sh --help
$ ./cmake/apple/run-ios-smoke-test.sh
Builds tests/ios_smoke_test.cpp against the simulator slice of the xcframework and runs it in an iOS Simulator: it stands up a listen socket on loopback, connects to it, and round-trips a reliable message, which exercises the crypto backend, protobuf, the socket thread and SNP. It boots a simulator if none is running, and shuts that one back down afterwards.
Build the dependencies for one platform/architecture at a time:
$ ./cmake/apple/build-apple-deps.sh --platform iphoneos --arch arm64
$ ./cmake/apple/build-apple-deps.sh --platform iphonesimulator --arch arm64
Each invocation installs into build/apple-deps/<platform>-<arch>/. Then
configure and build the library against one of those prefixes:
$ PREFIX=$PWD/build/apple-deps/iphoneos-arm64
$ cmake -S . -B build/iphoneos-arm64 -G Ninja \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_SYSROOT=iphoneos \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DCMAKE_OSX_DEPLOYMENT_TARGET=15.0 \
-DCMAKE_PREFIX_PATH=$PREFIX \
-DCMAKE_FIND_ROOT_PATH=$PREFIX \
-DOPENSSL_ROOT_DIR=$PREFIX
$ cmake --build build/iphoneos-arm64
CMAKE_FIND_ROOT_PATH is not redundant with CMAKE_PREFIX_PATH: when
cross-compiling, CMake will only look for libraries and headers underneath the
find-root paths, so without it find_package(OpenSSL) fails even though the
prefix is correct.
Presets are provided for the common cases:
$ cmake --preset ios-device # or ios-simulator, or ios-device-framework
$ cmake --build --preset ios-device
The static library (BUILD_STATIC_LIB, on by default) is the straightforward
choice, and is what the xcframework contains.
BUILD_SHARED_LIB is off by default on iOS. A dynamic library shipped
inside an app bundle is normally a framework -- that is what Xcode's Embed &
Sign and the App Store tooling expect; a bare .dylib can be embedded and
loaded too, but you have to handle the embedding and code signing yourself.
So on iOS, turning the shared library on gives you a framework by default:
$ cmake --preset ios-device-framework
That produces GameNetworkingSockets.framework, with the public headers under
Headers/steam/. It is not code-signed; sign it when you embed it (Xcode's
Embed & Sign).
BUILD_FRAMEWORK is a separate knob from BUILD_SHARED_LIB rather than a
synonym for it, because the two questions really are separate: whether to build
a shared library at all, and how to package it. -DBUILD_SHARED_LIB=ON alone
is enough on iOS -- BUILD_FRAMEWORK follows it. The separate option is there
so that macOS can opt in to a framework (-DBUILD_FRAMEWORK=ON, which keeps
the default macOS output a plain libGameNetworkingSockets.dylib for everything
that already expects one), and so that iOS can opt out with
-DBUILD_FRAMEWORK=OFF if you are doing your own packaging.
- Local network permission. On iOS 14 and later, the system requires user
consent before an app can talk to other devices on the local network. Without
an
NSLocalNetworkUsageDescriptionstring in yourInfo.plist, connections to peers on the LAN will simply never complete. Traffic to hosts off the local network is unaffected. - Backgrounding. iOS tears down UDP sockets when an app is suspended. Expect connections to drop when you go to the background, and reconnect on the way back rather than assuming the session survived.
- Examples, tests and the cert tool are command-line programs and cannot be built for iOS; the CMake configure step will tell you so if you ask for them. Build and run those in a separate macOS build directory.
- P2P/ICE is compiled in by default and uses the built-in native ICE client.
The Google WebRTC backend (
USE_STEAMWEBRTC) is not supported on iOS here.
The CMake and platform-detection plumbing recognizes these as well, so a build
should work if you supply dependencies for them. Only iOS and macOS are
actually built and tested; in particular cmake/apple/build-apple-deps.sh knows how
to configure OpenSSL for iOS and macOS only.