Check-ins for fancy table arguments, cmake namespace, and pass via array (table) instead of varargs

31 views
Skip to first unread message

E. Wing

unread,
Feb 17, 2008, 6:04:03 AM2/17/08
to cmak...@googlegroups.com
I checked in some changes to the Lua bindings.

First, I changed all the cmake API functions to exist in the cmake.
table (namespace) instead of using the cm_ prefix.

I implemented this in the LuaPublicAPIHelper.lua file. I basically
traversed through _G looking for strings with cm_ that were functions
and then assign the function to the cmake table with the name stripped
of its cm_ prefix. I then set the cm_ function in _G to nil.

I would have preferred to have just created everything directly to a
cmake table in C and avoid this dance, but my attempt to do so led to
seg-faults. I'm obviously doing it wrong. If anybody can teach me how
to do this correctly, I would appreciate it. You can grep the code for
LuaUtils_RegisterFunc. Currently the code block using it is disabled
by #ifdefs. The LuaUtils file is a file I created for people to add
generic Lua/C helper routines.

Next, I also expanded the fancy table handling I described in the
original wiki to apply to all CMake API functions. This code is
intertwined with the cmake namespace stuff since we are iterating
through all functions already. The code basically just takes the old
function and wraps it with the fancy argument handling I implemented
earlier for cm.add_library, and replaces the old function.


