1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# Copyright 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Support for the Qt GUI library version 3
# (http://www.trolltech.com/products/qt3/index.html).
# For new developments, it is recommended to use Qt4 via the qt4 Boost.Build
# module.
import modules ;
import feature ;
import errors ;
import type ;
import "class" : new ;
import generators ;
import project ;
import toolset : flags ;
# Convert this module into a project, so that we can declare targets here.
project.initialize $(__name__) ;
project qt3 ;
# Initialized the QT support module. The 'prefix' parameter tells where QT is
# installed. When not given, environmental variable QTDIR should be set.
#
rule init ( prefix ? )
{
if ! $(prefix)
{
prefix = [ modules.peek : QTDIR ] ;
if ! $(prefix)
{
errors.error
"QT installation prefix not given and QTDIR variable is empty" ;
}
}
if $(.initialized)
{
if $(prefix) != $(.prefix)
{
errors.error
"Attempt the reinitialize QT with different installation prefix" ;
}
}
else
{
.initialized = true ;
.prefix = $(prefix) ;
generators.register-standard qt3.moc : H : CPP(moc_%) : <allow>qt3 ;
# Note: the OBJ target type here is fake, take a look at
# qt4.jam/uic-h-generator for explanations that apply in this case as
# well.
generators.register [ new moc-h-generator-qt3
qt3.moc.cpp : MOCCABLE_CPP : OBJ : <allow>qt3 ] ;
# The UI type is defined in types/qt.jam, and UIC_H is only used in
# qt.jam, but not in qt4.jam, so define it here.
type.register UIC_H : : H ;
generators.register-standard qt3.uic-h : UI : UIC_H : <allow>qt3 ;
# The following generator is used to convert UI files to CPP. It creates
# UIC_H from UI, and constructs CPP from UI/UIC_H. In addition, it also
# returns UIC_H target, so that it can be mocced.
class qt::uic-cpp-generator : generator
{
rule __init__ ( )
{
generator.__init__ qt3.uic-cpp : UI UIC_H : CPP : <allow>qt3 ;
}
rule run ( project name ? : properties * : sources + )
{
# Consider this:
# obj test : test_a.cpp : <optimization>off ;
#
# This generator will somehow be called in this case, and,
# will fail -- which is okay. However, if there are <library>
# properties they will be converted to sources, so the size of
# 'sources' will be more than 1. In this case, the base generator
# will just crash -- and that's not good. Just use a quick test
# here.
local result ;
if ! $(sources[2])
{
# Construct CPP as usual
result = [ generator.run $(project) $(name)
: $(properties) : $(sources) ] ;
# If OK, process UIC_H with moc. It's pretty clear that
# the object generated with UIC will have Q_OBJECT macro.
if $(result)
{
local action = [ $(result[1]).action ] ;
local sources = [ $(action).sources ] ;
local mocced = [ generators.construct $(project) $(name)
: CPP : $(properties) : $(sources[2]) ] ;
result += $(mocced[2-]) ;
}
}
return $(result) ;
}
}
generators.register [ new qt::uic-cpp-generator ] ;
# Finally, declare prebuilt target for QT library.
local usage-requirements =
<include>$(.prefix)/include
<dll-path>$(.prefix)/lib
<library-path>$(.prefix)/lib
<allow>qt3
;
lib qt : : <name>qt-mt <threading>multi : : $(usage-requirements) ;
lib qt : : <name>qt <threading>single : : $(usage-requirements) ;
}
}
class moc-h-generator-qt3 : generator
{
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
}
rule run ( project name ? : property-set : sources * )
{
if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
{
name = [ $(sources[1]).name ] ;
name = $(name:B) ;
local a = [ new action $(sources[1]) : qt3.moc.cpp :
$(property-set) ] ;
local target = [
new file-target $(name) : MOC : $(project) : $(a) ] ;
local r = [ virtual-target.register $(target) ] ;
# Since this generator will return a H target, the linking generator
# won't use it at all, and won't set any dependency on it. However,
# we need the target to be seen by bjam, so that the dependency from
# sources to this generated header is detected -- if Jam does not
# know about this target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
return $(r) ;
}
}
}
# Query the installation directory. This is needed in at least two scenarios.
# First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
# plugins to the Qt-Tree.
#
rule directory
{
return $(.prefix) ;
}
# -f forces moc to include the processed source file. Without it, it would think
# that .qpp is not a header and would not include it from the generated file.
#
actions moc
{
$(.prefix)/bin/moc -f $(>) -o $(<)
}
# When moccing .cpp files, we don't need -f, otherwise generated code will
# include .cpp and we'll get duplicated symbols.
#
actions moc.cpp
{
$(.prefix)/bin/moc $(>) -o $(<)
}
space = " " ;
# Sometimes it's required to make 'plugins' available during uic invocation. To
# help with this we add paths to all dependency libraries to uic commane line.
# The intention is that it's possible to write
#
# exe a : ... a.ui ... : <uses>some_plugin ;
#
# and have everything work. We'd add quite a bunch of unrelated paths but it
# won't hurt.
#
flags qt3.uic-h LIBRARY_PATH <xdll-path> ;
actions uic-h
{
$(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
}
flags qt3.uic-cpp LIBRARY_PATH <xdll-path> ;
# The second target is uic-generated header name. It's placed in build dir, but
# we want to include it using only basename.
actions uic-cpp
{
$(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
}
|