Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | <!doctype HTML public "-//W3C//DTD HTML 3.2//EN">␊ |
2 | <html><head><title>␊ |
3 | User's Guide - tmake␊ |
4 | </title></head><body bgcolor="#ffffff">␊ |
5 | <p><h1 align=center>User's Guide - tmake</h1>␊ |
6 | ␊ |
7 | ␊ |
8 | <hr>␊ |
9 | <h2>Introduction</h2>␊ |
10 | ␊ |
11 | tmake is an easy-to-use tool from Troll Tech to create and maintain␊ |
12 | makefiles for software projects. It can be a painful task to manage␊ |
13 | makefiles manually, especially if you develop for more than one platform␊ |
14 | or use more than one compiler. tmake automates and streamlines this␊ |
15 | process and lets you spend your valuable time on writing code, not␊ |
16 | makefiles.␊ |
17 | ␊ |
18 | <p>␊ |
19 | Our main motivation for developing tmake was that we spent far too much␊ |
20 | time maintaining makefiles for <a href="http://www.troll.no/qt">Qt</a>,␊ |
21 | our cross-platform GUI toolkit. Qt supports around 15 flavors of Unix,␊ |
22 | Microsoft Windows, and around 15 different C++ compilers. We looked at␊ |
23 | GNU autoconf, but it was Unix-specific and not flexible enough in our␊ |
24 | opinion. Our makefile system also had to deal with Qt <a␊ |
25 | href="http://www.troll.no/qt/metaobjects.html">meta object compiler</a>␊ |
26 | (moc) issues. The moc program extracts meta information from C++ files and␊ |
27 | generates a C++ file with data tables etc. It takes extra work to add␊ |
28 | makefile rules for the moc and wanted to automate this task.␊ |
29 | ␊ |
30 | <p>␊ |
31 | tmake is written in Perl and requires that you have installed perl version␊ |
32 | 5 or newer. Basic use of tmake requires no perl knowledge, but if you know␊ |
33 | perl you can extend tmake and write your own makefile templates.␊ |
34 | ␊ |
35 | <p>␊ |
36 | <b>Windows users:</b> The tmake distribution for Win32 includes tmake.exe␊ |
37 | (built by the perl2exe utility) and you do not need to download and␊ |
38 | install perl unless you want to modify the tmake source code or run other␊ |
39 | perl scripts. You can download perl for Win32 (Windows NT and 95) from <a␊ |
40 | href="http://www.activestate.com">www.activestate.com</a>␊ |
41 | ␊ |
42 | <p>␊ |
43 | tmake is free software and you may use, copy, modify and distribute tmake␊ |
44 | and its documentation for any purpose and without any fee. See the␊ |
45 | LICENSE file for details.␊ |
46 | ␊ |
47 | <p>␊ |
48 | Feedback is highly appreciated. Contact the author, Haavard Nord <a␊ |
49 | href="mailto:hanord@troll.no">(hanord@troll.no)</a>, if you have ideas,␊ |
50 | patches etc. for tmake.␊ |
51 | ␊ |
52 | <hr>␊ |
53 | <h2>Installation</h2>␊ |
54 | ␊ |
55 | <ol>␊ |
56 | <li>Make sure you have perl version 5 or later installed (optional␊ |
57 | for Windows users).␊ |
58 | <li>Unpack the tmake tar.gz archive for Unix or the tmake .zip file for Windows.␊ |
59 | <li>Set the TMAKEPATH environment variable to the directories␊ |
60 | containing the template files (see below).␊ |
61 | <li>Add the tmake/bin directory to your PATH.␊ |
62 | </ol>␊ |
63 | ␊ |
64 | Here are some examples:<p>␊ |
65 | <strong>Unix Bourne shell:</strong><pre>␊ |
66 | TMAKEPATH=/local/tmake/lib/linux-g++␊ |
67 | PATH=$PATH:/local/tmake/bin␊ |
68 | export TMAKEPATH PATH␊ |
69 | </pre>␊ |
70 | ␊ |
71 | <strong>Unix C shell:</strong><pre>␊ |
72 | setenv TMAKEPATH /local/tmake/lib/linux-g++␊ |
73 | setenv PATH $PATH:/local/tmake/bin␊ |
74 | </pre>␊ |
75 | ␊ |
76 | <strong>Microsoft Windows:</strong><pre>␊ |
77 | set TMAKEPATH=c:\tmake\lib\win32-msvc␊ |
78 | set PATH=%PATH%;c:\tmake\bin␊ |
79 | </pre>␊ |
80 | ␊ |
81 | <p>␊ |
82 | The template directory name has the form <em>platform</em>-<em>compiler</em>␊ |
83 | and contains a platform configuration file (tmake.conf) and tmake template␊ |
84 | files.␊ |
85 | ␊ |
86 | <p>␊ |
87 | Supported platforms: AIX, Data General, FreeBSD, HPUX, SGI Irix, Linux,␊ |
88 | NetBSD, OpenBSD, OSF1/DEC, SCO, Solaris, SunOS, Ultrix, Unixware and␊ |
89 | Win32.␊ |
90 | ␊ |
91 | <p>␊ |
92 | You can find your platform-compiler combination in the <tt>tmake/lib</tt>.␊ |
93 | ␊ |
94 | <p>␊ |
95 | <b>Unix users:</b> tmake requires that perl is in /usr/bin. If your␊ |
96 | version of perl is elsewehere, either change the first line of tmake or␊ |
97 | make a small shell script which invokes tmake with the correct perl.␊ |
98 | ␊ |
99 | ␊ |
100 | <hr>␊ |
101 | <h2>Getting Started</h2>␊ |
102 | ␊ |
103 | Let's assume you have a small Qt application consisting of one C++ header␊ |
104 | file and two source files.␊ |
105 | ␊ |
106 | First you need to create a tmake project file, e.g. hello.pro:<pre>␊ |
107 | HEADERS = hello.h␊ |
108 | SOURCES = hello.cpp main.cpp␊ |
109 | TARGET = hello␊ |
110 | </pre>␊ |
111 | ␊ |
112 | Then run tmake to create a Makefile:<pre>␊ |
113 | tmake hello.pro -o Makefile␊ |
114 | </pre>␊ |
115 | And finally:<pre>␊ |
116 | make␊ |
117 | </pre>␊ |
118 | This builds the hello program. Remember to set the <code>TMAKEPATH</code>␊ |
119 | environment variable before you run tmake.␊ |
120 | <p>␊ |
121 | See <a href="m-linux-gcc.html">Makefile for Linux/g++</a>.<br>␊ |
122 | See <a href="m-win32-msvc.html">Makefile for Win32/msvc</a>␊ |
123 | (Microsoft Visual C++).<br>␊ |
124 | ␊ |
125 | ␊ |
126 | <hr>␊ |
127 | <h2>Makefile Templates</h2>␊ |
128 | ␊ |
129 | The tmake distribution includes three makefile templates and one␊ |
130 | configuration file for each platform/compiler combination. The␊ |
131 | <code>TMAKEPATH</code> environment variable tells tmake where to find␊ |
132 | these files:␊ |
133 | <p>␊ |
134 | <table border="0">␊ |
135 | <tr>␊ |
136 | <td> </td>␊ |
137 | <td>app.t</td>␊ |
138 | <td> </td>␊ |
139 | <td>Creates a makefile for building applications.</td>␊ |
140 | </tr>␊ |
141 | <tr>␊ |
142 | <td> </td>␊ |
143 | <td>lib.t</td>␊ |
144 | <td> </td>␊ |
145 | <td>Creates a makefile for building libraries.</td>␊ |
146 | </tr>␊ |
147 | <tr>␊ |
148 | <td> </td>␊ |
149 | <td>subdirs.t</td>␊ |
150 | <td> </td>␊ |
151 | <td>Creates a makefile for building targets in subdirectories.</td>␊ |
152 | </tr>␊ |
153 | <tr>␊ |
154 | <td> </td>␊ |
155 | <td>tmake.conf</td>␊ |
156 | <td> </td>␊ |
157 | <td>This configuration file contains compiler options and lists␊ |
158 | ␉ tools and libraries.␊ |
159 | </tr>␊ |
160 | </table>␊ |
161 | ␊ |
162 | ␊ |
163 | <p>␊ |
164 | The hello.pro project file above does not have a <code>TEMPLATE</code> or␊ |
165 | a <code>CONFIG</code> variable. The default template is <tt>app</tt> (the .t␊ |
166 | extension is optional) and the default configuration is <tt>qt warn_on␊ |
167 | release</tt>.␊ |
168 | ␊ |
169 | This project file produces exactly the same result as the hello.pro␊ |
170 | above:<pre>␊ |
171 | TEMPLATE = app␊ |
172 | CONFIG = qt warn_on release␊ |
173 | HEADERS = hello.h␊ |
174 | SOURCES = hello.cpp main.cpp␊ |
175 | TARGET = hello␊ |
176 | </pre>␊ |
177 | ␊ |
178 | ␊ |
179 | ␊ |
180 | <h4>Makefile Configuration</h4>␊ |
181 | ␊ |
182 | <p>␊ |
183 | The <code>CONFIG</code> variable is recognized by both the app.t and lib.t␊ |
184 | templates and specifies what compiler options to use and which extra␊ |
185 | libraries to link in.␊ |
186 | ␊ |
187 | These options control the compilation flags:␊ |
188 | <p>␊ |
189 | <table border="0">␊ |
190 | <tr>␊ |
191 | <td> </td>␊ |
192 | <td>release</td>␊ |
193 | <td> </td>␊ |
194 | <td>Compile with optimization enabled, ignored if␊ |
195 | "debug" is specified.</td>␊ |
196 | </tr>␊ |
197 | <tr>␊ |
198 | <td> </td>␊ |
199 | <td>debug</td>␊ |
200 | <td> </td>␊ |
201 | <td>Compile with debug options enabled.</td>␊ |
202 | </tr>␊ |
203 | <tr>␊ |
204 | <td> </td>␊ |
205 | <td>warn_on</td>␊ |
206 | <td> </td>␊ |
207 | <td>The compiler should emit more warnings than normally, ignored if␊ |
208 | "warn_off" is specified.</td>␊ |
209 | </tr>␊ |
210 | <tr>␊ |
211 | <td> </td>␊ |
212 | <td>warn_off</td>␊ |
213 | <td> </td>␊ |
214 | <td>The compiler should emit no warnings or as few as possible.</td>␊ |
215 | </tr>␊ |
216 | </table>␊ |
217 | ␊ |
218 | <p>␊ |
219 | These options defines the application/library type:␊ |
220 | <p>␊ |
221 | <table border="0">␊ |
222 | <tr>␊ |
223 | <td> </td>␊ |
224 | <td>qt</td>␊ |
225 | <td> </td>␊ |
226 | <td>The target is a Qt application/library and requires Qt header␊ |
227 | files/library.</td>␊ |
228 | </tr>␊ |
229 | <tr>␊ |
230 | <td> </td>␊ |
231 | <td>opengl</td>␊ |
232 | <td> </td>␊ |
233 | <td>The target requires the OpenGL (or Mesa) headers/libraries.</td>␊ |
234 | </tr>␊ |
235 | <tr>␊ |
236 | <td> </td>␊ |
237 | <td>x11</td>␊ |
238 | <td> </td>␊ |
239 | <td>The target is a X11 application or library.</td>␊ |
240 | </tr>␊ |
241 | <tr>␊ |
242 | <td> </td>␊ |
243 | <td>windows</td>␊ |
244 | <td> </td>␊ |
245 | <td>The target is a Win32 window application (app.t only).</td>␊ |
246 | </tr>␊ |
247 | <tr>␊ |
248 | <td> </td>␊ |
249 | <td>console</td>␊ |
250 | <td> </td>␊ |
251 | <td>The target is a Win32 console application (app.t only).</td>␊ |
252 | </tr>␊ |
253 | <tr>␊ |
254 | <td> </td>␊ |
255 | <td>dll</td>␊ |
256 | <td> </td>␊ |
257 | <td>The target is a shared object/DLL.</td>␊ |
258 | </tr>␊ |
259 | <tr>␊ |
260 | <td> </td>␊ |
261 | <td>staticlib</td>␊ |
262 | <td> </td>␊ |
263 | <td>The target is a static library (lib.t only).</td>␊ |
264 | </tr>␊ |
265 | </table>␊ |
266 | ␊ |
267 | <p>␊ |
268 | As an example, if the hello application uses both Qt and OpenGL and you␊ |
269 | want to compile it for debugging, your <code>CONFIG</code> line should␊ |
270 | read:<pre>␊ |
271 | CONFIG = qt opengl debug␊ |
272 | </pre>␊ |
273 | ␊ |
274 | <p>␊ |
275 | The most common tmake options and project variables are described here.␊ |
276 | See the tmake <a href="tmake_ref.html">reference manual</a> for␊ |
277 | details.<p>␊ |
278 | ␊ |
279 | ␊ |
280 | ␊ |
281 | <h4>The Application Template</h4>␊ |
282 | ␊ |
283 | The application template, app.t, lets you compile and link executable␊ |
284 | programs or shared objects (DLLs).␊ |
285 | ␊ |
286 | This template recognizes several variabless.␊ |
287 | <p>␊ |
288 | <table border="0">␊ |
289 | <tr>␊ |
290 | <td> </td>␊ |
291 | <td>HEADERS</td>␊ |
292 | <td> </td>␊ |
293 | <td>Header files.</td>␊ |
294 | </tr>␊ |
295 | <tr>␊ |
296 | <td> </td>␊ |
297 | <td>SOURCES</td>␊ |
298 | <td> </td>␊ |
299 | <td>Source files.</td>␊ |
300 | </tr>␊ |
301 | <tr>␊ |
302 | <td> </td>␊ |
303 | <td>TARGET</td>␊ |
304 | <td> </td>␊ |
305 | <td>Name of executable (adds .exe if on Windows).</td>␊ |
306 | </tr>␊ |
307 | <tr>␊ |
308 | <td> </td>␊ |
309 | <td>DESTDIR</td>␊ |
310 | <td> </td>␊ |
311 | <td>Where to put the target.</td>␊ |
312 | </tr>␊ |
313 | <tr>␊ |
314 | <td> </td>␊ |
315 | <td>DEFINES</td>␊ |
316 | <td> </td>␊ |
317 | <td>Tell compiler to define C preprocessor macros (-D option).</td>␊ |
318 | </tr>␊ |
319 | <tr>␊ |
320 | <td> </td>␊ |
321 | <td>INCLUDEPATH</td>␊ |
322 | <td> </td>␊ |
323 | <td>Sets the include file search path for the compiler (-I␊ |
324 | option).␊ |
325 | ␉</td>␊ |
326 | </tr>␊ |
327 | <tr>␊ |
328 | <td> </td>␊ |
329 | <td>DEPENDPATH</td>␊ |
330 | <td> </td>␊ |
331 | <td>Sets the dependency search path for tmake.</td>␊ |
332 | </tr>␊ |
333 | <tr>␊ |
334 | <td> </td>␊ |
335 | <td>DEF_FILE</td>␊ |
336 | <td> </td>␊ |
337 | <td>Win32 only: Link with a .def file.</td>␊ |
338 | </tr>␊ |
339 | <tr>␊ |
340 | <td> </td>␊ |
341 | <td>RC_FILE</td>␊ |
342 | <td> </td>␊ |
343 | <td>Win32 only: Use a .rc file (compile to temporary .res).␊ |
344 | ␉</td>␊ |
345 | </tr>␊ |
346 | <tr>␊ |
347 | <td> </td>␊ |
348 | <td>RES_FILE</td>␊ |
349 | <td> </td>␊ |
350 | <td>Win32 only: Link with a .res file.␊ |
351 | ␉</td>␊ |
352 | </tr>␊ |
353 | </table>␊ |
354 | ␊ |
355 | <p>␊ |
356 | ␊ |
357 | ␊ |
358 | <h4>The Library Template</h4>␊ |
359 | ␊ |
360 | The library template, lib.t, lets you compile and create static or shared␊ |
361 | libraries.␊ |
362 | ␊ |
363 | <p>␊ |
364 | The lib.t template supports the same project variables as app.t, but also␊ |
365 | <code>VERSION</code>. <code>VERSION</code> is the version number of the␊ |
366 | target library, e.g. 1.40. The version is important for shared libraries.␊ |
367 | ␊ |
368 | ␊ |
369 | ␊ |
370 | <h4>The Subdirs Template</h4>␊ |
371 | ␊ |
372 | The subdirs template, subdirs.t, lets you invoke make in subdirectories.␊ |
373 | ␊ |
374 | <p>The <code>SUBDIRS</code> variable contains the name of all subdirectories to␊ |
375 | be processed.␊ |
376 | ␊ |
377 | ␊ |
378 | <h4>Special Templates for Microsoft Visual C++</h4>␊ |
379 | ␊ |
380 | If you have Microsoft Visual C++ 5.0, you can use two special templates to␊ |
381 | generate a MSVC++ IDE project (.dsp file). After you have generated␊ |
382 | e.g. hello.dsp, choose "File"->"Open Workspace" and select the hello.dsp␊ |
383 | file. Visual C++ will then create a workspace (.dsw file) for you.<p>␊ |
384 | <table border="0">␊ |
385 | <tr>␊ |
386 | <td> </td>␊ |
387 | <td>vcapp.t</td>␊ |
388 | <td> </td>␊ |
389 | <td>Creates an application project file (Microsoft Visual C++ 5.0␊ |
390 | ␉only).</td>␊ |
391 | </tr>␊ |
392 | <tr>␊ |
393 | <td> </td>␊ |
394 | <td>vclib.t</td>␊ |
395 | <td> </td>␊ |
396 | <td>Creates a library project file (Microsoft Visual C++ 5.0␊ |
397 | ␉only).</td>␊ |
398 | </tr>␊ |
399 | </table>␊ |
400 | ␊ |
401 | <p>␊ |
402 | Run tmake to create a hello.dsp file (use -t to override the default␊ |
403 | template):<pre>␊ |
404 | tmake -t vcapp -o hello.dsp hello.pro␊ |
405 | </pre>␊ |
406 | ␊ |
407 | ␊ |
408 | <hr>␊ |
409 | <h2>Project File Syntax</h2>␊ |
410 | ␊ |
411 | The tmake project file has a very simple syntax. You may set␊ |
412 | project variables, append to project variables, remove from␊ |
413 | project variable and substitute project variables.␊ |
414 | ␊ |
415 | To set a project variable:<pre>␊ |
416 | HEADERS = gui.h xml.h url.h␊ |
417 | </pre>␊ |
418 | ␊ |
419 | If you cannot fit everything on one line, use '\' to split it up:<pre>␊ |
420 | HEADERS = gui.h \␊ |
421 | ␉ xml.h \␊ |
422 | ␉ url.h␊ |
423 | </pre>␊ |
424 | ␊ |
425 | <p>␊ |
426 | Project variables contains lists of items (such as header files,␊ |
427 | compiler options etc.) and use whitespace to separate the items.␊ |
428 | This means that tmake cannot deal with items containing whitespace.␊ |
429 | The INCLUDEPATH variable is an exception. If INCLUDEPATH contains␊ |
430 | one or more semicolons (;), tmake uses the semicolon to separate␊ |
431 | the include directories, hence you can have include directories␊ |
432 | containing whitespace (this is quite common on Windows).␊ |
433 | ␊ |
434 | <p>␊ |
435 | Here is an example:<pre>␊ |
436 | INCLUDEPATH = C:\Program Files\DBLib\Include;C:\qt\include␊ |
437 | </pre>␊ |
438 | ␊ |
439 | <p>␊ |
440 | tmake supports <em>project variable expension</em>. Use $$ to expand␊ |
441 | any project variable:<pre>␊ |
442 | ALLFILES = $$HEADERS $$SOURCES␊ |
443 | </pre>␊ |
444 | ␊ |
445 | <p>␊ |
446 | Most often you assign some value to a project variable, but you can␊ |
447 | also add to, remove from or replace parts of a project variable.<pre>␊ |
448 | A = abc␊ |
449 | X = xyz␊ |
450 | A += def␉␉␉# A = abc def␊ |
451 | X *= xyz␉␉␉# X = xyz␊ |
452 | B = $$A␉␉␉# B = abc def␊ |
453 | B -= abc␉␉␉# B = def␊ |
454 | X /= s/y/Y/␉␉# X = xYz␊ |
455 | </pre>␊ |
456 | The *= operation adds the value if the variable does not already contain it.␊ |
457 | The /= operation performs regular expression substitution.␊ |
458 | ␊ |
459 | <p>␊ |
460 | You can also set variables from the command line when running the tmake␊ |
461 | program. For instance, if you want to generate a makefile with debug␊ |
462 | information:<pre>␊ |
463 | tmake "CONFIG+=debug" hello.pro␊ |
464 | </pre>␊ |
465 | ␊ |
466 | <p>␊ |
467 | Use the <tt>unix:</tt> or <tt>win32:</tt> (conditional) qualifier if you want a␊ |
468 | platform-specific variable:<pre>␊ |
469 | SOURCES␉ = common.cpp # common for all platforms␊ |
470 | unix:SOURCES += unix.cpp␉ # additional sources for Unix␊ |
471 | win32:SOURCES += win32.cpp # additional sources for Windows␊ |
472 | unix:LIBS␉ += -lm␉ # on Unix we need the math lib␊ |
473 | </pre>␊ |
474 | If none of the platforms match, tmake looks for the variable in CONFIG␊ |
475 | variable:<pre>␊ |
476 | debug:SOURCES += dbgstuff.cpp # additional source for debugging␊ |
477 | </pre>␊ |
478 | ␊ |
479 | Finally, you can set platform and compiler-dependent variables:<pre>␊ |
480 | linux-g++:TMAKE_CFLAGS = -fno-rtti␊ |
481 | </pre>␊ |
482 | ␊ |
483 | <p>␊ |
484 | You may define your own project variables to be used by custom templates. A␊ |
485 | project variable is stored in <code>%project</code>, which is an associative␊ |
486 | Perl array. Access it like this: <code>$project{"var"}</code> or via the␊ |
487 | function <code>Project("var")</code>. For example, after reading␊ |
488 | "hello.pro", <code>$project{"SOURCES"}</code> contains "hello.cpp␊ |
489 | main.cpp".<p>␊ |
490 | ␊ |
491 | ␊ |
492 | <hr>␊ |
493 | <h2><a name="usage"></a>Running tmake</h2>␊ |
494 | ␊ |
495 | Usage:<pre>␊ |
496 | tmake [options] <em>project files or project settings</em>␊ |
497 | </pre>␊ |
498 | Options:<pre>␊ |
499 | -e expr Evaluate the Perl expression. Ignores the template file.␊ |
500 | -nodepend Don't generate dependency information.␊ |
501 | -o <em>file</em> Write output to <em>file</em> instead of stdout.␊ |
502 | -t <em>file</em> Specify a template <em>file</em>.␊ |
503 | -unix Force tmake into Unix mode.␊ |
504 | -v Verbose/debugging on.␊ |
505 | -win32 Force tmake into Win32 mode.␊ |
506 | </pre>␊ |
507 | ␊ |
508 | The -t option overrides any <code>TEMPLATE</code> variable in the project file.␊ |
509 | <p>␊ |
510 | The default project file extension is ".pro". The default template file␊ |
511 | extension is ".t". If you do not specify these extension tmake will␊ |
512 | automatically add them for you.␊ |
513 | ␊ |
514 | <p>␊ |
515 | Example of basic use:<pre>␊ |
516 | tmake hello -o Makefile␊ |
517 | </pre>␊ |
518 | ␊ |
519 | <p>␊ |
520 | Example of how to create a makefile with debugging information:<pre>␊ |
521 | tmake "CONFIG+=debug" hello -o Makefile␊ |
522 | </pre>␊ |
523 | ␊ |
524 | <p>␊ |
525 | Exmaple of how to specify a TMAKEPATH:<pre>␊ |
526 | tmake "TMAKEPATH=/local/tmake/lib/hpux-g++" hello.pro -o Makefile␊ |
527 | </pre>␊ |
528 | ␊ |
529 | Example of how to evaluate a perl expression (print names of headers␊ |
530 | and source files):<pre>␊ |
531 | tmake hello -e 'Expand("HEADERS","SOURCES")'␊ |
532 | </pre>␊ |
533 | ␊ |
534 | <hr>␊ |
535 | <h2><a name="progen"></a>The progen Utility</h2>␊ |
536 | ␊ |
537 | The progen utility creates project files for you. It can be used like␊ |
538 | this:<pre>␊ |
539 | progen -n hello -o hello.pro␊ |
540 | </pre>␊ |
541 | If no .cpp or .h files are specified on the command line, progen␊ |
542 | searches for .cpp and .h (except moc_*.cpp) in the current directory␊ |
543 | and below.␊ |
544 | <p>␊ |
545 | Usage:<pre>␊ |
546 | progen [options] [<em>C/C++ header files and source files</em>]␊ |
547 | </pre>␊ |
548 | Options:<pre>␊ |
549 | -lower Lower-case letters in filenames (useful on Windows).␊ |
550 | -n <em>name</em> Specify a project name (<code>TARGET</code>).␊ |
551 | -o <em>file</em> Write output to <em>file</em> instead of stdout.␊ |
552 | -t <em>file</em> Specify a template <em>file</em>.␊ |
553 | </pre>␊ |
554 | ␊ |
555 | ␊ |
556 | <hr>␊ |
557 | <h2>Advanced Topics</h2>␊ |
558 | ␊ |
559 | In most cases you will be happy with using tmake as described above, but␊ |
560 | sometimes you need to add special compiler options or even add new␊ |
561 | makefile rules. This chapter describes how to customize your makefiles.␊ |
562 | ␊ |
563 | <h4>Conditional Project Settings</h4>␊ |
564 | ␊ |
565 | If you need a special compiler option etc., you can add platform-dependent␊ |
566 | settings in your project file:<pre> ␊ |
567 | solaris-cc:TMAKE_CC = /opt/bin/CC_5.0␊ |
568 | solaris-cc:TMAKE_CFLAGS = -pts␊ |
569 | unix:TMAKE_LIBS = -lXext␊ |
570 | win32:INCLUDEPATH = c:\myinclude␊ |
571 | win32-borland:DEFINES = NO_BOOL␊ |
572 | </pre>␊ |
573 | ␊ |
574 | You can prefix a project variable with unix: or win32: to make it specific for␊ |
575 | either Unix or Windows. You can also prefix a variable with␊ |
576 | <em>platform-compiler</em> ␊ |
577 | ␊ |
578 | <h4>Your Own Templates</h4>␊ |
579 | ␊ |
580 | If you know Perl programming, there is virtually no limitation to what you␊ |
581 | can do with tmake. First you need to know how tmake works.␊ |
582 | ␊ |
583 | <h4>Template Processing</h4>␊ |
584 | ␊ |
585 | When you run tmake, it first reads the <tt>tmake.conf</tt> file.␊ |
586 | This configuration file has the same syntax as the project file.␊ |
587 | ␊ |
588 | tmake then reads the project file and sets the project variables it␊ |
589 | finds, e.g. <code>HEADERS</code>, <code>SOURCES</code> etc.␊ |
590 | ␊ |
591 | All variables and values are stored in a global associative Perl hash␊ |
592 | array called <code>project</code>. For example,␊ |
593 | <code>$project{"SOURCES"}</code> contains "hello.cpp main.cpp"␊ |
594 | after processing hello.pro.␊ |
595 | ␊ |
596 | When both the <tt>tmake.conf</tt> and the project files have been␊ |
597 | read, tmake starts reading the template file line by line and␊ |
598 | executes any Perl code it finds in the template.␊ |
599 | ␊ |
600 | <ul>␊ |
601 | <li>Anything after <code>#$</code> until newline is␊ |
602 | evaluated as perl code. The perl code is substituted␊ |
603 | with the contents of the <code>$text</code>␊ |
604 | variable.␊ |
605 | <li>Block of perl code: <code>#${</code> until␊ |
606 | <code>#$}</code>.␊ |
607 | <li>Comments; <code>#!</code> until newline is stripped.␊ |
608 | <li>Anything else is copied directly from the template to␊ |
609 | the output.␊ |
610 | </ul>␊ |
611 | ␊ |
612 | <p>␊ |
613 | Example:<pre>␊ |
614 | #! This is a comment which will be removed.␊ |
615 | This text will appear in the output.␊ |
616 | #$ $text = "The header file(s) are: " . $project{"HEADERS"};␊ |
617 | # This text also appears in the output.␊ |
618 | #${␊ |
619 | $a = 12;␊ |
620 | $b = 13;␊ |
621 | $text = $a * $b;␊ |
622 | #$}␊ |
623 | That's all.␊ |
624 | </pre>␊ |
625 | Output:<pre>␊ |
626 | This text will appear in the output.␊ |
627 | The header file(s) are: hello.h␊ |
628 | # This text also appears in the output.␊ |
629 | 156␊ |
630 | That's all.␊ |
631 | </pre>␊ |
632 | ␊ |
633 | ␊ |
634 | <h3>Using tmake With Lex and Yacc</h3>␊ |
635 | ␊ |
636 | The standard tmake templates knows how to process C and C++ files, but␊ |
637 | sometimes you need to process additional files and link them into your␊ |
638 | project. A typical example is to process lex and yacc files when you're␊ |
639 | building a parser.␊ |
640 | ␊ |
641 | <p>␊ |
642 | Parser template:<pre>␊ |
643 | #!␊ |
644 | #! parser.t: This is a custom template for building a parser␊ |
645 | #!␊ |
646 | #$ IncludeTemplate("app.t");␊ |
647 | ␊ |
648 | ####### Lex/yacc programs and options␊ |
649 | ␊ |
650 | LEX␉ =␉flex␊ |
651 | YACC =␉#$ $text = ($is_unix ? "yacc -d" : "byacc -d");␊ |
652 | ␊ |
653 | ####### Lex/yacc files␊ |
654 | ␊ |
655 | LEXIN =␉#$ Expand("LEXINPUT");␊ |
656 | LEXOUT =␉lex.yy.c␊ |
657 | YACCIN =␉#$ Expand("YACCINPUT");␊ |
658 | YACCOUT =␉y.tab.c␊ |
659 | YACCHDR =␉y.tab.h␊ |
660 | PARSER =␉#$ Expand("PARSER");␊ |
661 | ␊ |
662 | ####### Process lex/yacc files␊ |
663 | ␊ |
664 | $(LEXOUT): $(LEXIN)␊ |
665 | $(LEX) $(LEXIN)␊ |
666 | ␊ |
667 | $(PARSER): $(YACCIN) $(LEXOUT)␊ |
668 | $(YACC) $(YACCIN)␊ |
669 | #$ $text = ($is_unix ? "-rm -f " : "-del ") . '$(PARSER)';␊ |
670 | #$ $text = ($is_unix ? "-mv " : "-ren ") . '$(YACCOUT) $(PARSER)'; ␊ |
671 | </pre>␊ |
672 | ␊ |
673 | The parser template adds some extra rules to the application template␊ |
674 | in order to build the lex and yacc portions of the project. This␊ |
675 | template is portable across Unix and Windows since it generates different␊ |
676 | commands depending on the <code>$is_unix</code> variable.␊ |
677 | ␊ |
678 | <p>␊ |
679 | To learn more about the Expand() function and other Perl functions which␊ |
680 | tmake provides, consult the <a href="tmake_ref.html">reference manual</a>.␊ |
681 | ␊ |
682 | <p>␊ |
683 | Example project file:<pre>␊ |
684 | TEMPLATE = parser.t␊ |
685 | CONFIG = console release␊ |
686 | LEXINPUT = lexer.l␊ |
687 | YACCINPUT = grammar.y␊ |
688 | PARSER = parser.cpp␊ |
689 | SOURCES = $$PARSER \␊ |
690 | node.cpp \␊ |
691 | asmgen.cpp␊ |
692 | TARGET = parser␊ |
693 | </pre>␊ |
694 | ␊ |
695 | Here we use macro expansion <code>$$PARSER</code> to avoid writing parser.cpp␊ |
696 | two places.␊ |
697 | ␊ |
698 | ␊ |
699 | <h3>Counting the Number of Code Lines</h3>␊ |
700 | ␊ |
701 | tmake is generic since it is based on Perl. You can create your own␊ |
702 | templates for other purposes than producing makefiles. Here is an example␊ |
703 | template that counts the number of code lines in our project.␊ |
704 | ␊ |
705 | <p>␊ |
706 | Template wc.t:<pre>␊ |
707 | #! Template that count number of C++ lines.␊ |
708 | The number of C++ code lines for #$ $text=$project_name;␊ |
709 | #${␊ |
710 | $files = $project{"HEADERS"} . " " . $project{"SOURCES"};␊ |
711 | $text = `wc -l $files`;␊ |
712 | #$}␊ |
713 | </pre>␊ |
714 | Run it:<pre>␊ |
715 | tmake -t wc hello␊ |
716 | </pre>␊ |
717 | Output:<pre>␊ |
718 | The number of C++ code lines for hello.pro␊ |
719 | 25 hello.h␊ |
720 | 98 hello.cpp␊ |
721 | 38 main.cpp␊ |
722 | 161 total␊ |
723 | </pre>␊ |
724 | This will only work if the wc program is installed on your system.␊ |
725 | ␊ |
726 | ␊ |
727 | </body></html>␊ |
728 |