Then I changed the Lua/C interface in cmCommand::cmLuaFunc to pass a
single table instead of using a variable number of arguments. I
verified that Lua's variable number of arguments for function call has
a fixed limit. By default, it is 2048 (as a #define). For CMake, this
may be a problem because for large projects, there may be a long list
of files in a single function call.

Prior to this check in, the cmCommand::cmLuaFunc binding took all
parameters in through the var-arg system. To avoid this being a
trouble point, I changed the implementation so it now expects a single
array (table) containing all the arguments.

In the fancy argument handling system, I removed the call to unpack()
so a single table gets passed. Multiple flat arguments are coalesced
into a single table (array) argument by this wrapper.


But to completely avoid this problem, scripters should be made aware
of this hard coded limit. If they are encouraged to put their files in
tables which has other advantages such as reusing to specify IDE
adding, installing, frameworks, etc, then the event of a user hitting
the problem becomes remote:

cmake.add_library("simpleLib", cmake.STATIC, sources)

If users don't do this and get into trouble, the work-around is easy
though and can be told to use the following tricks which add braces:

cmake.add_library("simpleLib", cmake.STATIC, {'source1.cxx', 'source2.cxx'})
or
cmake.add_library({"simpleLib", cmake.STATIC, 'source1.cxx', 'source2.cxx'})


In the latter case, since Lua has syntactic sugar for omitting
parenthesis for single argument functions, users may also do this:

cmake.add_library{"simpleLib", cmake.STATIC, 'source1.cxx', 'source2.cxx'}


Finally I synced up with the offiicial CMake CVS several days ago.


Thanks,
Eric

Ken Martin

unread,
Feb 18, 2008, 1:28:14 PM2/18/08
to CMakeLua
> First, I changed all the cmake API functions to exist in the cmake.
> table (namespace) instead of using the cm_ prefix.

Good.

> I implemented this in the LuaPublicAPIHelper.lua file. I basically
> traversed through _G looking for strings with cm_ that were functions
> and then assign the function to the cmake table with the name stripped
> of its cm_ prefix. I then set the cm_ function in _G to nil.
>
> I would have preferred to have just created everything directly to a
> cmake table in C and avoid this dance

Sounds like something that can be fixed.

Some random notes from a couple other posts etc...

bootstraping: personally my take is let CMake bootstrap without Lua
and add in the Lua support in stage 2 of the build at the same time as
ctest/cpack/ccmake/curl/etc etc are all built.

syntax/OO etc: my gut feeling is stick fairly close to the current
CMake syntax in terms of function names/arguments. While I like the OO
approach I think right now we will get more mileage (and less work)
from staying more consistent. The exception for me would be get
methods. I feel like they should return values in typical Lua style. I
provided one example of this in my implementation.

CMake/Lua variables: this is the big technical issue in my mind. While
properties are more common in CMake 2.6 and translate easily to Lua,
CMake still relies on a boat load of variables. So we are stuck with
variables in the CMake space for this to work. configure_file makes
use of variables and the generators read from variables to control
their output. So what do we do?

-- expose the cmake.set command in Lua and distinguish Lua variables
from CMake variables and tell folks that some things must be "set" in
CMake to work. (yuck)

-- Create some code such that when a variable is retrieved in CMake it
also looks in some Lua variable table (no clue how to do this but I
bet it can be done with standard hooks) This is nicer from the user's
perspective but I worry over the implementation. This is where a code
converter could come into play such that ALL CMake language files
parsed by CMake get converted in memory and passed off to the Lua
interpreter. My concern here is that I am not sure a full working
converter could be written, I'm pretty sure a 95% working one can be
done but let's face it, scoping in CMake is different from Lua and a
converter would probably be ugly if it tried to handle that
difference. But yet some CMake code will rely on it..:(

I'm not really sure what to do on this issue but I know it is a big
risk item.

Ken

E. Wing

unread,
Feb 19, 2008, 10:48:36 PM2/19/08
to cmak...@googlegroups.com
> bootstraping: personally my take is let CMake bootstrap without Lua
> and add in the Lua support in stage 2 of the build at the same time as
> ctest/cpack/ccmake/curl/etc etc are all built.

I don't actually understand how the bootstrapping process works. I
think the problem is that since we have Lua code now in the CMake
core, the headers (and presumably symbols) aren't found. I'm not sure
how to shift this to stage 2.


> CMake/Lua variables: this is the big technical issue in my mind. While
> properties are more common in CMake 2.6 and translate easily to Lua,
> CMake still relies on a boat load of variables. So we are stuck with
> variables in the CMake space for this to work. configure_file makes
> use of variables and the generators read from variables to control
> their output. So what do we do?


To share global variables, if there is a centralized place in the
CMake/C++ code where a CMake-script variable is set/get, we can simply
copy this variable to the Lua state using lua_setglobal/lua_getglobal.
Thus we should be able to keep these variables in-sync. On the
CMake-script side, anytime we set, we also set Lua. The Lua-script
side is a little trickier. If the Lua side sets, we need to make sure
the CMake-script side can see the update when needed. The easiest
answer might be that anytime the C++ code 'get' is used, make sure to
fetch the value from Lua and compare to the value in C++ memory and
resolve the differences on demand.

Gonzalo told me that he was thinking of extending this idea one step
further and just replace the current internal C++ representation of
variables entirely with Lua so there is no duplication of values and
no synchronization problem.


> -- expose the cmake.set command in Lua and distinguish Lua variables
> from CMake variables and tell folks that some things must be "set" in
> CMake to work. (yuck)
>
> -- Create some code such that when a variable is retrieved in CMake it
> also looks in some Lua variable table (no clue how to do this but I
> bet it can be done with standard hooks) This is nicer from the user's
> perspective but I worry over the implementation. This is where a code
> converter could come into play such that ALL CMake language files
> parsed by CMake get converted in memory and passed off to the Lua
> interpreter. My concern here is that I am not sure a full working
> converter could be written, I'm pretty sure a 95% working one can be
> done but let's face it, scoping in CMake is different from Lua and a
> converter would probably be ugly if it tried to handle that
> difference. But yet some CMake code will rely on it..:(
>
> I'm not really sure what to do on this issue but I know it is a big
> risk item.
>


I see variables and 'set' having several different issues.
Correct me if I'm wrong, but 'set' seems to combine 3 different ideas
into one call.
1) Simple assignment (a=b)
2) Building up a list (t = {a, b, c})
3) Marking a (non-list?) variable as a GUI item with additional metadata

I see the first two easily using native Lua mechanisms without the
need for a 'set' function.
The third item is trickier. Here are some random ideas that I don't
claim to be good or bad.

- One idea is to use regular Lua tables, and users are expected to
fill in predefined keys if they use them. Convenience functions can be
provided to help fill these is like 'set', though maybe it would be
useful here to break away from the CMake API and rename the function
to something that denotes a GUI variable if that is only what it is.
Still yucky, but maybe not quite as yucky as before.

