Compiling code at runtime

Hello, my name is Saulo and I’m trying to build a game where the player can write a code in C language (maybe on a widget) and then execute it. However, to acomplish this I need a way to get the C code written by the player, compile it and execute.

My ideas where:

  1. Trying a way to include a generic C++ compiler, or some short, as a new module on UE4 and then use this compiler to create a dynamic-link library(dll) from the player’s C code, link my C++ function, let’s say foo() to the C code main() function and execute foo() on my code, as it would be executing the main() function (due to linking). However, I could not find any way to download a C++ compiler as a third-party library, so that I could include on UE4 modules. The only information I’ve found was how to install a C++ compiler on my machine, how to create dll from a c++ compiler, how to use Visual Studio to compile code, etc…
    2)I’ve been trying to find a way to use the UE4 own C++ compiler to create this dynamic-link library from the player’s C code, but haven’t find any useful information about this.

Thing is, as I will be packing this game, I can’t assure that the player will have a C++ compiler on his machine. Therefore, I need a way to build the game with a built-in C++ compiler.
Thank you!

You won’t get anywhere with C; try Lua or Python.
I’m working on my own for the same kind project of yours, runtime scripting…

I think this is going to be your best bet.

I don’t think Unreal will ever be suitable for something like that - it’s just not what the engine was designed to do.

Hey guys, thanks for the quick answer! Thing is, I really need the player to write C code :frowning:

I’ve found this C++ compiler called “Embarcadero”. I’ve downloaded it and it’s some kind of a “portable C++ compiler” where “bcc32c.exe” open the compiler, asking for a input file. I was able to feed this compiler a “test.cpp” file and execute it through Visual Studio, calling the bcc32c.exe from “system()” function (that opens cmd and execute my command. Something like “system(C:\bin\bcc32c.exe [input_file])”). Which gave me a “test.obj”. (Now I’m studying how to make a dll from that);

I was wondering. This C++ compiler folder has the following structure:

  1. \bin(Where the bcc32c.exe executable is)
  2. \include
  3. \lib

It resembles a lot a third-party library folder structure… Do you guys think I could get this to be a UE4 module? If not, could I somehow tell Unreal to take this whole folder (the root of the C++ Compiler) and go through with the packaged game, inside it’s folders? And from my Unreal code I could get the path to this folder and execute the bcc32c.exe from cmd commands myself on a separated thread.

Thanks!

You’re going to have write permissions to the Saved folder within packaged games, so I would hazard a guess as to that you might be able to fudge the compiler in there?

Yeah…Maybe that’s a workarround. I can also manually put the compiler on the final folder, but I’m afraid it will broke the C++ hardcoded path to it when the game gets installed on users machine.

Putting aside the technical issues there, the security implications are massive. If you let someone write C/C++ code and then compile and execute that code (or worse, let some remote person do it in a multiplayer game) - you are asking for trouble. As other’s have said, I would use something like Lua (or make a visual scripting language made out of blocks so you can control exactly what can be compiled) - but just text -> compiler is HUGELY risky.

SQL Sanitization is bad enough - can you imagine being given the task of sanitizing ALL of c++!?

MalikGames wants C, not C++.
C can be compiled, it can also be interpreted, and it can even be made “safe” (by inserting read/write barriers before/after each pointer dereference)
Pointers could also be “smart” and carry size/block information, so you wouldn’t read/write outside allocated blocks of memory.

I would recommend designing the runtime system you want, first, and figure out how to interact with the Unreal engine. You’d probably need a system that ties into the Blueprint/Kismet level, rather than the low-level C/C++ API.
You would want to use mechanical/automatic tools to generate the “headers” for each game module, and the bindings necessary from your runtime to the Kismet system.
Then build an interpreted C parser where you just run the AST tree as your “script.”
Once all of that works, you can try JIT generating code out of the AST tree to speed up the code execution – but you’d still have to live with the runtime performance overhead of going through the Kismet interface.

One problem with JIT code generation is that the iOS platform doesn’t allow any kind of runtime code generation. If you want to target mobile, you’re pretty much stuck with just interpreting the AST, or maybe you can get some more performance out of turning it into a “threaded” bytecode interpreter (which, confusingly, has nothing to do with multi-threading – look it up.)

