Expedite progress – think in the future, become estranged from the now.
2016-03-15
03:35:05
Use Premake (5) and Start Winning
The Setup
Here we are assuming that you have the following systems and you want a competent and easy-to-use cross-platform and native-centric compiling solution:
- Mac OS 10.6.8
- XCode 4.2
- Windows 7
- Visual Studio 2013
- Linux
- GNU Make w/ GCC 4
The Problem
In my experience, many cross-platform build solutions feel very clunky (CMake) or use a specific IDE to provide cross-platform support (Code::Blocks, GNU Make w/ GCC on Windows with many shivs).
In the case of the former, I prefer highly portable and very small programs that are easy to deploy to any environment – CMake does not fulfill this. In the case of the latter, I prefer to use the tools intended for a given platform, as it is a headache not only for oneself to set up all the specific requirements, but it is cumbersome to those who wish to simply build your project.
Towards this end, we are searching for a solution that focuses on using native tools, is portable, and easy to use.
The answer that I’ve found is Premake – version 5 to be exact.
The Solution: Premake
What is Premake
Premake is…
Why Premake
- Single lua script
- Portable binary with built-in lua
Example premake5.lua
Let’s say you have an SDL2 project that uses OpenGL and you want the following directory structure:
- Project/
- src/
- build/
src is where the project source code lies, and build is where you want the project files to end up. After compilation, you want the binary to be placed in the project root.
To create a script compatible with generating project files for Linux, Windows, and Mac OS X, you would use a script similar to the following:
solution "Project"
configurations { "Debug", "Release" }
location ("build/" .. _ACTION)
project "Project"
kind "WindowedApp"
language "C++"
targetdir "./"
location ("build" .. _ACTION)
files { "src/**.hpp", "src/**.cpp" }
configuration { "linux" }
buildoptions { "-I/usr/include/SDL2/" }
links { "SDL2", "GLEW", "GL", "pthread" }
configuration "windows"
links { "glew32", "opengl32", "SDL2", "SDL2main", "ws2_32" }
configuration "macosx"
syslibdirs { "/Library/Frameworks/" }
libdirs { "/Library/Frameworks/" }
links { "SDL2.framework", "OpenGL.framework" }
includedirs { "/Library/Frameworks/SDL2.framework/Headers/" }
sysincludedirs { "/Library/Frameworks/SDL2.framework/Headers/" }
The Linux Build
On Linux, you have multiple options, but here we assume GNU make is our target project file:
premake5 gmake
Afterwards, you can simply enter the build/gmake directory and run make
:
cd build/gmake && make && cd ../..
Now you can execute your program:
./Project
The Windows Build
On Windows you also have multiple possible IDE project files, but here we assume Visual Studio 2013:
premake5 vs2013
Now you can open your project file generated in build/vs2013/ and build/run it.
From The Command-line: vsbuild
However, if you’re like me, you might prefer being able to use the terminal to build and run your project as well.
My solution was to create two scripts to be executed: a shell script that executes a batch file.
The wrapper shell script is simple enough:
#!/bin/bash
cmd /c C:/Users/kts/.local/bin/vsbuild.bat "$@"
The batch is also fairly simple, but you may have to adjust it if you’re not using Visual Studio 2013:
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
msbuild %*
Now instead of opening the project file with VS, you can simply navigate to the
build/vs2013 directory and run vsbuild
:
cd build/vs2013 && vsbuild && cd …/…
You can then execute your program: ./Project.exe
Note: There are some issues with how stdout is handled from within mintty/cygwin – output was only flushed when the program finished.
- Compile:
vsbuild
- Clean:
vsbuild /t:clean
The Mac Build
Mac OS X also has multiple options, but here we are using XCode4 due to an older laptop:
premake5 xcode4
You can then open your project file with XCode and do the normal build/run.
Or use the command-line: cd build/xcode4 && xcodebuild && cd …/…
You can then run your program:
./Project
Note: There are some obvious problems with not creating an application bundle, so you likely want to clear the targetdir project directive.
- Compile:
xcodebuild
- Clean:
xcodebuild clean