- Building on top of that idea, we could change the above to use Lua
metatables. It's probably a little cleaner than the above and may let
us do a few extra things while hiding things from the users, but we
still do have the yucky variable mismatch between primitives and GUI
variables. But maybe by making the GUI distinction, people won't think
it's so yucky?

- Maybe there is a way to keep everything using primitive constructs.
At the C++ API level, we could try hiding extra information in the Lua
registry. As you kind of suggested, we have a hidden variable table in
Lua which contains the additional metadata for every relevant variable
that needs it. I think though we still may need a 'set' like API call
to allow users to specify this additional information and also clue us
into creating a hidden registry entry for this variable.

As for a converter, I think I'm feeling slightly less ambitious. Most
of my thoughts about bridging have been focused on the peaceful
coexistence of both interpreters, not converting one into the other.
My thinking is that the two interpreters only need to communicate with
each other via two mechanisms: (global) variables and (global)
functions. Admittedly, most of my focus has been preoccupied with
variables because I'm not sure about the behavioral mismatches such as
with scoping. But if there is a good/easy way to call a CMake-script
function/macro from C++, then maybe it would be simple to bridge this
gap too though as we could just forward the function calls between the
two interpreters. But I'm thinking the more common case of
interoperability is simply invoking whole scripts (as opposed to
functions) via things like the Find*.cmake scripts, so it is mostly
the variables that are mostly what's communicated and the
functionality is mostly a black box that the caller doesn't need to
worry about.

Thanks,
Eric

Ken Martin

unread,
Feb 28, 2008, 4:02:45 PM2/28/08
to cmak...@googlegroups.com
> I don't actually understand how the bootstrapping process works. I
> think the problem is that since we have Lua code now in the CMake
> core, the headers (and presumably symbols) aren't found. I'm not sure
> how to shift this to stage 2.

Eric poked me :) So a late reply. Bootstrapping builds a stripped down
version of CMake in stage 1. This is then run on the CMake source tree to
build makefiles to build the real CMake as well as ctest, cpack etc. The
stripped down CMake does not even include all the CMake commands, only a
subset that is required to build CMake itself. For Lua you do not want to
mess with the bootstrap at all. Just let it do things the old way. What
this means is that any Lua code in classes that are built as part of the
bootstrap process need to have a

#if defined(CMAKE_BUILD_WITH_CMAKE)
// some lua stuff
#endif

Around them. That way cmake will still bootstrap OK without worrying over
any Lua stuff. Basically take your source tree, try to bootstrap it, and
where there are errors start putting in #ifdefs. This should be pretty
straight forward, really no technical issues here.

> To share global variables, if there is a centralized place in the
> CMake/C++ code where a CMake-script variable is set/get, we can simply
> copy this variable to the Lua state using lua_setglobal/lua_getglobal.
> Thus we should be able to keep these variables in-sync. On the
> CMake-script side, anytime we set, we also set Lua. The Lua-script
> side is a little trickier. If the Lua side sets, we need to make sure
> the CMake-script side can see the update when needed. The easiest
> answer might be that anytime the C++ code 'get' is used, make sure to
> fetch the value from Lua and compare to the value in C++ memory and
> resolve the differences on demand.

CMake variables are stored in two places. 1) in cmMakefile.cxx
DefinitionStack. This is a vector of maps of string to string. When a
function is entered the scope is pushed and a new map is put onto the
vector. A scope pop removes the last entry from the vector. Variable lookup
in CMake first checks the map at the end of this vector to see if the
variable is defined there. If it is not then it checks the cache. See
GetDefinition in cmMakefile.cxx for the implementation.


> Gonzalo told me that he was thinking of extending this idea one step
> further and just replace the current internal C++ representation of
> variables entirely with Lua so there is no duplication of values and
> no synchronization problem.

The trick I suspect is that CMake variables have their o

