added release.txt blurb. Fixed spelling typo in Defaults.xml
[scons.git] / test / Docbook / basedir / htmlhelp / image / manual.xml
blob067c76e56325507ab8517d4c71b9ceed9b0ae23a
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
4   Copyright (c) 2001-2010 The SCons Foundation
6   Permission is hereby granted, free of charge, to any person obtaining
7   a copy of this software and associated documentation files (the
8   "Software"), to deal in the Software without restriction, including
9   without limitation the rights to use, copy, modify, merge, publish,
10   distribute, sublicense, and/or sell copies of the Software, and to
11   permit persons to whom the Software is furnished to do so, subject to
12   the following conditions:
14   The above copyright notice and this permission notice shall be included
15   in all copies or substantial portions of the Software.
17   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
18   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 -->
26 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
27 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
28 <article>
29   <title>The SCons qt4 tool</title>
31   <articleinfo>
32     <author>
33       <surname>Dirk Baechle</surname>
34     </author>
36     <pubdate>2010-12-06</pubdate>
37   </articleinfo>
39   <section id="basics">
40     <title>Basics</title>
42     <para>This tool can be used to compile Qt projects, designed for versions
43     4.x.y and higher. It is not usable for Qt3 and older versions, since some
44     of the helper tools (<literal>moc</literal>, <literal>uic</literal>)
45     behave different.</para>
47     <section id="install">
48       <title>Install</title>
50       <para>Installing it, requires you to copy (or, even better: checkout)
51       the contents of the package's <literal>qt4</literal> folder to</para>
53       <orderedlist>
54         <listitem>
55           <para><quote><literal>/path_to_your_project/site_scons/site_tools/qt4</literal></quote>,
56           if you need the Qt4 Tool in one project only, or</para>
57         </listitem>
59         <listitem>
60           <para><quote><literal>~/.scons/site_scons/site_tools/qt4</literal></quote>,
61           for a system-wide installation under your current login.</para>
62         </listitem>
63       </orderedlist>
65       <para>For more infos about this, please refer to</para>
67       <itemizedlist>
68         <listitem>
69           <para>the SCons User's Guide, chap. 17.7 "Where to put your custom
70           Builders and Tools" and</para>
71         </listitem>
73         <listitem>
74           <para>the SCons Tools Wiki page at <ulink
75           url="https://github.com/SCons/scons/wiki/ToolsIndex">https://github.com/SCons/scons/wiki/ToolsIndex</ulink>.</para>
76         </listitem>
77       </itemizedlist>
78     </section>
80     <section id="activation">
81       <title>How to activate</title>
83       <para>For activating the tool "qt4", you have to add its name to the
84       Environment constructor, like this</para>
86       <screen>env = Environment(tools=['default','qt4'])
87 </screen>
89       <para>On its startup, the Qt4 tool tries to read the variable
90       <literal>QT4DIR</literal> from the current Environment and
91       <literal>os.environ</literal>. If it is not set, the value of
92       <literal>QTDIR</literal> (in Environment/<literal>os.environ</literal>)
93       is used as a fallback.</para>
95       <para>So, you either have to explicitly give the path of your Qt4
96       installation to the Environment with</para>
98       <screen>env['QT4DIR'] = '/usr/local/Trolltech/Qt-4.2.3'
99 </screen>
101       <para>or set the <literal>QT4DIR</literal> as environment variable in
102       your shell.</para>
103     </section>
105     <section id="requirements">
106       <title>Requirements</title>
108       <para>Under Linux, "qt4" uses the system tool
109       <literal>pkg-config</literal> for automatically setting the required
110       compile and link flags of the single Qt4 modules (like QtCore,
111       QtGui,...). This means that</para>
113       <orderedlist>
114         <listitem>
115           <para>you should have <literal>pkg-config</literal> installed,
116           and</para>
117         </listitem>
119         <listitem>
120           <para>you additionally have to set
121           <literal>PKG_CONFIG_PATH</literal> in your shell environment, such
122           that it points to $<literal>QT4DIR/lib/pkgconfig</literal> (or
123           $<literal>QT4DIR/lib</literal> for some older versions).</para>
124         </listitem>
125       </orderedlist>
127       <para>Based on these two environment variables
128       (<literal>QT4DIR</literal> and <literal>PKG_CONFIG_PATH</literal>), the
129       "qt4" tool initializes all <literal>QT4_*</literal> construction
130       variables listed in the Reference manual. This happens when the tool is
131       "detected" during Environment construction. As a consequence, the setup
132       of the tool gets a two-stage process, if you want to override the values
133       provided by your current shell settings:</para>
135       <screen># Stage 1: create plain environment
136 qtEnv = Environment()
137 # Set new vars
138 qtEnv['QT4DIR'] = '/usr/local/Trolltech/Qt-4.2.3
139 qtEnv['ENV']['PKG_CONFIG_PATH'] = '/usr/local/Trolltech/Qt-4.2.3/lib/pkgconfig'
140 # Stage 2: add qt4 tool
141 qtEnv.Tool('qt4')
142 </screen>
143     </section>
144   </section>
146   <section id="boilerplate">
147     <title>Suggested boilerplate</title>
149     <para>Based on the requirements above, we suggest a simple ready-to-go
150     setup as follows:</para>
152     <para>SConstruct</para>
154     <screen># Detect Qt version
155 qtdir = detectLatestQtDir()
157 # Create base environment
158 baseEnv = Environment()
159 #...further customization of base env
161 # Clone Qt environment
162 qtEnv = baseEnv.Clone()
163 # Set QT4DIR and PKG_CONFIG_PATH
164 qtEnv['ENV']['PKG_CONFIG_PATH'] = os.path.join(qtdir, 'lib/pkgconfig')
165 qtEnv['QT4DIR'] = qtdir
166 # Add qt4 tool
167 qtEnv.Tool('qt4')
168 #...further customization of qt env
170 # Export environments
171 Export('baseEnv qtEnv')
173 # Your other stuff...
174 # ...including the call to your SConscripts
175 </screen>
177     <para>In a SConscript</para>
179     <screen># Get the Qt4 environment
180 Import('qtEnv')
181 # Clone it
182 env = qtEnv.clone()
183 # Patch it
184 env.Append(CCFLAGS=['-m32']) # or whatever
185 # Use it
186 env.StaticLibrary('foo', Glob('*.cpp'))
187 </screen>
189     <para>The detection of the Qt directory could be as simple as directly
190     assigning a fixed path</para>
192     <screen>def detectLatestQtDir():
193     return "/usr/local/qt4.3.2"
194 </screen>
196     <para>or a little more sophisticated</para>
198     <screen># Tries to detect the path to the installation of Qt with
199 # the highest version number
200 def detectLatestQtDir():
201     if sys.platform.startswith("linux"):
202         # Simple check: inspect only '/usr/local/Trolltech'
203         paths = glob.glob('/usr/local/Trolltech/*')
204         if len(paths):
205             paths.sort()
206             return paths[-1]
207         else:
208             return ""
209     else:
210         # Simple check: inspect only 'C:\Qt'
211         paths = glob.glob('C:\\Qt\\*')
212         if len(paths):
213             paths.sort()
214             return paths[-1]
215         else:
216             return os.environ.get("QTDIR","")
217 </screen>
218   </section>
220   <section id="firstproject">
221     <title>A first project</title>
223     <para>The following SConscript is for a simple project with some cxx
224     files, using the QtCore, QtGui and QtNetwork modules:</para>
226     <screen>Import('qtEnv')
227 env = qtEnv.Clone()
228 env.EnableQt4Modules([
229                       'QtGui',
230                       'QtCore',
231                       'QtNetwork'
232                      ])
233 # Add your CCFLAGS and CPPPATHs to env here...
235 env.Program('foo', Glob('*.cpp')) 
236 </screen>
237   </section>
239   <section id="mocup">
240     <title>MOC it up</title>
242     <para>For the basic support of automocing, nothing needs to be done by the
243     user. The tool usually detects the <literal>Q_OBJECT</literal> macro and
244     calls the <quote><literal>moc</literal></quote> executable
245     accordingly.</para>
247     <para>If you don't want this, you can switch off the automocing by
248     a</para>
250     <screen>env['QT4_AUTOSCAN'] = 0
251 </screen>
253     <para>in your SConscript file. Then, you have to moc your files
254     explicitly, using the Moc4 builder.</para>
256     <para>You can also switch to an extended automoc strategy with</para>
258     <screen>env['QT4_AUTOSCAN_STRATEGY'] = 1
259 </screen>
261     <para>Please read the description of the
262     <literal>QT4_AUTOSCAN_STRATEGY</literal> variable in the Reference manual
263     for details.</para>
265     <para>For debugging purposes, you can set the variable
266     <literal>QT4_DEBUG</literal> with</para>
268     <screen>env['QT4_DEBUG'] = 1
269 </screen>
271     <para>which outputs a lot of messages during automocing.</para>
272   </section>
274   <section id="forms">
275     <title>Forms (.ui)</title>
277     <para>The header files with setup code for your GUI classes, are not
278     compiled automatically from your <literal>.ui</literal> files. You always
279     have to call the Uic4 builder explicitly like</para>
281     <screen>env.Uic4(Glob('*.ui'))
282 env.Program('foo', Glob('*.cpp'))
283 </screen>
284   </section>
286   <section id="resources">
287     <title>Resource files (.qrc)</title>
289     <para>Resource files are not built automatically, you always have to add
290     the names of the <literal>.qrc</literal> files to the source list for your
291     program or library:</para>
293     <screen>env.Program('foo', Glob('*.cpp')+Glob('*.qrc'))
294 </screen>
296     <para>For each of the Resource input files, its prefix defines the name of
297     the resulting resource. An appropriate
298     <quote><literal>-name</literal></quote> option is added to the call of the
299     <literal>rcc</literal> executable by default.</para>
301     <para>You can also call the Qrc4 builder explicitly as</para>
303     <screen>qrccc = env.Qrc4('foo') # ['foo.qrc'] -&gt; ['qrc_foo.cc']
304 </screen>
306     <para>or (overriding the default suffix)</para>
308     <screen>qrccc = env.Qrc4('myprefix_foo.cxx','foo.qrc') # -&gt; ['qrc_myprefix_foo.cxx']
309 </screen>
311     <para>and then add the resulting cxx file to the sources of your
312     Program/Library:</para>
314     <screen>env.Program('foo', Glob('*.cpp') + qrccc)
315 </screen>
316   </section>
318   <section id="translation">
319     <title>Translation files</title>
321     <para>The update of the <literal>.ts</literal> files and the conversion to
322     binary <literal>.qm</literal> files is not done automatically. You have to
323     call the corresponding builders on your own.</para>
325     <para>Example for updating a translation file:</para>
327     <screen>env.Ts4('foo.ts','.') # -&gt; ['foo.ts']
328 </screen>
330     <para>By default, the <literal>.ts</literal> files are treated as
331     <emphasis>precious</emphasis> targets. This means that they are not
332     removed prior to a rebuild, but simply get updated. Additionally, they do
333     not get cleaned on a <quote><literal>scons -c</literal></quote>. If you
334     want to delete the translation files on the
335     <quote><literal>-c</literal></quote> SCons command, you can set the
336     variable <quote><literal>QT4_CLEAN_TS</literal></quote> like this</para>
338     <screen>env['QT4_CLEAN_TS']=1
339 </screen>
341     <para>Example for releasing a translation file, i.e. compiling it to a
342     <literal>.qm</literal> binary file:</para>
344     <screen>env.Qm4('foo') # ['foo.ts'] -&gt; ['foo.qm']
345 </screen>
347     <para>or (overriding the output prefix)</para>
349     <screen>env.Qm4('myprefix','foo') # ['foo.ts'] -&gt; ['myprefix.qm']
350 </screen>
352     <para>As an extension both, the Ts4() and Qm4 builder, support the
353     definition of multiple targets. So, calling</para>
355     <screen>env.Ts4(['app_en','app_de'], Glob('*.cpp'))
356 </screen>
358     <para>and</para>
360     <screen>env.Qm4(['app','copy'], Glob('*.ts'))
361 </screen>
363     <para>should work fine.</para>
365     <para>Finally, two short notes about the support of directories for the
366     Ts4() builder. You can pass an arbitrary mix of cxx files and subdirs to
367     it, as in</para>
369     <screen>env.Ts4('app_en',['sub1','appwindow.cpp','main.cpp']))
370 </screen>
372     <para>where <literal>sub1</literal> is a folder that gets scanned
373     recursively for cxx files by <literal>lupdate</literal>. But like this,
374     you lose all dependency information for the subdir, i.e. if a file inside
375     the folder changes, the .ts file is not updated automatically! In this
376     case you should tell SCons to always update the target:</para>
378     <screen>ts = env.Ts4('app_en',['sub1','appwindow.cpp','main.cpp'])
379 env.AlwaysBuild(ts)
380 </screen>
382     <para>Last note: specifying the current folder
383     <quote><literal>.</literal></quote> as input to Ts4() and storing the
384     resulting .ts file in the same directory, leads to a dependency cycle! You
385     then have to store the .ts and .qm files outside of the current folder, or
386     use <literal>Glob('*.cpp'))</literal> instead.</para>
387   </section>
388 </article>