<div dir="ltr">For those interested: I have written a pure cmake module which allows Object Oriented programming in CMake<div><br></div><div>you can download it through my blog at <a href="http://thetoeb.wordpress.com/2014/02/25/object-oriented-cmake-next-iteration/">http://thetoeb.wordpress.com/2014/02/25/object-oriented-cmake-next-iteration/</a></div>
<div><br></div><div>I also have a question: Will CMake script ever support higher language features like scoped function names, eval, dynamic functions, return values (the workarounds for these features are costing me alot of performance)?</div>
<div><br></div><div><br></div><div>Here is an example of what you can do with the library:</div><div><br></div><div><div>function(test)</div><div><span class="" style="white-space:pre"> </span></div><div><span class="" style="white-space:pre"> </span>### using objects</div>
<div><span class="" style="white-space:pre"> </span>### =============</div><div><span class="" style="white-space:pre"> </span># oo-cmake is very similar to javascript</div><div><span class="" style="white-space:pre"> </span># I actually used the javascript reference to figure out how things could be done :)</div>
<div><span class="" style="white-space:pre"> </span># oo-cmake is a pure object oriented language like javascript (only objects no types per se)</div><div><span class="" style="white-space:pre"> </span># oo-cmake is currently file based and relies heavily on dynamic functions so to be upfront about it:</div>
<div><span class="" style="white-space:pre"> </span># oo-cmake is very slow (depending on what your doing)</div><div><br></div><div><span class="" style="white-space:pre"> </span>## creating a object</div><div><span class="" style="white-space:pre"> </span>## =================</div>
<div><span class="" style="white-space:pre"> </span>obj_new(myobject)</div><div><span class="" style="white-space:pre"> </span># ${myobject} now is a reference to an object</div><div><span class="" style="white-space:pre"> </span>obj_exists(${myobject} _exists)</div>
<div><span class="" style="white-space:pre"> </span>assert(_exists)</div><div><br></div><div><span class="" style="white-space:pre"> </span>## deleting a object</div><div><span class="" style="white-space:pre"> </span>## =================</div>
<div><span class="" style="white-space:pre"> </span># oo-cmake does not contains automatic memory management</div><div><span class="" style="white-space:pre"> </span># you can however remove all objects by calling obj_cleanup </div>
<div><span class="" style="white-space:pre"> </span># (a very crude way of garbage collection) I would suggest calling it at the end of cmake.</div><div><span class="" style="white-space:pre"> </span>obj_new(object_to_delete)</div>
<div><span class="" style="white-space:pre"> </span>obj_delete(${object_to_delete})</div><div><span class="" style="white-space:pre"> </span># object_to_delete still contains the same reference</div><div><span class="" style="white-space:pre"> </span># but the object does not exists anymore and the following returns false</div>
<div><span class="" style="white-space:pre"> </span>obj_exists(${object_to_delete} _exists)</div><div><span class="" style="white-space:pre"> </span>assert(NOT _exists)</div><div><br></div><div><br></div><div><span class="" style="white-space:pre"> </span>## setting and setting property</div>
<div><span class="" style="white-space:pre"> </span>## ==================</div><div><span class="" style="white-space:pre"> </span>obj_new(myobject)</div><div><span class="" style="white-space:pre"> </span># call obj_set passing the object reference</div>
<div><span class="" style="white-space:pre"> </span># the propertyname 'key1' and the value 'val1'</div><div><span class="" style="white-space:pre"> </span># everything beyond 'key1' is saved (as a list)</div>
<div><span class="" style="white-space:pre"> </span>obj_set(${myobject} key1 "val1")</div><div><span class="" style="white-space:pre"> </span>#call obj_get passing the object refernce the result variable and</div>
<div><span class="" style="white-space:pre"> </span># the key which is to be gotten</div><div><span class="" style="white-space:pre"> </span>obj_get(${myobject} theValue key1)</div><div><span class="" style="white-space:pre"> </span>assert(theValue)</div>
<div><span class="" style="white-space:pre"> </span>assert(${theValue} STREQUAL "val1")</div><div><br></div><div><br></div><div><span class="" style="white-space:pre"> </span>## setting a function and calling it</div>
<div><span class="" style="white-space:pre"> </span>## =================================</div><div><span class="" style="white-space:pre"> </span>obj_new(obj)</div><div><span class="" style="white-space:pre"> </span>obj_set(${obj} last_name "Becker")</div>
<div><span class="" style="white-space:pre"> </span>obj_set(${obj} first_name "Tobias")</div><div><span class="" style="white-space:pre"> </span>#obj_setfunction accepts any function (cmake command, string function, file function, unique function (see function tutorial))</div>
<div><span class="" style="white-space:pre"> </span># if you use a cmake function be sure that it will not be overwritten</div><div><span class="" style="white-space:pre"> </span># the safest way to add a function is to use obj_declarefunction</div>
<div><span class="" style="white-space:pre"> </span># you can either specify the key where it is to be stored or not</div><div><span class="" style="white-space:pre"> </span># if you do not specify it the name of the function is used</div>
<div><span class="" style="white-space:pre"> </span>function(greet result)</div><div><span class="" style="white-space:pre"> </span># in the function you have read access to all fields of the proeprty</div><div><span class="" style="white-space:pre"> </span># as will as to 'this' which contains the reference to the object</div>
<div><br></div><div><span class="" style="white-space:pre"> </span># this sets the variable ${result} in PARENT_SCOPE (returning values in cmake)</div><div><span class="" style="white-space:pre"> </span>set(${result} "Hello ${first_name} ${last_name}!" PARENT_SCOPE)</div>
<div><br></div><div><span class="" style="white-space:pre"> </span>endfunction()</div><div><span class="" style="white-space:pre"> </span>obj_setfunction(${obj} greet)</div><div><span class="" style="white-space:pre"> </span>obj_callmember(${obj} greet res)</div>
<div><span class="" style="white-space:pre"> </span>assert(res)</div><div><span class="" style="white-space:pre"> </span>assert(${res} STREQUAL "Hello Tobias Becker!")</div><div><span class="" style="white-space:pre"> </span># alternatively you can also use obj_declarefunction</div>
<div><span class="" style="white-space:pre"> </span># this is actually the easiest way to define a function in code</div><div><span class="" style="white-space:pre"> </span>obj_declarefunction(${obj} say_goodbye)</div><div>
<span class="" style="white-space:pre"> </span>function(${say_goodbye} result)</div><div><span class="" style="white-space:pre"> </span>set(${result} "Goodbye ${first_name} ${last_name}!" PARENT_SCOPE)</div><div>
<span class="" style="white-space:pre"> </span>endfunction()</div><div><span class="" style="white-space:pre"> </span>obj_callmember(${obj} say_goodbye res)</div><div><span class="" style="white-space:pre"> </span>assert(res)</div>
<div><span class="" style="white-space:pre"> </span>assert(res STREQUAL "Goodbye Tobias Becker!")</div><div><br></div><div><span class="" style="white-space:pre"> </span>## built in methods</div><div><span class="" style="white-space:pre"> </span>## ================</div>
<div><span class="" style="white-space:pre"> </span># obj_new creates a object which automatically inherits Object</div><div><span class="" style="white-space:pre"> </span># Object contains some functions e.g. to_string, print, ...</div>
<div><span class="" style="white-space:pre"> </span># </div><div><span class="" style="white-space:pre"> </span>obj_new(obj)</div><div><span class="" style="white-space:pre"> </span>obj_callmember(${obj} print)</div><div>
<br></div><div><span class="" style="white-space:pre"> </span># this prints all members</div><div><span class="" style="white-space:pre"> </span># ie</div><div><span class="" style="white-space:pre"> </span>#{</div><div>
<span class="" style="white-space:pre"> </span># print: [function], </div>
<div><span class="" style="white-space:pre"> </span># to_string: [function], </div><div><span class="" style="white-space:pre"> </span># __ctor__: [object :object_Y3dVWkChKi], </div><div><span class="" style="white-space:pre"> </span># __proto__: [object :object_AztQwnKoE7], </div>
<div><span class="" style="white-space:pre"> </span>#}</div><div><br></div><div><br></div><div><span class="" style="white-space:pre"> </span>## constructors</div><div><span class="" style="white-space:pre"> </span>## ============</div>
<div><span class="" style="white-space:pre"> </span># you can easily define a object type via constructor</div><div><span class="" style="white-space:pre"> </span>function(MyObject)</div><div><span class="" style="white-space:pre"> </span># declare a function on the prototype (which is accessible for all objects)</div>
<div><span class="" style="white-space:pre"> </span># inheriting from MyObject</div><div><span class="" style="white-space:pre"> </span>obj_declarefunction(${__proto__} myMethod)</div><div><span class="" style="white-space:pre"> </span>function(${myMethod} result)</div>
<div><span class="" style="white-space:pre"> </span>set(${result} "myMethod: ${myValue}" PARENT_SCOPE)</div><div><span class="" style="white-space:pre"> </span>this_set(myNewProperty "this is a text ${myValue}")</div>
<div><span class="" style="white-space:pre"> </span>endfunction()</div><div><br></div><div><span class="" style="white-space:pre"> </span># set a field for the object</div><div><span class="" style="white-space:pre"> </span>this_set(myValue "hello")</div>
<div><span class="" style="white-space:pre"> </span>endfunction()</div><div><br></div><div><span class="" style="white-space:pre"> </span>obj_new(obj MyObject)</div><div><span class="" style="white-space:pre"> </span># type of object will now be MyObject</div>
<div><span class="" style="white-space:pre"> </span>obj_gettype(${obj} type)</div><div><span class="" style="white-space:pre"> </span>assert(type)</div><div><span class="" style="white-space:pre"> </span>assert(${type} STREQUAL MyObject)</div>
<div><span class="" style="white-space:pre"> </span># call</div><div><span class="" style="white-space:pre"> </span>obj_callmember(${obj} myMethod res)</div><div><span class="" style="white-space:pre"> </span>assert(res)</div>
<div><span class="" style="white-space:pre"> </span>assert(${res} STREQUAL "myMethod: hello")</div><div><span class="" style="white-space:pre"> </span>obj_set(${obj} myValue "othervalue")</div><div><span class="" style="white-space:pre"> </span>obj_callmember(${obj} myMethod res)</div>
<div><span class="" style="white-space:pre"> </span>assert(res)</div><div><span class="" style="white-space:pre"> </span>assert(${res} STREQUAL "myMethod: othervalue")</div><div><span class="" style="white-space:pre"> </span>obj_get(${obj} res myNewProperty)</div>
<div><span class="" style="white-space:pre"> </span>assert(res)</div><div><span class="" style="white-space:pre"> </span>assert(${res} STREQUAL "this is a text othervalue")</div><div><br></div><div><span class="" style="white-space:pre"> </span>## functors</div>
<div><span class="" style="white-space:pre"> </span>## ========</div><div><br></div><div><span class="" style="white-space:pre"> </span>## binding a function</div><div><span class="" style="white-space:pre"> </span>## ==================</div>
<div><span class="" style="white-space:pre"> </span># you can bind any function to an object without</div><div><span class="" style="white-space:pre"> </span># setting it as property</div><div><span class="" style="white-space:pre"> </span># causing the function to get access to 'this'</div>
<div><span class="" style="white-space:pre"> </span># and all defined properties</div><div><span class="" style="white-space:pre"> </span>function(anyfunction)</div><div><span class="" style="white-space:pre"> </span>this_callmember(print)</div>
<div><span class="" style="white-space:pre"> </span>endfunction()</div><div><span class="" style="white-space:pre"> </span>obj_new(obj)</div><div><span class="" style="white-space:pre"> </span>obj_bindcall(${obj} anyfunction)</div>
<div><span class="" style="white-space:pre"> </span>## print the object</div><div><span class="" style="white-space:pre"> </span># alternatively you can bind the function to the object</div><div><span class="" style="white-space:pre"> </span>obj_bind(boundfu ${obj} anyfunction)</div>
<div><span class="" style="white-space:pre"> </span>call_function(${boundfu})</div><div><span class="" style="white-space:pre"> </span># prints the object</div><div><span class="" style="white-space:pre"> </span># alternatively you can bind and import then function</div>
<div><span class="" style="white-space:pre"> </span># beware that you might overwrite a defined function if you append REDEFINE</div><div><span class="" style="white-space:pre"> </span># </div><div><span class="" style="white-space:pre"> </span>obj_bindimport(${obj} anyfunction myBoundFunc REDEFINE)</div>
<div><span class="" style="white-space:pre"> </span>myBoundFunc()</div><div><span class="" style="white-space:pre"> </span># print the object</div><div><br></div><div><br></div><div><br></div><div><span class="" style="white-space:pre"> </span>## extended a 'type'</div>
<div><span class="" style="white-space:pre"> </span>## =================</div><div><br></div><div>endfunction()</div></div></div>