CMake:Experiments With Lua

From KitwarePublic
Jump to: navigation, search

Here (http://www.cmake.org/Wiki/Image:CMakeLua.zip) is a source tree for a CMake that also accepts Lua as input. All cmake commands are wrapped and one (get_property) has also been converted to be a function as a test case. This is just an experiment. There is a LuaTest test case (found under CMake/Tests) that works and is shown below. All cmake commands are lower case and are prepended with cm_. I'm not well versed on Lua and this is not a complete conversion. If a listfile ends in .lua then it will be parsed as lua code, otherwise it will be parsed using the usual CMake language.

-- a simple test case
cm_project ("LuaTest");

cm_add_executable ("LuaTest", "simple.cxx");

sources = {
  "simpleLib.cxx",
  "simpleCLib.c", 
  "simpleWe.cpp"
}

cm_add_library ("simpleLib", "STATIC", unpack(sources));

cm_target_link_libraries ("LuaTest", "simpleLib");

print("The location of simpleLib is: " .. 
  cm_get_property("TARGET", "simpleLib", "LOCATION"));

Notes

  • The original attached file only seems to support the Makefile generator.
  • Bootstrap doesn't work. Use an existing version of CMake to build instead of bootstrap.

Comment

The 'unpack(sources)' call feels pretty unnatural. This is easily avoided by using a table (array of strings) instead of a variable argument. But this brings up a bigger issue. Different users may package their data in different ways. We should probably try to support these different ways (within reason). This attached program demonstrates how to use an intermediate function to handle arguments passed in as varargs, or as a table, or as nested tables, or even as interspersed tables and strings. A simple example is attached here: http://www.cmake.org/Wiki/Image:FlexibleArgumentHelper.zip

Since the current Lua binding seems to be fairly clever and compact by centralizing the interface into a single function, rather than changing this and implementing a lot more C code, we can instead create an intermediate helper function that is implemented completely in Lua. This helper function then actually becomes the public API and the the direct C/Lua binding can be thought of as a private API function. This Lua function then handles all the argument variations and sanitizes the input into what the C/Lua interface expects.

Similarly, this approach can be used to return values in ways that may seem more natural to a scripter. For example, for functions that return values through one of the parameters, the Lua function could re-arrange it so that these values are returned through the normal return value mechanism.

This example uses a simple recursive function to parse the table. This allows for some interesting combinations: We could pass like before:

cm.add_library ("simpleLib", cm.STATIC, unpack(sources));

We could pass as a table instead:

cm.add_library ("simpleLib", cm.STATIC, sources);


We can have nested tables:

another_table = { "file1.c", {"file2.c", "file3.c"}, {{"file4.c"}} }
cm.add_library ("simpleLib", cm.STATIC, another_table);

We can also combine, and intersperse them:

cm.add_library ("simpleLib", cm.STATIC, sources, "another_file.c", another_table);


External Links

To make experimentation a little easier, we have set up a Mercurial repository at: http://www.assembla.com/spaces/CMakeLua

We are using Tailor and Mercurial to try to keep these experimental changes in sync with CVS head which gives us more time to play with the code (to avoid becoming too out-of-date) and also giving us all the usual benefits a distributed SCM provides. The repository also includes an integrated version of the table support as described in the Comments section above.