7.9 KiB
This document details how to compile a basic plugin in Visual Studio, MinGW, or GCC/Clang.
To find the functions and variables available for use in plugins, look for CC_API/CC_VAR in the .h files.
Source code of some actual plugins
Setup
You need to download and install either Visual Studio, MinGW, or GCC/Clang.
Note: MinGW/GCC/Clang are relatively small, while Visual Studio is gigabytes in size. If you're just trying to compile a plugin on Windows you might want to use MinGW. See main readme.
I assume your directory is structured like this:
src/...
TestPlugin.c
Or in other words, in a directory somewhere, you have a file named TestPlugin.c, and then a sub-directory named src which contains the game's source code.
Basic plugin
#include "src/PluginAPI.h"
#include "src/Chat.h"
#include "src/Game.h"
#include "src/String.h"
static void TestPlugin_Init(void) {
cc_string msg = String_FromConst("Hello world!");
Chat_Add(&msg);
}
PLUGIN_EXPORT int Plugin_ApiVersion = 1;
PLUGIN_EXPORT struct IGameComponent Plugin_Component = { TestPlugin_Init };
Here's a basic plugin that shows "Hello world" in chat when the game starts.
Note that src/PluginAPI.h must always be included as the first header.
Writing plugins in C++
Exported plugin functions must be surrounded with extern "C", i.e.
extern "C" {
PLUGIN_EXPORT int Plugin_ApiVersion = 1;
PLUGIN_EXPORT struct IGameComponent Plugin_Component = { TestPlugin_Init };
}
Otherwise your plugin will not load. (you'll see error getting plugin version in-game)
Compiling
Plugin compilation instructions differs depending on the compiler and operating system
Linux
Cross compiling for Windows 32-bit
Cross compiling for Windows 64-bit
macOS
Windows
Compiling - Linux
Using gcc or clang
Compiling
cc TestPlugin.c -o TestPlugin.so -shared -fPIC
Then put TestPlugin.so into your game's plugins folder. Done.
Cross compiling for Windows 32 bit using mingw-w64
Setup
- Create
ClassiCube.exeby either:- Compiling the game, see
Cross compiling for windows (32 bit)in main readme - Downloading 32 bit ClassiCube from https://www.classicube.net/download/#dl-win
- Compiling the game, see
- Install the
mingw-w64-toolspackage (if it isn't already) - Generate the list of exported symbols from
ClassiCube.exeby running:gendef ClassiCube.exe
- Create a linkable library from the exported symbols list by running:
i686-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe
TODO: also document alternate method of compiling the game using --out-implib
Compiling
i686-w64-mingw32-gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube
Then put TestPlugin.dll into your game's plugins folder. Done.
Cross compiling for Windows 64 bit using mingw-w64
Setup
- Create
ClassiCube.exeby either:- Compiling the game, see
Cross compiling for windows (64 bit)in main readme - Downloading 64 bit ClassiCube from https://www.classicube.net/download/#dl-win
- Compiling the game, see
- Install the
mingw-w64-toolspackage (if it isn't already) - Generate the list of exported symbols from
ClassiCube.exeby running:gendef ClassiCube.exe
- Create a linkable library from the exported symbols list by running:
x86_64-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe
TODO: also document alternate method of compiling the game using --out-implib
Compiling
x86_64-w64-mingw32-gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube
Then put TestPlugin.dll into your game's plugins folder. Done.
Compiling - macOS
Using gcc or clang
Compiling
cc TestPlugin.c -o TestPlugin.dylib -undefined dynamic_lookup
Then put TestPlugin.dylib into your game's plugins folder. Done.
Compiling - Windows
Using Visual Studio
TODO more detailed when I have some more time...
Setup
- Compile the game, see
Compiling - Windows > using Visual Studioin main readme - Find the
ClassiCube.libthat was generated when compiling the game. Usually it is in eithersrc\x64\Debugorsrc\x86\Debug. - Add a new
Empty Projectto the ClassiCube solution, then add the plugin .c files to it
Note: If the plugin provides a .vcxproj file, you can skip step 2 and just open that project file instead.
Configuration - alternative #1
The simplest way of linking to the .lib file is simply adding the following code to one of the plugin's .c files
#ifdef _MSC_VER
#ifdef _WIN64
#pragma comment(lib, "[GAME SRC FOLDER]/x64/Debug/ClassiCube.lib")
#else
#pragma comment(lib, "[GAME SRC FOLDER]/x86/Debug/ClassiCube.lib")
#endif
#endif
replacing [GAME SRC FOLDER] with the full path of src folder (e.g. C:/Dev/ClassiCube/src)
Configuration - alternative #2
The more complicated way of linking to the .lib file is to add it to the plugin's project configuration file
Right click the plugin project in the Solution Explorer pane, then click Properties
TODO: add screenshots here
TODO: may need to configure include directories
-
In
Configuration properties->General, make sureConfiguration typeis set toDynamic library (.DLL) -
In
Configuration properties->Linker->Input, click the dropdown button forAdditional Dependencies, then clickEdit. Add the full path toClassiCube.lib, then clickOK
Compiling
Build the project. There should be a line in the build output that tells you where you can find the .dll file like this:
Project1.vcxproj -> C:\classicube-dev\testplugin\src\x64\Debug\TestPlugin.dll
Then put TestPlugin.dll into your game's plugins folder. Done.
Using mingw-w64
Setup
- Create
ClassiCube.exeby either:- Compiling the game, see
Compiling for windows (MinGW-w64)in main readme - Downloading ClassiCube from https://www.classicube.net/download/#dl-win
- Compiling the game, see
- Generate the list of exported symbols in
ClassiCube.exeby running:gendef ClassiCube.exe
- Create a linkable library from the exported symbols list by running:
dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe
Compiling
gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube
Then put TestPlugin.dll into your game's plugins folder. Done.
Notes for compiling for Windows
Ensuring your plugin works when the ClassiCube exe isn't named ClassiCube.exe
If you follow the prior compilation instructions, the compiled DLL will have a runtime dependancy on ClassiCube.exe
However, this means that if the executable is e.g. named ClassiCube (2).exe instead. the plugin DLL will fail to load
To avoid this problem, you must
- Stop linking to
ClassiCube(e.g. forMinGW, remove the-L . -lClassiCube) - Load all functions and variables exported from ClassiCube via
GetProcAddressinstead
This is somewhat tedious to do - see here for some examples of plugins which do this
Compiling ultra small plugin DLLs - MinGW
If you ONLY use code from the game (no external libraries and no C standard library functions):
- You can add
-nostartfiles -Wl,--entry=0to the compile flags to reduce the DLL size (e.g from 11 to 4 kb)
This isn't necessary to do though, and plugin DLLs work completely fine without doing this.