Build testing lua script (in progress)

As mentioned before, I am working on a quick script to generate project files in order to evaluate what build program I am going to use. The initial script hasn’t been that hard to write and I have been generating some projects to test with CMake.

The things that I have remaining to really make the script useful are:

  1. How to do cross file inclusion?
  2. How to test compile/build times with each build system?
  3. How to post code?

How to do cross file inclusion?
There are some easy ways to do this and some really involved ways. For simplicity sake I think I am going to leave the inclusion as is for now in sort of a “best case” scenario until I can time the different systems. Then I think that I will simply pick a random selection of headers to include in each of the files that is shared between each project time that I generate. The ideal would be to follow some of the techniques from Lakos’ Large-Scale C++ Software Design that is on my “to read” list.

How to test compile/build times with each build system?
For my usage of this script I think that I’m going to just want to run a scenario and get all the results back. I’m finding that it is easier to edit the actual script file rather than doing a bunch of complicated command lines (glue/scripting languages are great for fast iteration) so I think I will actually combine the timing script in with the generation script. It should be fairly easy to get the times in lua to the second at least (I don’t mean profiling lua although that might come in useful later). So, one script but one of the issues I am running into with CMake and will probably have to look at with other tests is if I am using the same compiler and compiler flags or if this is just part of the test. I think I’m going to start with apples to oranges tests with the CMake file stuff at least but I will have to keep in mind if I will have a requirement for cross platform compilation on one machine. If I do have to cross compile, XJam might be a new contender. I also haven’t tackled the generation step of CMake within lua. I’m interested in any feedback on people that have done this.

How to post code?

Finally there is one other peculiar issue I didn’t really think about when I signed up for wordpress, I’m not sure the best way to post code snippets on this site. It seems like I can only post images, video and audio and not a good old text file. I think that something like Source Forge or Google Code are a bit of over kill for one file. In the short term when I think my code has the above described functionality I might dump it in one of those, but for now I will try and include it below for those interested and hope that it comes out looking ok. Keep in mind this is my first lua program so if I am missing anything long time lua programmers would recommend for style or ease of implementation, I am all ears.

— buildtest lua script
— Public domain C++ project generator for testing build systems from
— You are free to use this in any way you see fit and any use of this
— code is at your own risk.

— Version 0.1
— Currently the only thing working is the number of libraries and they are
— not currently doing cross library or even cross file inclusion so this is
— the most simple dependency possible.

— Use is basically lua buildtest.lua, you can specify the lib numbers on
— the commandline, but it is probably better to edit the GLOBALS section of
— the script

— – Clean up code for distribution
— – Addin executables
— – Factor in a way to do multiple build files (JAM,KJAM,SCONS, etc.)
— – Find a way to time and test the builds (same script or separate?)
— – Determine if CMake always needs to regenerate files etc.
— – (time generation for add/removing files)

— Functions ——————————————————————
function createDir(dirname)
io.write(“Creating directory…”,dirname,”\n”)
os.execute(“mkdir ” .. dirname)

function writeProject(prefix, paths, filenames, filecontents)
for i, v in pairs(paths) do
createDir(prefix .. “\\” .. v)
for i, v in pairs(filenames) do
outputFileName = string.format(“%s\\%s”, prefix, v)
local outputFile = assert(, “w”))

— GLOBALS ——————————————————————–
NumExes = 1
NumExeSourceFiles = 5
NumLibs = 25
NumLibSourceFiles = 500

if #arg > 0 then
NumExes = arg[1]
if #arg > 1 then
NumExeSourceFiles = arg[2]
if #arg > 2 then
NumLibs = arg[3]
if #arg > 3 then
NumLibSourceFiles = arg[4]
— TODO add asserts that these are actually numbers, do better parsing

io.write(“Generating project with “, NumExes, ” exes,”, NumExeSourceFiles, ” src”, “\n”)

math.randomseed(3) — Used to grab random header and function inclusions
— Generate Libraries
headerList = {}
local directories = {}
local fileList = {}
local fileContents = {}

fileList[#fileList+1] = “CMakeLists.txt”

fileContents[1] = “cmake_minimum_required(VERSION 2.6)\n” .. “project(BuildTest)\n” .. “include_directories(.)\n”
for iLib = 1, NumLibs do
directories[iLib] = string.format(“Lib%03d”, iLib)
directory = directories[iLib]
fileContents[1] = fileContents[1] .. “add_subdirectory(” .. directory .. “)\n”
— createDir(directory)

cmakefilename = directory .. “\\” .. “CMakeLists.txt”
fileList[#fileList+1] = cmakefilename
cmakefileContentIndex = #fileContents+1
fileContents[cmakefileContentIndex] = “add_library(“” ”
for iLibSrc = 1, NumLibSourceFiles do
— Header
hfilename = string.format(“%s\\LibSrc%03d.h”, directory, iLibSrc)
fileList[#fileList+1] = hfilename
fileContents[#fileContents+1] = (“// Generated header file\n”)

— Source File
filename = string.format(“LibSrc%03d.cpp”, iLibSrc)
fileList[#fileList+1] = directory .. “\\” .. filename
fileContents[#fileContents+1] = “// Generated source file\n”
fileContents[#fileContents] = fileContents[#fileContents]..”#include \<“..hfilename..”>\n”

fileContents[cmakefileContentIndex] = fileContents[cmakefileContentIndex] .. filename .. ” ”

— Function header and body
for iFunction = 1, 10 do
— Write out set number of function
functionName = string.format(“%s_Src%03d_Func%03d”, directory, iLibSrc, iFunction)
fileContents[#fileContents-1] = fileContents[#fileContents-1] .. “int ” .. functionName .. “();\n”

fileContents[#fileContents] = fileContents[#fileContents] .. “int ” .. functionName .. “()\n”
fileContents[#fileContents] = fileContents[#fileContents] .. “{\n”
fileContents[#fileContents] = fileContents[#fileContents] .. “\t return 0;\n”
fileContents[#fileContents] = fileContents[#fileContents] .. “}\n”
fileContents[cmakefileContentIndex] = fileContents[cmakefileContentIndex] .. “)”

writeProject(“cmake”, directories, fileList, fileContents)

This entry was posted in Technical and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s