This is of course tons of work. If you really want C syntax, then that’s what you have to do. If you want runtime scriptability, LUA seems like a better choice, even though I strongly dislike it as a language. It’s super easy to integrate with any kind of host application, there are reasonable tools for it, and it underpins pretty successful game platforms like … all of Roblox.

Hey, thanks for the heads up! Fortunately, the game is singleplayer only! So I don’t really see how this would be a risk in our game. Honestly, if the player wants to write a malicious C code and run, it will be affecting his machine, so it’s his fault…And if somehow he modifies the game on his end, it will all be local, so all good!

Thank you so much for the super detailed reply jwatte! Really appreciate it!

So yeah, C is a MUST here. No scripiting language, no LUA, no Python or some other language should be considered, unfortunately:(

As I state from my last reply, we shouldn’t be concerned with making it “safe” to run the player’s C code, as it’s not a multiplayer game. Also, any malicious code will affect his own machine and any changes to the game will be local - All good!

And yes, we are considering how we are going to integrate everything to the Blueprint/Kismet system. For now, I’m working on making it work on pure C++, without all the overhead of Unreal’s compilation. On the next post I will show what I have done so far. We are aware of JIT code generation, as we’re going to “insert” the headers and also some functions so we can integrate everything with our game. But this is the next step.

Lastly, the game is windows only, so no mobile :slight_smile:

So, to keep things clear here, I’m going to show you guys, and for anyone interested in the future, what I’ve got right now:

I’ve managed to find a “portable” C++ compiler called MinGW through the “portableapps.com”. Here’s the link: C/C++ compiler portable | PortableApps.com . As I researched, portable apps offers a program that takes a installer and remove it’s folder so we can use the program without any installation. The download link on the forum I quoted may be kind shady, but I ran a antivirus and scans and seems all good. The problem with this “portable” C++ compiler is that I have to add the “\bin” folder to the PATH environment variables. However, this should be fairly easy to do on player’s machine, as we can set it on runtime.

Next, I’ve created a pure C++ code to test what I’m aiming for here. Here’s the code:


#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <fstream>

using namespace std;

typedef int (*importFunction) (int);

int main(){
    //Writing library(This is be done by the student)
    //Header
    ofstream Header ( "tmp.h" );
    Header << "#ifndef tmp_h__
#define tmp_h__
 extern int MyFunc(int x)
#endif
";
    Header.close();

    //Implementation
    ofstream Impl ( "tmp.c" );
    Impl << "#include <stdio.h>

int MyFunc(int x){return x * 4;}
";
    Impl.close();

    //Compiling and creating the shared library through cmd(EnvironmentVariable must be set to use "gcc")
    system("gcc -c -Wall -fpic C:/Users/Labtime/tmp.c");
    system("gcc -shared -o tmp.dll C:/Users/Labtime/tmp.o");

    //Loading library
    HINSTANCE fLib = LoadLibraryW(L"C:\\Users\\Labtime\	mp.dll");
    if(fLib){
        cout << "Loaded Library
";
        //Linking function and testing
        importFunction testFunc; 
        testFunc = (importFunction)GetProcAddress(fLib,"MyFunc");
        if(testFunc){
            cout <<"Found function, executing:
";
            cout << "Result:" << testFunc(2);
        }
    }
    return 0;
}

As you can see, this is what I’m aiming for right now. On the first couple of lines I’ve created two files (tmp.c and tmp.h) to create a shared library out of it. On our game, the player will be the one who will write the “tmp.c” and we are working on creating the “tmp.h” at runtime by analizing the “tmp.c” from user’s input - This will be a kind difficult task to do, I believe, but we will get there. After that, I compile “tmp.c” and create a shared library from those “tmp.o” using our “portable” C++ compiler, running commands on CMD through the “system()” function. Lastly, we load the created library and link the functions so we can use it on our C++ code (as you can see in my example).

So how do we intend to run the player’s code? We are going to link the C code main() function to one of your functions, like “m_main() = (importFunction)GetProcAddress(fLib,“main”)” and then when the player clicks on a button like “Execute code”. We are going to call the “m_main()” we just linked and read the output log to collect the informations.

Of course, we need to make it all work inside Unreal, maybe using some Unreal functions like “FPlatformProcess::GetDllHandle” and “FPlatformProcess::GetDllExport”.