Premake         Setting up Ogre projects using premake

I am coming to you today to tell you about a little something called 'premake'. Premake is a program which parses a simple lua file, and generates project files and Makefiles for several popular IDEs.

This is how it works.

First, lets get premake: http://premake.sourceforge.net/download

I trust you know how to install software, if not, you should learn how before coding your own :-)

Now that you are armed with premake, lets make the premake.lua file. But first! I'll show you my favorite directory structure:

Doxyfile  - in ur headers, makin ur documentions!
    bin       - for ur bins 
    doc       - where the docs is at
    include   - headers (.h and .hpp)
    media     - fun things like .mesh, materials and textures!
    premake.lua - our best friend
    src       - sources (.c and .cpp)


So now that we know the way to lay out our project, lets start with premake! Here is a template premake.lua:

project.name = "MyProject" 
 
 project.config["Debug"].bindir = "bin/debug"
 project.config["Release"].bindir = "bin/release"
 
 -- package config
 package = newpackage()
 package.name = "MyProgam"
 package.kind = "exe"
 package.language = "c++"
 package.config["Debug"].objdir = "obj/debug"
 package.config["Release"].objdir = "obj/release"
 
 -- package files
 package.files = {
     matchrecursive( "src/*.c", "src/*.cpp", "include/*.h", "include/*.hpp" ),
 }
 
 -- defines
 if windows then
     package.defines = { "WIN32", "_WIN32", "_WINDOWS" }
 elseif linux then
     package.defines = { "LINUX" }
 elseif macosx then
     package.defines = { "MACOSX" }
 end
 
 package.config.Debug.defines = { "DEBUG", "_DEBUG", "_STLP_DEBUG" }
 package.config.Release.defines = { "NDEBUG", "_NDEBUG" }
 
 -- include paths
 if windows then
     package.includepaths = {
         "include",
         "Your/Ogre/Dir",
     }
 elseif linux then
     package.includepaths = {
         "include",
         "/usr/include/OGRE/",
     }
 elseif macosx then
     package.includepaths = {
         "include",
     }
 end
  
 -- library paths
 if windows then
     package.libpaths = {
         "Ogre/Lib/Dir",
     }
     package.config.Debug.libpaths = {
     }
     package.config.Release.libpaths = {
     }
 elseif linux then
     package.libpaths = {
         "/usr/lib/OGRE/",
     }
     package.config.Debug.libpaths = {
     }
     package.config.Release.libpaths = {
     }
 elseif macosx then
     -- See the bottom of the file for the mac
     -- way of doing this.
     package.libpaths = {
     }
     package.config.Debug.libpaths = {
     }
     package.config.Release.libpaths = { 
     }
 end
 
 -- linking libs
 if windows then
     package.links = {
     }
     package.config.Debug.links = {
         "OgreMain_d",
     }
     package.config.Release.links = {
         "OgreMain",
     }
 elseif linux then
     -- Whatever is here gets passed to ld like -lTheNameIPut
     package.links = {
         "OgreMain",
     }
     package.config.Debug.links = {
     }
     package.config.Release.links = {
     }
 elseif macosx then
     -- Again, see the bottom of the file for the
     -- mac way of doing this.
     package.links = {
     }
     package.config.Debug.links = {
     }
     package.config.Release.links = {
     }
 end
 
 -- Documentate our code when we compile Release mode.
 -- post build commands
 if windows then
     package.config["Release"].postbuildcommands = { "doxygen Doxyfile"}
 elseif linux then
     package.config["Release"].postbuildcommands = { "doxygen Doxyfile"}
 elseif macosx then
     package.config["Release"].postbuildcommands = { "doxygen Doxyfile"}
 end
 
 -- platform specific compiler options
 -- mac lovin - they do this -framework thing, hence the no "OgreMain" under Mac's linking libs
 if macosx then
     package.buildoptions = { "-framework Ogre" }
 end

I think that it is fairly self explanitory (I know no lua, I just read example premakes ;p). I've tried to highlight most everything important. You can leave out the checks for a certain OS if you don't care about it. Almost every option has a "base" option and then a specific one for the build mode, Debug or Release (you can add custom modes). You can see in the windows one we link the debug lib for debug and the release lib for release. Fun.

'Windows Users: Don't put your funny \ slashes in as paths. Premake uses standard paths with / slashes and converts them. Also remember case sensitivity, I know your not affected, but consider your POSIX friends.

Remember, the full manual is at premake.sf.net, check it out if you wan't to know all the syntax. Because its not in my example doesn't mean you can't do it! Be smart, read the manual (its very short and well written) :-)

Now that we have this file, we want out project files! Observe:

premake --target ''targetname''

Where targets can be:

vs2005    Visual Studio 2005 (or Express)
 vs2003    Visual Studio 2003
 vs2002    Visual Studio 2002
 vs6    Visual Studio 6
 gnu    GNU make
 sharpdev    SharpDevelop
 monodev    MonoDevelop
 cb-gcc    Code::Blocks with GCC

You will now find you have a very sexy project file waiting for you. If you add new files to your project just run the premake command again to regenerate, it takes a fraction of a second.

That should be bug free...if I have a silly syntax error please inform me. kcbanner on freenode, or kcbanner at gmail dot com. All feedback appreciated, enjoy :-D