Introduction
PEP is a tiny C++ crossplatform framework generator to give your C++ workflow some speed!
It will output some basic classes, and you're ready to go!
This article could be interesting for some of you coders out there.
WARNING : I'm Dutch, so enjoy the language in this article :)
Scenario
Do you remember those 'hey let's write a little non-IDE C/C++ for this idea' feelings?
Aren't these feelings beautiful? :)
OK, so you put on your favourite Drum'N'Bass CD (or music of your taste) and you start with enthusiasm.
But soon, these feelings get ruined by writing crossplatform Makefiles, singletons, directories, configuring...instead of coding the real deal! :(
Since I got tired of these 'creativity killing tasks', I started writing this so now we can start coding our ideas right away!
It all boils down to this little shellscript cmd:
kn0r pep # ./pep
Usage: pep <project name> <target directory>
Requirements
Just a compiler, svn installed, and a Unix environment will do.
(Tested on GNU gcc/DevCpp/Mingw32/Cygwin compilers)
Features
- shellscript: The PEP shellscript automatically renames all classes of the PEP framework to your projectname
- .ini parser: Easily read/write .ini files and access for in-application use
- framework: You'll get a basic working crossplatform skeleton with a singleton to start
- assertions: At runtime you will hunt down bugs more easily with the '
_assert()
' function - outputclass: Comfortable debugging variables with the '
_()
' & '_say()
' function, also gets logged to 'log.txt' - memoryleaks: Free memoryleaks! (joking) if compilerflag -DDEBUG flag is enabled, you'll get nice information on the memory leaks of your app
- Makefiles templates for different platforms (also an
DevCpp
projectfile)
Using the Code
Ok, get the zip, and let's do the following at your Linux prompt:
kn0r pep # ./pep myproject myproject
[x] creating directory
[x] getting hottest source in town!
A myproject
A myproject/COMPILING
A myproject/src
A myproject/src/pep
A myproject/src/pep/ini.cpp
A myproject/src/pep/output.cpp
A myproject/src/pep/ini.h
A myproject/src/pep/pep.cpp
A myproject/src/pep/global.h
A myproject/src/pep/output.h
A myproject/src/pep/pep.h
A myproject/src/main.cpp
A myproject/src/debug.cpp
A myproject/bin
A myproject/bin/pep.ini
A myproject/bin/data
A myproject/obj
A myproject/prj
A myproject/prj/Makefile.dreamcast
A myproject/prj/pep-DevCpp.dev
A myproject/prj/configure
A myproject/prj/configure.ac
A myproject/prj/Makefile.inc
A myproject/prj/Makefile.macosx
A myproject/prj/Makefile.windows
A myproject/prj/Makefile.linux
A myproject/README
Exported revision 7.
[x] Unzipping module.
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] Preparing files 'myproject'
[x] install completed.
OK.....you must probably think "what was that?"
Well, very simple, the sourcefiles are extracted and files are renamed to 'myproject'.
Let's take a look at our directory 'myproject', which has just been created:
|-- INSTALL <- documentation about how to compile
|-- README <- this document
|-- bin <- the binaries will be put here
| |-- data <- a directory where application files can be located
| |-- [log.txt] <- debug information will be stored here
| |-- [myproject] <- linux binary
| |-- [myproject.bin] <- dreamcast binary
| `-- [myproject.exe] <- windows binary
|-- obj <- here the .o files are stored
|-- prj
| |-- Makefile.dreamcast
| |-- Makefile.inc <- here the .cpp can be specified for the
GNU style compilers
| |-- Makefile.linux
| |-- Makefile.macosx
| |-- Makefile.windows
| |-- configure
| |-- configure.ac <- starting point for autotools
| `-- myproject-DevCpp.dev <- devcpp project file
`-- src
|-- debug.cpp <- here the memory leak checking is done
|-- main.cpp
`-- myproject
|-- global.h
|-- output.cpp <- class for logging and outputting variables
|-- output.h
|-- ini.h <- class for read/writing ini files
|-- ini.cpp
|-- myproject.cpp
`-- myproject.h <- the 'core' engine, a basic singleton
btw. files between the [ ] are generated after the first compile
Now..let's look at our main
function:
int main(){
string str;
int done = 1;
myproject *p = myproject::get();
_say( "Welcome to '%s'", p->config->GetValue( "settings", "appname" ).c_str() );
_( TRACE("outputting some debug info%i"), done );
_( ERROR("triggering an error! %i"), done );
_( WARNING("triggering a warning %i"), done );
_( FATAL("triggering some fatal error %a, immediate exit!"), done );
_assert( p != 0, "p must not be null" );
_assert( p == 0, "p must be null" );
p->config->SetValueI( "settings", "somesetting", 1234 );
p->config->WriteFile();
delete p;
_say("all done", 0);
return 1;
}
Basically what happens is: first the myproject-engine object is created (through a singleton), then we send some data to our outputclass. After that we do some assertions, which are handy developer tools. Finally we write some stuff to the .ini file and we clean up.
You must think... what's with the _( ) function? Well we do this in order to display extra information for debugging purposes. Just check out this output :
kn0r myproject # cd prj/
kn0r prj # make -f Makefile.linux all
c++ -DDEBUG -DLOG -c ../src/main.cpp -o ../obj/main.o -DDEBUG -DLOG
c++ -DDEBUG -DLOG -c ../src/myproject/output.cpp -o ../obj/output.o -DDEBUG -DLOG
c++ -DDEBUG -DLOG -c ../src/myproject/myproject.cpp -o ../obj/myproject.o -DDEBUG -DLOG
c++ -DDEBUG -DLOG -c ../src/myproject/ini.cpp -o ../obj/ini.o -DDEBUG -DLOG
c++ -DDEBUG -DLOG -o ../bin/myproject
../obj/main.o ../obj/output.o ../obj/myproject.o ../obj/ini.o -lm
kn0r prj # cd ../bin
kn0r bin # ./myproject
myproject> Welcome to 'myApplication v1.0'
myproject> [TRACE@../src/main.cpp:30] outputting some debug info1
myproject> [ERROR@../src/main.cpp:31] triggering an error! 1
myproject> [WARNING@../src/main.cpp:32] triggering a warning 1
myproject> [FATAL@../src/main.cpp:33] triggering
some fatal error 0x0.0000000000001p-1022, immediate exit!
myproject> [ASSERTION@../src/main.cpp:36] p must be null
myproject> delete myproject!
myproject> all done
0xb7f40e54
*** WARNING: GCC 3 or later is detected
delete: freed 0x8058048 (size 893, 0 bytes still allocated)
Background
Every time when I started a project aimed at different platforms, I found myself writing the same 'from scratch'-stuff again and again.
In many cases, it was wise to stay away from massive GUI IDEs.
I found out that when I started developing with commandline GCC, it's more easy to port that Windows than vice versa.
But...commandline stuff has its downsides...writing Makefiles is very laborious, even with Makefile-generators.
I was irritated and annoyed of writing the same stuff over and over again...so I decided to write this basic framework generator to keep it SIMPLE.
Credits
- Tim Gerritsen (gloomy)
- Leon van Kammen (sqz)
- IZI-Services
- Wu Yongwei for his wonderful 'nvwa' C++ utilities
- Adam Clauss & Shane Hill - for their great crossplatform ini file reader/writer
History
- [20-11-2008] v1.0 first sketch
- [23-04-2009] v1.1 added inifiles and fixed minor bugs