> I see variables and 'set' having several different issues.
> Correct me if I'm wrong, but 'set' seems to combine 3 different ideas
> into one call.
> 1) Simple assignment (a=b)
> 2) Building up a list (t = {a, b, c})
> 3) Marking a (non-list?) variable as a GUI item with additional metadata

Item 1 is really the stumbling block IMO (well that combined with get). For
item 3 Lua can just continue to use the set command. My take would really be
to take a project and convert it to Lua and see what problems are run into.
We know for simple projects the Lua stuff works, I just think for a bigger
projects the variable mix issue will surface and need to be addressed.

Ken

P.S. I wish CMake was using a better revision control system. We may
eventually switch to a distributed VC system where these "lua experiements"
can be done much more easily in parallel.

P.P.S. I think the best approach is to keep it simple and do incremental
improvements to what is there. Big redesigns can easily stall out.

E. Wing

unread,
Feb 29, 2008, 2:56:50 AM2/29/08
to cmak...@googlegroups.com
Hi Ken,
Thanks for the response. First, it looks like one of your responses
was cut off. Can you complete your thought:

> > Gonzalo told me that he was thinking of extending this idea one step
> > further and just replace the current internal C++ representation of
> > variables entirely with Lua so there is no duplication of values and
> > no synchronization problem.
>
> The trick I suspect is that CMake variables have their o
>

Next, w.r.t. bootstrapping:


>
> #if defined(CMAKE_BUILD_WITH_CMAKE)
> // some lua stuff
> #endif

This is pretty clear, thanks. Though out of curiosity, what would be
involved in making it so Lua was built with the bootstrap process
instead? I partly ask because I recall a few areas that looked a
little more intertwined with the regular code, and during a
particularly difficult merge conflict I resolved, I think I made it
worse. (I know this needs to be refactored this at some point.) But
I'm wondering at this point if it would be easier to to include Lua in
the bootstrap process. (For now, I'll assume it always uses the
embedded Lua source and not some pre-existing version on the system.)


> P.S. I wish CMake was using a better revision control system. We may
> eventually switch to a distributed VC system where these "lua experiements"
> can be done much more easily in parallel.

Yes, that would be really nice. I've already posted my feelings once
on the main CMake list, so I won't repeat them here. But I noticed
that Bryan O'Sullivan is on the main CMake list. That right there is
reason enough to choose Mercurial :)


> P.P.S. I think the best approach is to keep it simple and do incremental
> improvements to what is there. Big redesigns can easily stall out.

Yes, I completely agree.

Thanks,
Eric

Peter Kümmel

unread,
Mar 2, 2008, 4:52:36 PM3/2/08
to CMakeLua
On Feb 18, 7:28 pm, Ken Martin <ken.mar...@kitware.com> wrote:

> CMake/Lua variables: this is the big technical issue in my mind. While
> properties are more common in CMake 2.6 and translate easily to Lua,
> CMake still relies on a boat load of variables. So we are stuck with
> variables in the CMake space for this to work. configure_file makes
> use of variables and the generators read from variables to control
> their output. So what do we do?
>
> -- Create some code such that when a variable is retrieved in CMake it
> also looks in some Lua variable table (no clue how to do this but I
> bet it can be done with standard hooks)

Is the DefinitionStack in cmCMakefile always up to date?
Is it enough to allways call GetDefinition from Lua?

Here I already have this running:

compiler = GetDefinition("CMAKE_CXX_COMPILER")
print("Compiler: " .. compiler .."\n");

And with metatables we could use the cmake variables directly:

setmetatable(_G, {__index = function (_, n) return GetDefinition(n)
end})
print(CMAKE_CXX_COMPILER .."\n"); --> this also works!


The same is possible with AddDefinition.
How much would us help such binding?

Peter

E. Wing

unread,
Mar 3, 2008, 6:30:31 AM3/3/08
to cmak...@googlegroups.com
> > -- Create some code such that when a variable is retrieved in CMake it
> > also looks in some Lua variable table (no clue how to do this but I
> > bet it can be done with standard hooks)
>
> Is the DefinitionStack in cmCMakefile always up to date?
> Is it enough to allways call GetDefinition from Lua?
>
> Here I already have this running:
>
> compiler = GetDefinition("CMAKE_CXX_COMPILER")
> print("Compiler: " .. compiler .."\n");
>
> And with metatables we could use the cmake variables directly:
>
> setmetatable(_G, {__index = function (_, n) return GetDefinition(n)
> end})
> print(CMAKE_CXX_COMPILER .."\n"); --> this also works!
>
>
> The same is possible with AddDefinition.
> How much would us help such binding?
>
> Peter

