Thursday, May 30, 2013

Google Summer of Code: Simple DirectMedia Layer Meta-build System

Greetings,

Besides the rather long title, I'm here to post the introduction of my Google Summer of Code (GSoC) Simple DirectMedia Layer (SDL) meta-build system project. This blog exists to display my efforts on GSoC projects, my first being the SDL meta-build system. I'll briefly go over the project and, in subsequent days/weeks/months, I will continue to post my efforts as I construct a meta-build system.

Overview of Meta-Build Systems

First of all, what is a meta-build system? Imagine creating a new project (regardless of the language, but we can specifically reference C for the sake of SDL) and you're working mainly with one platform...say GNU/Linux on a 64-bit architecture. You're using makefiles with gcc, knowing various aspects of compiling 64-bit C applications using gcc (such as a long being 8 bytes). But eventually, you decide that you want your application to be buildable on multiple platforms, say Win64. So you have a few options: you could create a Visual Studio project to house your project (recreating the efforts of your earlier makefiles), or you could install MinGW or Cygwin and try to hack your earlier makefiles into working on Windows in those stripped environments, to name a few. Nevertheless, a very annoying pattern arises: every platform, architecture, and even compiler that you want to target will require unique parameters and build settings. Many platform-based build systems allow for multiple configurations to handle different compilers and, with a little work, also different architectures.

The problem is targeting many platforms without having to continue redoing the build systems for each one. This can be done in a decent manner if you are using the same Integrated Development Environment across each platform (such as Eclipse, which is platform-independent). Configuring the project files to properly build across many platforms can be a real pain, though. Beyond that, many people who may use your project likely prefer their own setup (ie, some people will prefer using Visual Studio on windows to trying makefiles with Cygwin or MinGW).

What option do we have then?

The answer is a meta-build system. It is thusly named because it builds/generators build files. Generating build files seems like a neat concept, but we need to be critical the build system is adequate for what we want. It has to satisfy various criteria:

  1. It must be platform-independent, at least to each platform our application is going to target
  2. It must be easily extensible, incase we need to implement per-project build options (such as searching for dependencies)
  3. Ideally, it should be portable so it can be packaged with the project's source code on some Version Control System (like SVN or GIT)
I won't go into depth about various meta-build systems, but I am going to highlight premake here. From my experience, premake massively satisfies the above conditions. It's platform-independent (source code is available), it's extensible (uses lua to create build generation scripts), and it's portable (doesn't require any additional dependencies to support lua) and works out of the box. It can also target most major desired platforms.

Premake has its cons, though this can and will be mitigated throughout the project. There are other meta-build systems available, but I feel as though premake is the best option for SDL (especially given its size and magnitude), plus it's proved to be a dependable option. It's the system of choice for SDL.

SDL and Premake

As mentioned, I am deciding to use premake as the meta-build system for SDL. SDL currently maintains various Visual Studio projects for building on windows, an XCode project for MacOSX, and cmake files for other build targets. There is a need to consolidate all of the different build targets into a single system, to increase maintainability (change one to change all, versus having to actually go and change all), portability (cmake requires installation prior to use, making it very inconvenient), and flexibility (again, lua). Integrating a lightweight meta-build system was the answer, so premake was the choice.

The goal of this project is to create a single premake setup which slowly replaces each of the targeted platforms of SDL, possibly with the chance of adding more platforms per-choice of the user. SDL currently targets a plethora of platforms, including Linux 32/64, Windows using MSVC, Windows using Cygwin or MinGW, MacOSX and iOS, and android, to name some. As a result, supporting each individual platform is a goal in itself, and will require overcoming one of premake's cons: searching for dependencies.

In the coming weeks, I hope to post more regarding the dependencies of each of SDL's build targets, thus categorizing and organizing what the replacement premake lua script will need to be able to support. Additional research will need to be taken into how the Visual Studio and XCode projects are setup, plus what sort of dependencies the CMake scripts look for and how that can be replaced by lua with premake.

That's all I have for now. Feel free to comment or post any questions on the SDL Developer Mailing List, or as a comment on this blog.

Cheers.

2 comments:

  1. Why not just evolve existing cmake buildsystem? Currently cmake project implemented on SDL2 itself, it's pretty stable for now. All that left is integrate SDL_* libraries (and don't break anything else).

    With cmake you can generate every project files (VS2012 and Xcode included). No need to manually rewrite each project-file - issue one cmake command and all of them will be updated.

    I think that using buildsystem as external dependency is good point - you can easly update it for new feature (like a Visual Studio 2012 support). Bundled buildsystem can may lead to some troubles in future - you can stuck in particular version and cannot port it to new without rewriting whole work.

    ReplyDelete
    Replies
    1. The CMake configuration in SDL is well done, I would agree with that. In fact, my project may not even touch the *nix side of things. The primary focus right now is making it easier to maintain the Visual Studio and XCode projects, which have to be manually handled right now. In the best case scenario, there could only be three build systems left to handle: CMake, Premake, and Android. I more or less could likely build a generation script for android without too much hassle, so even that may be off the table.

      The idea is the people using CMake prefer it and there's really no reason to stop using something that's already stable. Now, the reason against using CMake for everything else is because it's simply not convenient. It's especially convenient for *nix users and, conversely, it's especially inconvenient for everyone else. Premake's portability makes it convenient for anyone, though not a very suitable replacement to CMake specifically for *nix users who already have it.

      Your last point is valid, though Premake is very flexible in how it does things. From what I've seen, it maintains backward compatibility. My current approach of the project is using Premake in very unintentional ways and, yes, it leads to incompatibilities in Premake 5 (currently using 4). I plan on mitigating this by generating the LUA scripts instead of dynamically working with the elements in premake, leading to full compatibility. I can even go so far as slightly altering the generated LUA scripts based on the target of premake, offering much more flexibility than is even needed.

      I appreciate your reply. Thank you!

      Delete