Imported Upstream version 0.1.9998svn2813+dfsg
Gianfranco Costamagna
8 years ago
0 | # $Id: header.kmk 2796 2015-09-15 23:36:00Z bird $ | |
0 | # $Id: header.kmk 2813 2016-03-13 12:56:18Z bird $ | |
1 | 1 | ## @file |
2 | 2 | # kBuild - File included at top of a makefile. |
3 | 3 | # |
78 | 78 | # The revision in which this file was last modified. |
79 | 79 | # This can be useful when using development versions of kBuild. |
80 | 80 | # |
81 | KMK_REVISION := $(patsubst %:,, $Rev: 2796 $ ) | |
81 | KMK_REVISION := $(patsubst %:,, $Rev: 2813 $ ) | |
82 | 82 | |
83 | 83 | |
84 | 84 | # |
188 | 188 | # build types. (PORTME) |
189 | 189 | # |
190 | 190 | KBUILD_OSES := darwin dos dragonfly freebsd haiku l4 linux netbsd nt openbsd os2 solaris win os-agnostic |
191 | KBUILD_ARCHES := x86 amd64 sparc32 sparc64 s390 s390x ppc32 ppc64 mips32 mips64 ia64 hppa32 hppa64 arm alpha | |
191 | KBUILD_ARCHES := x86 amd64 sparc32 sparc64 s390 s390x ppc32 ppc64 mips32 mips64 ia64 hppa32 hppa64 arm alpha noarch | |
192 | 192 | KBUILD_ARCHES_64 := amd64 sparc64 s390x ppc64 mips64 ia64 hppa64 alpha |
193 | 193 | KBUILD_ARCHES_32 := x86 sparc32 s390 ppc32 mips32 hppa32 arm |
194 | 194 |
0 | # $Id: NASM.kmk 2750 2015-01-23 12:24:02Z bird $ | |
0 | # $Id: NASM.kmk 2808 2016-01-30 15:13:32Z bird $ | |
1 | 1 | ## @file |
2 | 2 | # kBuild Tool Config - Netwide Assembler v0.98+. |
3 | 3 | # |
34 | 34 | |
35 | 35 | # Tool Specific Properties |
36 | 36 | ifndef PATH_TOOL_NASM |
37 | PATH_TOOL_NASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/nasm/v*.*)) | |
38 | ifneq ($(PATH_TOOL_NASM),) | |
39 | PATH_TOOL_NASM := $(call lastword,$(PATH_TOOL_NASM)) | |
37 | PATH_TOOL_NASM := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/nasm/v*.*))) | |
38 | if "$(PATH_TOOL_NASM)" == "" && "$(KBUILD_DEVTOOLS_HST_ALT)" != "" | |
39 | PATH_TOOL_NASM := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/nasm/v*.*))) | |
40 | 40 | endif |
41 | 41 | else |
42 | 42 | # Resolve any fancy stuff once and for all. |
75 | 75 | -l $(outbase).lst\ |
76 | 76 | -o $(obj)\ |
77 | 77 | $(abspath $(source)) |
78 | $(QUIET)$(REDIRECT) -wo $(dep) -- $(TOOL_NASM_AS)\ | |
78 | $(QUIET)$(REDIRECT) -C $(PATH_OUT_BASE) -wo $(dep) -- $(TOOL_NASM_AS) -DKBUILD_GENERATING_MAKEFILE_DEPENDENCIES\ | |
79 | 79 | $(flags) $(addsuffix /,$(addprefix -i, $(incs))) $(addprefix -D, $(defs))\ |
80 | 80 | -l $(outbase).lst\ |
81 | 81 | -o $(obj)\ |
82 | 82 | $(abspath $(source)) \ |
83 | -M | |
83 | -M -MP | |
84 | 84 | endef |
85 | 85 |
0 | # $Id: qt3.kmk 2726 2014-02-26 23:23:54Z bird $ | |
0 | # $Id: qt3.kmk 2805 2016-01-28 11:08:44Z bird $ | |
1 | 1 | ## @file |
2 | 2 | # Qt 3.3.x unit. |
3 | 3 | # |
4 | 4 | |
5 | 5 | # |
6 | # Copyright (c) 2008-2014 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net> | |
6 | # Copyright (c) 2008-2016 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net> | |
7 | 7 | # |
8 | 8 | # This file is part of kBuild. |
9 | 9 | # |
37 | 37 | UNIT_qt3 = qt3 |
38 | 38 | |
39 | 39 | |
40 | ifndef UNIT_qt4 | |
41 | # Add our target properties (same as qt4). | |
40 | if !defined(UNIT_qt4) && !defined(UNIT_qt5) | |
41 | # Add our target properties (same as qt4 & qt5). | |
42 | 42 | PROPS_SINGLE += QTTOOL MOCTOOL UICTOOL LRCTOOL QT_TRANSLATIONS_INST QT_TRANSLATIONS_TEMPLATE QT_PREFIX |
43 | 43 | PROPS_ACCUMULATE_R += MOCDEFS MOCFLAGS UICFLAGS LRCFLAGS QT_TRANSLATIONS QT_MOCSRCS QT_MOCHDRS |
44 | 44 | endif |
0 | # $Id: qt4.kmk 2787 2015-08-13 09:16:00Z bird $ | |
0 | # $Id: qt4.kmk 2805 2016-01-28 11:08:44Z bird $ | |
1 | 1 | ## @file |
2 | 2 | # Qt 4 unit. |
3 | 3 | # |
4 | 4 | |
5 | 5 | # |
6 | # Copyright (c) 2008-2014 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net> | |
6 | # Copyright (c) 2008-2016 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net> | |
7 | 7 | # |
8 | 8 | # This file is part of kBuild. |
9 | 9 | # |
37 | 37 | UNIT_qt4 = qt4 |
38 | 38 | |
39 | 39 | |
40 | ifndef UNIT_qt3 | |
41 | # Add our target properties (same as qt3). | |
40 | if !defined(UNIT_qt3) && !defined(UNIT_qt5) | |
41 | # Add our target properties (same as qt3 & qt5). | |
42 | 42 | PROPS_SINGLE += QTTOOL MOCTOOL UICTOOL LRCTOOL QT_TRANSLATIONS_INST QT_TRANSLATIONS_TEMPLATE QT_PREFIX |
43 | 43 | PROPS_ACCUMULATE_R += MOCDEFS MOCFLAGS UICFLAGS LRCFLAGS QT_TRANSLATIONS QT_MOCSRCS QT_MOCHDRS |
44 | 44 | endif |
0 | # $Id: qt5.kmk 2807 2016-01-28 13:21:41Z bird $ | |
1 | ## @file | |
2 | # Qt 5 unit. | |
3 | # | |
4 | ||
5 | # | |
6 | # Copyright (c) 2008-2016 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net> | |
7 | # | |
8 | # This file is part of kBuild. | |
9 | # | |
10 | # kBuild is free software; you can redistribute it and/or modify | |
11 | # it under the terms of the GNU General Public License as published by | |
12 | # the Free Software Foundation; either version 2 of the License, or | |
13 | # (at your option) any later version. | |
14 | # | |
15 | # kBuild is distributed in the hope that it will be useful, | |
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | # GNU General Public License for more details. | |
19 | # | |
20 | # You should have received a copy of the GNU General Public License | |
21 | # along with kBuild; if not, write to the Free Software | |
22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
23 | # | |
24 | # | |
25 | # As a special exception you are granted permission to include this file, via | |
26 | # the kmk include directive, as you wish without this in itself causing the | |
27 | # resulting makefile, program or whatever to be covered by the GPL license. | |
28 | # This exception does not however invalidate any other reasons why the makefile, | |
29 | # program, whatever should not be covered the GPL. | |
30 | # | |
31 | # | |
32 | ||
33 | ||
34 | ifdef UNIT_qt5 | |
35 | $(error kBuild: The qt5 unit was included twice!) | |
36 | endif | |
37 | UNIT_qt5 = qt5 | |
38 | ||
39 | ||
40 | if !defined(UNIT_qt3) && !defined(UNIT_qt4) | |
41 | # Add our target properties (same as qt3 & qt4). | |
42 | PROPS_SINGLE += QTTOOL MOCTOOL UICTOOL LRCTOOL QT_TRANSLATIONS_INST QT_TRANSLATIONS_TEMPLATE QT_PREFIX | |
43 | PROPS_ACCUMULATE_R += MOCDEFS MOCFLAGS UICFLAGS LRCFLAGS QT_TRANSLATIONS QT_MOCSRCS QT_MOCHDRS | |
44 | endif | |
45 | PROPS_SINGLE += RCCTOOL QT_INFIX | |
46 | PROPS_ACCUMULATE_R += RCCFLAGS QT_MODULES | |
47 | ||
48 | ||
49 | ## @todo use pkg-config? | |
50 | ||
51 | # | |
52 | # The QT5 SDK. | |
53 | # | |
54 | # This is implemented here rather than in sdks/QT5.kmk to enforce the global USES. | |
55 | # It also makes things easier to develop, with fewer files I mean. | |
56 | # | |
57 | ## @todo the SDK might actually not be necessary as it turns out... For now it servers | |
58 | # a purpose if the host differs from the target, in theory at least. | |
59 | SDK_QT5 = Qt5 | |
60 | ||
61 | # SDK Specific Properties | |
62 | # PATH_SDK_QT5 - The general Qt5 root directory. | |
63 | # PATH_SDK_QT5_INC - The include directory. | |
64 | # PATH_SDK_QT5_LIB.amd64 - The lib directory for AMD64. | |
65 | # PATH_SDK_QT5_LIB.x86 - The lib directory for X86. | |
66 | # PATH_SDK_QT5_LIB - The lib directory for KBUILD_TARGET. | |
67 | ifndef PATH_SDK_QT5 | |
68 | PATH_SDK_QT5 := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/qt/v5*))) | |
69 | ifeq ($(PATH_SDK_QT5),) | |
70 | # If target == host, try look for Qt in the various platform specific places. | |
71 | ifeq ($(KBUILD_TARGET),$(KBUILD_HOST)) | |
72 | ifeq ($(KBUILD_TARGET),darwin) | |
73 | PATH_SDK_QT5 := $(patsubst %/Frameworks/QtCore.framework/Versions/5,%,$(firstword $(wildcard /Library/Frameworks/QtCore.framework/Versions/5))) | |
74 | else ifeq ($(KBUILD_TARGET),win) | |
75 | # No idea here yet... | |
76 | else ifeq ($(KBUILD_TARGET),ose) | |
77 | # No port... | |
78 | else | |
79 | # The Unices. Includes and esp. libs are tricky, so override the PATH_SDK_QT5_LIB* stuff if it doesn't work. | |
80 | # Try find the general root of thing by looking for the qt4to5 program, if not found, then look for rcc. | |
81 | PATH_SDK_QT5 := $(patsubst %/bin/qt4to5-qt5,%,$(firstword $(wildcard \ | |
82 | /usr/bin/qt4to5-qt5 \ | |
83 | /usr/local/bin/qt4to5-qt5 \ | |
84 | /usr/qt/5/bin/qt4to5-qt5 \ | |
85 | /usr/share/qt5/bin/qt4to5-qt5 \ | |
86 | ))) | |
87 | ifeq ($(PATH_SDK_QT5),) | |
88 | PATH_SDK_QT5 := $(patsubst %/bin/qt4to5,%,$(firstword $(wildcard \ | |
89 | /usr/bin/qt4to5 \ | |
90 | /usr/local/bin/qt4to5 \ | |
91 | /usr/qt/5/bin/qt4to5 \ | |
92 | /usr/share/qt5/bin/qt4to5 \ | |
93 | ))) | |
94 | endif | |
95 | ifeq ($(PATH_SDK_QT5),) | |
96 | PATH_SDK_QT5 := $(patsubst %/bin/rcc-qt5,%,$(firstword $(wildcard \ | |
97 | /usr/bin/rcc-qt5 \ | |
98 | /usr/local/bin/rcc-qt5 \ | |
99 | /usr/qt/5/bin/rcc-qt5 \ | |
100 | /usr/share/qt5/bin/rcc-qt5 \ | |
101 | ))) | |
102 | endif | |
103 | ifeq ($(PATH_SDK_QT5),) | |
104 | PATH_SDK_QT5 := $(patsubst %/bin/rcc,%,$(firstword $(wildcard \ | |
105 | /usr/bin/rcc \ | |
106 | /usr/local/bin/rcc \ | |
107 | /usr/qt/5/bin/rcc \ | |
108 | /usr/share/qt5/bin/rcc \ | |
109 | ))) | |
110 | endif | |
111 | ifneq ($(PATH_SDK_QT5),) | |
112 | export PATH_SDK_QT5 | |
113 | ||
114 | # Locate the include files. | |
115 | ifeq ($(PATH_SDK_QT5_INC),) | |
116 | PATH_SDK_QT5_INC := $(patsubst %/QtCore/qglobal.h,%,$(firstword $(wildcard \ | |
117 | $(PATH_SDK_QT5)/include/QtCore/qglobal.h \ | |
118 | $(PATH_SDK_QT5)/include/qt5/QtCore/qglobal.h \ | |
119 | /usr/include/qt5/QtCore/qtglobal.h \ | |
120 | /usr/local/include/qt5/QtCore/qtglobal.h \ | |
121 | ))) | |
122 | ifneq ($(PATH_SDK_QT5_INC),) | |
123 | export PATH_SDK_QT5_INC | |
124 | endif | |
125 | endif | |
126 | ||
127 | # Now for the libraries (mostly for helping out finding the KBUILD_TARGET libs). | |
128 | ifeq ($(PATH_SDK_QT5_LIB.x86),) | |
129 | PATH_SDK_QT5_LIB.x86 := $(patsubst %/libQt5Core$(SUFF_DLL),%,$(firstword $(wildcard \ | |
130 | $(PATH_SDK_QT5)/lib32/libQt5Core$(SUFF_DLL) \ | |
131 | $(PATH_SDK_QT5)/lib32/qt5/libQt5Core$(SUFF_DLL) \ | |
132 | /usr/lib32/libQt5Core$(SUFF_DLL) \ | |
133 | /usr/lib32/qt5/libQt5Core$(SUFF_DLL) \ | |
134 | /usr/lib/i386-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
135 | /usr/local/lib32/libQt5Core$(SUFF_DLL) \ | |
136 | /usr/local/lib32/qt5/libQt5Core$(SUFF_DLL) \ | |
137 | /usr/local/lib/i386-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
138 | $(PATH_SDK_QT5)/lib/libQt5Core$(SUFF_DLL) \ | |
139 | $(PATH_SDK_QT5)/lib/qt5/libQt5Core$(SUFF_DLL) \ | |
140 | $(PATH_SDK_QT5)/lib/i386-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
141 | ))) | |
142 | ifneq ($(PATH_SDK_QT5_LIB.x86),) | |
143 | export PATH_SDK_QT5_LIB.x86 | |
144 | endif | |
145 | endif | |
146 | ifeq ($(PATH_SDK_QT5_LIB.amd64),) | |
147 | PATH_SDK_QT5_LIB.amd64 := $(patsubst %/libQt5Core$(SUFF_DLL),%,$(firstword $(wildcard \ | |
148 | $(PATH_SDK_QT5)/lib64/libQt5Core$(SUFF_DLL) \ | |
149 | $(PATH_SDK_QT5)/lib64/qt5/libQt5Core$(SUFF_DLL) \ | |
150 | $(PATH_SDK_QT5)/lib/amd64/libQt5Core$(SUFF_DLL) \ | |
151 | /usr/lib64/libQt5Core$(SUFF_DLL) \ | |
152 | /usr/lib64/qt5/libQt5Core$(SUFF_DLL) \ | |
153 | /usr/lib/amd64/libQt5Core$(SUFF_DLL) \ | |
154 | /usr/lib/x86_64-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
155 | /usr/local/lib64/libQt5Core$(SUFF_DLL) \ | |
156 | /usr/local/lib64/qt5/libQt5Core$(SUFF_DLL) \ | |
157 | /usr/local/lib/amd64/libQt5Core$(SUFF_DLL) \ | |
158 | /usr/local/lib/x86_64-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
159 | $(PATH_SDK_QT5)/lib/libQt5Core$(SUFF_DLL) \ | |
160 | $(PATH_SDK_QT5)/lib/qt5/libQt5Core$(SUFF_DLL) \ | |
161 | $(PATH_SDK_QT5)/lib/x86_64-linux-gnu/libQt5Core$(SUFF_DLL) \ | |
162 | ))) | |
163 | ifneq ($(PATH_SDK_QT5_LIB.amd64),) | |
164 | export PATH_SDK_QT5_LIB.amd64 | |
165 | endif | |
166 | endif | |
167 | ||
168 | # And finally, the library path for KBUILD_TARGET. | |
169 | ifeq ($(PATH_SDK_QT5_LIB),) | |
170 | PATH_SDK_QT5_LIB := $(PATH_SDK_QT5_LIB.$(KBUILD_TARGET_ARCH)) | |
171 | ifeq ($(PATH_SDK_QT5_LIB),) | |
172 | PATH_SDK_QT5_LIB := $(patsubst %/libQt5Core$(SUFF_DLL),%,$(firstword $(wildcard \ | |
173 | $(PATH_SDK_QT5)/lib/libQt5Core$(SUFF_DLL) \ | |
174 | $(PATH_SDK_QT5)/lib/qt5/libQt5Core$(SUFF_DLL) \ | |
175 | /usr/lib/libQt5Core$(SUFF_DLL) \ | |
176 | /usr/lib/qt5/libQt5Core$(SUFF_DLL) \ | |
177 | /usr/local/lib/libQt5Core$(SUFF_DLL) \ | |
178 | /usr/local/lib/qt5/libQt5Core$(SUFF_DLL) \ | |
179 | ))) | |
180 | endif | |
181 | ifneq ($(PATH_SDK_QT5_LIB),) | |
182 | export PATH_SDK_QT5_LIB | |
183 | endif | |
184 | endif | |
185 | ||
186 | endif | |
187 | endif # Unices | |
188 | endif | |
189 | # Found it? | |
190 | ifeq ($(PATH_SDK_QT5),) | |
191 | $(warning kBuild: Couldn't find the Qt5 headers and libaries...) | |
192 | PATH_SDK_QT5 := $(KBUILD_DEVTOOLS_TRG)/qt/not-found | |
193 | endif | |
194 | endif | |
195 | else | |
196 | # Resolve any fancy stuff once and for all. | |
197 | PATH_SDK_QT5 := $(PATH_SDK_QT5) | |
198 | endif | |
199 | ||
200 | # Libraries can be in either Frameworks or lib depending on how you | |
201 | # build it on the mac. The .dmg installs into Frameworks but builds into lib. | |
202 | ifeq ($(KBUILD_TARGET),darwin) | |
203 | ifndef PATH_SDK_QT5_LIB | |
204 | ifneq ($(wildcard $(PATH_SDK_QT5)/Frameworks),) | |
205 | PATH_SDK_QT5_LIB ?= $(PATH_SDK_QT5)/Frameworks | |
206 | else | |
207 | PATH_SDK_QT5_LIB ?= $(PATH_SDK_QT5)/lib | |
208 | endif | |
209 | endif | |
210 | else | |
211 | PATH_SDK_QT5_LIB ?= $(PATH_SDK_QT5)/lib | |
212 | PATH_SDK_QT5_INC ?= $(PATH_SDK_QT5)/include | |
213 | endif | |
214 | ||
215 | # The bits that kBuild picks up. | |
216 | # (nothing here) | |
217 | ||
218 | ||
219 | # | |
220 | # The QT5 tool. | |
221 | # | |
222 | # This is implemented here rather than in tools/QT5.kmk to enforce the global USES. | |
223 | # It also makes things easier to develop, with fewer files I mean. | |
224 | # | |
225 | TOOL_QT5 = Qt5 | |
226 | ||
227 | # Tool Specific Properties | |
228 | # PATH_TOOL_QT5 - Obsolete. | |
229 | # PATH_TOOL_QT5_BIN - The | |
230 | # TOOL_QT5_BIN_SUFF - | |
231 | if !defined(PATH_TOOL_QT5_BIN) && defined(PATH_TOOL_QT5) | |
232 | PATH_TOOL_QT5_BIN := $(PATH_TOOL_QT5)/bin | |
233 | endif | |
234 | ifndef PATH_TOOL_QT5_BIN | |
235 | PATH_TOOL_QT5_BIN := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/qt/v5*/bin))) | |
236 | if "$(PATH_TOOL_QT5_BIN)" == "" && "$(KBUILD_DEVTOOLS_HST_ALT)" != "" | |
237 | PATH_TOOL_QT5_BIN := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/qt/v5*/bin))) | |
238 | endif | |
239 | ifeq ($(PATH_TOOL_QT5_BIN),) | |
240 | ifdef TOOL_QT5_BIN_SUFF | |
241 | TOOL_QT5_BIN_SUFF := $(TOOL_QT5_BIN_SUFF) | |
242 | endif | |
243 | # Try looking for moc-qt5 / moc-$(suffix) first. | |
244 | ifneq ($(TOOL_QT5_BIN_SUFF),) | |
245 | PATH_TOOL_QT5_BIN := $(patsubst %/moc$(TOOL_QT5_BIN_SUFF),%,$(firstword $(wildcard \ | |
246 | /usr/lib/qt5/bin/moc$(TOOL_QT5_BIN_SUFF) \ | |
247 | /usr/qt/5/bin/moc$(TOOL_QT5_BIN_SUFF) \ | |
248 | /usr/share/qt5/bin/moc$(TOOL_QT5_BIN_SUFF) \ | |
249 | /usr/local/bin/moc$(TOOL_QT5_BIN_SUFF) \ | |
250 | /usr/bin/moc$(TOOL_QT5_BIN_SUFF) \ | |
251 | ))) | |
252 | else | |
253 | PATH_TOOL_QT5_BIN := $(patsubst %/moc-qt5,%,$(firstword $(wildcard \ | |
254 | /usr/lib/qt5/bin/moc-qt5 \ | |
255 | /usr/qt/5/bin/moc-qt5 \ | |
256 | /usr/share/qt5/bin/moc-qt5 \ | |
257 | /usr/local/bin/moc-qt5 \ | |
258 | /usr/bin/moc-qt5 \ | |
259 | ))) | |
260 | ifneq ($(PATH_TOOL_QT5_BIN),) | |
261 | TOOL_QT5_BIN_SUFF := -qt5 | |
262 | else | |
263 | # If no luck, try looking for moc in the qt5 specific locations. | |
264 | PATH_TOOL_QT5_BIN := $(patsubst %/moc,%,$(firstword $(wildcard \ | |
265 | /usr/lib/qt5/bin/moc \ | |
266 | /usr/qt/5/bin/moc \ | |
267 | /usr/share/qt5/bin/moc \ | |
268 | ))) | |
269 | endif | |
270 | endif | |
271 | # If still no go, try looking for qt4to5 and rcc. | |
272 | ifeq ($(PATH_TOOL_QT5_BIN),) | |
273 | PATH_TOOL_QT5_BIN := $(patsubst %/qt4to5,%,$(firstword $(wildcard \ | |
274 | /usr/lib/qt5/bin/qt4to5 \ | |
275 | /usr/qt/5/bin/qt4to5 \ | |
276 | /usr/share/qt5/bin/qt4to5 \ | |
277 | /usr/local/bin/qt4to5 \ | |
278 | /usr/bin/qt4to5 \ | |
279 | ))) | |
280 | endif | |
281 | ifeq ($(PATH_TOOL_QT5_BIN),) | |
282 | PATH_TOOL_QT5_BIN := $(patsubst %/rcc$(TOOL_QT5_BIN_SUFF),%,$(firstword $(wildcard \ | |
283 | /usr/lib/qt5/bin/rcc$(TOOL_QT5_BIN_SUFF) \ | |
284 | /usr/qt/5/bin/rcc$(TOOL_QT5_BIN_SUFF) \ | |
285 | /usr/share/qt5/bin/rcc$(TOOL_QT5_BIN_SUFF) \ | |
286 | /usr/local/bin/rcc$(TOOL_QT5_BIN_SUFF) \ | |
287 | /usr/bin/rcc$(TOOL_QT5_BIN_SUFF) \ | |
288 | ))) | |
289 | endif | |
290 | if "$(PATH_TOOL_QT5_BIN)" == "" && "$(TOOL_QT5_BIN_SUFF)" != "" | |
291 | PATH_TOOL_QT5_BIN := $(patsubst %/rcc,%,$(firstword $(wildcard \ | |
292 | /usr/lib/qt5/bin/rcc \ | |
293 | /usr/qt/5/bin/rcc \ | |
294 | /usr/share/qt5/bin/rcc \ | |
295 | /usr/local/bin/rcc \ | |
296 | /usr/bin/rcc \ | |
297 | ))) | |
298 | endif | |
299 | ifneq ($(PATH_TOOL_QT5_BIN),) | |
300 | export PATH_TOOL_QT5_BIN | |
301 | endif | |
302 | endif | |
303 | # If not found, we'll enter the 'pathless' mode. | |
304 | else | |
305 | # Resolve any fancy stuff once and for all. | |
306 | PATH_TOOL_QT5_BIN := $(PATH_TOOL_QT5_BIN) | |
307 | endif | |
308 | ifneq ($(PATH_TOOL_QT5_BIN),) | |
309 | TOOL_QT5_MOC ?= $(PATH_TOOL_QT5_BIN)/moc$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
310 | TOOL_QT5_UIC ?= $(PATH_TOOL_QT5_BIN)/uic$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
311 | ifndef TOOL_QT5_RCC | |
312 | TOOL_QT5_RCC := $(PATH_TOOL_QT5_BIN)/rcc$(HOST_SUFF_EXE) | |
313 | ifeq ($(wildcard $(TOOL_QT5_RCC)),) | |
314 | TOOL_QT5_RCC := $(PATH_TOOL_QT5_BIN)/rcc$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
315 | endif | |
316 | endif | |
317 | TOOL_QT5_LRC ?= $(PATH_TOOL_QT5_BIN)/lrelease$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
318 | TOOL_QT5_LUPDATE ?= $(PATH_TOOL_QT5_BIN)/lupdate$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
319 | else | |
320 | # Pathless, relies on the environment. | |
321 | TOOL_QT5_MOC ?= moc$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
322 | TOOL_QT5_UIC ?= uic$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
323 | TOOL_QT5_RCC ?= rcc$(HOST_SUFF_EXE) | |
324 | TOOL_QT5_LRC ?= lrelease$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
325 | TOOL_QT5_LUPDATE ?= lupdate$(TOOL_QT5_BIN_SUFF)$(HOST_SUFF_EXE) | |
326 | endif | |
327 | ||
328 | # General Properties used by kBuild and/or units/qt.kmk | |
329 | TOOL_QT5_MOCFLAGS ?= | |
330 | TOOL_QT5_MOCINCS ?= | |
331 | TOOL_QT5_MOCDEFS ?= | |
332 | TOOL_QT5_MOCDEFS.darwin ?= __APPLE__ __GNUC__ | |
333 | TOOL_QT5_MOCDEFS.solaris ?= __sun | |
334 | TOOL_QT5_MOCDEFS.win.amd64 ?= WIN64 | |
335 | TOOL_QT5_MOCDEFS.win.x86 ?= WIN32 | |
336 | ||
337 | ||
338 | ## MOC a C++ source file. | |
339 | # @param $(target) Normalized main target name. | |
340 | # @param $(source) Source filename (relative). | |
341 | # @param $(out) Object file name. This shall be (re)created by the compilation. | |
342 | # @param $(dep) Dependcy file. This may be (re)created by the compilation. | |
343 | # @param $(flags) Flags. | |
344 | # @param $(defs) Definitions. | |
345 | # @param $(incs) Includes. | |
346 | # @param $(outbase) Output basename (full). Use this for list files and such. | |
347 | # | |
348 | TOOL_QT5_MOC_CPP_DEPEND = | |
349 | TOOL_QT5_MOC_CPP_DEPORD = | |
350 | TOOL_QT5_MOC_CPP_OUTPUT = | |
351 | TOOL_QT5_MOC_CPP_OUTPUT_MAYBE = | |
352 | define TOOL_QT5_MOC_CPP_CMDS | |
353 | $(QUIET)$(TOOL_QT5_MOC)\ | |
354 | $(flags)\ | |
355 | $(addprefix -I, $(incs))\ | |
356 | $(addprefix -D, $(defs))\ | |
357 | -o $(out)\ | |
358 | $(source) | |
359 | endef | |
360 | ||
361 | ## MOC a C++ header file. | |
362 | # @param $(target) Normalized main target name. | |
363 | # @param $(source) Source filename (relative). | |
364 | # @param $(out) Object file name. This shall be (re)created by the compilation. | |
365 | # @param $(dep) Dependcy file. This may be (re)created by the compilation. | |
366 | # @param $(flags) Flags. | |
367 | # @param $(defs) Definitions. | |
368 | # @param $(incs) Includes. | |
369 | # @param $(outbase) Output basename (full). Use this for list files and such. | |
370 | # | |
371 | TOOL_QT5_MOC_HPP_DEPEND = | |
372 | TOOL_QT5_MOC_HPP_DEPORD = | |
373 | TOOL_QT5_MOC_HPP_OUTPUT = | |
374 | TOOL_QT5_MOC_HPP_OUTPUT_MAYBE = | |
375 | define TOOL_QT5_MOC_HPP_CMDS | |
376 | $(QUIET)$(TOOL_QT5_MOC)\ | |
377 | $(flags)\ | |
378 | $(addprefix -I, $(incs))\ | |
379 | $(addprefix -D, $(defs))\ | |
380 | -o $(out)\ | |
381 | $(source) | |
382 | endef | |
383 | ||
384 | ## Compile a Qt user interface file (.ui). | |
385 | # @param $(target) Normalized main target name. | |
386 | # @param $(source) Source filename (relative). | |
387 | # @param $(out) Object file name. This shall be (re)created by the compilation. | |
388 | # @param $(dep) Dependcy file. This may be (re)created by the compilation. | |
389 | # @param $(flags) Flags. | |
390 | # @param $(defs) Definitions. | |
391 | # @param $(incs) Includes. | |
392 | # @param $(outbase) Output basename (full). Use this for list files and such. | |
393 | # | |
394 | TOOL_QT5_UIC_UI_DEPEND = | |
395 | TOOL_QT5_UIC_UI_DEPORD = | |
396 | TOOL_QT5_UIC_UI_OUTPUT = | |
397 | TOOL_QT5_UIC_UI_OUTPUT_MAYBE = | |
398 | define TOOL_QT5_UIC_UI_CMDS | |
399 | $(QUIET)$(TOOL_QT5_UIC)\ | |
400 | $(flags)\ | |
401 | -o $(out)\ | |
402 | $(source) | |
403 | endef | |
404 | ||
405 | ## Compile a Qt resource file (.qrc). | |
406 | # @param $(target) Normalized main target name. | |
407 | # @param $(source) Source filename (relative). | |
408 | # @param $(out) Object file name. This shall be (re)created by the compilation. | |
409 | # @param $(dep) Dependcy file. This may be (re)created by the compilation. | |
410 | # @param $(flags) Flags. | |
411 | # @param $(defs) Definitions. | |
412 | # @param $(incs) Includes. | |
413 | # @param $(outbase) Output basename (full). Use this for list files and such. | |
414 | # | |
415 | # @remarks The sed script generating the dependency file is a bit naive. | |
416 | TOOL_QT5_RCC_QRC_DEPEND = | |
417 | TOOL_QT5_RCC_QRC_DEPORD = | |
418 | TOOL_QT5_RCC_QRC_OUTPUT = | |
419 | TOOL_QT5_RCC_QRC_OUTPUT_MAYBE = | |
420 | define TOOL_QT5_RCC_QRC_CMDS | |
421 | $(QUIET)$(TOOL_QT5_RCC)\ | |
422 | $(flags)\ | |
423 | -o $(out)\ | |
424 | $(source) | |
425 | $(QUIET2)$(APPEND) $(dep) '\' | |
426 | $(QUIET2)$(APPEND) $(dep) '$(out): \' | |
427 | $(QUIET2)$(APPEND) $(dep) '$(source) \' | |
428 | $(QUIET2)$(SED) \ | |
429 | -e '/^[[:blank:]]*<file[[:blank:]][^>]*>/!d' \ | |
430 | -e 's/^.*<file[[:blank:]][^>]*>\([^<]*\)<\/file>.*$$$$/\1/' \ | |
431 | -e 's|^[^/][^:]|$(abspathex $(dir $(source)),$(defpath))/&|' \ | |
432 | -e 's|$$$$| \\|' \ | |
433 | --append $(dep) \ | |
434 | $(source) | |
435 | $(QUIET2)$(APPEND) $(dep) | |
436 | $(QUIET2)$(SED) \ | |
437 | -e '/^[[:blank:]]*<file[[:blank:]][^>]*>/!d' \ | |
438 | -e 's/^.*<file[[:blank:]][^>]*>\([^<]*\)<\/file>.*$$$$/\1/' \ | |
439 | -e 's|^[^/][^:]|$(abspathex $(dir $(source)),$(defpath))/&|' \ | |
440 | -e 's|$$$$|:\n|' \ | |
441 | --append $(dep) \ | |
442 | $(source) | |
443 | $(QUIET2)$(APPEND) $(dep) | |
444 | endef | |
445 | ||
446 | ## Compile a Qt translation file (.ts). | |
447 | # @param $(target) Normalized main target name. | |
448 | # @param $(source) Source filename (relative). | |
449 | # @param $(out) Object file name. This shall be (re)created by the compilation. | |
450 | # @param $(dep) Dependcy file. This may be (re)created by the compilation. | |
451 | # @param $(flags) Flags. | |
452 | # @param $(defs) Definitions. | |
453 | # @param $(incs) Includes. | |
454 | # @param $(outbase) Output basename (full). Use this for list files and such. | |
455 | # | |
456 | TOOL_QT5_LRC_TS_DEPEND = | |
457 | TOOL_QT5_LRC_TS_DEPORD = | |
458 | TOOL_QT5_LRC_TS_OUTPUT = | |
459 | TOOL_QT5_LRC_TS_OUTPUT_MAYBE = | |
460 | define TOOL_QT5_LRC_TS_CMDS | |
461 | $(QUIET)$(TOOL_QT5_LRC)\ | |
462 | $(flags)\ | |
463 | $(source)\ | |
464 | -qm $(out) | |
465 | endef | |
466 | ||
467 | ||
468 | ||
469 | # | |
470 | # | |
471 | # Back to the Qt5 unit. | |
472 | # | |
473 | # | |
474 | ||
475 | ||
476 | ## wrapper for the lrelease (LRC) command dependencies. | |
477 | ifndef NO_COMPILE_CMDS_DEPS | |
478 | _UNIT_QT5_LRC_CMDS_DEP = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_QT5_LRC_CMDS_PREV_),$$(commands $(out)),FORCE) | |
479 | else | |
480 | _UNIT_QT5_LRC_CMDS_DEP = | |
481 | endif | |
482 | ||
483 | ## | |
484 | # def_unit_qt5_target_pre_handle_translation helper that is expanded before evaluation. | |
485 | # | |
486 | # This is necessary to resolve reference to local variables before doing | |
487 | # assignments and setting up commands. They would otherwise be resolved | |
488 | # later in a different context and the result would be completely wrong. | |
489 | # | |
490 | define def_unit_qt5_target_pre_handle_translation_dx | |
491 | ||
492 | $(out) + $(more_output) +| $(maybe_output): \ | |
493 | $(deps) \ | |
494 | $(value _UNIT_QT5_LRC_CMDS_DEP) \ | |
495 | | \ | |
496 | $(orderdeps) | |
497 | %$$(call MSG_TOOL,lrelease,$(target),$(source),$$@) | |
498 | $(QUIET2)$(RM) -f $(out) $(more_output) $(maybe_output) $(dep) | |
499 | ||
500 | $(cmds) | |
501 | ||
502 | ifndef NO_COMPILE_CMDS_DEPS | |
503 | %$$(QUIET2)$$(APPEND) '$(dep)' | |
504 | %$$(QUIET2)$$(APPEND) '$(dep)' 'define $(target)_$(subst :,_,$(source))_QT5_LRC_CMDS_PREV_' | |
505 | %$$(QUIET2)$$(APPEND) -c '$(dep)' '$(out)' | |
506 | %$$(QUIET2)$$(APPEND) '$(dep)' 'endef' | |
507 | endif | |
508 | ||
509 | $(target)_CLEAN += $(out) $(more_output) $(maybe_output) $(dep) | |
510 | $(target)-inst-nls_SOURCES += $(out) | |
511 | ||
512 | endef # def_unit_qt5_target_pre_handle_translation_dx | |
513 | ||
514 | ## | |
515 | # Handle a source file listed in QT_TRANSLATIONS. | |
516 | # | |
517 | # The files listed in QT_TRANSLATIONS are translation files (.ts) which needs | |
518 | # to be translated into .qm files that are loadble by Qt. | |
519 | # | |
520 | # @remarks Invoked via $(evalvalctx ). | |
521 | define def_unit_qt5_target_pre_handle_translation | |
522 | local type := LRC | |
523 | ||
524 | # fetch the properties. | |
525 | local tool := $(kb-src-tool dummy_var) | |
526 | local qtnlsdir := $($(target)_0_OUTDIR)/qtnls | |
527 | local outbase := $(qtnlsdir)/$(notdir $(basename $(source))) | |
528 | local out := $(outbase).qm | |
529 | local dep := $(out).dep | |
530 | local flags := $(kb-src-prop FLAGS,dummy_var,right-to-left) | |
531 | local deps := $(kb-src-prop DEPS,dummy_var,left-to-right) | |
532 | local orderdeps := $(call DIRDEP,$(dir $(outbase))) $(kb-src-prop ORDERDEPS,dummy_var,left-to-right) | |
533 | ||
534 | # default path + source dep. | |
535 | ifneq ($(defpath),) | |
536 | local source := $(abspathex $(source),$(defpath)) | |
537 | local deps := $(abspathex $(deps),$(defpath)) $(source) | |
538 | local incs := $(abspathex $(incs),$(defpath)) | |
539 | else | |
540 | local deps += $(source) | |
541 | endif | |
542 | ||
543 | # call the tool | |
544 | ifndef TOOL_$(tool)_LRC_TS_CMDS | |
545 | $(error kBuild: qt lrelease tool not found: TOOL_$(tool)_LRC_TS_CMDS) | |
546 | endif | |
547 | local cmds := $(TOOL_$(tool)_LRC_TS_CMDS) | |
548 | local more_output := $(TOOL_$(tool)_LRC_TS_OUTPUT) | |
549 | local maybe_output := $(TOOL_$(tool)_LRC_TS_OUTPUT_MAYBE) | |
550 | local deps += $(TOOL_$(tool)_LRC_TS_DEPEND) | |
551 | local orderdeps += $(TOOL_$(tool)_LRC_TS_DEPORD) | |
552 | ||
553 | # generate the link rule and update some source and target variables. | |
554 | ifndef NO_COMPILE_CMDS_DEPS | |
555 | $(eval includedep $(dep)) | |
556 | endif | |
557 | $(eval $(def_unit_qt5_target_pre_handle_translation_dx)) | |
558 | ||
559 | endef # def_unit_qt5_target_pre_handle_translation | |
560 | ||
561 | ||
562 | ||
563 | ## wrapper for the UIC command dependencies. | |
564 | ifndef NO_COMPILE_CMDS_DEPS | |
565 | _UNIT_QT5_RCC_CMDS_DEP = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_QT5_RCC_CMDS_PREV_),$$(commands $(out)),FORCE) | |
566 | else | |
567 | _UNIT_QT5_RCC_CMDS_DEP = | |
568 | endif | |
569 | ||
570 | ## | |
571 | # def_unit_qt5_target_pre_handle_qrc helper that is expanded before evaluation. | |
572 | # | |
573 | # This is necessary to resolve reference to local variables before doing | |
574 | # assignments and setting up commands. They would otherwise be resolved | |
575 | # later in a different context and the result would be completely wrong. | |
576 | # | |
577 | define def_unit_qt5_target_pre_handle_rcc_dx | |
578 | ||
579 | $(out) +| $(realout) $(more_output) $(maybe_output): \ | |
580 | $(deps) \ | |
581 | $(value _UNIT_QT5_RCC_CMDS_DEP) \ | |
582 | | \ | |
583 | $(orderdeps) | |
584 | %$$(call MSG_TOOL,rcc,$(target),$(source),$$@) | |
585 | $(QUIET2)$(RM) -f $(out) $(more_output) $(maybe_output) $(dep) | |
586 | ||
587 | $(cmds) | |
588 | ||
589 | $(QUIET)$(CP) --changed -f $(out) $(realout) | |
590 | ifndef NO_COMPILE_CMDS_DEPS | |
591 | %$$(QUIET2)$$(APPEND) '$(dep)' | |
592 | %$$(QUIET2)$$(APPEND) '$(dep)' 'define $(target)_$(subst :,_,$(source))_QT5_RCC_CMDS_PREV_' | |
593 | %$$(QUIET2)$$(APPEND) -c '$(dep)' '$(out)' | |
594 | %$$(QUIET2)$$(APPEND) '$(dep)' 'endef' | |
595 | endif | |
596 | ||
597 | $(target)_INTERMEDIATES += $(realout) | |
598 | $(target)_GEN_SOURCES_ += $(realout) | |
599 | $(target)_CLEAN += $(out) $(realout) $(more_output) $(maybe_output) $(dep) | |
600 | ||
601 | endef # def_unit_qt5_target_pre_handle_rcc_dx | |
602 | ||
603 | ## | |
604 | # Source handler for .qrc sources (Qt resource files). | |
605 | # | |
606 | # @remarks $(evalvalctx me). | |
607 | define def_unit_qt5_src_handler_qrc | |
608 | local type := RCC | |
609 | ||
610 | # fetch the properties. | |
611 | local tool := $(kb-src-tool dummy_var) | |
612 | local qtrccdir := $($(target)_0_OUTDIR)/qtrcc | |
613 | local outbase := $(qtrccdir)/$(notdir $(basename $(source))) | |
614 | local out := $(outbase).tmp.gen.cpp | |
615 | local realout := $(outbase).gen.cpp | |
616 | local dep := $(realout).dep | |
617 | local flags := $(kb-src-prop FLAGS,dummy_var,right-to-left) | |
618 | local deps := $(kb-src-prop DEPS,dummy_var,left-to-right) | |
619 | local orderdeps := $(call DIRDEP,$(dir $(outbase))) $(kb-src-prop ORDERDEPS,dummy_var,left-to-right) | |
620 | ||
621 | # default path + source dep. | |
622 | ifneq ($(defpath),) | |
623 | local source := $(abspathex $(source),$(defpath)) | |
624 | local deps := $(abspathex $(deps),$(defpath)) $(source) | |
625 | local incs := $(abspathex $(incs),$(defpath)) | |
626 | else | |
627 | local deps += $(source) | |
628 | endif | |
629 | ||
630 | # call the tool | |
631 | ifndef TOOL_$(tool)_RCC_QRC_CMDS | |
632 | $(error kBuild: qt rcc tool not found: TOOL_$(tool)_RCC_QRC_CMDS) | |
633 | endif | |
634 | local cmds := $(TOOL_$(tool)_RCC_QRC_CMDS) | |
635 | local more_output := $(TOOL_$(tool)_RCC_QRC_OUTPUT) | |
636 | local maybe_output := $(TOOL_$(tool)_RCC_QRC_OUTPUT_MAYBE) | |
637 | local deps += $(TOOL_$(tool)_RCC_QRC_DEPEND) | |
638 | local orderdeps += $(TOOL_$(tool)_RCC_QRC_DEPORD) | |
639 | ||
640 | # generate the link rule and update some source and target variables. | |
641 | ifndef NO_COMPILE_CMDS_DEPS | |
642 | $(eval includedep $(dep)) | |
643 | endif | |
644 | $(eval $(def_unit_qt5_target_pre_handle_rcc_dx)) | |
645 | ||
646 | endef # def_unit_qt5_src_handler_qrc | |
647 | ||
648 | ||
649 | ||
650 | ## wrapper for the UIC command dependencies. | |
651 | ifndef NO_COMPILE_CMDS_DEPS | |
652 | _UNIT_QT5_UIC_CMDS_DEP = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_QT5_UIC_CMDS_PREV_),$$(commands $(out)),FORCE) | |
653 | else | |
654 | _UNIT_QT5_UIC_CMDS_DEP = | |
655 | endif | |
656 | ||
657 | ## | |
658 | # def_unit_qt5_src_handler_ui helper that is expanded before evaluation. | |
659 | # | |
660 | # This is necessary to resolve reference to local variables before doing | |
661 | # assignments and setting up commands. They would otherwise be resolved | |
662 | # later in a different context and the result would be completely wrong. | |
663 | # | |
664 | define def_unit_qt5_target_pre_handle_ui_dx | |
665 | ||
666 | $(out) +| $(realout) $(more_output) $(maybe_output): \ | |
667 | $(deps) \ | |
668 | $(value _UNIT_QT5_UIC_CMDS_DEP) \ | |
669 | | \ | |
670 | $(orderdeps) | |
671 | %$$(call MSG_TOOL,uic,$(target),$(source),$$@) | |
672 | $(QUIET2)$(RM) -f $(out) $(more_output) $(maybe_output) $(dep) | |
673 | ||
674 | $(cmds) | |
675 | ||
676 | $(QUIET)$(CP) --changed -f $(out) $(realout) | |
677 | ifndef NO_COMPILE_CMDS_DEPS | |
678 | %$$(QUIET2)$$(APPEND) '$(dep)' | |
679 | %$$(QUIET2)$$(APPEND) '$(dep)' 'define $(target)_$(subst :,_,$(source))_QT5_UIC_CMDS_PREV_' | |
680 | %$$(QUIET2)$$(APPEND) -c '$(dep)' '$(out)' | |
681 | %$$(QUIET2)$$(APPEND) '$(dep)' 'endef' | |
682 | endif | |
683 | ||
684 | $(target)_INTERMEDIATES += $(realout) | |
685 | $(target)_CLEAN += $(out) $(realout) $(more_output) $(maybe_output) $(dep) | |
686 | ||
687 | endef # def_unit_qt5_target_pre_handle_ui_dx | |
688 | ||
689 | ## | |
690 | # Source handler for .ui sources. | |
691 | # | |
692 | # @remarks $(evalvalctx me). | |
693 | define def_unit_qt5_src_handler_ui | |
694 | local type := UIC | |
695 | ||
696 | # fetch the properties. | |
697 | local tool := $(kb-src-tool dummy_var) | |
698 | local qtuicdir := $($(target)_0_OUTDIR)/qtuic | |
699 | local outbase := $(qtuicdir)/$(notdir $(basename $(source))) | |
700 | local out := $(outbase).tmp.gen.h | |
701 | local realout := $(outbase).gen.h | |
702 | local dep := $(realout).dep | |
703 | local flags := $(kb-src-prop FLAGS,dummy_var,right-to-left) | |
704 | local deps := $(kb-src-prop DEPS,dummy_var,left-to-right) | |
705 | local orderdeps := $(call DIRDEP,$(dir $(outbase))) $(kb-src-prop ORDERDEPS,dummy_var,left-to-right) | |
706 | ||
707 | # default path + source dep. | |
708 | ifneq ($(defpath),) | |
709 | local source := $(abspathex $(source),$(defpath)) | |
710 | local deps := $(abspathex $(deps),$(defpath)) $(source) | |
711 | local incs := $(abspathex $(incs),$(defpath)) | |
712 | else | |
713 | local deps += $(source) | |
714 | endif | |
715 | ||
716 | # call the tool | |
717 | ifndef TOOL_$(tool)_UIC_UI_CMDS | |
718 | $(error kBuild: qt uic tool not found: TOOL_$(tool)_UIC_UI_CMDS) | |
719 | endif | |
720 | local cmds := $(TOOL_$(tool)_UIC_UI_CMDS) | |
721 | local more_output := $(TOOL_$(tool)_UIC_UI_OUTPUT) | |
722 | local maybe_output := $(TOOL_$(tool)_UIC_UI_OUTPUT_MAYBE) | |
723 | local deps += $(TOOL_$(tool)_UIC_UI_DEPEND) | |
724 | local orderdeps += $(TOOL_$(tool)_UIC_UI_DEPORD) | |
725 | ||
726 | # generate the link rule and update some source and target variables. | |
727 | ifndef NO_COMPILE_CMDS_DEPS | |
728 | $(eval includedep $(dep)) | |
729 | endif | |
730 | $(eval $(def_unit_qt5_target_pre_handle_ui_dx)) | |
731 | ||
732 | endef # def_unit_qt5_src_handler_ui | |
733 | ||
734 | ||
735 | ||
736 | ## wrapper for the MOC command dependencies. | |
737 | ifndef NO_COMPILE_CMDS_DEPS | |
738 | _UNIT_QT5_MOC_HPP_CMDS_DEP = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_QT5_MOC_HPP_CMDS_PREV_),$$(commands $(out)),FORCE) | |
739 | else | |
740 | _UNIT_QT5_MOC_HPP_CMDS_DEP = | |
741 | endif | |
742 | ||
743 | ## | |
744 | # def_unit_qt5_target_pre_handle_moc_hdr helper that is expanded before evaluation. | |
745 | # | |
746 | # This is necessary to resolve reference to local variables before doing | |
747 | # assignments and setting up commands. They would otherwise be resolved | |
748 | # later in a different context and the result would be completely wrong. | |
749 | # | |
750 | define def_unit_qt5_target_pre_handle_moc_hdr_dx | |
751 | ||
752 | $(out) +| $(realout) $(more_output) $(maybe_output): \ | |
753 | $(deps) \ | |
754 | $(value _UNIT_QT5_MOC_HPP_CMDS_DEP) \ | |
755 | | \ | |
756 | $(orderdeps) | |
757 | %$$(call MSG_TOOL,moc,$(target),$(source),$$@) | |
758 | $(QUIET2)$(RM) -f $(out) $(more_output) $(maybe_output) $(dep) | |
759 | ||
760 | $(cmds) | |
761 | ||
762 | $(QUIET)$(CP) --changed -f $(out) $(realout) | |
763 | ifndef NO_COMPILE_CMDS_DEPS | |
764 | %$$(QUIET2)$$(APPEND) '$(dep)' | |
765 | %$$(QUIET2)$$(APPEND) '$(dep)' 'define $(target)_$(subst :,_,$(source))_QT5_MOC_HPP_CMDS_PREV_' | |
766 | %$$(QUIET2)$$(APPEND) -c '$(dep)' '$(out)' | |
767 | %$$(QUIET2)$$(APPEND) '$(dep)' 'endef' | |
768 | endif | |
769 | ||
770 | $(target)_INTERMEDIATES += $(realout) | |
771 | $(target)_GEN_SOURCES_ += $(realout) | |
772 | $(target)_CLEAN += $(out) $(realout) $(more_output) $(maybe_output) $(dep) | |
773 | ||
774 | endef | |
775 | ||
776 | ## | |
777 | # Handle a source file listed in QT_MOCHDRS. | |
778 | # | |
779 | # The files listed in QT_MOCHDRS uses the Q_OBJECT macro and we will | |
780 | # generate a .cpp file for each of them and add it to the generated | |
781 | # sources so that it's compiled and linked. (There is an alternative | |
782 | # way to do this where the .cpp file is included, this isn't currently | |
783 | # supported by this unit.) | |
784 | # | |
785 | # @remarks Invoked via $(evalvalctx ). | |
786 | define def_unit_qt5_target_pre_handle_moc_hdr | |
787 | local type := MOC | |
788 | ||
789 | # fetch the properties. | |
790 | local tool := $(kb-src-tool dummy_var) | |
791 | local outbase := $(qtmocdir)/$(notdir $(basename $(source))) | |
792 | local out := $(outbase).tmp.cpp | |
793 | local realout := $(outbase).cpp | |
794 | local dep := $(realout).dep | |
795 | local defs := $(kb-src-prop DEFS,dummy_var,left-to-right) | |
796 | local incs := $(kb-src-prop INCS,dummy_var,right-to-left) | |
797 | local flags := $(kb-src-prop FLAGS,dummy_var,right-to-left) | |
798 | local deps := $(kb-src-prop DEPS,dummy_var,left-to-right) | |
799 | local orderdeps := $(call DIRDEP,$(dir $(outbase))) $(kb-src-prop ORDERDEPS,dummy_var,left-to-right) | |
800 | ||
801 | # default path + source dep. | |
802 | ifneq ($(defpath),) | |
803 | local source := $(abspathex $(source),$(defpath)) | |
804 | local deps := $(abspathex $(deps),$(defpath)) $(source) | |
805 | local incs := $(abspathex $(incs),$(defpath)) | |
806 | else | |
807 | local deps += $(source) | |
808 | endif | |
809 | ||
810 | # call the tool | |
811 | ifndef TOOL_$(tool)_MOC_HPP_CMDS | |
812 | $(error kBuild: qt moc tool not found: TOOL_$(tool)_MOC_HPP_CMDS) | |
813 | endif | |
814 | local cmds := $(TOOL_$(tool)_MOC_HPP_CMDS) | |
815 | local more_output := $(TOOL_$(tool)_MOC_HPP_OUTPUT) | |
816 | local maybe_output := $(TOOL_$(tool)_MOC_HPP_OUTPUT_MAYBE) | |
817 | local deps += $(TOOL_$(tool)_MOC_HPP_DEPEND) | |
818 | local orderdeps += $(TOOL_$(tool)_MOC_HPP_DEPORD) | |
819 | ||
820 | # generate the link rule and update some source and target variables. | |
821 | ifndef NO_COMPILE_CMDS_DEPS | |
822 | $(eval includedep $(dep)) | |
823 | endif | |
824 | $(eval $(def_unit_qt5_target_pre_handle_moc_hdr_dx)) | |
825 | ||
826 | endef # def_unit_qt5_target_pre_handle_moc_hdr | |
827 | ||
828 | ||
829 | ## wrapper for the MOC command dependencies. | |
830 | ifndef NO_COMPILE_CMDS_DEPS | |
831 | _UNIT_QT5_MOC_CPP_CMDS_DEP = $$(comp-cmds-ex $$($(target)_$(subst :,_,$(source))_QT5_MOC_CPP_CMDS_PREV_),$$(commands $(out)),FORCE) | |
832 | else | |
833 | _UNIT_QT5_MOC_CPP_CMDS_DEP = | |
834 | endif | |
835 | ||
836 | ## | |
837 | # def_unit_qt5_target_pre_handle_moc_src helper that is expanded before evaluation. | |
838 | # | |
839 | # This is necessary to resolve reference to local variables before doing | |
840 | # assignments and setting up commands. They would otherwise be resolved | |
841 | # later in a different context and the result would be completely wrong. | |
842 | # | |
843 | define def_unit_qt5_target_pre_handle_moc_src_dx | |
844 | ||
845 | $(out) +| $(realout) $(more_output) $(maybe_output): \ | |
846 | $(deps) \ | |
847 | $(value _UNIT_QT5_MOC_CPP_CMDS_DEP) \ | |
848 | | \ | |
849 | $(orderdeps) | |
850 | %$$(call MSG_TOOL,moc,$(target),$(source),$$@) | |
851 | $(QUIET2)$(RM) -f $(out) $(more_output) $(maybe_output) $(dep) | |
852 | ||
853 | $(cmds) | |
854 | ||
855 | $(QUIET)$(CP) --changed -f $(out) $(realout) | |
856 | ifndef NO_COMPILE_CMDS_DEPS | |
857 | %$$(QUIET2)$$(APPEND) '$(dep)' | |
858 | %$$(QUIET2)$$(APPEND) '$(dep)' 'define $(target)_$(subst :,_,$(source))_QT5_MOC_CPP_CMDS_PREV_' | |
859 | %$$(QUIET2)$$(APPEND) -c '$(dep)' '$(out)' | |
860 | %$$(QUIET2)$$(APPEND) '$(dep)' 'endef' | |
861 | endif | |
862 | ||
863 | $(target)_INTERMEDIATES += $(realout) | |
864 | $(target)_CLEAN += $(out) $(realout) $(more_output) $(maybe_output) $(dep) | |
865 | ||
866 | endef | |
867 | ||
868 | ## | |
869 | # Handle a source file listed in QT_MOCSRCS. | |
870 | # | |
871 | # The files listed in QT_MOCSRCS uses the Q_OBJECT macro and will include | |
872 | # a .moc file that we're expected to generate here. | |
873 | # | |
874 | # @remarks Invoked via $(evalvalctx ). | |
875 | define def_unit_qt5_target_pre_handle_moc_src | |
876 | local type := MOC | |
877 | ||
878 | # fetch the properties. | |
879 | local tool := $(kb-src-tool dummy_var) | |
880 | local outbase := $(qtmocdir)/$(notdir $(basename $(source))) | |
881 | local out := $(outbase).tmp.moc | |
882 | local realout := $(outbase).moc | |
883 | local dep := $(realout).dep | |
884 | local defs := $(kb-src-prop DEFS,dummy_var,left-to-right) | |
885 | local incs := $(kb-src-prop INCS,dummy_var,right-to-left) | |
886 | local flags := $(kb-src-prop FLAGS,dummy_var,right-to-left) | |
887 | local deps := $(kb-src-prop DEPS,dummy_var,left-to-right) | |
888 | local orderdeps := $(call DIRDEP,$(dir $(outbase))) $(kb-src-prop ORDERDEPS,dummy_var,left-to-right) | |
889 | ||
890 | # default path + source dep. | |
891 | ifneq ($(defpath),) | |
892 | local source := $(abspathex $(source),$(defpath)) | |
893 | local deps := $(abspathex $(deps),$(defpath)) $(source) | |
894 | local incs := $(abspathex $(incs),$(defpath)) | |
895 | else | |
896 | local deps += $(source) | |
897 | endif | |
898 | ||
899 | # call the tool | |
900 | ifndef TOOL_$(tool)_MOC_CPP_CMDS | |
901 | $(error kBuild: qt moc tool not found: TOOL_$(tool)_MOC_CPP_CMDS) | |
902 | endif | |
903 | local cmds := $(TOOL_$(tool)_MOC_CPP_CMDS) | |
904 | local more_output := $(TOOL_$(tool)_MOC_CPP_OUTPUT) | |
905 | local maybe_output := $(TOOL_$(tool)_MOC_CPP_OUTPUT_MAYBE) | |
906 | local deps += $(TOOL_$(tool)_MOC_CPP_DEPEND) | |
907 | local orderdeps += $(TOOL_$(tool)_MOC_CPP_DEPORD) | |
908 | ||
909 | # generate the link rule and update some source and target variables. | |
910 | ifndef NO_COMPILE_CMDS_DEPS | |
911 | $(eval includedep $(dep)) | |
912 | endif | |
913 | $(eval $(def_unit_qt5_target_pre_handle_moc_src_dx)) | |
914 | ||
915 | endef # def_unit_qt5_target_pre_handle_moc_src | |
916 | ||
917 | ||
918 | ## | |
919 | # Adds sources containing Q_OBJECT to QT_MOCSRCS. | |
920 | define def_unit_qt5_target_pre_cpp_source | |
921 | ifneq ($(file-size $(source)),-1) | |
922 | ifneq ($(strip $(shell $(SED) -f $(KBUILD_PATH)/units/qt-Q_OBJECT.sed $(source))),) | |
923 | $(eval $(target)_QT_MOCSRCS += $(source)) | |
924 | endif | |
925 | endif | |
926 | endef # def_unit_qt5_target_pre_cpp_source | |
927 | ||
928 | ## | |
929 | # Invoked early in the processing of a target that uses the Qt unit. | |
930 | # | |
931 | # It will append the qt source handlers to the target (.h, .ui, .ts, | |
932 | # .png, .bmp, .gif). | |
933 | # | |
934 | # It will then check all the C++ sources and check which needs | |
935 | # a .moc files and generate rules and dependencies fofor these | |
936 | # | |
937 | define def_unit_qt5_target_pre | |
938 | ||
939 | # Make QTTOOL the default for the specific Qt tools instead of TOOL. | |
940 | ifneq ($($(target)_QTTOOL),) | |
941 | ifeq ($($(target)_MOCTOOL),) | |
942 | $(target)_MOCTOOL := $($(target)_QTTOOL) | |
943 | endif | |
944 | ifeq ($($(target)_UICTOOL),) | |
945 | $(target)_UICTOOL := $($(target)_QTTOOL) | |
946 | endif | |
947 | ifeq ($($(target)_RCCTOOL),) | |
948 | $(target)_RCCTOOL := $($(target)_QTTOOL) | |
949 | endif | |
950 | ifeq ($($(target)_LRCTOOL),) | |
951 | $(target)_LRCTOOL := $($(target)_QTTOOL) | |
952 | endif | |
953 | endif | |
954 | ||
955 | # Deal with QT_MODULES, QT_PREFIX and QT_INFIX. | |
956 | local qt_modules := \ | |
957 | $($(target)_QT_MODULES.$(bld_trg)) \ | |
958 | $($(target)_QT_MODULES.$(bld_trg_arch)) \ | |
959 | $($(target)_QT_MODULES.$(bld_trg).$(bld_trg_arch)) \ | |
960 | $($(target)_QT_MODULES.$(bld_trg_cpu)) \ | |
961 | $($(target)_QT_MODULES.$(bld_type)) \ | |
962 | $($(target)_QT_MODULES) | |
963 | local qt_prefix := $(firstword \ | |
964 | $($(target)_QT_PREFIX.$(bld_trg)) \ | |
965 | $($(target)_QT_PREFIX.$(bld_trg_arch)) \ | |
966 | $($(target)_QT_PREFIX.$(bld_trg).$(bld_trg_arch)) \ | |
967 | $($(target)_QT_PREFIX.$(bld_trg_cpu)) \ | |
968 | $($(target)_QT_PREFIX.$(bld_type)) \ | |
969 | $($(target)_QT_PREFIX)) | |
970 | local qt_infix := $(firstword \ | |
971 | $($(target)_QT_INFIX.$(bld_trg)) \ | |
972 | $($(target)_QT_INFIX.$(bld_trg_arch)) \ | |
973 | $($(target)_QT_INFIX.$(bld_trg).$(bld_trg_arch)) \ | |
974 | $($(target)_QT_INFIX.$(bld_trg_cpu)) \ | |
975 | $($(target)_QT_INFIX.$(bld_type)) \ | |
976 | $($(target)_QT_INFIX)) | |
977 | ifeq ($(bld_trg),darwin) | |
978 | # Adding -F to CXXFLAGS is necessary to make #include <QtCore/qstring.h> stuff work... | |
979 | $(eval $(target)_CXXFLAGS += -F$(PATH_SDK_QT5_LIB) ) | |
980 | $(eval $(target)_OBJCXXFLAGS += -F$(PATH_SDK_QT5_LIB) ) | |
981 | $(eval $(target)_LDFLAGS += -F$(PATH_SDK_QT5_LIB) $(foreach module,$(qt_modules), -framework $(qt_prefix)Qt$(module)$(qt_infix)) ) | |
982 | $(eval $(target)_INCS += $(foreach module,$(qt_modules), $(PATH_SDK_QT5_LIB)/$(qt_prefix)Qt$(module)$(qt_infix).framework/Versions/5/Headers) ) | |
983 | else | |
984 | ifeq ($(bld_trg),win) | |
985 | $(eval $(target)_LIBS += $(foreach module,$(qt_modules), $(PATH_SDK_QT5_LIB)/$(qt_prefix)Qt5$(module)$(qt_infix)$(SUFF_LIB)) ) | |
986 | ifeq ($(tool_do),LINK_PROGRAM) | |
987 | $(eval $(target)_LIBS += $(PATH_SDK_QT5_LIB)/$(qt_prefix)qtmain$(qt_infix)$(SUFF_LIB) ) | |
988 | endif | |
989 | else | |
990 | $(eval $(target)_LIBS += $(foreach module,$(qt_modules), $(PATH_SDK_QT5_LIB)/lib$(qt_prefix)Qt5$(module)$(qt_infix)$(SUFF_DLL)) ) | |
991 | endif | |
992 | $(eval $(target)_INCS += $(addprefix $(PATH_SDK_QT5_INC)/Qt,$(qt_modules)) $(PATH_SDK_QT5_INC) ) | |
993 | endif | |
994 | $(eval $(target)_DEFS += $(foreach module,$(toupper $(qt_modules)), QT_$(module)_LIB) ) | |
995 | ||
996 | ||
997 | # Autodetect source files with Q_OBJECT references if QT_MOCSRCS is undefined. (slow) | |
998 | # Tip: Use target_QT_MOCSRCS = $(NO_SUCH_VARIABLE) to avoid this. | |
999 | ifndef $(target)_QT_MOCSRCS | |
1000 | $(foreach source, $(filter %.cxx %.CXX %.cpp %.CPP %.cc %.CC,\ | |
1001 | $($(target)_SOURCES.$(bld_trg)) \ | |
1002 | $($(target)_SOURCES.$(bld_trg_arch)) \ | |
1003 | $($(target)_SOURCES.$(bld_trg).$(bld_trg_arch)) \ | |
1004 | $($(target)_SOURCES.$(bld_trg_cpu)) \ | |
1005 | $($(target)_SOURCES.$(bld_type)) \ | |
1006 | $($(target)_SOURCES) \ | |
1007 | ), $(evalval def_unit_qt5_target_pre_cpp_source)) | |
1008 | endif | |
1009 | ||
1010 | # Install source handlers for .ui files. | |
1011 | $(target)_SRC_HANDLERS += \ | |
1012 | .ui:def_unit_qt5_src_handler_ui \ | |
1013 | .UI:def_unit_qt5_src_handler_ui \ | |
1014 | .qrc:def_unit_qt5_src_handler_qrc \ | |
1015 | .qrc:def_unit_qt5_src_handler_qrc | |
1016 | ||
1017 | # Calc the MOC and UI output directories and add them to BLDDIRS and INCS. | |
1018 | local qtmocdir := $($(target)_0_OUTDIR)/qtmoc | |
1019 | local qtuicdir := $($(target)_0_OUTDIR)/qtuic | |
1020 | local qtrccdir := $($(target)_0_OUTDIR)/qtrcc | |
1021 | local qtnlsdir := $($(target)_0_OUTDIR)/qtnls | |
1022 | $(eval $(target)_BLDDIRS += $(qtmocdir) $(qtuicdir) $(qtrccdir) $(qtnlsdir)) | |
1023 | $(eval $(target)_INCS += $(qtmocdir) $(qtuicdir)) | |
1024 | ||
1025 | # Deal with QT_MOCSRCS. | |
1026 | $(foreach source, \ | |
1027 | $($(target)_QT_MOCSRCS.$(bld_trg)) \ | |
1028 | $($(target)_QT_MOCSRCS.$(bld_trg_arch)) \ | |
1029 | $($(target)_QT_MOCSRCS.$(bld_trg).$(bld_trg_arch)) \ | |
1030 | $($(target)_QT_MOCSRCS.$(bld_trg_cpu)) \ | |
1031 | $($(target)_QT_MOCSRCS.$(bld_type)) \ | |
1032 | $($(target)_QT_MOCSRCS) \ | |
1033 | , $(evalvalctx def_unit_qt5_target_pre_handle_moc_src)) | |
1034 | ||
1035 | # Deal with QT_MOCHDRS. | |
1036 | $(foreach source, \ | |
1037 | $($(target)_QT_MOCHDRS.$(bld_trg)) \ | |
1038 | $($(target)_QT_MOCHDRS.$(bld_trg_arch)) \ | |
1039 | $($(target)_QT_MOCHDRS.$(bld_trg).$(bld_trg_arch)) \ | |
1040 | $($(target)_QT_MOCHDRS.$(bld_trg_cpu)) \ | |
1041 | $($(target)_QT_MOCHDRS.$(bld_type)) \ | |
1042 | $($(target)_QT_MOCHDRS) \ | |
1043 | , $(evalvalctx def_unit_qt5_target_pre_handle_moc_hdr)) | |
1044 | ||
1045 | # Deal with QT_TRANSLATIONS. | |
1046 | # ASSUMES (_ALL_)INSTALLS is processed after the targets using this unit. | |
1047 | local translations := \ | |
1048 | $($(target)_QT_TRANSLATIONS.$(bld_trg)) \ | |
1049 | $($(target)_QT_TRANSLATIONS.$(bld_trg_arch)) \ | |
1050 | $($(target)_QT_TRANSLATIONS.$(bld_trg).$(bld_trg_arch)) \ | |
1051 | $($(target)_QT_TRANSLATIONS.$(bld_trg_cpu)) \ | |
1052 | $($(target)_QT_TRANSLATIONS.$(bld_type)) \ | |
1053 | $($(target)_QT_TRANSLATIONS) | |
1054 | ifneq ($(strip $(translations)),) | |
1055 | local expr := _ALL_INSTALLS_IMPLICIT += $(target)-inst-nls | |
1056 | $(eval $(expr)) | |
1057 | ifdef $(target)_QT_TRANSLATIONS_TEMPLATE | |
1058 | $(target)-inst-nls_TEMPLATE := $($(target)_QT_TRANSLATIONS_TEMPLATE) | |
1059 | else | |
1060 | $(target)-inst-nls_MODE := 0644 | |
1061 | endif | |
1062 | ifdef $(target)_QT_TRANSLATIONS_INST | |
1063 | $(target)-inst-nls_INST := $($(target)_QT_TRANSLATIONS_INST) | |
1064 | endif | |
1065 | $(target)-inst-nls_SOURCES := | |
1066 | $(foreach source, $(translations)\ | |
1067 | , $(evalvalctx def_unit_qt5_target_pre_handle_translation)) | |
1068 | endif | |
1069 | ||
1070 | endef # def_unit_qt5_target_pre | |
1071 | ||
1072 | ||
1073 | # | |
1074 | # Rule for debugging. | |
1075 | # | |
1076 | unit-qt5-show-vars: | |
1077 | @$(ECHO) 'The Qt5 SDK variables:' | |
1078 | @$(ECHO) ' PATH_SDK_QT5 = "$(PATH_SDK_QT5)"' | |
1079 | @$(ECHO) ' PATH_SDK_QT5_INC = "$(PATH_SDK_QT5_INC)"' | |
1080 | @$(ECHO) ' PATH_SDK_QT5_LIB = "$(PATH_SDK_QT5_LIB)"' | |
1081 | @$(ECHO) ' PATH_SDK_QT5_LIB.amd64 = "$(PATH_SDK_QT5_LIB.amd64)"' | |
1082 | @$(ECHO) ' PATH_SDK_QT5_LIB.x86 = "$(PATH_SDK_QT5_LIB.x86)"' | |
1083 | @$(ECHO) 'The Qt5 TOOL variables:' | |
1084 | @$(ECHO) ' PATH_TOOL_QT5_BIN = "$(PATH_TOOL_QT5_BIN)"' | |
1085 | @$(ECHO) ' TOOL_QT5_BIN_SUFF = "$(TOOL_QT5_BIN_SUFF)"' | |
1086 | @$(ECHO) ' TOOL_QT5_MOC = "$(TOOL_QT5_MOC)"' | |
1087 | @$(ECHO) ' TOOL_QT5_UIC = "$(TOOL_QT5_UIC)"' | |
1088 | @$(ECHO) ' TOOL_QT5_RCC = "$(TOOL_QT5_RCC)"' | |
1089 | @$(ECHO) ' TOOL_QT5_LRC = "$(TOOL_QT5_LRC)"' | |
1090 | @$(ECHO) ' TOOL_QT5_LUPDATE = "$(TOOL_QT5_LUPDATE)"' | |
1091 |
0 | /* $Id: shinstance.c 2784 2015-05-24 17:29:04Z bird $ */ | |
0 | /* $Id: shinstance.c 2809 2016-02-05 09:13:42Z bird $ */ | |
1 | 1 | /** @file |
2 | 2 | * The shell instance methods. |
3 | 3 | */ |
180 | 180 | } |
181 | 181 | |
182 | 182 | /** |
183 | * Clones a string vector like enviorn or argv. | |
183 | * Clones a string vector like environ or argv. | |
184 | 184 | * |
185 | 185 | * @returns 0 on success, -1 and errno on failure. |
186 | 186 | * @param psh The shell to associate the allocations with. |
198 | 198 | items++; |
199 | 199 | |
200 | 200 | /* alloc clone array. */ |
201 | *dstp = dst = sh_malloc(psh, sizeof(*dst) * items + 1); | |
201 | *dstp = dst = sh_malloc(psh, sizeof(*dst) * (items + 1)); | |
202 | 202 | if (!dst) |
203 | 203 | return -1; |
204 | 204 |
0 | 0 | #ifdef CONFIG_WITH_COMPILER |
1 | /* $Id: kmk_cc_exec.c 2801 2015-09-20 19:13:24Z bird $ */ | |
1 | /* $Id: kmk_cc_exec.c 2811 2016-03-12 13:26:33Z bird $ */ | |
2 | 2 | /** @file |
3 | 3 | * kmk_cc - Make "Compiler". |
4 | 4 | */ |
125 | 125 | /** How to declare a no-return function. |
126 | 126 | * Place between scope (if any) and return type. */ |
127 | 127 | #ifdef _MSC_VER |
128 | # define KMK_CC_FN_NO_RETURN declspec(noreturn) | |
128 | # define KMK_CC_FN_NO_RETURN __declspec(noreturn) | |
129 | 129 | #elif defined(__GNUC__) |
130 | 130 | # define KMK_CC_FN_NO_RETURN __attribute__((__noreturn__)) |
131 | 131 | #endif |
554 | 554 | /** [local|override|export] define variable ... endef - KMKCCEVALASSIGNDEF. */ |
555 | 555 | kKmkCcEvalInstr_assign_define, |
556 | 556 | |
557 | /** export variable1 [variable2...] - KMKCCEVALEXPORT. */ | |
557 | /** export variable1 [variable2...] - KMKCCEVALVARIABLES. */ | |
558 | 558 | kKmkCcEvalInstr_export, |
559 | /** unexport variable1 [variable2...] - KMKCCEVALEXPORT. */ | |
559 | /** unexport variable1 [variable2...] - KMKCCEVALVARIABLES. */ | |
560 | 560 | kKmkCcEvalInstr_unexport, |
561 | 561 | /** export - KMKCCEVALCORE. */ |
562 | 562 | kKmkCcEvalInstr_export_all, |
563 | 563 | /** unexport - KMKCCEVALCORE. */ |
564 | 564 | kKmkCcEvalInstr_unexport_all, |
565 | /** [local|override] undefine - KMKCCEVALVARIABLES. */ | |
566 | kKmkCcEvalInstr_undefine, | |
567 | ||
565 | 568 | |
566 | 569 | /** [else] ifdef variable - KMKCCEVALIFDEFPLAIN. */ |
567 | 570 | kKmkCcEvalInstr_ifdef_plain, |
686 | 689 | typedef KMKCCEVALASSIGNDEF *PKMKCCEVALASSIGNDEF; |
687 | 690 | |
688 | 691 | /** |
689 | * Instruction format for kKmkCcEvalInstr_export and kKmkCcEvalInstr_unexport. | |
690 | */ | |
691 | typedef struct kmk_cc_eval_export | |
692 | * Instruction format for kKmkCcEvalInstr_export, kKmkCcEvalInstr_unexport and | |
693 | * kKmkCcEvalInstr_undefine. | |
694 | */ | |
695 | typedef struct kmk_cc_eval_variables | |
692 | 696 | { |
693 | 697 | /** The core instruction. */ |
694 | 698 | KMKCCEVALCORE Core; |
695 | 699 | /** The number of variables named in aVars. */ |
696 | 700 | uint32_t cVars; |
701 | /** Whether the 'local' qualifier was used (undefine only). */ | |
702 | uint8_t fLocal; | |
697 | 703 | /** Pointer to the next instruction. */ |
698 | 704 | PKMKCCEVALCORE pNext; |
699 | 705 | /** The variable names. |
700 | 706 | * Expressions will be expanded and split on space. |
701 | 707 | * @remarks Plain text names are in variable_strcache. */ |
702 | 708 | KMKCCEXPSUBPROGORPLAIN aVars[1]; |
703 | } KMKCCEVALEXPORT; | |
704 | typedef KMKCCEVALEXPORT *PKMKCCEVALEXPORT; | |
705 | /** Calculates the size of an KMKCCEVALEXPORT structure for @a a_cVars. */ | |
706 | #define KMKCCEVALEXPORT_SIZE(a_cVars) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVPATH, aVars, a_cVars) | |
709 | } KMKCCEVALVARIABLES; | |
710 | typedef KMKCCEVALVARIABLES *PKMKCCEVALVARIABLES; | |
711 | /** Calculates the size of an KMKCCEVALVARIABLES structure for @a a_cVars. */ | |
712 | #define KMKCCEVALVARIABLES_SIZE(a_cVars) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVARIABLES, aVars, a_cVars) | |
707 | 713 | |
708 | 714 | /** |
709 | 715 | * Core structure for all conditionals (kKmkCcEvalInstr_if*). |
1038 | 1044 | "unexport", |
1039 | 1045 | "export_all", |
1040 | 1046 | "unexport_all", |
1047 | "undefine", | |
1041 | 1048 | "ifdef_plain", |
1042 | 1049 | "ifndef_plain", |
1043 | 1050 | "ifdef_dynamic", |
1113 | 1120 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, 'l', KMK_CC_EVAL_CH_1ST_IN_VARIABLE_KEYWORD); /* local */ |
1114 | 1121 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, 'o', KMK_CC_EVAL_CH_1ST_IN_VARIABLE_KEYWORD); /* override */ |
1115 | 1122 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, 'p', KMK_CC_EVAL_CH_1ST_IN_VARIABLE_KEYWORD); /* private */ |
1116 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, 'u', KMK_CC_EVAL_CH_1ST_IN_VARIABLE_KEYWORD); /* undefine */ | |
1123 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, 'u', KMK_CC_EVAL_CH_1ST_IN_VARIABLE_KEYWORD); /* undefine, unexport */ | |
1117 | 1124 | |
1118 | 1125 | /* Assignment punctuation and recipe stuff. */ |
1119 | 1126 | KMK_CC_EVAL_BM_OR(g_abEvalCcChars, '=', KMK_CC_EVAL_CH_SPACE_VAR_OR_RECIPE); |
3389 | 3396 | && (a_pchLine)[14] == (a_pszWord)[14] \ |
3390 | 3397 | && (a_pchLine)[15] == (a_pszWord)[15]) |
3391 | 3398 | #endif |
3399 | ||
3400 | /** See if the given string match a constant string. */ | |
3401 | #define KMK_CC_STRCMP_CONST(a_pchLeft, a_cchLeft, a_pszConst, a_cchConst) \ | |
3402 | ( (a_cchLeft) == (a_cchConst) \ | |
3403 | && KMK_CC_WORD_COMP_CONST_##a_cchConst(a_pchLeft, a_pszConst) ) | |
3404 | ||
3392 | 3405 | /** See if a starting of a given length starts with a constant word. */ |
3393 | #define KMK_CC_WORD_COMP_IS_EOL(a_pCompiler, a_pchLine, a_cchLine) \ | |
3406 | #define KMK_CC_EVAL_WORD_COMP_IS_EOL(a_pCompiler, a_pchLine, a_cchLine) \ | |
3394 | 3407 | ( (a_cchLine) == 0 \ |
3395 | 3408 | || KMK_CC_EVAL_IS_SPACE((a_pchLine)[0]) \ |
3396 | 3409 | || ((a_pchLine)[0] == '\\' && (a_pchLine)[1] == (a_pCompiler)->chFirstEol) ) \ |
3397 | 3410 | |
3398 | 3411 | /** See if a starting of a given length starts with a constant word. */ |
3399 | #define KMK_CC_WORD_COMP_CONST(a_pCompiler, a_pchLine, a_cchLine, a_pszWord, a_cchWord) \ | |
3412 | #define KMK_CC_EVAL_WORD_COMP_CONST(a_pCompiler, a_pchLine, a_cchLine, a_pszWord, a_cchWord) \ | |
3400 | 3413 | ( (a_cchLine) >= (a_cchWord) \ |
3401 | 3414 | && ( (a_cchLine) == (a_cchWord) \ |
3402 | 3415 | || KMK_CC_EVAL_IS_SPACE((a_pchLine)[a_cchWord]) \ |
5185 | 5198 | pchWord += 2; |
5186 | 5199 | cchLeft -= 2; |
5187 | 5200 | |
5188 | if (KMK_CC_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
5201 | if (KMK_CC_EVAL_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
5189 | 5202 | return kmk_cc_eval_do_if(pCompiler, pchWord, cchLeft, 1 /* in else */); |
5190 | 5203 | |
5191 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "eq", 2)) | |
5204 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "eq", 2)) | |
5192 | 5205 | return kmk_cc_eval_do_ifeq( pCompiler, pchWord + 2, cchLeft - 2, 1 /* in else */, 1 /* positive */); |
5193 | 5206 | |
5194 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "def", 3)) | |
5207 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "def", 3)) | |
5195 | 5208 | return kmk_cc_eval_do_ifdef(pCompiler, pchWord + 3, cchLeft - 3, 1 /* in else */, 1 /* positive */); |
5196 | 5209 | |
5197 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "neq", 3)) | |
5210 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "neq", 3)) | |
5198 | 5211 | return kmk_cc_eval_do_ifeq( pCompiler, pchWord + 3, cchLeft - 3, 1 /* in else */, 0 /* positive */); |
5199 | 5212 | |
5200 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "1of", 3)) | |
5213 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "1of", 3)) | |
5201 | 5214 | return kmk_cc_eval_do_if1of(pCompiler, pchWord + 3, cchLeft - 3, 1 /* in else */, 1 /* positive */); |
5202 | 5215 | |
5203 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "ndef", 4)) | |
5216 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "ndef", 4)) | |
5204 | 5217 | return kmk_cc_eval_do_ifdef(pCompiler, pchWord + 4, cchLeft - 4, 1 /* in else */, 0 /* positive */); |
5205 | 5218 | |
5206 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "n1of", 4)) | |
5219 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "n1of", 4)) | |
5207 | 5220 | return kmk_cc_eval_do_if1of(pCompiler, pchWord + 4, cchLeft - 4, 1 /* in else */, 0 /* positive */); |
5208 | 5221 | |
5209 | 5222 | pchWord -= 2; |
5298 | 5311 | PKMKCCEVALINCLUDE pInstr = (PKMKCCEVALINCLUDE)kmk_cc_block_alloc_eval(pCompiler->ppBlockTail, |
5299 | 5312 | KMKCCEVALINCLUDE_SIZE(cWords)); |
5300 | 5313 | pInstr->Core.enmOpcode = enmOpcode; |
5301 | pInstr->Core.iLine = 0; | |
5314 | pInstr->Core.iLine = pCompiler->iLine; | |
5302 | 5315 | pInstr->cFiles = cWords; |
5303 | 5316 | kmk_cc_eval_init_spp_array_from_duplicated_words(pCompiler, cWords, pCompiler->paWords, pInstr->aFiles); |
5304 | 5317 | kmk_cc_block_realign(pCompiler->ppBlockTail); |
5328 | 5341 | static int kmk_cc_eval_handle_recipe_cont_colon(PKMKCCEVALCOMPILER pCompiler, const char *pchWord0, size_t cchWord0, |
5329 | 5342 | const char *pchColon, size_t cchLeft, unsigned fQualifiers) |
5330 | 5343 | { |
5331 | kmk_cc_eval_fatal(pCompiler, pchWord0, "recipe handling not implemented yet"); | |
5344 | kmk_cc_eval_fatal(pCompiler, pchWord0, "recipe handling not implemented yet (#1)"); | |
5332 | 5345 | return 1; |
5333 | 5346 | } |
5334 | 5347 | |
5336 | 5349 | static int kmk_cc_eval_handle_recipe_cont_2nd_word(PKMKCCEVALCOMPILER pCompiler, const char *pchWord0, size_t cchWord0, |
5337 | 5350 | const char *pchWord, size_t cchLeft, unsigned fQualifiers) |
5338 | 5351 | { |
5339 | kmk_cc_eval_fatal(pCompiler, pchWord, "recipe handling not implemented yet"); | |
5352 | kmk_cc_eval_fatal(pCompiler, pchWord, "recipe handling not implemented yet (#2)"); | |
5340 | 5353 | return 1; |
5341 | 5354 | } |
5342 | 5355 | |
5343 | 5356 | |
5344 | 5357 | static void kmk_cc_eval_handle_recipe(PKMKCCEVALCOMPILER pCompiler, const char *pszEqual, const char *pchWord, size_t cchLeft) |
5345 | 5358 | { |
5346 | kmk_cc_eval_fatal(pCompiler, pchWord, "recipe handling not implemented yet"); | |
5359 | kmk_cc_eval_fatal(pCompiler, pchWord, "recipe handling not implemented yet (#3)"); | |
5347 | 5360 | } |
5348 | 5361 | |
5349 | 5362 | static void kmk_cc_eval_end_of_recipe(PKMKCCEVALCOMPILER pCompiler) |
5356 | 5369 | |
5357 | 5370 | |
5358 | 5371 | /** |
5359 | * Parses a 'undefine variable [..]' expression. | |
5372 | * Common worker for handling export (non-assign), undefine and unexport. | |
5373 | * | |
5374 | * For instructions using the KMKCCEVALVARIABLES structure. | |
5375 | * | |
5376 | * @returns 1 to indicate we've handled a keyword (see | |
5377 | * kmk_cc_eval_try_handle_keyword). | |
5378 | * @param pCompiler The compiler state. | |
5379 | * @param pchWord First non-space chare after the keyword. | |
5380 | * @param cchLeft The number of chars left to parse on this line. | |
5381 | * @param fQualifiers The qualifiers. | |
5382 | */ | |
5383 | static int kmk_cc_eval_do_with_variable_list(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, | |
5384 | KMKCCEVALINSTR enmOpcode, unsigned fQualifiers) | |
5385 | { | |
5386 | if (cchLeft) | |
5387 | { | |
5388 | /* | |
5389 | * Parse the variable name list. GNU make is using normal word | |
5390 | * handling here, so we can share code with the include directives. | |
5391 | */ | |
5392 | unsigned cWords = kmk_cc_eval_parse_words(pCompiler, pchWord, cchLeft); | |
5393 | KMK_CC_EVAL_DPRINTF(("%s: cWords=%d\n", g_apszEvalInstrNms[enmOpcode], cWords)); | |
5394 | if (cWords) | |
5395 | { | |
5396 | PKMKCCEVALVARIABLES pInstr = (PKMKCCEVALVARIABLES)kmk_cc_block_alloc_eval(pCompiler->ppBlockTail, | |
5397 | KMKCCEVALVARIABLES_SIZE(cWords)); | |
5398 | pInstr->Core.enmOpcode = enmOpcode; | |
5399 | pInstr->Core.iLine = pCompiler->iLine; | |
5400 | pInstr->cVars = cWords; | |
5401 | kmk_cc_eval_init_spp_array_from_duplicated_words(pCompiler, cWords, pCompiler->paWords, pInstr->aVars); | |
5402 | kmk_cc_block_realign(pCompiler->ppBlockTail); | |
5403 | } | |
5404 | else | |
5405 | KMK_CC_ASSERT(0); | |
5406 | } | |
5407 | /* else: NOP */ | |
5408 | return 1; | |
5409 | } | |
5410 | ||
5411 | ||
5412 | /** | |
5413 | * Parses a '[qualifiers] undefine variable [..]' expression. | |
5360 | 5414 | * |
5361 | 5415 | * A 'undefine' directive is final, any qualifiers must preceed it. So, we just |
5362 | 5416 | * have to extract the variable names now. |
5370 | 5424 | */ |
5371 | 5425 | static int kmk_cc_eval_do_var_undefine(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, unsigned fQualifiers) |
5372 | 5426 | { |
5373 | kmk_cc_eval_fatal(pCompiler, pchWord, "undefine handling not implemented yet"); | |
5374 | return 1; | |
5375 | } | |
5376 | ||
5377 | ||
5378 | /** | |
5379 | * Parses a 'define variable' expression. | |
5380 | * | |
5381 | * A 'define' directive is final, any qualifiers must preceed it. So, we just | |
5382 | * have to extract the variable name now, well and find the corresponding | |
5383 | * 'endef'. | |
5427 | KMK_CC_EVAL_SKIP_SPACES_AFTER_WORD(pCompiler, pchWord, cchLeft); | |
5428 | if (!cchLeft) | |
5429 | kmk_cc_eval_fatal(pCompiler, pchWord, "undefine requires a variable name"); | |
5430 | ||
5431 | /** @todo GNU make doesn't actually do the list thing for undefine, it seems | |
5432 | * to assume everything after it is a single variable... Going with | |
5433 | * simple common code for now. */ | |
5434 | return kmk_cc_eval_do_with_variable_list(pCompiler, pchWord, cchLeft, kKmkCcEvalInstr_undefine, fQualifiers); | |
5435 | } | |
5436 | ||
5437 | ||
5438 | /** | |
5439 | * Parses a '[qualifiers] unexport variable [..]' expression. | |
5440 | * | |
5441 | * A 'unexport' directive is final, any qualifiers must preceed it. So, we just | |
5442 | * have to extract the variable names now. | |
5384 | 5443 | * |
5385 | 5444 | * @returns 1 to indicate we've handled a keyword (see |
5386 | 5445 | * kmk_cc_eval_try_handle_keyword). |
5389 | 5448 | * @param cchLeft The number of chars left to parse on this line. |
5390 | 5449 | * @param fQualifiers The qualifiers. |
5391 | 5450 | */ |
5451 | static int kmk_cc_eval_do_var_unexport(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, unsigned fQualifiers) | |
5452 | { | |
5453 | PKMKCCEVALCORE pInstr; | |
5454 | ||
5455 | /* | |
5456 | * Join paths with undefine and export, unless it's an unexport all directive. | |
5457 | */ | |
5458 | KMK_CC_EVAL_SKIP_SPACES_AFTER_WORD(pCompiler, pchWord, cchLeft); | |
5459 | if (cchLeft) | |
5460 | return kmk_cc_eval_do_with_variable_list(pCompiler, pchWord, cchLeft, kKmkCcEvalInstr_unexport, fQualifiers); | |
5461 | ||
5462 | /* | |
5463 | * We're unexporting all variables. | |
5464 | */ | |
5465 | pInstr = kmk_cc_block_alloc_eval(pCompiler->ppBlockTail, sizeof(*pInstr)); | |
5466 | pInstr->enmOpcode = kKmkCcEvalInstr_unexport_all; | |
5467 | pInstr->iLine = pCompiler->iLine; | |
5468 | return 1; | |
5469 | } | |
5470 | ||
5471 | ||
5472 | /** | |
5473 | * Parses a 'define variable' expression. | |
5474 | * | |
5475 | * A 'define' directive is final, any qualifiers must preceed it. So, we just | |
5476 | * have to extract the variable name now, well and find the corresponding | |
5477 | * 'endef'. | |
5478 | * | |
5479 | * @returns 1 to indicate we've handled a keyword (see | |
5480 | * kmk_cc_eval_try_handle_keyword). | |
5481 | * @param pCompiler The compiler state. | |
5482 | * @param pchWord First char after 'define'. | |
5483 | * @param cchLeft The number of chars left to parse on this line. | |
5484 | * @param fQualifiers The qualifiers. | |
5485 | */ | |
5392 | 5486 | static int kmk_cc_eval_do_var_define(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, unsigned fQualifiers) |
5393 | 5487 | { |
5394 | 5488 | |
5398 | 5492 | } |
5399 | 5493 | |
5400 | 5494 | |
5401 | static int kmk_cc_eval_handle_assignment_or_recipe(PKMKCCEVALCOMPILER pCompiler, const char *pchTmp, | |
5402 | const char *pchWord, size_t cchLeft, unsigned fQualifiers) | |
5495 | static int kmk_cc_eval_handle_assignment_or_recipe(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, | |
5496 | unsigned fQualifiers) | |
5403 | 5497 | { |
5404 | 5498 | /* |
5405 | 5499 | * We're currently at a word which may or may not be a variable name |
5616 | 5710 | cchValue = kmk_cc_eval_prep_normal_line(pCompiler, pchWord, cchLeft); |
5617 | 5711 | fPlainValue = memchr(pchWord, '$', cchLeft) == NULL; |
5618 | 5712 | |
5713 | ||
5619 | 5714 | /* |
5620 | 5715 | * Emit the instruction. |
5621 | 5716 | */ |
5655 | 5750 | |
5656 | 5751 | |
5657 | 5752 | /** |
5658 | * Parses a 'local [override] variable = value' expression. | |
5753 | * Parses a 'local [override] variable = value', 'local define variable', and | |
5754 | * 'local undefine variable [...]' expressions. | |
5659 | 5755 | * |
5660 | 5756 | * The 'local' directive must be first and it does not permit any qualifiers at |
5661 | 5757 | * the moment. Should any be added later, they will have to come after 'local'. |
5673 | 5769 | if (cchLeft) |
5674 | 5770 | { |
5675 | 5771 | /* |
5676 | * Find the end of the variable name. | |
5772 | * Check for 'local define' and 'local undefine' | |
5677 | 5773 | */ |
5678 | ||
5679 | } | |
5680 | else | |
5681 | kmk_cc_eval_fatal(pCompiler, pchWord, "Expected variable name, assignment operator and value after 'local'"); | |
5682 | return 1; | |
5683 | } | |
5684 | ||
5685 | ||
5686 | /** | |
5687 | * Parses 'export [variable]' and 'export [qualifiers] variable = value' | |
5688 | * expressions. | |
5689 | * | |
5690 | * When we find the 'export' directive at the start of a line, we need to | |
5691 | * continue parsing with till we can tell the difference between the two forms. | |
5692 | * | |
5693 | * @returns 1 to indicate we've handled a keyword (see | |
5694 | * kmk_cc_eval_try_handle_keyword). | |
5695 | * @param pCompiler The compiler state. | |
5696 | * @param pchWord First char after 'define'. | |
5697 | * @param cchLeft The number of chars left to parse on this line. | |
5698 | * @param fQualifiers The qualifiers. | |
5699 | */ | |
5700 | static int kmk_cc_eval_handle_var_export(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft, unsigned fQualifiers) | |
5701 | { | |
5702 | kmk_cc_eval_fatal(pCompiler, pchWord, "export not implemented yet"); | |
5774 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)) /* final */ | |
5775 | return kmk_cc_eval_do_var_define(pCompiler, pchWord + 6, cchLeft + 6, KMK_CC_EVAL_QUALIFIER_LOCAL); | |
5776 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)) /* final */ | |
5777 | return kmk_cc_eval_do_var_undefine(pCompiler, pchWord + 8, cchLeft + 8, KMK_CC_EVAL_QUALIFIER_LOCAL); | |
5778 | ||
5779 | /* | |
5780 | * Simpler to just join paths with the rest here, even if we could | |
5781 | * probably optimize the parsing a little if we liked. | |
5782 | */ | |
5783 | return kmk_cc_eval_handle_assignment_or_recipe(pCompiler, pchWord, cchLeft, KMK_CC_EVAL_QUALIFIER_LOCAL); | |
5784 | } | |
5785 | kmk_cc_eval_fatal(pCompiler, pchWord, "Expected variable name, assignment operator and value after 'local'"); | |
5703 | 5786 | return 1; |
5704 | 5787 | } |
5705 | 5788 | |
5725 | 5808 | char ch = *pchWord; |
5726 | 5809 | if (KMK_CC_EVAL_IS_1ST_IN_VARIABLE_KEYWORD(ch)) |
5727 | 5810 | { |
5728 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)) /* final */ | |
5811 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)) /* final */ | |
5729 | 5812 | return kmk_cc_eval_do_var_define(pCompiler, pchWord + 6, cchLeft - 6, fQualifiers); |
5730 | 5813 | |
5731 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)) /* final */ | |
5732 | return kmk_cc_eval_do_var_undefine(pCompiler, pchWord + 6, cchLeft - 6, fQualifiers); | |
5733 | ||
5734 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)) | |
5814 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)) /* final */ | |
5815 | return kmk_cc_eval_do_var_undefine(pCompiler, pchWord + 8, cchLeft -86, fQualifiers); | |
5816 | ||
5817 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "unexport", 8)) /* final */ | |
5818 | return kmk_cc_eval_do_var_unexport(pCompiler, pchWord + 8, cchLeft - 8, fQualifiers); | |
5819 | ||
5820 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)) | |
5735 | 5821 | { |
5736 | 5822 | if (!(fQualifiers & KMK_CC_EVAL_QUALIFIER_EXPORT)) |
5737 | 5823 | fQualifiers |= KMK_CC_EVAL_QUALIFIER_EXPORT; |
5742 | 5828 | continue; |
5743 | 5829 | } |
5744 | 5830 | |
5745 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)) | |
5831 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)) | |
5746 | 5832 | { |
5747 | 5833 | if (!(fQualifiers & KMK_CC_EVAL_QUALIFIER_OVERRIDE)) |
5748 | 5834 | fQualifiers |= KMK_CC_EVAL_QUALIFIER_OVERRIDE; |
5753 | 5839 | continue; |
5754 | 5840 | } |
5755 | 5841 | |
5756 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)) | |
5842 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)) | |
5757 | 5843 | { |
5758 | 5844 | if (!(fQualifiers & KMK_CC_EVAL_QUALIFIER_PRIVATE)) |
5759 | 5845 | fQualifiers |= KMK_CC_EVAL_QUALIFIER_PRIVATE; |
5773 | 5859 | { |
5774 | 5860 | const char *pchEqual = (const char *)memchr(pchWord, '=', cchLeft); |
5775 | 5861 | if (pchEqual) |
5776 | return kmk_cc_eval_handle_assignment_or_recipe(pCompiler, pchEqual, pchWord, cchLeft, fQualifiers); | |
5862 | return kmk_cc_eval_handle_assignment_or_recipe(pCompiler, pchWord, cchLeft, fQualifiers); | |
5777 | 5863 | } |
5778 | 5864 | return 0; |
5779 | 5865 | } |
5785 | 5871 | |
5786 | 5872 | |
5787 | 5873 | /** |
5874 | * Parses 'export [variable]' and 'export [qualifiers] variable = value' | |
5875 | * expressions. | |
5876 | * | |
5877 | * When we find the 'export' directive at the start of a line, we need to | |
5878 | * continue parsing with till we can tell the difference between the two forms. | |
5879 | * | |
5880 | * @returns 1 to indicate we've handled a keyword (see | |
5881 | * kmk_cc_eval_try_handle_keyword). | |
5882 | * @param pCompiler The compiler state. | |
5883 | * @param pchWord First char after 'define'. | |
5884 | * @param cchLeft The number of chars left to parse on this line. | |
5885 | */ | |
5886 | static int kmk_cc_eval_handle_var_export(PKMKCCEVALCOMPILER pCompiler, const char *pchWord, size_t cchLeft) | |
5887 | { | |
5888 | KMK_CC_EVAL_SKIP_SPACES_AFTER_WORD(pCompiler, pchWord, cchLeft); | |
5889 | ||
5890 | if (cchLeft) | |
5891 | { | |
5892 | unsigned iSavedEscEol; | |
5893 | unsigned cWords; | |
5894 | ||
5895 | /* | |
5896 | * We need to figure out whether this is an assignment or a export statement, | |
5897 | * in the latter case join paths with 'export' and 'undefine'. | |
5898 | */ | |
5899 | const char *pchEqual = (const char *)memchr(pchWord, '=', cchLeft); | |
5900 | if (!pchEqual) | |
5901 | return kmk_cc_eval_do_with_variable_list(pCompiler, pchWord, cchLeft, kKmkCcEvalInstr_export, 0 /*fQualifiers*/); | |
5902 | ||
5903 | /* | |
5904 | * Found an '=', could be an assignment. Let's take the easy way out | |
5905 | * and just parse the whole statement into words like we would do if | |
5906 | * it wasn't an assignment, and then check the words out for | |
5907 | * assignment keywords and operators. | |
5908 | */ | |
5909 | iSavedEscEol = pCompiler->iEscEol; | |
5910 | cWords = kmk_cc_eval_parse_words(pCompiler, pchWord, cchLeft); | |
5911 | if (cWords) | |
5912 | { | |
5913 | PKMKCCEVALVARIABLES pInstr; | |
5914 | PKMKCCEVALWORD pWord = pCompiler->paWords; | |
5915 | unsigned iWord = 0; | |
5916 | while (iWord < cWords) | |
5917 | { | |
5918 | /* Trailing assignment operator or terminal assignment directive ('undefine' | |
5919 | and 'unexport' makes no sense here but GNU make ignores that). */ | |
5920 | if ( ( pWord->cchWord > 1 | |
5921 | && pWord->pchWord[pWord->cchWord - 1] == '=') | |
5922 | || KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "define", 6) | |
5923 | || KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "undefine", 8) | |
5924 | || KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "unexport", 8) ) | |
5925 | { | |
5926 | pCompiler->iEscEol = iSavedEscEol; | |
5927 | return kmk_cc_eval_try_handle_var_with_keywords(pCompiler, pchWord, cchLeft, KMK_CC_EVAL_QUALIFIER_EXPORT); | |
5928 | } | |
5929 | ||
5930 | /* If not a variable assignment qualifier, it must be a variable name | |
5931 | followed by an assignment operator. */ | |
5932 | if (iWord + 1 < cWords) | |
5933 | { | |
5934 | if ( !KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "export", 6) | |
5935 | && !KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "private", 7) | |
5936 | && !KMK_CC_STRCMP_CONST(pWord->pchWord, pWord->cchWord, "override", 8)) | |
5937 | { | |
5938 | pWord++; | |
5939 | if ( pWord->cchWord > 0 | |
5940 | && ( pWord->pchWord[0] == '=' | |
5941 | || ( pWord->cchWord > 1 | |
5942 | && pWord->pchWord[1] == '=' | |
5943 | && ( pWord->pchWord[0] == ':' | |
5944 | || pWord->pchWord[0] == '+' | |
5945 | || pWord->pchWord[0] == '?' | |
5946 | || pWord->pchWord[0] == '<') ) ) ) | |
5947 | { | |
5948 | pCompiler->iEscEol = iSavedEscEol; | |
5949 | return kmk_cc_eval_try_handle_var_with_keywords(pCompiler, pchWord, cchLeft, | |
5950 | KMK_CC_EVAL_QUALIFIER_EXPORT); | |
5951 | } | |
5952 | break; | |
5953 | } | |
5954 | } | |
5955 | else | |
5956 | break; | |
5957 | /* next */ | |
5958 | pWord++; | |
5959 | iWord++; | |
5960 | } | |
5961 | ||
5962 | /* | |
5963 | * It's not an assignment. | |
5964 | * (This is the same as kmk_cc_eval_do_with_variable_list does.) | |
5965 | */ | |
5966 | pInstr = (PKMKCCEVALVARIABLES)kmk_cc_block_alloc_eval(pCompiler->ppBlockTail, KMKCCEVALVARIABLES_SIZE(cWords)); | |
5967 | pInstr->Core.enmOpcode = kKmkCcEvalInstr_export; | |
5968 | pInstr->Core.iLine = pCompiler->iLine; | |
5969 | pInstr->cVars = cWords; | |
5970 | kmk_cc_eval_init_spp_array_from_duplicated_words(pCompiler, cWords, pCompiler->paWords, pInstr->aVars); | |
5971 | kmk_cc_block_realign(pCompiler->ppBlockTail); | |
5972 | } | |
5973 | else | |
5974 | KMK_CC_ASSERT(0); | |
5975 | } | |
5976 | else | |
5977 | { | |
5978 | /* | |
5979 | * We're exporting all variables. | |
5980 | */ | |
5981 | PKMKCCEVALCORE pInstr = kmk_cc_block_alloc_eval(pCompiler->ppBlockTail, sizeof(*pInstr)); | |
5982 | pInstr->enmOpcode = kKmkCcEvalInstr_export_all; | |
5983 | pInstr->iLine = pCompiler->iLine; | |
5984 | } | |
5985 | return 1; | |
5986 | } | |
5987 | ||
5988 | ||
5989 | /** | |
5788 | 5990 | * When entering this function we know that the first two character in the first |
5789 | 5991 | * word both independently occurs in keywords. |
5790 | 5992 | * |
5809 | 6011 | */ |
5810 | 6012 | if (KMK_CC_EVAL_IS_1ST_IN_VARIABLE_KEYWORD(ch)) |
5811 | 6013 | { |
5812 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "local", 5)) | |
6014 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "local", 5)) | |
5813 | 6015 | return kmk_cc_eval_do_var_local(pCompiler, pchWord + 5, cchLeft - 5); |
5814 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)) | |
6016 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)) | |
5815 | 6017 | return kmk_cc_eval_do_var_define(pCompiler, pchWord + 6, cchLeft - 6, 0); |
5816 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)) | |
5817 | return kmk_cc_eval_handle_var_export(pCompiler, pchWord + 6, cchLeft - 6, 0); | |
5818 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)) | |
6018 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)) | |
6019 | return kmk_cc_eval_handle_var_export(pCompiler, pchWord + 6, cchLeft - 6); | |
6020 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)) | |
5819 | 6021 | return kmk_cc_eval_do_var_undefine(pCompiler, pchWord + 8, cchLeft - 8, 0); |
5820 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)) | |
6022 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "unexport", 8)) | |
6023 | return kmk_cc_eval_do_var_unexport(pCompiler, pchWord + 8, cchLeft - 8, 0); | |
6024 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)) | |
5821 | 6025 | { |
5822 | 6026 | if (kmk_cc_eval_try_handle_var_with_keywords(pCompiler, pchWord + 8, cchLeft - 8, KMK_CC_EVAL_QUALIFIER_OVERRIDE)) |
5823 | 6027 | return 1; |
5824 | 6028 | pCompiler->iEscEol = iSavedEscEol; |
5825 | 6029 | } |
5826 | else if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)) | |
6030 | else if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)) | |
5827 | 6031 | { |
5828 | 6032 | if (kmk_cc_eval_try_handle_var_with_keywords(pCompiler, pchWord + 7, cchLeft - 7, KMK_CC_EVAL_QUALIFIER_PRIVATE)) |
5829 | 6033 | return 1; |
5843 | 6047 | /* 'if...' */ |
5844 | 6048 | if (ch2 == 'f') |
5845 | 6049 | { |
5846 | if (KMK_CC_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
6050 | if (KMK_CC_EVAL_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
5847 | 6051 | return kmk_cc_eval_do_if(pCompiler, pchWord, cchLeft, 0 /* in else */); |
5848 | 6052 | |
5849 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "eq", 2)) | |
6053 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "eq", 2)) | |
5850 | 6054 | return kmk_cc_eval_do_ifeq( pCompiler, pchWord + 2, cchLeft - 2, 0 /* in else */, 1 /* positive */); |
5851 | 6055 | |
5852 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "def", 3)) | |
6056 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "def", 3)) | |
5853 | 6057 | return kmk_cc_eval_do_ifdef(pCompiler, pchWord + 3, cchLeft - 3, 0 /* in else */, 1 /* positive */); |
5854 | 6058 | |
5855 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "neq", 3)) | |
6059 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "neq", 3)) | |
5856 | 6060 | return kmk_cc_eval_do_ifeq( pCompiler, pchWord + 3, cchLeft - 3, 0 /* in else */, 0 /* positive */); |
5857 | 6061 | |
5858 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "1of", 3)) | |
6062 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "1of", 3)) | |
5859 | 6063 | return kmk_cc_eval_do_if1of(pCompiler, pchWord + 3, cchLeft - 3, 0 /* in else */, 1 /* positive */); |
5860 | 6064 | |
5861 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "ndef", 4)) | |
6065 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "ndef", 4)) | |
5862 | 6066 | return kmk_cc_eval_do_ifdef(pCompiler, pchWord + 4, cchLeft - 4, 0 /* in else */, 0 /* positive */); |
5863 | 6067 | |
5864 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "n1of", 4)) | |
6068 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "n1of", 4)) | |
5865 | 6069 | return kmk_cc_eval_do_if1of(pCompiler, pchWord + 4, cchLeft - 4, 0 /* in else */, 0 /* positive */); |
5866 | 6070 | } |
5867 | 6071 | /* include... */ |
5869 | 6073 | { |
5870 | 6074 | pchWord += 5; |
5871 | 6075 | cchLeft -= 5; |
5872 | if (KMK_CC_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
6076 | if (KMK_CC_EVAL_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
5873 | 6077 | return kmk_cc_eval_do_include(pCompiler, pchWord, cchLeft, kKmkCcEvalInstr_include); |
5874 | 6078 | if (cchLeft >= 3 && KMK_CC_WORD_COMP_CONST_3(pchWord, "dep")) |
5875 | 6079 | { |
5876 | 6080 | pchWord += 3; |
5877 | 6081 | cchLeft -= 3; |
5878 | if (KMK_CC_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
6082 | if (KMK_CC_EVAL_WORD_COMP_IS_EOL(pCompiler, pchWord, cchLeft)) | |
5879 | 6083 | return kmk_cc_eval_do_include(pCompiler, pchWord, cchLeft, kKmkCcEvalInstr_includedep); |
5880 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-queue", 6)) | |
6084 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-queue", 6)) | |
5881 | 6085 | return kmk_cc_eval_do_include(pCompiler, pchWord + 6, cchLeft - 6, kKmkCcEvalInstr_includedep_queue); |
5882 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-flush", 6)) | |
6086 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-flush", 6)) | |
5883 | 6087 | return kmk_cc_eval_do_include(pCompiler, pchWord + 6, cchLeft - 6, kKmkCcEvalInstr_includedep_flush); |
5884 | 6088 | } |
5885 | 6089 | } |
5886 | 6090 | } |
5887 | 6091 | else if (ch == 'e') /* A few directives starts with 'e'. */ |
5888 | 6092 | { |
5889 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "else", 4)) | |
6093 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "else", 4)) | |
5890 | 6094 | return kmk_cc_eval_do_else(pCompiler, pchWord + 4, cchLeft - 4); |
5891 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "endif", 5)) | |
6095 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "endif", 5)) | |
5892 | 6096 | return kmk_cc_eval_do_endif(pCompiler, pchWord + 5, cchLeft - 5); |
5893 | 6097 | /* export and endef are handled elsewhere, though stray endef's may end up here... */ |
5894 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)); | |
6098 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "export", 6)); | |
5895 | 6099 | |
5896 | 6100 | } |
5897 | 6101 | else /* the rest. */ |
5898 | 6102 | { |
5899 | if ( KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "sinclude", 8) | |
5900 | || KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-include", 8)) | |
6103 | if ( KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "sinclude", 8) | |
6104 | || KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "-include", 8)) | |
5901 | 6105 | return kmk_cc_eval_do_include(pCompiler, pchWord + 8, cchLeft - 8, kKmkCcEvalInstr_include_silent); |
5902 | if (KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "vpath", 5)) | |
6106 | if (KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "vpath", 5)) | |
5903 | 6107 | return kmk_cc_eval_do_vpath(pCompiler, pchWord + 5, cchLeft - 5); |
5904 | 6108 | |
5905 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "local", 5)); | |
5906 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)); | |
5907 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)); | |
5908 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)); | |
5909 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "unexport", 8)); | |
5910 | KMK_CC_ASSERT(!KMK_CC_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)); | |
6109 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "local", 5)); | |
6110 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "define", 6)); | |
6111 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "private", 7)); | |
6112 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "override", 8)); | |
6113 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "unexport", 8)); | |
6114 | KMK_CC_ASSERT(!KMK_CC_EVAL_WORD_COMP_CONST(pCompiler, pchWord, cchLeft, "undefine", 8)); | |
5911 | 6115 | } |
5912 | 6116 | |
5913 | 6117 | pCompiler->iEscEol = iSavedEscEol; |
6147 | 6351 | { |
6148 | 6352 | pchTmp = (const char *)memchr(pchWord, '=', cchLeft); |
6149 | 6353 | if (pchTmp) |
6150 | kmk_cc_eval_handle_assignment_or_recipe(&Compiler, pchTmp, pchWord, cchLeft, 0); | |
6354 | kmk_cc_eval_handle_assignment_or_recipe(&Compiler, pchWord, cchLeft, 0 /*fQualifiers*/); | |
6151 | 6355 | else |
6152 | 6356 | kmk_cc_eval_handle_recipe(&Compiler, pchTmp, pchWord, cchLeft); |
6153 | 6357 | } |
0 | /* $Id: kDepObj.c 2759 2015-01-28 16:14:00Z bird $ */ | |
0 | /* $Id: kDepObj.c 2804 2016-01-07 20:47:06Z bird $ */ | |
1 | 1 | /** @file |
2 | 2 | * kDepObj - Extract dependency information from an object file. |
3 | 3 | */ |
53 | 53 | * Defined Constants And Macros * |
54 | 54 | *******************************************************************************/ |
55 | 55 | /*#define DEBUG*/ |
56 | #define DEBUG | |
57 | 56 | #ifdef DEBUG |
58 | 57 | # define dprintf(a) printf a |
59 | 58 | # define dump(pb, cb, offBase) depHexDump(pb,cb,offBase) |
0 | /* $Id: redirect.c 2779 2015-02-24 03:50:12Z bird $ */ | |
0 | /* $Id: redirect.c 2812 2016-03-13 11:22:53Z bird $ */ | |
1 | 1 | /** @file |
2 | 2 | * kmk_redirect - Do simple program <-> file redirection (++). |
3 | 3 | */ |
4 | 4 | |
5 | 5 | /* |
6 | * Copyright (c) 2007-2014 knut st. osmundsen <bird-kBuild-spamx@anduin.net> | |
6 | * Copyright (c) 2007-2016 knut st. osmundsen <bird-kBuild-spamx@anduin.net> | |
7 | 7 | * |
8 | 8 | * This file is part of kBuild. |
9 | 9 | * |
32 | 32 | #include <errno.h> |
33 | 33 | #include <fcntl.h> |
34 | 34 | #if defined(_MSC_VER) |
35 | # include <ctype.h> | |
35 | 36 | # include <io.h> |
36 | 37 | # include <direct.h> |
37 | 38 | # include <process.h> |
48 | 49 | #endif |
49 | 50 | |
50 | 51 | |
52 | /********************************************************************************************************************************* | |
53 | * Global Variables * | |
54 | *********************************************************************************************************************************/ | |
55 | /** Number of times the '-v' switch was seen. */ | |
56 | static unsigned g_cVerbosity = 0; | |
57 | ||
58 | ||
51 | 59 | #if defined(_MSC_VER) |
60 | ||
61 | /** | |
62 | * Checks if this is an Watcom option where we must just pass thru the string | |
63 | * as-is. | |
64 | * | |
65 | * This is currnetly only used for -d (defining macros). | |
66 | * | |
67 | * @returns 1 if pass-thru, 0 if not. | |
68 | * @param pszArg The argument to consider. | |
69 | */ | |
70 | static int isWatcomPassThruOption(const char *pszArg) | |
71 | { | |
72 | char ch = *pszArg++; | |
73 | if (ch != '-' && ch != '/') | |
74 | return 0; | |
75 | ch = *pszArg++; | |
76 | switch (ch) | |
77 | { | |
78 | /* Example: -d+VAR="string-value" */ | |
79 | case 'd': | |
80 | if (ch == '+') | |
81 | ch = *pszArg++; | |
82 | if (!isalpha(ch) && ch != '_') | |
83 | return 0; | |
84 | return 1; | |
85 | ||
86 | default: | |
87 | return 0; | |
88 | } | |
89 | } | |
90 | ||
91 | ||
52 | 92 | /** |
53 | 93 | * Replaces arguments in need of quoting. |
54 | 94 | * |
63 | 103 | * @param fWatcomBrainDamage Set if we're catering for wcc, wcc386 or similar |
64 | 104 | * OpenWatcom tools. They seem to follow some |
65 | 105 | * ancient or home made quoting convention. |
106 | * @param pStdErr For verbose debug info. | |
66 | 107 | */ |
67 | static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage) | |
108 | static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage, FILE *pStdErr) | |
68 | 109 | { |
69 | 110 | int i; |
70 | 111 | for (i = 0; i < argc; i++) |
71 | 112 | { |
72 | const char *pszOrg = argv[i]; | |
113 | const char *pszOrgOrg = argv[i]; | |
114 | const char *pszOrg = pszOrgOrg; | |
73 | 115 | size_t cchOrg = strlen(pszOrg); |
74 | 116 | const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg); |
75 | 117 | const char *pszProblem = NULL; |
92 | 134 | char ch; |
93 | 135 | int fComplicated = pszQuotes || (cchOrg > 0 && pszOrg[cchOrg - 1] == '\\'); |
94 | 136 | size_t cchNew = fComplicated ? cchOrg * 2 + 2 : cchOrg + 2; |
95 | char *pszNew = (char *)malloc(cchNew + 1); | |
137 | char *pszNew = (char *)malloc(cchNew + 1 /*term*/ + 3 /*passthru hack*/); | |
96 | 138 | |
97 | 139 | argv[i] = pszNew; |
98 | 140 | |
99 | /* Watcom does not grok "-i=c:\program files\watcom\h", it thing | |
100 | it's a source specification. The quote must follow the equal. */ | |
141 | /* Watcom does not grok stuff like "-i=c:\program files\watcom\h", | |
142 | it think it's a source specification. In that case the quote | |
143 | must follow the equal sign. */ | |
101 | 144 | if (fWatcomBrainDamage) |
102 | 145 | { |
103 | 146 | size_t cchUnquoted = 0; |
105 | 148 | cchUnquoted = 1; |
106 | 149 | else if (pszOrg[0] == '-' || pszOrg[0] == '/') /* Switch quoting. */ |
107 | 150 | { |
108 | const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); | |
109 | if ( pszNeedQuoting == NULL | |
110 | || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes)) | |
111 | pszNeedQuoting = pszProblem ? pszProblem : pszQuotes; | |
151 | if (isWatcomPassThruOption(pszOrg)) | |
152 | cchUnquoted = strlen(pszOrg) + 1; | |
112 | 153 | else |
113 | pszNeedQuoting++; | |
114 | cchUnquoted = pszNeedQuoting - pszOrg; | |
154 | { | |
155 | const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); /* For -i=dir and similar. */ | |
156 | if ( pszNeedQuoting == NULL | |
157 | || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes)) | |
158 | pszNeedQuoting = pszProblem ? pszProblem : pszQuotes; | |
159 | else | |
160 | pszNeedQuoting++; | |
161 | cchUnquoted = pszNeedQuoting - pszOrg; | |
162 | } | |
115 | 163 | } |
116 | 164 | if (cchUnquoted) |
117 | 165 | { |
167 | 215 | *pszNew++ = '"'; |
168 | 216 | *pszNew = '\0'; |
169 | 217 | } |
218 | ||
219 | if (g_cVerbosity > 0) | |
220 | { | |
221 | if (argv[i] == pszOrgOrg) | |
222 | fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, pszOrgOrg); | |
223 | else | |
224 | { | |
225 | fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, argv[i]); | |
226 | fprintf(pStdErr, "kmk_redirect: debug:(orig[%i]=%s<eos>)\n", i, pszOrgOrg); | |
227 | } | |
228 | } | |
170 | 229 | } |
171 | 230 | |
172 | 231 | /*for (i = 0; i < argc; i++) fprintf(stderr, "argv[%u]=%s;;\n", i, argv[i]);*/ |
173 | 232 | } |
174 | #endif /* _MSC_VER */ | |
175 | ||
176 | ||
177 | #ifdef _MSC_VER | |
233 | ||
234 | ||
178 | 235 | /** Used by safeCloseFd. */ |
179 | 236 | static void __cdecl ignore_invalid_parameter(const wchar_t *a, const wchar_t *b, const wchar_t *c, unsigned d, uintptr_t e) |
180 | 237 | { |
181 | 238 | } |
182 | #endif | |
239 | ||
240 | #endif /* _MSC_VER */ | |
183 | 241 | |
184 | 242 | |
185 | 243 | /** |
217 | 275 | static int usage(FILE *pOut, const char *argv0) |
218 | 276 | { |
219 | 277 | fprintf(pOut, |
220 | "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] -- <program> [args]\n" | |
278 | "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] [-v] -- <program> [args]\n" | |
221 | 279 | " or: %s --help\n" |
222 | 280 | " or: %s --version\n" |
223 | 281 | "\n" |
240 | 298 | "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n" |
241 | 299 | "not following normal quoting conventions on Windows, OS/2, and DOS.\n" |
242 | 300 | "\n" |
301 | "The -v switch is for making the thing more verbose.\n" | |
302 | "\n" | |
243 | 303 | "This command was originally just a quick hack to avoid invoking the shell\n" |
244 | 304 | "on Windows (cygwin) where forking is very expensive and has exhibited\n" |
245 | 305 | "stability issues on SMP machines. It has since grown into something like\n" |
255 | 315 | int i; |
256 | 316 | #if defined(_MSC_VER) |
257 | 317 | intptr_t rc; |
318 | #else | |
319 | int j; | |
258 | 320 | #endif |
259 | 321 | FILE *pStdErr = stderr; |
260 | 322 | FILE *pStdOut = stdout; |
468 | 530 | } |
469 | 531 | |
470 | 532 | /* |
533 | * Verbose operation switch? | |
534 | */ | |
535 | if (*psz == 'v') | |
536 | { | |
537 | g_cVerbosity++; | |
538 | continue; | |
539 | } | |
540 | ||
541 | /* | |
471 | 542 | * Close the specified file descriptor (no stderr/out/in aliases). |
472 | 543 | */ |
473 | 544 | if (*psz == 'c') |
748 | 819 | } |
749 | 820 | |
750 | 821 | /* MSC is a PITA since it refuses to quote the arguments... */ |
751 | quoteArguments(argc - i, &argv[i], fWatcomBrainDamage); | |
822 | quoteArguments(argc - i, &argv[i], fWatcomBrainDamage, pStdErr); | |
752 | 823 | rc = _spawnvp(_P_WAIT, argv[i], &argv[i]); |
753 | 824 | if (rc == -1 && pStdErr) |
754 | 825 | { |
757 | 828 | } |
758 | 829 | return rc; |
759 | 830 | #else |
831 | if (g_cVerbosity > 0) | |
832 | for (j = i; j < argc; j++) | |
833 | fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", j - i, argv[j]); | |
760 | 834 | execvp(argv[i], &argv[i]); |
761 | 835 | fprintf(pStdErr, "%s: error: _execvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno)); |
762 | 836 | return 1; |