Wow, this is terrific Peter. This is so elegant and simple, I'm
smacking my forehead.

Ken, what say you? Are these the only two entry points and are they
always up-to-date?

Peter, could you check in your changes or post a Mercurial repo we can
pull if you're not ready to fully commit? You may also upload to the
"Files" section on Assembla. I would love to experiment with this
further.

Also, Ken, for list types in CMake, are these just single strings with
semi-colons in the string and GetDefintion will just return this
string? If so, I'm wondering if we should automatically split the
string and compose a table to return in __index metamethod.
Conversely, I suppose we should take a table of strings and flatten it
to a string with semi-colons for the __newindex metamethod. Though I'm
wondering if there are cases where this will be a problem.

Thanks,
Eric

Ken Martin

unread,
Mar 3, 2008, 11:24:17 AM3/3/08
to cmak...@googlegroups.com
>
> Is the DefinitionStack in cmCMakefile always up to date?
> Is it enough to allways call GetDefinition from Lua?
>

Yes the definition stack is always up to date for variables set from CMake.
As Lua files are processed I am still pushing and popping the stack the same
as if they were CMake script files. I am not pushing or poping as Lua goes
into other state (e.g. when Lua goes into a Lua function)


> Here I already have this running:
>
> compiler = GetDefinition("CMAKE_CXX_COMPILER")
> print("Compiler: " .. compiler .."\n");
>
> And with metatables we could use the cmake variables directly:
>
> setmetatable(_G, {__index = function (_, n) return GetDefinition(n)
> end})
> print(CMAKE_CXX_COMPILER .."\n"); --> this also works!
>
>
> The same is possible with AddDefinition.
> How much would us help such binding?


Does this mean that ALL variables accessed in Lua call GetDefinition? Does
this basically replace the standard Lua variable referencing? Hmm

Ken

Peter Kümmel

unread,
Mar 3, 2008, 6:12:50 PM3/3/08
to cmak...@googlegroups.com
E. Wing wrote:
>
> Wow, this is terrific Peter. This is so elegant and simple, I'm
> smacking my forehead.
>
> Ken, what say you? Are these the only two entry points and are they
> always up-to-date?
>
> Peter, could you check in your changes or post a Mercurial repo we can
> pull if you're not ready to fully commit? You may also upload to the
> "Files" section on Assembla. I would love to experiment with this
> further.
>

I've pushed the repo with a new branch containing my changes.

> Also, Ken, for list types in CMake, are these just single strings with
> semi-colons in the string and GetDefintion will just return this
> string? If so, I'm wondering if we should automatically split the
> string and compose a table to return in __index metamethod.
> Conversely, I suppose we should take a table of strings and flatten it
> to a string with semi-colons for the __newindex metamethod. Though I'm
> wondering if there are cases where this will be a problem.

I think it is a good idea to only use tables on the Lua side.

>
> Thanks,
> Eric
>
> >

--
Peter Kümmel

E. Wing

unread,
Mar 3, 2008, 6:25:34 PM3/3/08
to cmak...@googlegroups.com
> > Here I already have this running:
> >
> > compiler = GetDefinition("CMAKE_CXX_COMPILER")
> > print("Compiler: " .. compiler .."\n");
> >
> > And with metatables we could use the cmake variables directly:
> >
> > setmetatable(_G, {__index = function (_, n) return GetDefinition(n)
> > end})
> > print(CMAKE_CXX_COMPILER .."\n"); --> this also works!
> >
> >
> > The same is possible with AddDefinition.
> > How much would us help such binding?
>
>
> Does this mean that ALL variables accessed in Lua call GetDefinition? Does
> this basically replace the standard Lua variable referencing? Hmm


