C++ Scripting: Part 6 – Building the C++ Plugin
Today we’ll continue the series by addressing a nagging problem: how do we build the C++ plugin? With C# we inherit, for better or worse, Unity’s build system where we just edit .cs
files and press the play button. This doesn’t work with C++, so we’ll need to build something similar that’s just as easy to use.
Table of Contents
- Part 1: C#/C++ Communication
- Part 2: Update C++ Without Restarting the Editor
- Part 3: Object-Oriented Bindings
- Part 4: Performance Validation
- Part 5: Bindings Code Generator
- Part 6: Building the C++ Plugin
- Part 7: MonoBehaviour Messages
- Part 8: Platform-Dependent Compilation
- Part 9: Out and Ref Parameters
- Part 10: Full Generics Support
- Part 11: Collaborators, Structs, and Enums
- Part 12: Exceptions
- Part 13: Operator Overloading, Indexers, and Type Conversion
- Part 14: Arrays
- Part 15: Delegates
- Part 16: Events
- Part 17: Boxing and Unboxing
- Part 18: Array Index Operator
- Part 19: Implement C# Interfaces with C++ Classes
- Part 20: Performance Improvements
- Part 21: Implement C# Properties and Indexers in C++
- Part 22: Full Base Type Support
- Part 23: Base Type APIs
- Part 24: Default Parameters
- Part 25: Full Type Hierarchy
- Part 26: Hot Reloading
- Part 27: Foreach Loops
- Part 28: Value Types Overhaul
- Part 29: Factory Functions and New MonoBehaviours
- Part 30: Overloaded Types and Decimal
First off, this build system is very basic. Then again, so is Unity’s build system. In a way, basic is a good thing.
For iOS, we don’t have a problem. C++ files in a Unity project’s Assets
directory are simply added to the Xcode project and built along with the IL2CPP output. There’s no need for a build system at all! Of course we don’t want to support only iOS, so we’ll need something for other platforms.
One approach would be to create makefiles and IDE projects for every possible OS and IDE. That’s pretty onerous though, so we won’t take that approach. Instead, we’ll generate those build scripts and projects using a widely-used tool called CMake. That’ll allow us to make a single build script and run CMake on it to generate whatever kind of build scripts or IDE projects we want.
First we place a CMakeLists.txt
file in our Assets
directory. This file tells CMake where our source is, what language it’s in, what features we need, and so forth. Users of the C++ scripting system never need to modify this file. Instead, they just run a few simple commands:
# Make a directory to build in mkdir cmake # Go to the build directory cd cmake # Build the Xcode project cmake -G "Xcode" /path/to/unity/project/Assets
CMake has now created an Xcode project, in this example. You can use it just like any other Xcode project. Just open the NativeScript.xcodeproj
file and click “Product > Build”.
The power of CMake is in the -G "Xcode"
part of that command. That tells CMake to build an Xcode project, but we could have just as easily told it to build makefiles for a command-line build instead:
# Make a directory to build in mkdir cmake # Go to the build directory cd cmake # Build the makefiles cmake -G "Unix Makefiles" /path/to/unity/project/Assets
Then just type make
to build the C++ plugin. No matter what “generator” you specify with -G
, the resulting project should build the C++ plugin the same way.
The same goes for cross-compiling to Android. Just add -DANDROID_NDK=/path/to/android/ndk
to tell it where your Android NDK is installed and you’re ready to go.
CMake works on Windows, too. You can use it with any version of Microsoft Visual Studio, even the free Community version. Just specify -G "Visual Studio 15 2017 Win64"
. Older versions work, too.
This means we can go back to the C++ workflow we outlined in part two of this series:
- Edit C++ sources
- Compile C++
- Switch to the Unity editor window
- Run the game
The vague “Compile C++” step is now more concrete: build however is appropriate for your CMake generator. Since we’ll probably use an IDE like Xcode or Visual Studio and just click a “build” button, the steps are just these:
- Edit C++ sources
- Click “build” in your IDE
- Switch to the Unity editor window
- Run the game
With this build system in place, scripting in C++ is now quite easy regardless of which platform you’re working on.
#1 by Giang Tong on September 14th, 2020 ·
Hi Jackson,
I am following this series and it has been enjoyable so far. I have one question regarding this post though: why do you put the Cmake project in the Asset folder? Do you think it is easier to manage with a standalone C++ project and the Unity project only need to know about the dll native plugin? Also there are .meta files with every source file if they are in Assets/. These are some disadvantage that I can think of and I am curious about why you put the CMake project inside Assets/ in the first place.
Again, amazing work!
Cheers,
Giang
#2 by jackson on September 14th, 2020 ·
I’m glad you’re enjoying the series. There’s no strong reason to put the C++ code under
Assets
, but it seemed a bit more “normal” to me to have it there alongside the C# code.#3 by Giang Tong on September 14th, 2020 ·
So that is purely a matter of preference. Thanks for clearing that out!