RubyObjC 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +351 -0
- data/INTRODUCTION +137 -0
- data/USAGE +113 -0
- data/app/Rakefile +6 -0
- data/app/main.rb +36 -0
- data/app/random.rb +65 -0
- data/bin/rubyapp +18 -0
- data/lib/librubyobjc.a +0 -0
- data/lib/objc.bundle +0 -0
- data/lib/rake/cocoa.rb +428 -0
- data/lib/resources/English.lproj/InfoPlist.strings +0 -0
- data/lib/resources/English.lproj/MainMenu.nib/classes.nib +4 -0
- data/lib/resources/English.lproj/MainMenu.nib/info.nib +17 -0
- data/lib/resources/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
- data/lib/rubyobjcapp +0 -0
- data/libffi/LICENSE +20 -0
- metadata +65 -0
data/COPYING
ADDED
@@ -0,0 +1,351 @@
|
|
1
|
+
==GNU GENERAL PUBLIC LICENSE
|
2
|
+
Version 2, June 1991
|
3
|
+
|
4
|
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5
|
+
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
6
|
+
|
7
|
+
Everyone is permitted to copy and distribute verbatim copies
|
8
|
+
of this license document, but changing it is not allowed.
|
9
|
+
|
10
|
+
===Preamble
|
11
|
+
|
12
|
+
The licenses for most software are designed to take away your freedom
|
13
|
+
to share and change it. By contrast, the GNU General Public License is
|
14
|
+
intended to guarantee your freedom to share and change free
|
15
|
+
software--to make sure the software is free for all its users. This
|
16
|
+
General Public License applies to most of the Free Software
|
17
|
+
Foundation's software and to any other program whose authors commit to
|
18
|
+
using it. (Some other Free Software Foundation software is covered by
|
19
|
+
the GNU Library General Public License instead.) You can apply it to
|
20
|
+
your programs, too.
|
21
|
+
|
22
|
+
When we speak of free software, we are referring to freedom, not price.
|
23
|
+
Our General Public Licenses are designed to make sure that you have
|
24
|
+
the freedom to distribute copies of free software (and charge for this
|
25
|
+
service if you wish), that you receive source code or can get it if you
|
26
|
+
want it, that you can change the software or use pieces of it in new
|
27
|
+
free programs; and that you know you can do these things.
|
28
|
+
|
29
|
+
To protect your rights, we need to make restrictions that forbid anyone
|
30
|
+
to deny you these rights or to ask you to surrender the rights. These
|
31
|
+
restrictions translate to certain responsibilities for you if you
|
32
|
+
distribute copies of the software, or if you modify it.
|
33
|
+
|
34
|
+
For example, if you distribute copies of such a program, whether gratis
|
35
|
+
or for a fee, you must give the recipients all the rights that you
|
36
|
+
have. You must make sure that they, too, receive or can get the source
|
37
|
+
code. And you must show them these terms so they know their rights.
|
38
|
+
|
39
|
+
We protect your rights with two steps: (1) copyright the software, and
|
40
|
+
(2) offer you this license which gives you legal permission to copy,
|
41
|
+
distribute and/or modify the software.
|
42
|
+
|
43
|
+
Also, for each author's protection and ours, we want to make certain
|
44
|
+
that everyone understands that there is no warranty for this free
|
45
|
+
software. If the software is modified by someone else and passed on, we
|
46
|
+
want its recipients to know that what they have is not the original, so
|
47
|
+
that any problems introduced by others will not reflect on the original
|
48
|
+
authors' reputations.
|
49
|
+
|
50
|
+
Finally, any free program is threatened constantly by software patents.
|
51
|
+
We wish to avoid the danger that redistributors of a free program will
|
52
|
+
individually obtain patent licenses, in effect making the program
|
53
|
+
proprietary. To prevent this, we have made it clear that any patent
|
54
|
+
must be licensed for everyone's free use or not licensed at all.
|
55
|
+
|
56
|
+
The precise terms and conditions for copying, distribution and
|
57
|
+
modification follow.
|
58
|
+
|
59
|
+
GNU GENERAL PUBLIC LICENSE
|
60
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61
|
+
0. This License applies to any program or other work which contains a
|
62
|
+
notice placed by the copyright holder saying it may be distributed
|
63
|
+
under the terms of this General Public License. The "Program",
|
64
|
+
below, refers to any such program or work, and a "work based on
|
65
|
+
the Program" means either the Program or any derivative work under
|
66
|
+
copyright law: that is to say, a work containing the Program or a
|
67
|
+
portion of it, either verbatim or with modifications and/or
|
68
|
+
translated into another language. (Hereinafter, translation is
|
69
|
+
included without limitation in the term "modification".) Each
|
70
|
+
licensee is addressed as "you".
|
71
|
+
|
72
|
+
Activities other than copying, distribution and modification are
|
73
|
+
not covered by this License; they are outside its scope. The act
|
74
|
+
of running the Program is not restricted, and the output from the
|
75
|
+
Program is covered only if its contents constitute a work based on
|
76
|
+
the Program (independent of having been made by running the
|
77
|
+
Program). Whether that is true depends on what the Program does.
|
78
|
+
|
79
|
+
1. You may copy and distribute verbatim copies of the Program's
|
80
|
+
source code as you receive it, in any medium, provided that you
|
81
|
+
conspicuously and appropriately publish on each copy an appropriate
|
82
|
+
copyright notice and disclaimer of warranty; keep intact all the
|
83
|
+
notices that refer to this License and to the absence of any
|
84
|
+
warranty; and give any other recipients of the Program a copy of
|
85
|
+
this License along with the Program.
|
86
|
+
|
87
|
+
You may charge a fee for the physical act of transferring a copy,
|
88
|
+
and you may at your option offer warranty protection in exchange
|
89
|
+
for a fee.
|
90
|
+
|
91
|
+
2. You may modify your copy or copies of the Program or any portion
|
92
|
+
of it, thus forming a work based on the Program, and copy and
|
93
|
+
distribute such modifications or work under the terms of Section 1
|
94
|
+
above, provided that you also meet all of these conditions:
|
95
|
+
|
96
|
+
a. You must cause the modified files to carry prominent notices
|
97
|
+
stating that you changed the files and the date of any change.
|
98
|
+
|
99
|
+
b. You must cause any work that you distribute or publish, that
|
100
|
+
in whole or in part contains or is derived from the Program
|
101
|
+
or any part thereof, to be licensed as a whole at no charge
|
102
|
+
to all third parties under the terms of this License.
|
103
|
+
|
104
|
+
c. If the modified program normally reads commands interactively
|
105
|
+
when run, you must cause it, when started running for such
|
106
|
+
interactive use in the most ordinary way, to print or display
|
107
|
+
an announcement including an appropriate copyright notice and
|
108
|
+
a notice that there is no warranty (or else, saying that you
|
109
|
+
provide a warranty) and that users may redistribute the
|
110
|
+
program under these conditions, and telling the user how to
|
111
|
+
view a copy of this License. (Exception: if the Program
|
112
|
+
itself is interactive but does not normally print such an
|
113
|
+
announcement, your work based on the Program is not required
|
114
|
+
to print an announcement.)
|
115
|
+
|
116
|
+
These requirements apply to the modified work as a whole. If
|
117
|
+
identifiable sections of that work are not derived from the
|
118
|
+
Program, and can be reasonably considered independent and separate
|
119
|
+
works in themselves, then this License, and its terms, do not
|
120
|
+
apply to those sections when you distribute them as separate
|
121
|
+
works. But when you distribute the same sections as part of a
|
122
|
+
whole which is a work based on the Program, the distribution of
|
123
|
+
the whole must be on the terms of this License, whose permissions
|
124
|
+
for other licensees extend to the entire whole, and thus to each
|
125
|
+
and every part regardless of who wrote it.
|
126
|
+
|
127
|
+
Thus, it is not the intent of this section to claim rights or
|
128
|
+
contest your rights to work written entirely by you; rather, the
|
129
|
+
intent is to exercise the right to control the distribution of
|
130
|
+
derivative or collective works based on the Program.
|
131
|
+
|
132
|
+
In addition, mere aggregation of another work not based on the
|
133
|
+
Program with the Program (or with a work based on the Program) on
|
134
|
+
a volume of a storage or distribution medium does not bring the
|
135
|
+
other work under the scope of this License.
|
136
|
+
|
137
|
+
3. You may copy and distribute the Program (or a work based on it,
|
138
|
+
under Section 2) in object code or executable form under the terms
|
139
|
+
of Sections 1 and 2 above provided that you also do one of the
|
140
|
+
following:
|
141
|
+
|
142
|
+
a. Accompany it with the complete corresponding machine-readable
|
143
|
+
source code, which must be distributed under the terms of
|
144
|
+
Sections 1 and 2 above on a medium customarily used for
|
145
|
+
software interchange; or,
|
146
|
+
|
147
|
+
b. Accompany it with a written offer, valid for at least three
|
148
|
+
years, to give any third-party, for a charge no more than your
|
149
|
+
cost of physically performing source distribution, a complete
|
150
|
+
machine-readable copy of the corresponding source code, to be
|
151
|
+
distributed under the terms of Sections 1 and 2 above on a
|
152
|
+
medium customarily used for software interchange; or,
|
153
|
+
|
154
|
+
c. Accompany it with the information you received as to the offer
|
155
|
+
to distribute corresponding source code. (This alternative is
|
156
|
+
allowed only for noncommercial distribution and only if you
|
157
|
+
received the program in object code or executable form with
|
158
|
+
such an offer, in accord with Subsection b above.)
|
159
|
+
|
160
|
+
The source code for a work means the preferred form of the work for
|
161
|
+
making modifications to it. For an executable work, complete
|
162
|
+
source code means all the source code for all modules it contains,
|
163
|
+
plus any associated interface definition files, plus the scripts
|
164
|
+
used to control compilation and installation of the executable.
|
165
|
+
However, as a special exception, the source code distributed need
|
166
|
+
not include anything that is normally distributed (in either
|
167
|
+
source or binary form) with the major components (compiler,
|
168
|
+
kernel, and so on) of the operating system on which the executable
|
169
|
+
runs, unless that component itself accompanies the executable.
|
170
|
+
|
171
|
+
If distribution of executable or object code is made by offering
|
172
|
+
access to copy from a designated place, then offering equivalent
|
173
|
+
access to copy the source code from the same place counts as
|
174
|
+
distribution of the source code, even though third parties are not
|
175
|
+
compelled to copy the source along with the object code.
|
176
|
+
|
177
|
+
4. You may not copy, modify, sublicense, or distribute the Program
|
178
|
+
except as expressly provided under this License. Any attempt
|
179
|
+
otherwise to copy, modify, sublicense or distribute the Program is
|
180
|
+
void, and will automatically terminate your rights under this
|
181
|
+
License. However, parties who have received copies, or rights,
|
182
|
+
from you under this License will not have their licenses
|
183
|
+
terminated so long as such parties remain in full compliance.
|
184
|
+
|
185
|
+
5. You are not required to accept this License, since you have not
|
186
|
+
signed it. However, nothing else grants you permission to modify
|
187
|
+
or distribute the Program or its derivative works. These actions
|
188
|
+
are prohibited by law if you do not accept this License.
|
189
|
+
Therefore, by modifying or distributing the Program (or any work
|
190
|
+
based on the Program), you indicate your acceptance of this
|
191
|
+
License to do so, and all its terms and conditions for copying,
|
192
|
+
distributing or modifying the Program or works based on it.
|
193
|
+
|
194
|
+
6. Each time you redistribute the Program (or any work based on the
|
195
|
+
Program), the recipient automatically receives a license from the
|
196
|
+
original licensor to copy, distribute or modify the Program
|
197
|
+
subject to these terms and conditions. You may not impose any
|
198
|
+
further restrictions on the recipients' exercise of the rights
|
199
|
+
granted herein. You are not responsible for enforcing compliance
|
200
|
+
by third parties to this License.
|
201
|
+
|
202
|
+
7. If, as a consequence of a court judgment or allegation of patent
|
203
|
+
infringement or for any other reason (not limited to patent
|
204
|
+
issues), conditions are imposed on you (whether by court order,
|
205
|
+
agreement or otherwise) that contradict the conditions of this
|
206
|
+
License, they do not excuse you from the conditions of this
|
207
|
+
License. If you cannot distribute so as to satisfy simultaneously
|
208
|
+
your obligations under this License and any other pertinent
|
209
|
+
obligations, then as a consequence you may not distribute the
|
210
|
+
Program at all. For example, if a patent license would not permit
|
211
|
+
royalty-free redistribution of the Program by all those who
|
212
|
+
receive copies directly or indirectly through you, then the only
|
213
|
+
way you could satisfy both it and this License would be to refrain
|
214
|
+
entirely from distribution of the Program.
|
215
|
+
|
216
|
+
If any portion of this section is held invalid or unenforceable
|
217
|
+
under any particular circumstance, the balance of the section is
|
218
|
+
intended to apply and the section as a whole is intended to apply
|
219
|
+
in other circumstances.
|
220
|
+
|
221
|
+
It is not the purpose of this section to induce you to infringe any
|
222
|
+
patents or other property right claims or to contest validity of
|
223
|
+
any such claims; this section has the sole purpose of protecting
|
224
|
+
the integrity of the free software distribution system, which is
|
225
|
+
implemented by public license practices. Many people have made
|
226
|
+
generous contributions to the wide range of software distributed
|
227
|
+
through that system in reliance on consistent application of that
|
228
|
+
system; it is up to the author/donor to decide if he or she is
|
229
|
+
willing to distribute software through any other system and a
|
230
|
+
licensee cannot impose that choice.
|
231
|
+
|
232
|
+
This section is intended to make thoroughly clear what is believed
|
233
|
+
to be a consequence of the rest of this License.
|
234
|
+
|
235
|
+
8. If the distribution and/or use of the Program is restricted in
|
236
|
+
certain countries either by patents or by copyrighted interfaces,
|
237
|
+
the original copyright holder who places the Program under this
|
238
|
+
License may add an explicit geographical distribution limitation
|
239
|
+
excluding those countries, so that distribution is permitted only
|
240
|
+
in or among countries not thus excluded. In such case, this
|
241
|
+
License incorporates the limitation as if written in the body of
|
242
|
+
this License.
|
243
|
+
|
244
|
+
9. The Free Software Foundation may publish revised and/or new
|
245
|
+
versions of the General Public License from time to time. Such
|
246
|
+
new versions will be similar in spirit to the present version, but
|
247
|
+
may differ in detail to address new problems or concerns.
|
248
|
+
|
249
|
+
Each version is given a distinguishing version number. If the
|
250
|
+
Program specifies a version number of this License which applies
|
251
|
+
to it and "any later version", you have the option of following
|
252
|
+
the terms and conditions either of that version or of any later
|
253
|
+
version published by the Free Software Foundation. If the Program
|
254
|
+
does not specify a version number of this License, you may choose
|
255
|
+
any version ever published by the Free Software Foundation.
|
256
|
+
|
257
|
+
10. If you wish to incorporate parts of the Program into other free
|
258
|
+
programs whose distribution conditions are different, write to the
|
259
|
+
author to ask for permission. For software which is copyrighted
|
260
|
+
by the Free Software Foundation, write to the Free Software
|
261
|
+
Foundation; we sometimes make exceptions for this. Our decision
|
262
|
+
will be guided by the two goals of preserving the free status of
|
263
|
+
all derivatives of our free software and of promoting the sharing
|
264
|
+
and reuse of software generally.
|
265
|
+
|
266
|
+
NO WARRANTY
|
267
|
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
|
268
|
+
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
269
|
+
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
270
|
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
271
|
+
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
|
272
|
+
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
273
|
+
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
|
274
|
+
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
275
|
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
|
276
|
+
SERVICING, REPAIR OR CORRECTION.
|
277
|
+
|
278
|
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
279
|
+
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
|
280
|
+
MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
|
281
|
+
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
282
|
+
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
283
|
+
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
284
|
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
|
285
|
+
OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
|
286
|
+
OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
|
287
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
288
|
+
|
289
|
+
END OF TERMS AND CONDITIONS
|
290
|
+
|
291
|
+
===How to Apply These Terms to Your New Programs
|
292
|
+
|
293
|
+
If you develop a new program, and you want it to be of the greatest
|
294
|
+
possible use to the public, the best way to achieve this is to make it
|
295
|
+
free software which everyone can redistribute and change under these
|
296
|
+
terms.
|
297
|
+
|
298
|
+
To do so, attach the following notices to the program. It is safest to
|
299
|
+
attach them to the start of each source file to most effectively convey
|
300
|
+
the exclusion of warranty; and each file should have at least the
|
301
|
+
"copyright" line and a pointer to where the full notice is found.
|
302
|
+
|
303
|
+
ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
|
304
|
+
Copyright (C) YYYY NAME OF AUTHOR
|
305
|
+
|
306
|
+
This program is free software; you can redistribute it and/or modify
|
307
|
+
it under the terms of the GNU General Public License as published by
|
308
|
+
the Free Software Foundation; either version 2 of the License, or
|
309
|
+
(at your option) any later version.
|
310
|
+
|
311
|
+
This program is distributed in the hope that it will be useful,
|
312
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
313
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
314
|
+
GNU General Public License for more details.
|
315
|
+
|
316
|
+
You should have received a copy of the GNU General Public License
|
317
|
+
along with this program; if not, write to the Free Software
|
318
|
+
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
319
|
+
|
320
|
+
Also add information on how to contact you by electronic and paper mail.
|
321
|
+
|
322
|
+
If the program is interactive, make it output a short notice like this
|
323
|
+
when it starts in an interactive mode:
|
324
|
+
|
325
|
+
Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
|
326
|
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
327
|
+
This is free software, and you are welcome to redistribute it
|
328
|
+
under certain conditions; type `show c' for details.
|
329
|
+
|
330
|
+
The hypothetical commands `show w' and `show c' should show the
|
331
|
+
appropriate parts of the General Public License. Of course, the
|
332
|
+
commands you use may be called something other than `show w' and `show
|
333
|
+
c'; they could even be mouse-clicks or menu items--whatever suits your
|
334
|
+
program.
|
335
|
+
|
336
|
+
You should also get your employer (if you work as a programmer) or your
|
337
|
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
338
|
+
necessary. Here is a sample; alter the names:
|
339
|
+
|
340
|
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
341
|
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
342
|
+
|
343
|
+
SIGNATURE OF TY COON, 1 April 1989
|
344
|
+
Ty Coon, President of Vice
|
345
|
+
|
346
|
+
This General Public License does not permit incorporating your program
|
347
|
+
into proprietary programs. If your program is a subroutine library,
|
348
|
+
you may consider it more useful to permit linking proprietary
|
349
|
+
applications with the library. If this is what you want to do, use the
|
350
|
+
GNU Library General Public License instead of this License.
|
351
|
+
|
data/INTRODUCTION
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
This is the documentation for RubyObjC,
|
2
|
+
a bridge connecting the Ruby and Objective-C languages.
|
3
|
+
It is automatically generated from the RubyObjC source files.
|
4
|
+
WARNING: This is a preliminary release. All features are subject to change.
|
5
|
+
|
6
|
+
=Copyright and License
|
7
|
+
|
8
|
+
RubyObjC is a copyrighted software product of Neon Design Technology, Inc.
|
9
|
+
It is released under the terms of the Ruby License.
|
10
|
+
See the LICENSE file for details.
|
11
|
+
|
12
|
+
=Requirements
|
13
|
+
|
14
|
+
RubyObjC has been tested on systems running Mac OS 10.4.8 and greater.
|
15
|
+
It is planned that other platforms will be supported in the future.
|
16
|
+
|
17
|
+
=Distribution
|
18
|
+
|
19
|
+
RubyObjC is distributed as a Ruby gem. To install it, use the following command:
|
20
|
+
|
21
|
+
gem install rubyobjc --source http://www.rubyobjc.com
|
22
|
+
|
23
|
+
=News
|
24
|
+
For the latest information about RubyObjC, visit http://www.rubyobjc.com.
|
25
|
+
|
26
|
+
=About RubyObjC
|
27
|
+
|
28
|
+
Ruby and Objective-C are powerful languages for software development that have complementary
|
29
|
+
strengths and weaknesses.
|
30
|
+
|
31
|
+
* Ruby is highly expressive, interpreted, and dynamic. It can be used to write standalone
|
32
|
+
programs and can be run interactively from a command line. It was specifically designed to be an
|
33
|
+
easy-to-use interface for software development. It is implemented in the C programming
|
34
|
+
language and has a well-defined interface for extensions written in C. However, because
|
35
|
+
Ruby is interpreted and extremely dynamic, it is poorly suited to the inner workings of
|
36
|
+
memory- or compute-intensive software applications.
|
37
|
+
|
38
|
+
* Objective-C is a compiled object-oriented extension of C.
|
39
|
+
It is much more verbose than Ruby and cannot be used interactively.
|
40
|
+
But because it is based on C, it can be used to write fast, efficient code and
|
41
|
+
has access to many powerful libraries. Also, Objective-C includes
|
42
|
+
a dynamic runtime environment that allows run-time introspection and definition of classes
|
43
|
+
and methods. This runtime environment is the key ingredient
|
44
|
+
that makes the RubyObjC bridge possible.
|
45
|
+
|
46
|
+
RubyObjC allows Ruby and Objective-C to be used together. With it, software developers
|
47
|
+
can use the strengths of both languages while avoiding their respective weaknesses.
|
48
|
+
|
49
|
+
Prior to RubyObjC, another bridge was developed between Ruby and Objective-C.
|
50
|
+
This bridge, RubyCocoa, is available under the Ruby license and is actively
|
51
|
+
supported by a small team of volunteers. Recently it has also received many
|
52
|
+
contributions from Laurent Sansonetti at Apple Computer, Inc.
|
53
|
+
|
54
|
+
RubyObjC was created so that emphasis could be placed on the following values:
|
55
|
+
|
56
|
+
====A GOOD BRIDGE GETS A LOT OF TRAFFIC
|
57
|
+
RubyObjC directly inserts handlers for Ruby methods in Objective-C method tables
|
58
|
+
and adds handlers for Objective-C methods to the Ruby method tables.
|
59
|
+
This allows method calls to be made more quickly than in bridges that resolve calls
|
60
|
+
dynamically, perhaps by using Ruby's "method_missing" method.
|
61
|
+
As a result, we can afford to cross the RubyObjC bridge frequently.
|
62
|
+
|
63
|
+
====YOU CAN NEVER BE TOO RICH, TOO THIN, OR TOO INTROSPECTIVE
|
64
|
+
Because handlers are inserted in the Ruby class method tables, Ruby's "methods" method
|
65
|
+
can be used to introspect the capabilities of Objective-C objects. More generally,
|
66
|
+
RubyObjC includes Ruby interfaces that provide direct access to the Objective-C
|
67
|
+
runtime and to data structures and statistics maintained by the RubyObjC bridge.
|
68
|
+
A machine- and human-readable log file also makes it easier to diagnose problems in
|
69
|
+
RubyObjC applications.
|
70
|
+
|
71
|
+
====CLARITY IS BEAUTY
|
72
|
+
To avoid ambiguity, only one naming convention is used to map Objective-C selector
|
73
|
+
names to Ruby. Some may find this less "beautiful", but the guiding principles are that
|
74
|
+
ambiguity undermines reliability and that reliability is an essential element of beauty.
|
75
|
+
|
76
|
+
Also, the source code for RubyObjC itself was written to be as clear and minimal as possible
|
77
|
+
so that RubyObjC could be reliably used in commercial software projects.
|
78
|
+
The emphasis is on clarity and reliability over completeness:
|
79
|
+
currently RubyObjC does not support the full range of bridged types that RubyCocoa does,
|
80
|
+
but it is believed that this limitation is easily worked around with project-specific
|
81
|
+
Ruby and Objective-C code. RubyObjC's deep Ruby interfaces to the Objective-C runtime
|
82
|
+
allow many more of these issues to be addressed directly from Ruby.
|
83
|
+
|
84
|
+
====LIBERTY, EQUALITY, FRATERNITY
|
85
|
+
In RubyObjC, Objective-C and Ruby are each important contributors that addresses weaknesses of the other.
|
86
|
+
Instead of forcing one language to fully adapt to the other, we blend them together in a powerful partnership.
|
87
|
+
|
88
|
+
====BUILD IT THE RUBY WAY
|
89
|
+
RubyObjC embraces Ruby as a systems-programming language and as a platform for domain-specific
|
90
|
+
language (DSL) development. Rake is used to build the bridge, RDoc is used to generate
|
91
|
+
documentation, testing is managed with Test::Unit, and RubyObjC is distributed as a Ruby gem.
|
92
|
+
|
93
|
+
RubyObjC includes a Rake task that can be used to build a Cocoa application.
|
94
|
+
When an application is written with Ruby code only, it can be built with no
|
95
|
+
compilation or linking. When the application includes Objective-C code, that code is
|
96
|
+
automatically compiled and linked into the executable. This allows Cocoa applications
|
97
|
+
to be easily built from the command line or your favorite text editor.
|
98
|
+
|
99
|
+
There's also an emphasis in RubyObjC toward minimizing dependence on Interface Builder for
|
100
|
+
constructing user interfaces. Examples illustrate the use of Ruby to
|
101
|
+
build interfaces by direct manipulation of Cocoa objects. This is leading to Ruby DSLs
|
102
|
+
for concisely designing interfaces and is loosening Objective-C's bondage to
|
103
|
+
platform-dependent graphical tools.
|
104
|
+
|
105
|
+
====PORTABILITY
|
106
|
+
Although Objective-C is most often used on Apple systems,
|
107
|
+
it is supported on other platforms by the GNU gcc compiler.
|
108
|
+
RubyObjC was designed to minimize dependencies on Apple proprietary features
|
109
|
+
so that it can be easily ported to other platforms.
|
110
|
+
It was originally developed on a prerelease version of Apple's OS X 10.5 (Leopard),
|
111
|
+
then was back-ported to OS X 10.4 (Tiger).
|
112
|
+
|
113
|
+
=Author
|
114
|
+
RubyObjC was written by me, Tim Burks.
|
115
|
+
Prior to its development, I built a web site that documented RubyCocoa.
|
116
|
+
I called it "RubyCocoa Resources" and you'll find it at http://www.rubycocoa.com.
|
117
|
+
|
118
|
+
=Acknowledgements
|
119
|
+
RubyObjC would not have been possible without the preceeding efforts of many giants.
|
120
|
+
Some of them include:
|
121
|
+
|
122
|
+
* Hisakuni FUJIMOTO, who developed RubyCocoa, the first bridge connecting Ruby and Objective-C.
|
123
|
+
Many others contributed to RubyCocoa development, notably Chris Thomas, Kimura WATARU,
|
124
|
+
Jonathan Paisley, and Laurent Sansonetti.
|
125
|
+
|
126
|
+
* Anthony Green, the creator of libffi, the library that allows function calls to be dynamically
|
127
|
+
constructed and made from C. The libffi port to OS X was done by the talented team
|
128
|
+
behind the PyObjC project.
|
129
|
+
|
130
|
+
* Jim Weirich, the author of Rake, the build system used by RubyObjC.
|
131
|
+
|
132
|
+
* Dave Thomas, who developed RDoc, the documentation system used by RubyObjC.
|
133
|
+
Evan Weaver created Allison, the RDoc template used to generate these web pages.
|
134
|
+
|
135
|
+
* Nathaniel Talbott, the creator of Test::Unit.
|
136
|
+
|
137
|
+
* Brad Cox and Yukihiro MATSUMOTO, who created the Objective-C and Ruby programming languages, respectively.
|
data/USAGE
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
RubyObjC includes tools for building Cocoa applications from pure-Ruby source code or from a mixture of Ruby and Objective-C sources.
|
2
|
+
|
3
|
+
=Project Template
|
4
|
+
|
5
|
+
To create a new Cocoa application, run the *rubyapp* command. Give it the application name as an argument. If no name is specified, the application will be called "app". In either case, a directory will be created for the application that contains a skeleton for a RubyObjC application. This consists of a main.rb Ruby file and a Rakefile.
|
6
|
+
|
7
|
+
The main.rb file will look something like this:
|
8
|
+
# Set the application search path
|
9
|
+
ObjC.set_path :LOCAL
|
10
|
+
|
11
|
+
# Activate any optional components
|
12
|
+
ObjC.require :Foundation
|
13
|
+
ObjC.require :AppKit
|
14
|
+
ObjC.require :console
|
15
|
+
ObjC.require :menu
|
16
|
+
|
17
|
+
# Load all ruby files in the application's Resource directory
|
18
|
+
ObjC.load_internal_files(__FILE__)
|
19
|
+
|
20
|
+
# Load any ruby files in same directory as the application
|
21
|
+
# optional -- use for development only!
|
22
|
+
#ObjC.load_external_files
|
23
|
+
|
24
|
+
# The application delegate configures the application
|
25
|
+
# after all basic services have been started
|
26
|
+
class ApplicationDelegate < ObjC::NSObject
|
27
|
+
imethod "applicationDidFinishLaunching:" do |sender|
|
28
|
+
make_menu "RubyObjC Demo"
|
29
|
+
console
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# keep a reference to the delegate to keep it safe
|
34
|
+
# from premature garbage-collection
|
35
|
+
$delegate = ApplicationDelegate.alloc.init
|
36
|
+
ObjC::NSApplication.sharedApplication.setDelegate_($delegate)
|
37
|
+
|
38
|
+
# if the app is started at the command line,
|
39
|
+
# we need this to make it take focus
|
40
|
+
ObjC::NSApplication.sharedApplication.activateIgnoringOtherApps_(true)
|
41
|
+
|
42
|
+
# start the main event loop
|
43
|
+
ObjC.NSApplicationMain(0, nil)
|
44
|
+
|
45
|
+
The first step in any RubyObjC application is to specify the search path to
|
46
|
+
use for any Ruby components required by the application. This can be either
|
47
|
+
:LOCAL (to use the search path of the Ruby installed locally on the system),
|
48
|
+
:INTERNAL (to only search for components within the application's Resource directory),
|
49
|
+
or a Ruby array of directory names.
|
50
|
+
Next, several built-in RubyObjC components are loaded using calls to ObjC.require.
|
51
|
+
Then all of the Ruby files in the application's Resource directory are loaded.
|
52
|
+
Next and optionally, any Ruby files in the same directory as the application are
|
53
|
+
loaded. This disabled by default but is sometimes useful during application
|
54
|
+
development. After this, the application's delegate is defined. This
|
55
|
+
allows us to specify actions to be performed after the application's data
|
56
|
+
structures and event handling loop have been initialized. In this case, we
|
57
|
+
create a set of menus and start an interactive console in a Cocoa window.
|
58
|
+
The delegate is instantiated and set for the application. Since delegates
|
59
|
+
are not retained by their client objects, we assign the delegate to a global
|
60
|
+
variable to keep it safe from Ruby's garbage collector. Then after a slight
|
61
|
+
hack for command-line starts, we enter the main Cocoa event loop.
|
62
|
+
|
63
|
+
The Rakefile is extremely simple:
|
64
|
+
|
65
|
+
require 'rake/cocoa'
|
66
|
+
|
67
|
+
Rake::CocoaApplication.new do |t|
|
68
|
+
t.application = 'RubyObjC'
|
69
|
+
t.identifier = 'com.rubyobjc.app'
|
70
|
+
end
|
71
|
+
|
72
|
+
It simply sets the name of the application and the application's identifier.
|
73
|
+
Application identifiers are like reversed domain names and are used to
|
74
|
+
uniquely describe Cocoa applications.
|
75
|
+
|
76
|
+
=Rake Tasks
|
77
|
+
|
78
|
+
To build the application, type "rake"; to run it, use "rake run".
|
79
|
+
|
80
|
+
If no Objective-C source files are present in the application directory,
|
81
|
+
the Rake::CocoaApplication task can build a Cocoa application without
|
82
|
+
compilation using a pre-built executable. Otherwise, all Objective-C
|
83
|
+
source files are compiled and linked with the RubyObjC and Ruby libraries
|
84
|
+
to create the application's executable. All Ruby source files and nib
|
85
|
+
files in the project directory are copied into the application and the
|
86
|
+
application's Info.plist file is automatically generated.
|
87
|
+
|
88
|
+
By default, universal applications are generated.
|
89
|
+
|
90
|
+
The "rake dmg" task will pack the compiled application in a disk image
|
91
|
+
(dmg) file for easy distribution.
|
92
|
+
|
93
|
+
=Command-Line and Script Usage
|
94
|
+
|
95
|
+
RubyObjC can also be used from the irb (Interactive Ruby) command line and
|
96
|
+
in Ruby scripts. Because it is distributed as a gem, you'll need to
|
97
|
+
<tt>require 'rubygems'</tt> first, then simply <tt>require 'objc'</tt>.
|
98
|
+
For example, to list the methods of NSObject, you might do this:
|
99
|
+
|
100
|
+
require 'rubygems'
|
101
|
+
require 'objc'
|
102
|
+
c = ObjC::Class.find("NSObject")
|
103
|
+
puts c.imethods.sort
|
104
|
+
|
105
|
+
You might prefer this, which also includes extra methods only available from Ruby:
|
106
|
+
|
107
|
+
require 'rubygems'
|
108
|
+
require 'objc'
|
109
|
+
o = ObjC::NSObject.alloc.init
|
110
|
+
puts o.methods.sort
|
111
|
+
|
112
|
+
There's a lot more that can happen when you put Ruby and the Objective-C runtime together.
|
113
|
+
|
data/app/Rakefile
ADDED
data/app/main.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Set the application search path
|
2
|
+
ObjC.set_path :LOCAL
|
3
|
+
|
4
|
+
# Activate any optional components
|
5
|
+
ObjC.require :Foundation
|
6
|
+
ObjC.require :AppKit
|
7
|
+
ObjC.require :console
|
8
|
+
ObjC.require :menu
|
9
|
+
|
10
|
+
# Load all ruby files in the application's Resource directory
|
11
|
+
ObjC.load_internal_files(__FILE__)
|
12
|
+
|
13
|
+
# Load any ruby files in same directory as the application
|
14
|
+
# optional -- use for development only!
|
15
|
+
#ObjC.load_external_files
|
16
|
+
|
17
|
+
# The application delegate configures the application
|
18
|
+
# after all basic services have been started
|
19
|
+
class ApplicationDelegate < ObjC::NSObject
|
20
|
+
imethod "applicationDidFinishLaunching:" do |sender|
|
21
|
+
make_menu "RubyObjC Demo"
|
22
|
+
console
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# keep a reference to the delegate to keep it safe
|
27
|
+
# from premature garbage-collection
|
28
|
+
$delegate = ApplicationDelegate.alloc.init
|
29
|
+
ObjC::NSApplication.sharedApplication.setDelegate_($delegate)
|
30
|
+
|
31
|
+
# if the app is started at the command line,
|
32
|
+
# we need this to make it take focus
|
33
|
+
ObjC::NSApplication.sharedApplication.activateIgnoringOtherApps_(true)
|
34
|
+
|
35
|
+
# start the main event loop
|
36
|
+
ObjC.NSApplicationMain(0, nil)
|
data/app/random.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Aaron Hillegass' RandomApp in 100% Ruby
|
2
|
+
# to see it the old-fashioned way, see Chapter 2 of Aaron's book:
|
3
|
+
# "Cocoa Programming for Mac OS X, 2nd Edition"
|
4
|
+
class RandomAppWindowController < ObjC::NSObject
|
5
|
+
attr_accessor :seedButton, :generateButton, :textField, :window
|
6
|
+
|
7
|
+
def init
|
8
|
+
super
|
9
|
+
styleMask = ObjC::NSTitledWindowMask + ObjC::NSClosableWindowMask + ObjC::NSMiniaturizableWindowMask
|
10
|
+
@window = with(ObjC::NSWindow.alloc.initWithContentRect_styleMask_backing_defer_(
|
11
|
+
[300,200,340,120], styleMask, ObjC::NSBackingStoreBuffered, false)) do |w|
|
12
|
+
w.set(:releasedWhenClosed => 0, :title => 'RandomApp')
|
13
|
+
@view = with(ObjC::NSView.alloc.initWithFrame_(w.frame)) do |v|
|
14
|
+
@seedButton = with(ObjC::NSButton.alloc.initWithFrame_([20,75,300,25])) do |b|
|
15
|
+
b.set({
|
16
|
+
:title => "Seed random number generator with time",
|
17
|
+
:action => "seed:", :target => self,
|
18
|
+
:bezelStyle => ObjC::NSRoundedBezelStyle
|
19
|
+
})
|
20
|
+
v.addSubview_ b
|
21
|
+
end
|
22
|
+
@generateButton = with(ObjC::NSButton.alloc.initWithFrame_([20,45,300,25])) do |b|
|
23
|
+
b.set({
|
24
|
+
:title => "Generate random number",
|
25
|
+
:action => "generate:", :target => self,
|
26
|
+
:bezelStyle => ObjC::NSRoundedBezelStyle
|
27
|
+
})
|
28
|
+
v.addSubview_ b
|
29
|
+
end
|
30
|
+
@textField = with(ObjC::NSTextField.alloc.initWithFrame_([20,20,300,20])) do |t|
|
31
|
+
t.set({
|
32
|
+
:objectValue => ObjC::NSCalendarDate.calendarDate,
|
33
|
+
:editable => false,
|
34
|
+
:drawsBackground => false,
|
35
|
+
:alignment => ObjC::NSCenterTextAlignment,
|
36
|
+
:bezeled => false
|
37
|
+
})
|
38
|
+
v.addSubview_ t
|
39
|
+
end
|
40
|
+
w.setContentView_ v
|
41
|
+
end
|
42
|
+
w.center
|
43
|
+
w.makeKeyAndOrderFront_ self
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
imethod "seed:" do |sender|
|
49
|
+
srand Time.now.to_i
|
50
|
+
@textField.setStringValue_ "generator seeded"
|
51
|
+
end
|
52
|
+
|
53
|
+
imethod "generate:" do |sender|
|
54
|
+
@textField.setIntValue_(rand(100) + 1)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def with(x)
|
59
|
+
yield x if block_given?; x
|
60
|
+
end if not defined? with
|
61
|
+
|
62
|
+
# create a RandomApp window
|
63
|
+
def raw
|
64
|
+
RandomAppWindowController.alloc.init
|
65
|
+
end
|
data/bin/rubyapp
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# create a skeletal cocoa application in the current directory
|
4
|
+
#
|
5
|
+
# usage: rubyapp <name>
|
6
|
+
#
|
7
|
+
# Copyright (c) 2007 Tim Burks, Neon Design Technology, Inc.
|
8
|
+
# For more information about this file, visit http://www.rubyobjc.com.
|
9
|
+
|
10
|
+
appname = (ARGV.length > 0) ? ARGV[0] : "app"
|
11
|
+
|
12
|
+
source = File.dirname(__FILE__) + '/../app'
|
13
|
+
dest = `pwd`.chomp + '/' + appname
|
14
|
+
|
15
|
+
puts "Creating skeleton app in #{dest}."
|
16
|
+
`cp -r #{source} '#{dest}'`
|
17
|
+
|
18
|
+
puts "Set the application name in #{dest}/Rakefile."
|
data/lib/librubyobjc.a
ADDED
Binary file
|
data/lib/objc.bundle
ADDED
Binary file
|
data/lib/rake/cocoa.rb
ADDED
@@ -0,0 +1,428 @@
|
|
1
|
+
#
|
2
|
+
# cocoa.rb
|
3
|
+
#
|
4
|
+
# Rake tasks for RubyObjC projects.
|
5
|
+
# Use them to build and test applications and bundles that use RubyObjC.
|
6
|
+
#
|
7
|
+
# Typical usage:
|
8
|
+
# -----------------------------------------------
|
9
|
+
# require 'rake/cocoa'
|
10
|
+
#
|
11
|
+
# Rake::CocoaApplication.new do |t|
|
12
|
+
# t.application = "My Application"
|
13
|
+
# t.identifier = 'com.rubyobjc.myapp'
|
14
|
+
# t.icon_file = 'myapp.icns'
|
15
|
+
# end
|
16
|
+
# -----------------------------------------------
|
17
|
+
#
|
18
|
+
# See the RubyObjC example projects for more examples,
|
19
|
+
# or just read the source below.
|
20
|
+
#
|
21
|
+
# Copyright (c) 2007 Tim Burks, Neon Design Technology, Inc.
|
22
|
+
# For more information about this file, visit http://www.rubyobjc.com.
|
23
|
+
|
24
|
+
require 'rake'
|
25
|
+
require 'rake/clean'
|
26
|
+
require 'rake/tasklib'
|
27
|
+
|
28
|
+
LIBDIR = File.dirname(__FILE__) + '/..'
|
29
|
+
BASEAPP = LIBDIR + '/rubyobjcapp'
|
30
|
+
|
31
|
+
module Rake
|
32
|
+
class CocoaTask < TaskLib
|
33
|
+
|
34
|
+
# helper function used by both applications and bundles
|
35
|
+
def generate_compilation_tasks
|
36
|
+
# source files must be in appropriate subdirectories ('objc', 'ruby', or 'resources')
|
37
|
+
@erb_headers = FileList['objc/*.rh']
|
38
|
+
@erb_files = FileList['objc/*.rm']
|
39
|
+
@bison_files = FileList['objc/*.y']
|
40
|
+
@flex_files = FileList['objc/*.l']
|
41
|
+
@c_files = FileList['objc/*.c']
|
42
|
+
@objc_files = FileList['*.m'] + FileList['objc/*.m']
|
43
|
+
|
44
|
+
@gcc_files = @objc_files + @c_files + @erb_files.sub(/\.r/, '.') + @bison_files.sub(/\.y$/, '.m') + @flex_files.sub(/\.l$/, '.m')
|
45
|
+
@gcc_objects = @gcc_files.sub(/\.c$/, '.o').sub(/\.m$/, '.o').uniq
|
46
|
+
|
47
|
+
@nib_files = FileList['English.lproj/*.nib'] + FileList['resources/English.lproj/*.nib']
|
48
|
+
@icon_files = FileList['*.icns'] + FileList['resources/*.icns']
|
49
|
+
|
50
|
+
@cc = "gcc"
|
51
|
+
@includes = %w{RubyCocoa Ruby}.map {|f| " -I/System/Library/Frameworks/#{f}.framework/Headers"}.join
|
52
|
+
@ldflags += " -isysroot /Developer/SDKs/MacOSX10.4u.sdk"
|
53
|
+
@ldflags += @frameworks.map {|framework| " -framework #{framework}"}.join
|
54
|
+
@ldflags += @libs.map {|lib| " -l#{lib}"}.join
|
55
|
+
@ldflags += @lib_dirs.map {|libdir| " -L#{libdir}"}.join + " -L#{LIBDIR}"
|
56
|
+
|
57
|
+
# default task for generated code, define it here in case there is none needed
|
58
|
+
task :generated
|
59
|
+
|
60
|
+
@generated_files = FileList.new
|
61
|
+
|
62
|
+
# remove all generated files
|
63
|
+
task :remove_generated do
|
64
|
+
sh "rm #{@generated_files}"
|
65
|
+
end
|
66
|
+
|
67
|
+
# rebuild all generated files
|
68
|
+
task :regenerate => [:remove_generated, :generated]
|
69
|
+
|
70
|
+
# ERB code generators for Objective-C code
|
71
|
+
(@erb_headers + @erb_files).each {|template|
|
72
|
+
generated = template.sub(/\.r/, '.')
|
73
|
+
task :generated => generated
|
74
|
+
file generated => template do |t|
|
75
|
+
sh "cd objc; erb #{File.basename(template)} > #{File.basename(generated)}"
|
76
|
+
end
|
77
|
+
CLOBBER.include(generated)
|
78
|
+
@generated_files.include(generated)
|
79
|
+
}
|
80
|
+
|
81
|
+
# YACC grammars
|
82
|
+
@bison_files.each {|bisonfile|
|
83
|
+
generatedsource = bisonfile.sub(/\.y$/, '.m')
|
84
|
+
generatedheader = bisonfile.sub(/\.y$/, '.h')
|
85
|
+
file generatedsource => bisonfile
|
86
|
+
CLOBBER.include(generatedsource, generatedheader)
|
87
|
+
@generated_files.include(generatedsource, generatedheader)
|
88
|
+
}
|
89
|
+
|
90
|
+
rule ".m" => [".y"] do |t|
|
91
|
+
basename = t.name.split('.')[0..-2].join('.')
|
92
|
+
prefix = t.name.gsub("objc/", "").gsub("Parser.m", "_").downcase
|
93
|
+
sh "/usr/local/bin/bison -d #{t.source} --name-prefix=#{prefix}"
|
94
|
+
sh "mv *.tab.* objc"
|
95
|
+
sh "mv #{basename}.tab.h #{basename}.h"
|
96
|
+
sh "sed -e 's/tab.c/m/' #{basename}.tab.c > #{basename}.m"
|
97
|
+
sh "rm #{basename}.tab.c"
|
98
|
+
end
|
99
|
+
|
100
|
+
# FLEX lexers
|
101
|
+
@flex_files.each {|flexfile|
|
102
|
+
generatedsource = flexfile.sub(/\.l$/, '.m')
|
103
|
+
file generatedsource => flexfile
|
104
|
+
CLOBBER.include(generatedsource)
|
105
|
+
@generated_files.include(generatedsource)
|
106
|
+
}
|
107
|
+
|
108
|
+
rule ".m" => [".l"] do |t|
|
109
|
+
prefix = t.name.gsub("objc/", "").gsub("Lexer.m", "_").downcase
|
110
|
+
sh "/usr/local/bin/flex -o#{t.name} --prefix=#{prefix} #{t.source}"
|
111
|
+
end
|
112
|
+
|
113
|
+
# basic compilation with gcc
|
114
|
+
rule ".o" => [".m"] do |t|
|
115
|
+
sh "#{@cc} #{@cflags} #{@arch} #{@includes} -c -o #{t.name} #{t.source}"
|
116
|
+
end
|
117
|
+
|
118
|
+
rule ".o" => [".c"] do |t|
|
119
|
+
sh "#{@cc} #{@cflags} #{@arch} #{@includes} -c -o #{t.name} #{t.source}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class CocoaApplication < CocoaTask
|
125
|
+
attr_accessor :application, :identifier, :icon_file, :frameworks, :info, :cflags, :ldflags, :resources, :arch
|
126
|
+
|
127
|
+
def initialize
|
128
|
+
@name = :app
|
129
|
+
@application = "RubyObjC"
|
130
|
+
@identifier = 'com.rubyobjc.app'
|
131
|
+
@icon_file = ''
|
132
|
+
@creator_code = '????'
|
133
|
+
@info = nil
|
134
|
+
@resources = []
|
135
|
+
|
136
|
+
@arch = "-arch i386 -arch ppc" # build universal apps by default
|
137
|
+
@cflags = "-g -Wall"
|
138
|
+
|
139
|
+
@frameworks = %w{Cocoa}
|
140
|
+
@libs = %w{objc rubyobjc}
|
141
|
+
@lib_dirs = []
|
142
|
+
@ldflags = ""
|
143
|
+
|
144
|
+
if @gcc_objects != []
|
145
|
+
if File.exist? "/System/Library/Frameworks/Ruby.framework"
|
146
|
+
@frameworks << "Ruby"
|
147
|
+
else
|
148
|
+
@libs << "ruby-static"
|
149
|
+
if File.exist? "/usr/local/lib/libruby-static.a"
|
150
|
+
@lib_dirs << "/usr/local/lib"
|
151
|
+
elsif File.exist? "/opt/local/lib/libruby-static.a"
|
152
|
+
@lib_dirs << "/opt/local/lib" # macports
|
153
|
+
@arch = "" # macports are never universal
|
154
|
+
else
|
155
|
+
raise "can't find Ruby.framework or libruby-static.a"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
yield self if block_given?
|
161
|
+
|
162
|
+
@app_dir = "#{@application}.app"
|
163
|
+
@contents_dir = "#{@app_dir}/Contents"
|
164
|
+
@executable_dir = "#{@contents_dir}/MacOS"
|
165
|
+
@resource_dir = "#{@contents_dir}/Resources"
|
166
|
+
@localized_dir = "#{@contents_dir}/Resources/English.lproj"
|
167
|
+
FileList[@app_dir, @contents_dir, @executable_dir, @resource_dir, @localized_dir].each {|d| directory d}
|
168
|
+
|
169
|
+
task :default => :app
|
170
|
+
|
171
|
+
desc "Build the application."
|
172
|
+
task :app => [:executable, :resources, :info_plist, :pkginfo]
|
173
|
+
|
174
|
+
desc "Run the application."
|
175
|
+
task :run => :app do
|
176
|
+
sh "open '#{@application}.app'"
|
177
|
+
end
|
178
|
+
|
179
|
+
desc "Debug the application by running it from the console; log messages will be displayed in the terminal."
|
180
|
+
task :debug => :app do
|
181
|
+
sh "'#{@executable_dir}/#{@application}'"
|
182
|
+
end
|
183
|
+
|
184
|
+
desc "Debug the application with gdb."
|
185
|
+
task :gdb => :app do
|
186
|
+
sh "gdb '#{@executable_dir}/#{@application}'"
|
187
|
+
end
|
188
|
+
|
189
|
+
desc "Build a disk image for distributing the application."
|
190
|
+
task :dmg => :app do
|
191
|
+
sh "rm -rf '#{@application}.dmg' dmg"
|
192
|
+
sh "mkdir dmg; cp -r '#{@application}.app' dmg"
|
193
|
+
sh "hdiutil create -srcdir dmg '#{@application}.dmg' -volname '#{@application}'"
|
194
|
+
sh "rm -rf dmg"
|
195
|
+
end
|
196
|
+
|
197
|
+
generate_compilation_tasks
|
198
|
+
|
199
|
+
@ruby_files = File.exist?("ruby") ? FileList['ruby/*.rb'] : FileList['*.rb']
|
200
|
+
@nu_files = File.exist?("nu") ? FileList['nu/*.nu'] : FileList['*.nu']
|
201
|
+
|
202
|
+
desc "Create the executable (subtask of app)."
|
203
|
+
task :executable => [:generated, @executable_dir, "#{@executable_dir}/#{@application}"]
|
204
|
+
if @gcc_objects == []
|
205
|
+
file "#{@executable_dir}/#{@application}" => BASEAPP do |t|
|
206
|
+
sh "cp #{BASEAPP} '#{t.name}'"
|
207
|
+
sh "chmod +x '#{t.name}'"
|
208
|
+
end
|
209
|
+
else
|
210
|
+
file "#{@executable_dir}/#{@application}" => @gcc_objects do |t|
|
211
|
+
sh "#{@cc} #{@gcc_objects} #{@cflags} #{@arch} #{@ldflags} -o '#{t.name}'"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
desc "Copy files to the application's Resources directory (subtask of app)."
|
216
|
+
task :resources => [@resource_dir, :infoplist_strings, :mainmenu]
|
217
|
+
[@ruby_files, @nu_files, @icon_files, @resources].each{|list| list.each {|f|
|
218
|
+
task :resources => "#{@resource_dir}/#{f.split("/")[-1]}"
|
219
|
+
file "#{@resource_dir}/#{f.split("/")[-1]}" => f do |t|
|
220
|
+
cp_r f, t.name
|
221
|
+
end
|
222
|
+
}}
|
223
|
+
|
224
|
+
@nib_files.each {|f|
|
225
|
+
g = f.split('/')[-1]
|
226
|
+
task :resources => "#{@localized_dir}/#{g}"
|
227
|
+
file "#{@localized_dir}/#{g}" => f do |t|
|
228
|
+
cp_r "English.lproj/#{g}", t.name
|
229
|
+
end
|
230
|
+
}
|
231
|
+
|
232
|
+
desc "Copy the default MainMenu.nib file, if necessary."
|
233
|
+
task :mainmenu => @localized_dir do |t|
|
234
|
+
cp_r LIBDIR+"/resources/English.lproj/MainMenu.nib", @localized_dir+"/MainMenu.nib" unless File.exist? "English.lproj/MainMenu.nib"
|
235
|
+
end
|
236
|
+
|
237
|
+
desc "Copy the default InfoPlist.strings file, if necessary."
|
238
|
+
task :infoplist_strings => @localized_dir do |t|
|
239
|
+
cp_r LIBDIR+"/resources/English.lproj/InfoPlist.strings", @localized_dir+"/InfoPlist.strings"
|
240
|
+
end
|
241
|
+
|
242
|
+
if File.exist?("lib")
|
243
|
+
task :resources => "#{@resource_dir}/lib"
|
244
|
+
file "#{@resource_dir}/lib" => "lib" do |t|
|
245
|
+
sh "rm -rf #{t.name}"
|
246
|
+
cp_r "lib", t.name
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
desc "Create the Info.plist file (subtask of app)."
|
251
|
+
task :info_plist => [@contents_dir, "#{@contents_dir}/Info.plist"]
|
252
|
+
file "#{@contents_dir}/Info.plist" do |t|
|
253
|
+
info = {
|
254
|
+
:CFBundleDevelopmentRegion => "English",
|
255
|
+
:CFBundleExecutable => @application,
|
256
|
+
:CFBundleIconFile => @icon_file,
|
257
|
+
:CFBundleIdentifier => @identifier,
|
258
|
+
:CFBundleInfoDictionaryVersion => "6.0",
|
259
|
+
:CFBundleName => @application,
|
260
|
+
:CFBundlePackageType => "APPL",
|
261
|
+
:CFBundleSignature => @creator_code,
|
262
|
+
:CFBundleVersion => "1.0",
|
263
|
+
:NSMainNibFile => "MainMenu",
|
264
|
+
:NSPrincipalClass => "NSApplication"
|
265
|
+
}
|
266
|
+
info = info.merge(@info) if @info
|
267
|
+
plist = PList.generate(info)
|
268
|
+
File.open(t.name, "w") {|f| f.write plist}
|
269
|
+
end
|
270
|
+
|
271
|
+
desc "Create the PkgInfo file (subtask of app)."
|
272
|
+
task :pkginfo => [@contents_dir, "#{@contents_dir}/PkgInfo"]
|
273
|
+
file "#{@contents_dir}/PkgInfo" do |t|
|
274
|
+
sh "echo -n 'APPL#{@creator_code}' > '#{t.name}'"
|
275
|
+
end
|
276
|
+
|
277
|
+
CLEAN.include("**/*.o") # all object files
|
278
|
+
CLOBBER.include("*.lproj/*~.nib") # backup nib files
|
279
|
+
CLOBBER.include("#{@app_dir}") # the application
|
280
|
+
CLOBBER.include(".gdb_history") # support files
|
281
|
+
|
282
|
+
if @gcc_objects != []
|
283
|
+
desc "Create a bundle containing all objc sources; bundles can be loaded for testing and debugging in Ruby."
|
284
|
+
task :bundle => [:generated, "#{@application.downcase}.bundle"]
|
285
|
+
file "#{@application.downcase}.bundle" => @gcc_objects do |t|
|
286
|
+
sh "#{@cc} #{@gcc_objects} #{@cflags} #{@arch} #{@ldflags} -o '#{@application.downcase}.bundle' -bundle"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
class CocoaBundle < CocoaTask
|
293
|
+
attr_accessor :bundle, :identifier, :icon_file, :frameworks, :info, :cflags, :ldflags, :resources, :arch
|
294
|
+
|
295
|
+
def initialize
|
296
|
+
@name = :bundle
|
297
|
+
@bundle = "RubyObjC"
|
298
|
+
@identifier = 'com.rubyobjc.bundle'
|
299
|
+
@info = nil
|
300
|
+
@resources = []
|
301
|
+
|
302
|
+
@arch = "-arch i386 -arch ppc" # build universal by default
|
303
|
+
@cflags = "-g -Wall"
|
304
|
+
|
305
|
+
@frameworks = %w{Cocoa}
|
306
|
+
@libs = %w{objc}
|
307
|
+
@lib_dirs = []
|
308
|
+
@ldflags = ""
|
309
|
+
|
310
|
+
yield self if block_given?
|
311
|
+
|
312
|
+
task :default => :bundle
|
313
|
+
|
314
|
+
desc "Build the bundle."
|
315
|
+
task :bundle => [:executable, :resources, :info_plist, :pkginfo]
|
316
|
+
|
317
|
+
@bundle_dir = "#{@bundle}.bundle"
|
318
|
+
@contents_dir = "#{@bundle_dir}/Contents"
|
319
|
+
@executable_dir = "#{@contents_dir}/MacOS"
|
320
|
+
@resource_dir = "#{@contents_dir}/Resources"
|
321
|
+
@localized_dir = "#{@contents_dir}/Resources/English.lproj"
|
322
|
+
|
323
|
+
FileList[@bundle_dir, @contents_dir, @executable_dir, @resource_dir, @localized_dir].each {|d| directory d}
|
324
|
+
|
325
|
+
generate_compilation_tasks
|
326
|
+
|
327
|
+
@ruby_files = File.exist?("ruby") ? FileList['ruby/*.rb'] : FileList['*.rb']
|
328
|
+
@nu_files = File.exist?("nu") ? FileList['nu/*.nu'] : FileList['*.nu']
|
329
|
+
|
330
|
+
desc "Create the executable (subtask of bundle)."
|
331
|
+
task :executable => [:generated, @executable_dir, "#{@executable_dir}/#{@bundle}"]
|
332
|
+
file "#{@executable_dir}/#{@bundle}" => @gcc_objects do |t|
|
333
|
+
sh "#{@cc} #{@gcc_objects} #{@c_objects} #{@cflags} #{@arch} #{@ldflags} -o '#{t.name}' -bundle"
|
334
|
+
end
|
335
|
+
|
336
|
+
desc "Copy files to the bundle's Resources directory (subtask of bundle)."
|
337
|
+
task :resources => [@resource_dir]
|
338
|
+
[@ruby_files, @nu_files, @icon_files, @resources].each{|list| list.each {|f|
|
339
|
+
task :resources => "#{@resource_dir}/#{f.split("/")[-1]}"
|
340
|
+
file "#{@resource_dir}/#{f.split("/")[-1]}" => f do |t|
|
341
|
+
cp_r f, t.name
|
342
|
+
end
|
343
|
+
}}
|
344
|
+
|
345
|
+
@nib_files.each {|f|
|
346
|
+
g = f.split('/')[-1]
|
347
|
+
task :resources => "#{@localized_dir}/#{g}"
|
348
|
+
file "#{@localized_dir}/#{g}" => f do |t|
|
349
|
+
cp_r "English.lproj/#{g}", t.name
|
350
|
+
end
|
351
|
+
}
|
352
|
+
|
353
|
+
if File.exist?("lib")
|
354
|
+
task :resources => "#{@resource_dir}/lib"
|
355
|
+
file "#{@resource_dir}/lib" => "lib" do |t|
|
356
|
+
sh "rm -rf #{t.name}"
|
357
|
+
cp_r "lib", t.name
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
desc "Create the Info.plist file (subtask of bundle)."
|
362
|
+
task :info_plist => [@contents_dir, "#{@contents_dir}/Info.plist"]
|
363
|
+
file "#{@contents_dir}/Info.plist" do |t|
|
364
|
+
info = {
|
365
|
+
:CFBundleDevelopmentRegion => "English",
|
366
|
+
:CFBundleExecutable => @bundle,
|
367
|
+
:CFBundleIdentifier => @identifier,
|
368
|
+
:CFBundleInfoDictionaryVersion => "6.0",
|
369
|
+
:CFBundleName => @bundle,
|
370
|
+
:CFBundlePackageType => "BNDL",
|
371
|
+
:CFBundleSignature => @creator_code,
|
372
|
+
:CFBundleVersion => "1.0",
|
373
|
+
:NSPrincipalClass => @bundle
|
374
|
+
}
|
375
|
+
info = info.merge(@info) if @info
|
376
|
+
plist = PList.generate(info)
|
377
|
+
File.open(t.name, "w") {|f| f.write plist}
|
378
|
+
end
|
379
|
+
|
380
|
+
desc "Create the PkgInfo file (subtask of bundle)."
|
381
|
+
task :pkginfo => [@contents_dir, "#{@contents_dir}/PkgInfo"]
|
382
|
+
file "#{@contents_dir}/PkgInfo" do |t|
|
383
|
+
sh "echo -n 'APPL#{@creator_code}' > '#{t.name}'"
|
384
|
+
end
|
385
|
+
|
386
|
+
desc "Test the bundle."
|
387
|
+
task :test => :bundle do
|
388
|
+
system "ruby -rtest/unit -e0 -- -v --pattern '/test_.*\.rb^/'"
|
389
|
+
end
|
390
|
+
|
391
|
+
CLEAN.include("**/*.o") # all object files
|
392
|
+
CLOBBER.include("*.lproj/*~.nib") # backup nib files
|
393
|
+
CLOBBER.include("#{@bundle_dir}") # the application
|
394
|
+
CLOBBER.include(".gdb_history") # support files
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
end
|
399
|
+
|
400
|
+
# Helper module for generating plists.
|
401
|
+
module PList
|
402
|
+
TAB = " "
|
403
|
+
def self.value(object, indent="")
|
404
|
+
if object.class == Hash
|
405
|
+
result = "#{indent}<dict>\n"
|
406
|
+
object.keys.sort_by{|k| k.to_s}.each {|key|
|
407
|
+
result += "#{indent}#{TAB}<key>#{key}</key>\n"
|
408
|
+
result += value(object[key], indent+TAB)
|
409
|
+
}
|
410
|
+
result += "#{indent}</dict>\n"
|
411
|
+
elsif object.class == Array
|
412
|
+
result = "#{indent}<array>\n"
|
413
|
+
result += object.map {|item| value(item, indent+TAB)}.join("")
|
414
|
+
result += "#{indent}</array>\n"
|
415
|
+
else
|
416
|
+
result = "#{indent}<string>#{object}</string>\n"
|
417
|
+
end
|
418
|
+
result
|
419
|
+
end
|
420
|
+
def self.generate(info)
|
421
|
+
plist = '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
|
422
|
+
plist += '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
|
423
|
+
plist += '<plist version="1.0">' + "\n"
|
424
|
+
plist += value(info)
|
425
|
+
plist += "</plist>\n"
|
426
|
+
plist
|
427
|
+
end
|
428
|
+
end
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>IBDocumentLocation</key>
|
6
|
+
<string>159 127 356 240 0 0 1920 1178 </string>
|
7
|
+
<key>IBEditorPositions</key>
|
8
|
+
<dict>
|
9
|
+
<key>29</key>
|
10
|
+
<string>156 406 338 44 0 0 1920 1178 </string>
|
11
|
+
</dict>
|
12
|
+
<key>IBFramework Version</key>
|
13
|
+
<string>451.0</string>
|
14
|
+
<key>IBSystem Version</key>
|
15
|
+
<string>9A241e</string>
|
16
|
+
</dict>
|
17
|
+
</plist>
|
Binary file
|
data/lib/rubyobjcapp
ADDED
Binary file
|
data/libffi/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
libffi - Copyright (c) 1996-2003 Red Hat, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
``Software''), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included
|
12
|
+
in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
18
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
19
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
20
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: RubyObjC
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2007-06-10 00:00:00 -07:00
|
8
|
+
summary: A bridge between Ruby and Objective-C
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: tim@neontology.com
|
12
|
+
homepage: http://www.rubyobjc.com/doc
|
13
|
+
rubyforge_project:
|
14
|
+
description: RubyObjC allows Ruby and Objective-C code to be easily mixed. Among its benefits, it allows developers to write Cocoa applications in pure Ruby.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Tim Burks
|
31
|
+
files:
|
32
|
+
- bin/rubyapp
|
33
|
+
- lib/librubyobjc.a
|
34
|
+
- lib/objc.bundle
|
35
|
+
- lib/rake
|
36
|
+
- lib/resources
|
37
|
+
- lib/rubyobjcapp
|
38
|
+
- lib/rake/cocoa.rb
|
39
|
+
- lib/resources/English.lproj
|
40
|
+
- lib/resources/English.lproj/InfoPlist.strings
|
41
|
+
- lib/resources/English.lproj/MainMenu.nib
|
42
|
+
- lib/resources/English.lproj/MainMenu.nib/classes.nib
|
43
|
+
- lib/resources/English.lproj/MainMenu.nib/info.nib
|
44
|
+
- lib/resources/English.lproj/MainMenu.nib/keyedobjects.nib
|
45
|
+
- app/Rakefile
|
46
|
+
- libffi/LICENSE
|
47
|
+
- app/main.rb
|
48
|
+
- app/random.rb
|
49
|
+
- INTRODUCTION
|
50
|
+
- COPYING
|
51
|
+
- USAGE
|
52
|
+
test_files: []
|
53
|
+
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
executables:
|
59
|
+
- rubyapp
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
dependencies: []
|
65
|
+
|