Hopefully Peter will correct me if I'm wrong, but I believe the
metamethod will only call GetDefinition if the normal Lua lookup
mechanism returns nil. So variables already registered in Lua's normal
global state will continue to work as before.

However, I think things might get a little dodgy with __newindex and
SetDefinition, at least with a naive implementation. All new global
variables registered after the metamethod is setup will attempt to go
through SetDefinition. I think this will be problematic for setting up
new functions, new tables, and importing native Lua libraries/modules
as they will try to funnel through SetDefinition. I think we can case
the thing to make sure functions do not go through SetDefinition.
Tables though I am less certain of.

I mentioned the idea of automatically converting CMake semi-colon
lists to tables and vice-versa, but on further thinking, I'm worried
about ambiguity problems where people actually use semicolons in
strings, but not to denote lists.

So I'm thinking a bit out loud here, but one idea I'm thinking about
is don't call SetDefinition unless the variable already exists in the
CMake Definitions list (otherwise, just keep it in Lua). Then on the
native-CMake script side, we implement something comparable to how the
Lua __index metamethod works (i.e. search CMake definitions first, and
if empty, search Lua globals).

Or maybe Gonzalo's idea of replacing CMake's definition storage
mechanism with Lua directly would be cleaner? This gives us more
types/metadata and solves the synchronization problem.

Thanks,
Eric

Peter Kümmel

unread,
Mar 3, 2008, 6:36:00 PM3/3/08
to cmak...@googlegroups.com
E. Wing wrote:
>>> Here I already have this running:
>>>
>>> compiler = GetDefinition("CMAKE_CXX_COMPILER")
>>> print("Compiler: " .. compiler .."\n");
>>>
>>> And with metatables we could use the cmake variables directly:
>>>
>>> setmetatable(_G, {__index = function (_, n) return GetDefinition(n)
>>> end})
>>> print(CMAKE_CXX_COMPILER .."\n"); --> this also works!
>>>
>>>
>>> The same is possible with AddDefinition.
>>> How much would us help such binding?
>>
>> Does this mean that ALL variables accessed in Lua call GetDefinition? Does
>> this basically replace the standard Lua variable referencing? Hmm
>
>
> Hopefully Peter will correct me if I'm wrong, but I believe the

No, you are right ;)
But I think we should play around a bit and see what would be best.

Peter

--
Peter Kümmel

Peter Kümmel

unread,
Mar 3, 2008, 6:31:23 PM3/3/08
to cmak...@googlegroups.com
Ken Martin wrote:
>
> Does this mean that ALL variables accessed in Lua call GetDefinition? Does
> this basically replace the standard Lua variable referencing? Hmm

No, only variables which could not be found in the global table.

But it could be a problem for the setter: Currently

CMAKE_VAR = "x"

triggers AddDefinition for all new variables, therefore

emptyTable = {}
print(emptyTable)

does not wotk, it prints nil instead of the address of the table.

But I don't think this is critical, the current code should only
demonstrate what in principle is possible:

set(a ${b})

becomes now in Lua

a = b

AND updates all the cmake variables.

What we need now is a command to execute Lua in a .txt file,
then we could write tests like this:

set(A a)
set(B b)

lua("A = B")

if(A STREQUAL "b")
...


Peter

E. Wing

unread,
Mar 4, 2008, 1:37:42 AM3/4/08
to cmak...@googlegroups.com
> What we need now is a command to execute Lua in a .txt file,
> then we could write tests like this:
>
> set(A a)
> set(B b)
>
> lua("A = B")
>
> if(A STREQUAL "b")
> ...

So good news here I think. We don't need to do anything special.
Instead of trying to come up with a contrived test case and special
code to invoke other scripts, I did a more real-world thing and called
cmake.find_package() on a traditional CMake-script based module and it
seemed to work. So adding these lines to the CMakeLists.lua in LuaTest
seemed to do the right thing:

cmake.find_package("OpenAL")
print("OPENAL_LIBRARY:", OPENAL_LIBRARY)
print("OPENAL_FOUND:", OPENAL_FOUND)

