Converting a gyp library to premake

by Dimitar Trendafilov January. 21, 13 01 Comment

Here at Coherent Labs, we have a large and cross-platform project. The build system is crucial for a project like ours – it pretty much defines the programmer workflow and iteration time. How we chose our build system deserves a blog post of its own. But at the end – we chose premake – it is very high level, generates almost perfect Visual Studio project files and you have a complete programming language for describing how to build your project.

The idea for this post was to show how to convert a classic C library using autotools (./configure && make) to a premake-based project. But half of the post would be a repetition of Converting a C library to gyp, because the most complex part is generating all the config files for the current platform. So I decided to take node-lame, a node-gyp based project and convert it to premake.

 

Premake projects are written in plain Lua, typically in a file called premake4.lua. The “Hello World” project file looks like:

 

Next step is to include the right config.h file. To make our lives simpler we are going to use “token replacement”, a  relatively new feature, available in the premake-dev branch. Token replacement allows
the declarative syntax of premake to fallback to imperative functions. So we write a global function and place  a call to it inside %{} in the include directory specification. This function will be called for each concrete configuration of the project and the %{} is replaced with the result.
 
libmpg123 has several functions written in assembly for x64 platforms, but they cannot be used on Windows. Here again we use Lua to avoid duplicating the lists of defines and files:
 
The next step is to define the dependencies between the projects. We include the projects in the solution and  for each project declare that it links with its dependencies. This will ensure that all projects will be built in the correct order and the correct outputs will be used for linking. Unfortunately the include paths dependencies are not solved so easily. bindings  depends on mpg123 and includes mpg123.h, so it needs deps/mpg123/src/libmpg123 as include path. But mpg123.h needs config.h, so bindings needs mpg123‘s config directory as include path, too. So each project has to know not only the directories of its dependencies, but their include directories also.
This is a point where gyp shines – ‘direct_dependent_settings’ allows you to add include and library paths to dependent projects. Premake has a planned feature – “usage projects” that will provide similar functionality.
As I said node-lame uses node-gyp, which takes care of installing the correct headers and libraries of node.js for your platform. With enough scripting in Lua we can achieve the same effect, but, for simplicity, we are going to add an option to premake4, specifying the location of the node.js source tree with built libraries.

 

At last lets see where the high abstraction of premake makes it so good:
This section sets linking against the static run-time and enables debug symbols on Windows and the architecture for Xcode.
 
And the same for premake (but on all platforms)

You may ask why bother converting third party libraries to your own build system. Well – to be sure they are build with the correct (same) settings as your own project and to avoid building all variants and committing them under source control – here we already have 18 combinations  of configurations and platforms – and no one wants to maintain that many binaries.

 

Follow Dimitar on Twitter: @DimitarNT

Social Shares

1 Comments

Leave Reply

Leave a Comment

  • malkia

    Tried premake4.3 today for the first time for a vs2010 project, and found out that just putting out platforms { \’x32\’, \’x64\’ } – works just fine – it creates the \”proper\” \’Win32\’ and \’x64\’

    Good article! Thanks!