What? Are you Crazy?
Scripting languages are a trendy thing. Take the game Morrowind by Bethesda Softworks, for example. This game runs a lot of scripts in a custom language: tons of scripts compiled in a pseudo bytecode form before to be run inside the game. Same for the game Age of Mythology by Ensemble Studios: it uses a custom script language for the computer AI programming. This is thus a critical part in several programs, and program's speed depends in a part on them.
I love speed. I love speedy programs, well-programmed applications. I'm still looking for speed, and I hope, like many of you. I then thought, as I was really inspired: why not embed a C++ compiler to use C++ as a compiled "scripting" language?
I thought about the well-known GNU GCC project. If you don't know it, it is an open-source C/C++/Java/others compiler, aiming primarily Linux platforms. The major advantage of this set of developer tools is that it is free. I thought I would be able to compile the GCC sources in a pretty Windows DLL; that revealed to be pretty impossible. I found out the MinGW project. This was pretty good: compiled compiler + Windows and standard headers + libraries in a relatively small package (15MB).
Surely, a 15MB package is actually big to some projects. But this article aims primarily big projects such as games. And, if you keep only the needed files (headers + libraries + c++ compiler) from the MinGW package, you will get easily to less than 4MB (compressed).
And, embedding MinGW is actually not necessary if you don't want to give end-user the ability to modify or create new scripts.
Actually Gecko brings you the fastest "scripting" language on the world! See the The Great Computer Language Shootout, and see how fast is gcc (even g++) compared to some well-known languages. Besides, using native machine code (compiled C++) allows having a very low memory usage, compared to some other scripting languages which can require an interpreter, or a bytecode interpreter. Furthermore, thanks to MinGW supplied libraries and headers, you have infinite possibilities: use windows.h functions, math.h functions, IO functions...
Another thing: you may be wondering: why Gecko? Gecko stands for "Gnu Embedded C++ KOmpiler" (I was really, really inspired this day :)). Gecko produces ECK files. ECK stands for "Embedded C++, Kompiled". ECK files are in fact renamed DLL files, as you may have guessed.
But What is Gecko?
The Gecko thing consists actually of several things:
- The idea of an embedded C++ compiler for scripting facility,
- The GeckoSetup tool which generates a lot a code for your convenience (GeckoSetup relies on PXPerl namespace).
- The
CGecko
class. Sample use:
CGecko gecko;
if (!gecko.IsEckUpToDate("test"))
gecko.Compile("test");
if (gecko.Load("test"))
{
if (gecko.RunThreaded())
{
printf("[Press any key to abort]");
getchar();
gecko.AbortThread();
}
}
Visually
The CGecko class - Public Methods
The CGecko
class relies on the CRedirect
class to redirect standard IO while running MinGW (class found on codeproject -- great thanks to his author).
Read carefully each comment before using functions.
class CGecko : protected CRedirect
{
public:
CGecko(void);
~CGecko(void);
void SetMinGWDir(LPCSTR szDir);
void SetGeckoDir(LPCSTR szDir);
bool eckIsUpToDate(LPCSTR szName);
bool eckExists(LPCSTR szName);
bool eckCompile(LPCSTR szName);
virtual void OnCommandStart(LPCSTR lpszCmdLine) {};
virtual void OnCommandSTDOUT(LPCSTR lpszOutput) {};
virtual void OnCommandSTDERR(LPCSTR lpszOutput) {};
virtual void OnCommandEnd(bool bSuccessful) {};
bool eckLoad(LPCSTR szName);
void eckUnload(void);
int eckRun(WPARAM wParam=0, LPARAM lParam=0);
int eckAbort(WPARAM wParam=0, LPARAM lParam=0);
int eckSendMessage(UINT nMsg, WPARAM wParam=0, LPARAM lParam=0);
bool eckRunThreaded(WPARAM wParam=0, LPARAM lParam=0,
int nPriority=THREAD_PRIORITY_NORMAL);
bool eckIsThreadRunning(void);
HANDLE GetThreadHandle(void);
bool eckAbortThread(DWORD dwTimeout=5000, bool bAllowKill=false);
};
Security, Reponsibility etc.
The only problem is: providing a C++ compiler and low-level functions to non-experienced users can be dangerous. If you integrate Gecko and embed MinGW, you must thus engage end-user responsibility and warn him about risks for his computer if he does whatsoever. This is why I put a big disclaimer: I won't be responsible for any damage caused by a mis-usage of the Gecko component, or by a script.
You can however choose not to embed MinGW: you will then be able to run ECK files but not to compile. That eliminates the problem.
Setup
- Create a file named gecko.natives.h in your project directory. Declare in it the functions you would like to access from within your scripts, according to the following model:
GECKO_NATIVE void GECKO_NATIVE_CALL SetPlayerHealth(int nNewHealth);
GECKO_NATIVE void GECKO_NATIVE_CALL AlertDamage(int nDamage);
GECKO_NATIVE void GECKO_NATIVE_CALL AppendOutput(LPCSTR szText);
GECKO_NATIVE int GECKO_NATIVE_CALL foo(int i);
GECKO_NATIVE const char* GECKO_NATIVE_CALL bar(LPCSTR a, float d);
...
Only C-style functions are supported for now. No classes here. Put the functions bodies in any .cpp file of your project, taking care to include MyGecko.h before: #include "MyGecko.h"
GECKO_NATIVE void GECKO_NATIVE_CALL SetPlayerHealth(int nNewHealth)
{
...
}
GECKO_NATIVE void GECKO_NATIVE_CALL AlertDamage(int nDamage)
{
...
}
...
- Run GeckoSetup.exe. Fill in the fields, click Go! and that's ok.
- Add MyGecko.cpp and MyGecko.h to your project (these files have been copied in your project directory). Wherever you need to use the
CGecko
class, include the file MyGecko.h.
That's all :)
About MinGW
Necessary Files
- In the doc directory, keep only the MinGW directory.
- In the lib directory, delete the gcc-lib sub-directory.
With these efforts you get to only 3.25 MB (zip-compressed).
Licensing Terms
URL - http://www.mingw.org/licensing.shtml:
Basic MinGW runtime MinGW base runtime package is uncopyrighted and placed in the public domain. This basically means that you can do what you want with the code.
w32api You are free to use, modify and copy this package. No restrictions are imposed on programs or object files compiled with this library. You may not restrict the the usage of this library. You may distribute this library as part of another package or as a modified package if and only if you do not restrict the usage of the portions consisting of this (optionally modified) library. If distributed as a modified package then this file must be included.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
MinGW profiling code MinGW profiling code is distributed under the GNU General Public License.
The development tools such as GCC, GDB, GNU Make, etc all covered by GNU General Public License.
Here is the relevant part of the GNU General Public License:
"1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program."
"3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)"
In a nutshell
If you want to embed the partial MinGW package in a noncommercial product: "Accompany it with the information you received as to the offer to distribute corresponding source code."
You must provide the source for the following packages if you plan to embed the partial MinGW package in a commercial product:
- gcc-core-3.3.1-20030804-1-src.tar.gz
- gcc-g++-3.3.1-20030804-1-src.tar.gz
- binutils-2.14.90-20030807-1-src.tar.gz
These packages can be found at: http://www.mingw.org/download.shtml
History
- 29 August 2003 : First release.