The output was:
OPENAL_LIBRARY: /System/Library/Frameworks/OpenAL.framework
OPENAL_FOUND: YES

So we have successfully run a traditional CMake-script module called
from a Lua module and read the results. I think things are looking
very good.

I'm predicting that for multiple subdirectories, we can mix
CMakeLists.txt and CMakeLists.lua. And I'm predicting we should be
able to use the CMake INCLUDE function. I will see about integrating
these into a test.


Thanks,
Eric

Peter Kümmel

unread,
Mar 5, 2008, 4:10:10 PM3/5/08
to cmak...@googlegroups.com

Yes, really good new.
And what next? Should we try do build cmake with
a Lua script? With this real world example we will see was misses.

Peter

Peter Kümmel

unread,
Mar 5, 2008, 4:24:21 PM3/5/08
to cmak...@googlegroups.com
E. Wing wrote:
> However, I think things might get a little dodgy with __newindex and
> SetDefinition, at least with a naive implementation. All new global
> variables registered after the metamethod is setup will attempt to go
> through SetDefinition. I think this will be problematic for setting up
> new functions, new tables, and importing native Lua libraries/modules
> as they will try to funnel through SetDefinition. I think we can case
> the thing to make sure functions do not go through SetDefinition.
> Tables though I am less certain of.

The actual functions for __index and __newindex are too simple.

My idea is to declare all CMake variables before using them, similar
to the example in the Lua book:
http://www.lua.org/pil/14.2.html

Then we could check before a variable-access if it is a cmake variable,
and only if it was declared as a cmake variable we use the C++ interface,
if not it is a plain lua call.

By this we've introduced a bit of a typing system which helps a lot on
big projects.

Peter

Peter Kümmel

unread,
Mar 5, 2008, 6:21:23 PM3/5/08
to cmak...@googlegroups.com
E. Wing wrote:
>> What we need now is a command to execute Lua in a .txt file,
>> then we could write tests like this:
>>
>> set(A a)
>> set(B b)
>>
>> lua("A = B")
>>
>> if(A STREQUAL "b")
>> ...
>

I couldn't stop me ;)

The the sandbox branch supports now the lua command (cmLuaCommand.cxx).

LuaTest/Command/CMakeLists.txt:

set(A a b c)
set(B a2b2c2)

lua(
"
setmetatable(_G, {
__index = function (_, n) return GetDefinition(n) end,
__newindex = function (_, n1, n2) AddDefinition(n1, n2) end})
"
)

lua("A = B")


if(A STREQUAL "a2b2c2")
message(STATUS "Lua test A = B passed")
else()
message(STATUS "Lua test A = B failed, A = ${A} B = ${B}")
endif()


And the output is:

-- Lua test A = B passed
-- Configuring done
-- Generating done


So it is possible now to mix Lua and CMake scripts in one file.

Pter

Peter Kümmel

unread,
Mar 6, 2008, 3:35:39 PM3/6/08
to cmak...@googlegroups.com
Ken Martin wrote:
> Does this mean that ALL variables accessed in Lua call GetDefinition? Does
> this basically replace the standard Lua variable referencing? Hmm

The cmake variables could be moved into a lua table:

# move the cmake variables into the cmake table

lua("
setmetatable(_G, nil)
setmetatable(cmake, {


__index = function (_, n) return GetDefinition(n) end,
__newindex = function (_, n1, n2) AddDefinition(n1, n2) end})
")

set(C a b c)
set(D a2b2c2)

lua("cmake.C = cmake.D")


if(C STREQUAL "a2b2c2")
message(STATUS "Lua test cmake.C = cmake.D passed")
else()
message(STATUS "Lua test cmake.C = cmake.D failed, cmake.C = ${C} cmake.D = ${d}")
endif()

lua("
t = {}
cmake.t = tostring(t)
")

message(STATUS "Address of Lua table t is ${t}")

gives the output

-- Detecting CXX compiler info - done


-- Lua test A = B passed

-- Lua test cmake.C = cmake.D passed
-- Address of Lua table t is table: 01EF17A8


-- Configuring done
-- Generating done


Peter

Reply all
Reply to author
Forward
0 new messages