From 63ab591b699ba7355394d25b3a1ccdbf87ac6ae8 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 13 May 2019 23:30:23 +1000 Subject: [PATCH] Document how to compile plugins on linux --- misc/plugin-dev.md | 106 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 misc/plugin-dev.md diff --git a/misc/plugin-dev.md b/misc/plugin-dev.md new file mode 100644 index 000000000..2165be02e --- /dev/null +++ b/misc/plugin-dev.md @@ -0,0 +1,106 @@ +This document details how to compile a basic plugin in Visual Studio, MinGW, or GCC. + +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](https://github.com/UnknownShadow200/ClassiCube-Plugins/tree/master/src) + +### Setup + +You need to download and install either Visual Studio, MinGW, or GCC. + +*Note: MinGW/GCC 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 +```C +#include "src/Chat.h" +#include "src/GameStructs.h" + +static void TestPlugin_Init(void) { + String msg = String_FromConst("Hello world!"); + Chat_Add(&msg); +} + +int Plugin_ApiVersion = 1; +struct IGameComponent Plugin_Component = { TestPlugin_Init }; +``` +Here's the idea for a basic plugin that shows "Hello world" in chat when the game starts. Alas, this won't compile... + +### Basic plugin boilerplate +```C +#include "src/Chat.h" +#include "src/GameStructs.h" + +#ifdef CC_BUILD_WIN + #define CC_API __declspec(dllimport) + #define CC_VAR __declspec(dllimport) + #define EXPORT __declspec(dllexport) +#else + #define CC_API + #define CC_VAR + #define EXPORT __attribute__((visibility("default"))) +#endif + +static void TestPlugin_Init(void) { + String msg = String_FromConst("Hello world!"); + Chat_Add(&msg); +} + +EXPORT int Plugin_ApiVersion = 1; +EXPORT struct IGameComponent Plugin_Component = { TestPlugin_Init }; +``` +With this boilerplate, we're ready to compile the plugin. +All plugins require this boilerplate, so feel free to copy and paste it. + +--- + +### Linux +#### For Linux +**Compiling** + +```gcc TestPlugin.c -o TestPlugin.so -shared -fPIC``` + +Then put ```TestPlugin.so``` into your game's ```plugins``` folder. Done. + +#### Cross compile for Windows 32 bit +**Prerequisites:** + +1) Compile the game, see ```Cross compiling for windows``` in main readme +2) Rename compiled executable to ClassiCube.exe +3) Install the ```mingw-w64-tools``` package + +**Compiling** + +First, generate list of exported symbols: + +```gendef src/ClassiCube.exe``` + +Next create a linkable library: + +```i686-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe``` + +Finally compile the plugin: + +```i686-w64-mingw32-gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube``` + +Then put ```TestPlugin.dll``` into your game's ```plugins``` folder. Done. + +##### Ultra small dlls +If you **ONLY** use code from the game (no external libraries and no C standard library functions), add ```-nostartfiles -Wl,--entry=0``` to the compile flags + +This step isn't necessary, the dll works fine without it. But it does reduce the size of the dll from 11 to 4 kb. + +#### Cross compile for Windows 64 bit +Repeat the steps of *Cross compile for Windows 32 bit*, but use ```x86_64-w64-mingw32``` instead of ```i686-w64-mingw32``` + + +### Windows +TODO when I have some more time... +