CMake:Experiments With Lua

From KitwarePublic
Revision as of 12:54, 10 December 2007 by Ewing2121 (talk | contribs)
Jump to navigationJump to 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"));


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);