A new version is available!

Premake 4.0 is now available at our new website.

This page describes Premake 3.7, the last release in the 3.x series.

Projects

The Premake project is the top-level object, synonymous with a Visual Studio solution. It provides the global configuration information and groups together the binary outputs that comprise the final result.

Here is a sample project script:

project.name = "MyProject"

dopackage("MainApp")
dopackage("MyLibrary")

First, realize that this script is really a script, not a static configuration file. That means that you can use conditionals, looping, the works. For more information, see the Lua Reference Manual.

The project name is used as the file name for the generated makefile, solution, etc., so avoid spaces and other special characters that might choke someone’s tools. Underscores seem to be fine everywhere. The script above would generate MyProject.sln for Visual Studio 2003, MyProject.dsw for Visual Studio 6, and Makefile for GNU make.

Next comes the list of packages that comprise the project. The function dopackage() acts like C’s #include command or Lua’s dofile() function, but it has some additional logic to locate the premake file in the target directory. I usually like to put the source code for each binary into its own subdirectory, which in this example is MainApp and MyLibrary. I also like to create a separate premake.lua script for each binary, and place it in the same directory as the source code, which is what I have done here. This example will look for package scripts named MainApp/premake.lua and MyLibrary/premake.lua. As a fallback it will also look for MainApp.lua and MyLibrary.lua.

While I’m on the subject, I should point out that you can use Lua’s dofile() function if you want to include code without creating a new package.

Inline Packages

Putting your packages into separate scripts isn’t the right solution for every project. If you like, you can also define your packages directly inline.

project.name = "MyProject"

package = newpackage()
package.name = "MainApp"
-- (configure package here)

package = newpackage()
package.name = "MyLibrary"
-- (configure package here)

Project Path

Sometimes, you might like to put the project’s premake.lua file in one place, but generate the makefile or solution somewhere else. In that case you can specify the project path, as shown below.

project.name = "MyProject"
project.path = "../build_files"

dopackage("MainApp")
dopackage("MyLibrary")

Note that the forward slash is always used as a path separator in Premake scripts. Premake will take care of translating the paths as appropriate for the target system.

Output Paths

You specify a global location for “binaries” (executables and shared libraries) and “libraries” (static libraries) at the project level.

project.name = "MyProject"
project.bindir = "bin"
project.libdir = "lib"

dopackage("MyApp")
dopackage("MyLibrary")

You can also set the path per configuration, like this:

project.name = "MyProject"

project.config["Debug"].bindir   = "bin/debug"
project.config["Release"].bindir = "bin/release"

dopackage("MyApp")
dopackage("MyLibrary")

Keep reading for more information on build configurations.

Custom Configurations

Premake defines “Debug” and “Release” configurations for every project by default. However, you can define your own set like this:

project.name = "MyProject"

project.configs = { "Debug", "ReleaseWithSymbols", "Release" }

dopackage("MyApp")
dopackage("MyLibrary")

The packages can then refer to these configurations by name. See the section on packages for more details.

Conditional Logic

I mentioned earlier that Premake scripts are really scripts, not just configuration files. Here is an example that uses Premake’s built-in OS variable to choose which packages to include in the build.

project.name = "MyProject"

dopackage("MyApp")

if (OS == "windows") then
  dopackage("WindowsLibrary")
elseif (OS == "macosx") then
  dopackage("MacLibrary")
else
  dopackage("PosixLibrary")
end

Or, you can use the OS names as variables directly:

project.name = "MyProject"

dopackage("MyApp")

if (windows) then
  dopackage("WindowsLibrary")
elseif (macosx) then
  dopackage("MacLibrary")
else
  dopackage("PosixLibrary")
end

Later on I’ll discuss how to add new commands to your project, which users can trigger with command-line arguments.