Codebase list kbuild / c0f9d32
Merge tag 'upstream/0.1.9998svn2780+dfsg' Upstream version 0.1.9998svn2780+dfsg Gianfranco Costamagna 9 years ago
58 changed file(s) with 3177 addition(s) and 375 deletion(s). Raw diff Collapse all Expand all
0 # $Id: footer-pass1.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: footer-pass1.kmk 2764 2015-01-28 18:51:46Z bird $
11 ## @file
22 # kBuild - Footer - Target lists - Pass 1.
33 #
106106 local insttype := both
107107 endif
108108 endif
109 ifn1of ($(insttype), none both stage)
110 $(error kBuild: Unknown value '$(insttype)' for '$(target)_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
111 endif
112109 $(target)_1_INSTTYPE := $(insttype)
113110
114 if1of ($(insttype), stage both)
115 local inst := $(strip $(firstdefined \
111 local inst := $(strip $(firstdefined \
116112 $(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
117113 $(target)_INST.$(bld_trg).$(bld_trg_arch) \
118114 $(target)_INST.$(bld_trg).$(bld_type) \
123119 $(target)_INST \
124120 definst \
125121 ,value))
126 local stage := $(strip $(firstdefined \
122 local stage := $(strip $(firstdefined \
127123 $(target)_STAGE.$(bld_trg).$(bld_trg_arch).$(bld_type) \
128124 $(target)_STAGE.$(bld_trg).$(bld_trg_arch) \
129125 $(target)_STAGE.$(bld_trg).$(bld_type) \
134130 $(target)_STAGE \
135131 inst \
136132 ,value))
133 if1of ($(insttype), stage both)
137134 $(target)_1_STAGE := $(stage)
138135 if "$(substr $(stage),-1,1)" == "/" # Multicast support requires addprefix/suffix.
139136 $(target)_1_STAGE_TARGET := $(addprefix $(PATH_STAGE)/,$(addsuffix $(notdir $(out)),$(stage)))
142139 else
143140 $(target)_1_STAGE_TARGET := $(addprefix $(PATH_STAGE)/,$(stage))
144141 endif
145 else
142 else if1of ($(insttype), none)
146143 $(target)_1_STAGE :=
147144 $(target)_1_STAGE_TARGET :=
145 else
146 $(error kBuild: Unknown value '$(insttype)' for '$(target)_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
148147 endif
149148 INSTARGET_$(target) := $($(target)_1_STAGE_TARGET)
150149
173172 $($(target)_DEBUG_INSTTYPE.$(bld_type)) \
174173 $($(target)_DEBUG_INSTTYPE) \
175174 $(insttype) )
176 ifn1of ($(debug_insttype), none both stage)
177 $(error kBuild: Unknown value '$(debug_insttype)' for '$(target)_DEBUG_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
178 endif
179175 $(target)_1_DEBUG_INSTTYPE := $(debug_insttype)
180176
181177 if1of ($(debug_insttype), stage both)
204200 ifndef $(target)_1_DEBUG_STAGE
205201 $(target)_1_DEBUG_STAGE := ./
206202 endif
207 else
203 else if1of ($(debug_insttype), none)
208204 $(target)_1_DEBUG_STAGE :=
205 else
206 $(error kBuild: Unknown value '$(debug_insttype)' for '$(target)_DEBUG_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
209207 endif
210208
211209 if1of ($(debug_insttype), both)
243241 ifndef $(target)_INST
244242 $(target)_INSTTYPE := none
245243 endif
246 $(evalval def_pass1_link_common)
244 $(evalvalctx def_pass1_link_common)
247245 endef
248246
249247 EXT := EXE
252250 tool_prefix := LD
253251 bld_trg_base_var := PLATFORM
254252 $(foreach target, $(_ALL_BLDPROGS), \
255 $(evalval def_pass1_bldprog))
253 $(evalvalctx def_pass1_bldprog))
256254
257255
258256 #
264262 tool_prefix := AR
265263 bld_trg_base_var := TARGET
266264 $(foreach target, $(_ALL_LIBRARIES), \
267 $(evalval def_pass1_link_common))
265 $(evalvalctx def_pass1_link_common))
268266
269267
270268 #
276274 tool_prefix := LD
277275 bld_trg_base_var := TARGET
278276 $(foreach target, $(_ALL_DLLS), \
279 $(evalval def_pass1_link_common))
277 $(evalvalctx def_pass1_link_common))
280278
281279
282280 #
292290 tool_prefix := AR
293291 bld_trg_base_var := TARGET
294292 $(foreach target, $(_ALL_IMPORT_LIBS), \
295 $(evalval def_pass1_link_common))
293 $(evalvalctx def_pass1_link_common))
296294 else
297295 EXT := DLL
298296 EXTPRE :=
300298 tool_prefix := LD
301299 bld_trg_base_var := TARGET
302300 $(foreach target, $(_ALL_IMPORT_LIBS), \
303 $(evalval def_pass1_link_common))
301 $(evalvalctx def_pass1_link_common))
304302 endif
305303
306304
313311 tool_prefix := LD
314312 bld_trg_base_var := TARGET
315313 $(foreach target, $(_ALL_PROGRAMS), \
316 $(evalval def_pass1_link_common))
314 $(evalvalctx def_pass1_link_common))
317315
318316
319317 #
325323 tool_prefix := LD
326324 bld_trg_base_var := TARGET
327325 $(foreach target, $(_ALL_SYSMODS), \
328 $(evalval def_pass1_link_common))
326 $(evalvalctx def_pass1_link_common))
329327
330328
331329 #
337335 tool_prefix := LD
338336 bld_trg_base_var := TARGET
339337 $(foreach target, $(_ALL_MISCBINS), \
340 $(evalval def_pass1_link_common))
338 $(evalvalctx def_pass1_link_common))
341339
342340
343341 #
451449 $(eval-opt-var def_pass1_install)
452450
453451 $(foreach target, $(_ALL_INSTALLS), \
454 $(evalval def_pass1_install))
452 $(evalvalctx def_pass1_install))
455453
456454 ifdef KBUILD_PROFILE_SELF
457455 $(evalcall def_profile_self, done pass 1)
0 # $Id: footer-pass2-compiling-targets.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: footer-pass2-compiling-targets.kmk 2762 2015-01-28 18:17:54Z bird $
11 ## @file
22 # kBuild - Footer - Target lists - Pass 2 - Compiling Targets.
33 #
269269 $($(target)_SOURCES.$(bld_trg_arch))\
270270 $($(target)_SOURCES.$(bld_trg_cpu))\
271271 $($(target)_SOURCES.$(bld_type))\
272 ,$(evalval def_src_handler_one) )
272 ,$(evalvalctx def_src_handler_one) )
273273
274274 $(foreach source,\
275275 $($(target)_GEN_SOURCES_)\
280280 $($(target)_GEN_SOURCES_.$(bld_trg_arch))\
281281 $($(target)_GEN_SOURCES_.$(bld_trg_cpu))\
282282 $($(target)_GEN_SOURCES_.$(bld_type))\
283 ,$(evalval def_src_handler_one) )
283 ,$(evalvalctx def_src_handler_one) )
284284 endef # def_target_sources
285285 $(eval-opt-var def_target_sources)
286286
405405 local debug_inst_path := $(PATH_INS)
406406 local debug_install_cmd := $(INSTALL)
407407 local debug_var := INSTALL
408 $(foreach debug_inst, $($(target)_1_DEBUG_INST), $(evalval def_target_install_only_debug))
408 $(foreach debug_inst, $($(target)_1_DEBUG_INST), $(evalvalctx def_target_install_only_debug))
409409 endif
410410
411411 local debug_inst_path := $(PATH_STAGE)
412412 local debug_install_cmd := $(INSTALL_STAGING)
413413 local debug_var := STAGE
414414 if1of ($($(target)_1_DEBUG_INSTTYPE), stage both)
415 $(foreach debug_inst, $($(target)_1_DEBUG_STAGE), $(evalval def_target_install_only_debug))
415 $(foreach debug_inst, $($(target)_1_DEBUG_STAGE), $(evalvalctx def_target_install_only_debug))
416416 endif
417417 if1of ($($(target)_1_INSTTYPE), stage both)
418418 ifndef debug_nostage
419 $(foreach debug_inst,$($(target)_1_STAGE), $(evalval def_target_install_only_debug))
419 $(foreach debug_inst,$($(target)_1_STAGE), $(evalvalctx def_target_install_only_debug))
420420 endif
421421 endif
422422
487487 $($(target)_USES.$(bld_trg))\
488488 $($(target)_USES.$(bld_type))\
489489 $($(target)_USES)
490 $(foreach unit,$(units),$(evalval def_unit_$(unit)_target_pre))
490 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
491491
492492 # source -> object
493493 $(evalval def_target_sources)
627627 typevar := _LIBS
628628 tool_do := LINK_LIBRARY
629629 mode := 0644
630 $(foreach target, $(_ALL_LIBRARIES), $(evalval def_lib))
630 $(foreach target, $(_ALL_LIBRARIES), $(evalvalctx def_lib))
631631
632632 ifdef KBUILD_PROFILE_SELF
633633 $(evalcall def_profile_self, done library targets)
690690 $($(target)_USES.$(bld_trg))\
691691 $($(target)_USES.$(bld_type))\
692692 $($(target)_USES)
693 $(foreach unit,$(units),$(evalval def_unit_$(unit)_target_pre))
693 $(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
694694
695695 # source -> object
696696 $(evalval def_target_sources)
966966 typevar := _BLDPROGS
967967 mode := 0755
968968 bld_trg_base_var := PLATFORM
969 $(foreach target, $(_ALL_BLDPROGS), $(evalval def_link_common))
969 $(foreach target, $(_ALL_BLDPROGS), $(evalvalctx def_link_common))
970970
971971 ifdef KBUILD_PROFILE_SELF
972972 $(evalcall def_profile_self, done build program targets)
984984 typevar := _DLLS
985985 mode := 0644
986986 bld_trg_base_var := TARGET
987 $(foreach target, $(_ALL_DLLS), $(evalval def_link_common))
987 $(foreach target, $(_ALL_DLLS), $(evalvalctx def_link_common))
988988
989989 ifdef KBUILD_PROFILE_SELF
990990 $(evalcall def_profile_self, done dll targets)
10041004 ifeq ($(filter-out nt os2 win win64 win32,$(KBUILD_TARGET)),)
10051005 EXT := LIB
10061006 tool_do := LINK_LIBRARY
1007 $(foreach target, $(_ALL_IMPORT_LIBS), $(evalval def_lib))
1007 $(foreach target, $(_ALL_IMPORT_LIBS), $(evalvalctx def_lib))
10081008 else
10091009 EXT := DLL
10101010 tool_do := LINK_DLL
1011 $(foreach target, $(_ALL_IMPORT_LIBS), $(evalval def_link_common))
1011 $(foreach target, $(_ALL_IMPORT_LIBS), $(evalvalctx def_link_common))
10121012 endif
10131013
10141014 ifdef KBUILD_PROFILE_SELF
10271027 typevar := _PROGRAMS
10281028 mode := 0755
10291029 bld_trg_base_var := TARGET
1030 $(foreach target, $(_ALL_PROGRAMS), $(evalval def_link_common))
1030 $(foreach target, $(_ALL_PROGRAMS), $(evalvalctx def_link_common))
10311031
10321032 ifdef KBUILD_PROFILE_SELF
10331033 $(evalcall def_profile_self, done program targets)
10451045 typevar := _SYSMODS
10461046 mode := 0644
10471047 bld_trg_base_var := TARGET
1048 $(foreach target, $(_ALL_SYSMODS), $(evalval def_link_common))
1048 $(foreach target, $(_ALL_SYSMODS), $(evalvalctx def_link_common))
10491049
10501050 ifdef KBUILD_PROFILE_SELF
10511051 $(evalcall def_profile_self, done sysmod targets)
10631063 typevar := _MISCBINS
10641064 mode := 0644
10651065 bld_trg_base_var := TARGET
1066 $(foreach target, $(_ALL_MISCBINS), $(evalval def_link_common))
1066 $(foreach target, $(_ALL_MISCBINS), $(evalvalctx def_link_common))
10671067
10681068 ifdef KBUILD_PROFILE_SELF
10691069 $(evalcall def_profile_self, done misc binary targets)
0 # $Id: header.kmk 2729 2014-03-16 00:21:49Z bird $
0 # $Id: header.kmk 2763 2015-01-28 18:25:31Z bird $
11 ## @file
22 # kBuild - File included at top of a makefile.
33 #
44
55 #
6 # Copyright (c) 2004-2014 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
6 # Copyright (c) 2004-2015 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
77 #
88 # This file is part of kBuild.
99 #
7878 # The revision in which this file was last modified.
7979 # This can be useful when using development versions of kBuild.
8080 #
81 KMK_REVISION := $(patsubst %:,, $Rev: 2729 $ )
81 KMK_REVISION := $(patsubst %:,, $Rev: 2763 $ )
8282
8383
8484 #
515515 # Deprecated legacy names.
516516 PATH_DEVTOOLS ?= $(KBUILD_DEVTOOLS)
517517 PATH_DEVTOOLS_TRG ?= $(KBUILD_DEVTOOLS_TRG)
518 PATH_DEVTOOLS_BLD ?= $(KBUILD_DEVTOOLS_TRG)
518519 PATH_DEVTOOLS_TRG_ALT ?= $(KBUILD_DEVTOOLS_TRG_ALT)
519520 PATH_DEVTOOLS_HST ?= $(KBUILD_DEVTOOLS_HST)
520521 PATH_DEVTOOLS_HST_ALT ?= $(KBUILD_DEVTOOLS_HST_ALT)
15641565
15651566
15661567 #
1568 # An internal define used by subheader.kmk and subfooter.kmk.
1569 # We keep them here to avoid redefining them for each sub-makefile.
1570 #
1571 define def_subfooter_header_target_pass
1572 ifndef $(target)_PATH
1573 ifndef $(target)_DEFPATH
1574 $(target)_DEFPATH := $(PATH_SUB_CURRENT)
1575 endif
1576 $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH), $(target)_DEFPATH)
1577 else ifndef $(target)_DEFPATH
1578 $(target)_DEFPATH := $($(target)_PATH)
1579 endif
1580 ifndef $(target)_MAKEFILE
1581 $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
1582 endif
1583 ifndef $(target)_0_OUTDIR
1584 $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
1585 $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR), $(target)_0_OUTDIR)
1586 endif
1587 endef
1588
1589
1590 #
15671591 # Validate any KBUILD_BLD_TYPES additions and finally the KBUILD_TYPE.
15681592 #
15691593 if1of ($(KBUILD_BLD_TYPES), $(KBUILD_OSES))
0 # $Id: subfooter.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: subfooter.kmk 2763 2015-01-28 18:25:31Z bird $
11 ## @file
22 # kBuild - File included at bottom of a makefile or sub-makefile.
33 #
44
55 #
6 # Copyright (c) 2006-2014 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
6 # Copyright (c) 2006-2015 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
77 #
88 # This file is part of kBuild.
99 #
4040 #
4141 # Set the default path for all new targets.
4242 #
43 define def_subheader
44 ifndef $(target)_PATH
45 ifndef $(target)_DEFPATH
46 $(target)_DEFPATH := $(PATH_SUB_CURRENT)
47 endif
48 $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH),$(target)_DEFPATH)
49 else ifndef $(target)_DEFPATH
50 $(target)_DEFPATH := $($(target)_PATH)
51 endif
52 ifndef $(target)_MAKEFILE
53 $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
54 endif
55 ifndef $(target)_0_OUTDIR
56 $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
57 $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR),$(target)_0_OUTDIR)
58 endif
59 endef
60
43 ## @todo Wish there was an easy way of only enumerating only new targets...
6144 $(foreach target,\
6245 $(ALL_TARGETS) \
6346 $(FETCHES) $(FETCHES.$(KBUILD_TARGET)) $(FETCHES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_CPU)) $(FETCHES.$(KBUILD_TYPE)) \
7154 $(MISCBINS) $(MISCBINS.$(KBUILD_TARGET)) $(MISCBINS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_CPU)) $(MISCBINS.$(KBUILD_TYPE)) \
7255 $(INSTALLS) $(INSTALLS.$(KBUILD_TARGET)) $(INSTALLS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_CPU)) $(INSTALLS.$(KBUILD_TYPE)) \
7356 $(OTHERS) $(OTHERS.$(KBUILD_TARGET)) $(OTHERS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_CPU)) $(OTHERS.$(KBUILD_TYPE)) \
74 ,$(evalval def_subheader))
75
57 ,$(if-expr defined($(target)_0_OUTDIR),,$(evalval def_subfooter_header_target_pass)))
7658
7759
7860 ifneq ($(_SUB_MAKEFILE_STACK),)
0 # $Id: subheader.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: subheader.kmk 2763 2015-01-28 18:25:31Z bird $
11 ## @file
22 # kBuild - File included at top of a makefile or sub-makefile.
33 #
44
55 #
6 # Copyright (c) 2006-2014 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
6 # Copyright (c) 2006-2015 knut st. osmundsen <bird-kBuild-spam-xiv@anduin.net>
77 #
88 # This file is part of kBuild.
99 #
5151 #
5252 # Set the default path and makefile for all new targets.
5353 #
54 define def_subfooter
55 ifndef $(target)_PATH
56 ifndef $(target)_DEFPATH
57 $(target)_DEFPATH := $(PATH_SUB_CURRENT)
58 endif
59 $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH), $(target)_DEFPATH)
60 else ifndef $(target)_DEFPATH
61 $(target)_DEFPATH := $($(target)_PATH)
62 endif
63 ifndef $(target)_MAKEFILE
64 $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
65 endif
66 ifndef $(target)_0_OUTDIR
67 $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
68 $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR), $(target)_0_OUTDIR)
69 endif
70 endef
71
54 ## @todo Wish there was an easy way of only enumerating only new targets...
7255 $(foreach target,\
7356 $(ALL_TARGETS) \
7457 $(FETCHES) $(FETCHES.$(KBUILD_TARGET)) $(FETCHES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_CPU)) $(FETCHES.$(KBUILD_TYPE)) \
8265 $(MISCBINS) $(MISCBINS.$(KBUILD_TARGET)) $(MISCBINS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_CPU)) $(MISCBINS.$(KBUILD_TYPE)) \
8366 $(INSTALLS) $(INSTALLS.$(KBUILD_TARGET)) $(INSTALLS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_CPU)) $(INSTALLS.$(KBUILD_TYPE)) \
8467 $(OTHERS) $(OTHERS.$(KBUILD_TARGET)) $(OTHERS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_CPU)) $(OTHERS.$(KBUILD_TYPE)) \
85 ,$(evalval def_subfooter))
68 ,$(if-expr defined($(target)_0_OUTDIR),,$(evalval def_subfooter_header_target_pass)))
8669
8770
8871 #
0 # $Id: ALP.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: ALP.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - ALP or later.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef PATH_TOOL_ALP
37 PATH_TOOL_ALP := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/alp/v*.*))
37 PATH_TOOL_ALP := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/alp/v*.*))
3838 ifneq ($(PATH_TOOL_ALP),)
3939 PATH_TOOL_ALP := $(call lastword,$(PATH_TOOL_ALP))
4040 endif
0 # $Id: GCC3.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GCC3.kmk 2775 2015-02-03 20:00:15Z bird $
11 ## @file
22 # kBuild Tool Config - Generic GCC v3.2.x or later Using The System GCC and Binutils.
33 #
236236 $(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
237237 $(QUIET)$(APPEND) -n $(out).ar-script \
238238 $(foreach o,$(objs), 'ADDMOD $(o)') \
239 $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
240 $(if $(filter %.def %.imp,$(othersrc))\
241 ,$(TOOL_GCC3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
239 $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
240 $(if $(filter %.def %.imp %.dll,$(othersrc))\
241 ,$(TOOL_GCC3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
242242 $(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
243243 $(QUIET)$(APPEND) $(out).ar-script 'SAVE'
244244 $(QUIET)$(APPEND) $(out).ar-script 'END'
273273 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
274274 $(call TOOL_GCC3_LD_MAP,$(outbase).map)
275275 ifeq ($(ld_debug),split)
276 $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
277 $(CHMOD) a-x $(outbase).debug
278 $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
276 $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
277 $(QUIET)$(CHMOD) a-x $(outbase).debug
278 $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
279279 endif
280280 endef
281281
309309 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
310310 $(call TOOL_GCC3_LD_MAP,$(outbase).map)
311311 ifeq ($(ld_debug),split)
312 $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
313 $(CHMOD) a-x $(outbase).debug
314 $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
312 $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
313 $(QUIET)$(CHMOD) a-x $(outbase).debug
314 $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
315315 endif
316316 endef
317317
343343 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
344344 $(call TOOL_GCC3_LD_SYSMOD_MAP,$(outbase).map)
345345 ifeq ($(ld_debug),split)
346 $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
347 $(CHMOD) a-x $(outbase).debug
348 $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
346 $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
347 $(QUIET)$(CHMOD) a-x $(outbase).debug
348 $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
349349 endif
350350 endef
351351
0 # $Id: GCC32.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GCC32.kmk 2775 2015-02-03 20:00:15Z bird $
11 ## @file
22 # kBuild Tool Config - Generic 32-bit GCC v3.2.x or later Using The System GCC.
33 #
231231 $(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
232232 $(QUIET)$(APPEND) -n $(out).ar-script \
233233 $(foreach o,$(objs), 'ADDMOD $(o)') \
234 $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
235 $(if $(filter %.def %.imp,$(othersrc))\
236 ,$(TOOL_GCC32_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
234 $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
235 $(if $(filter %.def %.imp %.dll,$(othersrc))\
236 ,$(TOOL_GCC32_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
237237 $(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
238238 $(QUIET)$(APPEND) $(out).ar-script 'SAVE'
239239 $(QUIET)$(APPEND) $(out).ar-script 'END'
267267 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
268268 $(call TOOL_GCC32_LD_MAP,$(outbase).map)
269269 ifeq ($(ld_debug),split)
270 $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
271 $(CHMOD) a-x $(outbase).debug
272 $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
270 $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
271 $(QUIET)$(CHMOD) a-x $(outbase).debug
272 $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
273273 endif
274274 endef
275275
302302 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
303303 $(call TOOL_GCC32_LD_MAP,$(outbase).map)
304304 ifeq ($(ld_debug),split)
305 $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
306 $(CHMOD) a-x $(outbase).debug
307 $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
305 $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
306 $(QUIET)$(CHMOD) a-x $(outbase).debug
307 $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
308308 endif
309309 endef
310310
336336 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
337337 $(call TOOL_GCC32_LD_SYSMOD_MAP,$(outbase).map)
338338 ifeq ($(ld_debug),split)
339 $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
340 $(CHMOD) a-x $(outbase).debug
341 $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
339 $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
340 $(QUIET)$(CHMOD) a-x $(outbase).debug
341 $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
342342 endif
343343 endef
344344
0 # $Id: GCC3OMF.kmk 2545 2011-09-13 19:09:05Z bird $
0 # $Id: GCC3OMF.kmk 2776 2015-02-03 20:38:12Z bird $
11 ## @file
22 # kBuild Tool Config - GCC v3 targeting OS/2 OMF.
33 #
4848 TOOL_GCC3OMF_LDFLAGS.sysmod ?= -nostdlib
4949 TOOL_GCC3OMF_LD_MAP ?= -Zmap=$(1)
5050 TOOL_GCC3OMF_LD_SYSMOD_MAP ?= -Zmap=$(1)
51 TOOL_GCC3OMF_RC = rc$(HOSTSUFF_EXE)
5152
5253 ifdef SLKRUNS
5354 TOOL_GCC3OMF_CC += -fmessage-length=0
7677 TOOL_GCC3OMF_ASFLAGS.debug ?= -g
7778 TOOL_GCC3OMF_ASFLAGS.profile ?= -g
7879 TOOL_GCC3OMF_ASOBJSUFF ?= .obj
80
81 TOOL_GCC3OMF_RCOBJSUFF ?= .res
82 TOOL_GCC3OMF_RCFLAGS ?= -n
83 TOOL_GCC3OMF_RCINCS ?= $(shell $(TOOL_GCC3OMF_CXX) -E -x c++ - 2>&1 < /dev/null \
84 | $(SED_EXT) -e "/search starts here/,/[Ee]nd of search list/!d" -e "/^ /!d")
7985
8086 TOOL_GCC3OMF_ARFLAGS ?= cr
8187 TOOL_GCC3OMF_ARLIBSUFF ?= .lib
201207 endef
202208
203209
210 ## Compile resource source.
211 # @param $(target) Normalized main target name.
212 # @param $(source) Source filename (relative).
213 # @param $(obj) Object file name. This shall be (re)created by the compilation.
214 # @param $(dep) Dependcy file. This shall be (re)created by the compilation.
215 # @param $(flags) Flags.
216 # @param $(defs) Definitions. No -D or something.
217 # @param $(incs) Includes. No -I or something.
218 # @param $(dirdep) Directory creation dependency.
219 # @param $(deps) Other dependencies.
220 #
221 # @param $(outbase) Output basename (full). Use this for list files and such.
222 # @param $(objsuff) Object suffix.
223 TOOL_GCC3OMF_COMPILE_RC_OUTPUT =
224 TOOL_GCC3OMF_COMPILE_RC_DEPEND =
225 TOOL_GCC3OMF_COMPILE_RC_DEPORD =
226 define TOOL_GCC3OMF_COMPILE_RC_CMDS
227 $(QUIET)$(REDIRECT) -E 'INCLUDE=' -- $(TOOL_GCC3OMF_RC) -r \
228 $(flags) $(addprefix -i, $(subst /,\\,$(subst /@unixroot,$(UNIXROOT),$(incs)))) $(addprefix -d, $(defs))\
229 $(subst /,\\,$(abspath $(source))) \
230 $(obj)
231 endef
204232 ## Link library
205233 # @param $(target) Normalized main target name.
206234 # @param $(out) Library name.
215243 TOOL_GCC3OMF_LINK_LIBRARY_DEPEND = $(othersrc)
216244 TOOL_GCC3OMF_LINK_LIBRARY_DEPORD =
217245 define TOOL_GCC3OMF_LINK_LIBRARY_CMDS
218 $(if $(filter %.def %.imp,$(othersrc))\
219 ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp,$(othersrc))\
246 $(if $(filter %.def %.imp %.dll,$(othersrc))\
247 ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp %.dll,$(othersrc))\
220248 $(NL)$(TAB)$(QUIET)$(QUIET)$(TOOL_GCC3OMF_AR_IMP) -o $(out) @$(outbase).rsp\
221249 $(NL)$(TAB)$(QUIET)$(RM) -f $(outbase).rsp)
222 $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp,$(othersrc))
223 $(TOOL_GCC3OMF_AR) @$(outbase).rsp
250 $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp %.dll,$(othersrc))
251 $(QUIET)$(TOOL_GCC3OMF_AR) @$(outbase).rsp
224252 endef
225253
226254
281309 $(othersrc)\
282310 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
283311 -Zmap=$(outbase).map
284 $(TOOL_GCC3OMF_LD) @$(outbase).rsp
312 $(QUIET)$(TOOL_GCC3OMF_LD) @$(outbase).rsp
285313 endef
286314
287315
0 # $Id: GCC64.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GCC64.kmk 2774 2015-02-03 19:56:24Z bird $
11 ## @file
22 # kBuild Tool Config - Generic 64-bit GCC v3.2.x or later Using The System GCC.
33 #
262262 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
263263 $(call TOOL_GCC64_LD_MAP,$(outbase).map)
264264 ifeq ($(ld_debug),split)
265 $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
266 $(CHMOD) a-x $(outbase).debug
267 $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
265 $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
266 $(QUIET)$(CHMOD) a-x $(outbase).debug
267 $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
268268 endif
269269 endef
270270
296296 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
297297 $(call TOOL_GCC64_LD_MAP,$(outbase).map)
298298 ifeq ($(ld_debug),split)
299 $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
300 $(CHMOD) a-x $(outbase).debug
301 $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
299 $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
300 $(QUIET)$(CHMOD) a-x $(outbase).debug
301 $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
302302 endif
303303 endef
304304
328328 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
329329 $(call TOOL_GCC64_LD_SYSMOD_MAP,$(outbase).map)
330330 ifeq ($(ld_debug),split)
331 $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
332 $(CHMOD) a-x $(outbase).debug
333 $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
331 $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
332 $(QUIET)$(CHMOD) a-x $(outbase).debug
333 $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
334334 endif
335335 endef
336336
0 # $Id: GXX3.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GXX3.kmk 2775 2015-02-03 20:00:15Z bird $
11 ## @file
22 # kBuild Tool Config - Generic GCC v3.2.x using the system GCC and Binutils, for building C++ code.
33 #
236236 $(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
237237 $(QUIET)$(APPEND) -n $(out).ar-script \
238238 $(foreach o,$(objs), 'ADDMOD $(o)') \
239 $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
240 $(if $(filter %.def %.imp,$(othersrc))\
241 ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
239 $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
240 $(if $(filter %.def %.imp %.dll,$(othersrc))\
241 ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
242242 $(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
243243 $(QUIET)$(APPEND) $(out).ar-script 'SAVE'
244244 $(QUIET)$(APPEND) $(out).ar-script 'END'
273273 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
274274 $(call TOOL_GXX3_LD_MAP,$(outbase).map)
275275 ifeq ($(ld_debug),split)
276 $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
277 $(CHMOD) a-x $(outbase).debug
278 $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
276 $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
277 $(QUIET)$(CHMOD) a-x $(outbase).debug
278 $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
279279 endif
280280 endef
281281
309309 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
310310 $(call TOOL_GXX3_LD_MAP,$(outbase).map)
311311 ifeq ($(ld_debug),split)
312 $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
313 $(CHMOD) a-x $(outbase).debug
314 $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
312 $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
313 $(QUIET)$(CHMOD) a-x $(outbase).debug
314 $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
315315 endif
316316 endef
317317
343343 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
344344 $(call TOOL_GXX3_LD_SYSMOD_MAP,$(outbase).map)
345345 ifeq ($(ld_debug),split)
346 $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
347 $(CHMOD) a-x $(outbase).debug
348 $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
346 $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
347 $(QUIET)$(CHMOD) a-x $(outbase).debug
348 $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
349349 endif
350350 endef
351351
0 # $Id: GXX32.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GXX32.kmk 2775 2015-02-03 20:00:15Z bird $
11 ## @file
22 # kBuild Tool Config - Generic 32-bit GCC v3.2.x or later using the system GCC, for building C++ code.
33 #
230230 $(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
231231 $(QUIET)$(APPEND) -n $(out).ar-script \
232232 $(foreach o,$(objs), 'ADDMOD $(o)') \
233 $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
234 $(if $(filter %.def %.imp,$(othersrc))\
235 ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
233 $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
234 $(if $(filter %.def %.imp %.dll,$(othersrc))\
235 ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
236236 $(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
237237 $(QUIET)$(APPEND) $(out).ar-script 'SAVE'
238238 $(QUIET)$(APPEND) $(out).ar-script 'END'
266266 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
267267 $(call TOOL_GXX32_LD_MAP,$(outbase).map)
268268 ifeq ($(ld_debug),split)
269 $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
270 $(CHMOD) a-x $(outbase).debug
271 $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
269 $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
270 $(QUIET)$(CHMOD) a-x $(outbase).debug
271 $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
272272 endif
273273 endef
274274
301301 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
302302 $(call TOOL_GXX32_LD_MAP,$(outbase).map)
303303 ifeq ($(ld_debug),split)
304 $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
305 $(CHMOD) a-x $(outbase).debug
306 $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
304 $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
305 $(QUIET)$(CHMOD) a-x $(outbase).debug
306 $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
307307 endif
308308 endef
309309
335335 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
336336 $(call TOOL_GXX32_LD_SYSMOD_MAP,$(outbase).map)
337337 ifeq ($(ld_debug),split)
338 $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
339 $(CHMOD) a-x $(outbase).debug
340 $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
338 $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
339 $(QUIET)$(CHMOD) a-x $(outbase).debug
340 $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
341341 endif
342342 endef
343343
0 # $Id: GXX3OMF.kmk 2545 2011-09-13 19:09:05Z bird $
0 # $Id: GXX3OMF.kmk 2776 2015-02-03 20:38:12Z bird $
11 ## @file
22 # kBuild Tool Config - GCC v3 targeting OS/2 OMF, for building C++ code.
33 #
4848 TOOL_GXX3OMF_LDFLAGS.sysmod ?= -nostdlib
4949 TOOL_GXX3OMF_LD_MAP ?= -Zmap=$(1)
5050 TOOL_GXX3OMF_LD_SYSMOD_MAP ?= -Zmap=$(1)
51 TOOL_GXX3OMF_RC = rc$(HOSTSUFF_EXE)
5152
5253 ifdef SLKRUNS
5354 TOOL_GXX3OMF_CC += -fmessage-length=0
7677 TOOL_GXX3OMF_ASFLAGS.debug ?= -g
7778 TOOL_GXX3OMF_ASFLAGS.profile ?= -g
7879 TOOL_GXX3OMF_ASOBJSUFF ?= .obj
80
81 TOOL_GXX3OMF_RCOBJSUFF ?= .res
82 TOOL_GXX3OMF_RCFLAGS ?= -n
83 TOOL_GXX3OMF_RCINCS ?= $(shell $(TOOL_GXX3OMF_CXX) -E -x c++ - 2>&1 < /dev/null \
84 | $(SED_EXT) -e "/search starts here/,/[Ee]nd of search list/!d" -e "/^ /!d")
7985
8086 TOOL_GXX3OMF_ARFLAGS ?= cr
8187 TOOL_GXX3OMF_ARLIBSUFF ?= .lib
201207 endef
202208
203209
210 ## Compile resource source.
211 # @param $(target) Normalized main target name.
212 # @param $(source) Source filename (relative).
213 # @param $(obj) Object file name. This shall be (re)created by the compilation.
214 # @param $(dep) Dependcy file. This shall be (re)created by the compilation.
215 # @param $(flags) Flags.
216 # @param $(defs) Definitions. No -D or something.
217 # @param $(incs) Includes. No -I or something.
218 # @param $(dirdep) Directory creation dependency.
219 # @param $(deps) Other dependencies.
220 #
221 # @param $(outbase) Output basename (full). Use this for list files and such.
222 # @param $(objsuff) Object suffix.
223 TOOL_GXX3OMF_COMPILE_RC_OUTPUT =
224 TOOL_GXX3OMF_COMPILE_RC_DEPEND =
225 TOOL_GXX3OMF_COMPILE_RC_DEPORD =
226 define TOOL_GXX3OMF_COMPILE_RC_CMDS
227 $(QUIET)$(REDIRECT) -E 'INCLUDE=' -- $(TOOL_GXX3OMF_RC) -r \
228 $(flags) $(addprefix -i, $(subst /,\\,$(subst /@unixroot,$(UNIXROOT),$(incs)))) $(addprefix -d, $(defs))\
229 $(subst /,\\,$(abspath $(source))) \
230 $(obj)
231 endef
232
233
204234 ## Link library
205235 # @param $(target) Normalized main target name.
206236 # @param $(out) Library name.
215245 TOOL_GXX3OMF_LINK_LIBRARY_DEPEND = $(othersrc)
216246 TOOL_GXX3OMF_LINK_LIBRARY_DEPORD =
217247 define TOOL_GXX3OMF_LINK_LIBRARY_CMDS
218 $(if $(filter %.def %.imp,$(othersrc))\
219 ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp,$(othersrc))\
248 $(if $(filter %.def %.imp %.dll,$(othersrc))\
249 ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp %.dll,$(othersrc))\
220250 $(NL)$(TAB)$(QUIET)$(QUIET)$(TOOL_GXX3OMF_AR_IMP) -o $(out) @$(outbase).rsp\
221251 $(NL)$(TAB)$(QUIET)$(RM) -f $(outbase).rsp)
222 $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp,$(othersrc))
223 $(TOOL_GXX3OMF_AR) @$(outbase).rsp
252 $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp %.dll,$(othersrc))
253 $(QUIET)$(TOOL_GXX3OMF_AR) @$(outbase).rsp
224254 endef
225255
226256
281311 $(othersrc)\
282312 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
283313 -Zmap=$(outbase).map
284 $(TOOL_GXX3OMF_LD) @$(outbase).rsp
314 $(QUIET)$(TOOL_GXX3OMF_LD) @$(outbase).rsp
285315 endef
286316
287317
0 # $Id: GXX64.kmk 2541 2011-08-03 09:51:30Z bird $
0 # $Id: GXX64.kmk 2774 2015-02-03 19:56:24Z bird $
11 ## @file
22 # kBuild Tool Config - Generic 64-bit GCC v3.2.x or later using the system GCC, for building C++ code.
33 #
262262 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
263263 $(call TOOL_GXX64_LD_MAP,$(outbase).map)
264264 ifeq ($(ld_debug),split)
265 $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
266 $(CHMOD) a-x $(outbase).debug
267 $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
265 $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
266 $(QUIET)$(CHMOD) a-x $(outbase).debug
267 $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
268268 endif
269269 endef
270270
296296 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
297297 $(call TOOL_GXX64_LD_MAP,$(outbase).map)
298298 ifeq ($(ld_debug),split)
299 $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
300 $(CHMOD) a-x $(outbase).debug
301 $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
299 $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
300 $(QUIET)$(CHMOD) a-x $(outbase).debug
301 $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
302302 endif
303303 endef
304304
328328 $(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
329329 $(call TOOL_GXX64_LD_SYSMOD_MAP,$(outbase).map)
330330 ifeq ($(ld_debug),split)
331 $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
332 $(CHMOD) a-x $(outbase).debug
333 $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
331 $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
332 $(QUIET)$(CHMOD) a-x $(outbase).debug
333 $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
334334 endif
335335 endef
336336
0 # $Id: JWASM.kmk 2730 2014-03-16 20:30:59Z bird $
0 # $Id: JWASM.kmk 2774 2015-02-03 19:56:24Z bird $
11 ## @file
22 # kBuild Tool Config - JWasm
33 #
3535
3636 # Tool Specific Properties
3737 ifndef TOOL_JWASM_AS
38 TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
38 TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
3939 ifeq ($(TOOL_JWASM_AS),)
4040 TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
4141 endif
5151 TOOL_JWASM_COMPILE_AS_DEPEND =
5252 TOOL_JWASM_COMPILE_AS_DEPORD =
5353 define TOOL_JWASM_COMPILE_AS_CMDS
54 $(TOOL_JWASM_AS) -c \
54 $(QUIET)$(TOOL_JWASM_AS) -c \
5555 $(strip $(flags)) \
5656 $(addprefix -D,$(defs)) \
5757 $(addprefix -I,$(incs)) \
0 # $Id: MASM510.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MASM510.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MASM v5.10
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_MASM510_AS
37 TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
37 TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
3838 ifeq ($(TOOL_MASM510_AS),)
3939 TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
4040 endif
0 # $Id: MASM600.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MASM600.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MASM v6.00
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_MASM600_AS
37 TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
37 TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
3838 ifeq ($(TOOL_MASM600_AS),)
3939 TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
4040 endif
0 # $Id: MASM610.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MASM610.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MASM v6.10
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_MASM610_AS
37 TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
37 TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
3838 ifeq ($(TOOL_MASM610_AS),)
3939 TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
4040 endif
0 # $Id: MASM6PLUS.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MASM6PLUS.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MASM v6 and later.
33 #
3535 # Tool Specific Properties
3636 ifndef TOOL_MASM6PLUS_AS
3737 TOOL_MASM6PLUS_AS := $(firstword $(rsort $(wildcard \
38 $(KBUILD_DEVTOOLS_BLD)/masm/*/bin$(if $(eq $(KBUILD_HOST),os2),p,)/ml$(HOSTSUFF_EXE)\
38 $(KBUILD_DEVTOOLS_HST)/masm/*/bin$(if $(eq $(KBUILD_HOST),os2),p,)/ml$(HOSTSUFF_EXE)\
3939 )))
4040 ifeq ($(TOOL_MASM6PLUS_AS),)
4141 TOOL_MASM6PLUS_AS := $(firstword $(rsort $(wildcard \
42 $(KBUILD_DEVTOOLS_BLD)/vcc/*/bin/ml$(HOSTSUFF_EXE) \
42 $(KBUILD_DEVTOOLS_HST)/vcc/*/bin/ml$(HOSTSUFF_EXE) \
4343 )))
4444 endif
4545 ifeq ($(TOOL_MASM6PLUS_AS),)
0 # $Id: MASM710.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MASM710.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MASM v7.10
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_MASM710_AS
37 TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
37 TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
3838 ifeq ($(TOOL_MASM710_AS),)
3939 TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
4040 endif
0 # $Id: MINGW32.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MINGW32.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MinGW32 GCC v3.3+.
33 #
3737
3838 # Tool Specific Properties
3939 ifndef PATH_TOOL_MINGW32
40 PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/mingw32/v*.*)
40 PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS_HST)/mingw32/v*.*)
4141 ifeq ($(PATH_TOOL_MINGW32),)
4242 PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/mingw32/v*.*)
4343 endif
0 # $Id: MINGWW64.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: MINGWW64.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - MinGW-W64.
33 #
3737
3838 # Tool Specific Properties
3939 ifndef PATH_TOOL_MINGWW64
40 PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/mingw-w64/r*)
40 PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS_HST)/mingw-w64/r*)
4141 ifeq ($(PATH_TOOL_MINGWW64),)
4242 PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS)/win.amd64/mingw-w64/r*)
4343 endif
0 # $Id: NASM.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: NASM.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - Netwide Assembler v0.98+.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef PATH_TOOL_NASM
37 PATH_TOOL_NASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/nasm/v*.*))
37 PATH_TOOL_NASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/nasm/v*.*))
3838 ifneq ($(PATH_TOOL_NASM),)
3939 PATH_TOOL_NASM := $(call lastword,$(PATH_TOOL_NASM))
4040 endif
0 # $Id: OPENWATCOM-16.kmk 2731 2014-06-28 14:58:12Z bird $
0 # $Id: OPENWATCOM-16.kmk 2749 2015-01-23 01:01:02Z bird $
11 ## @file
22 # kBuild Tool Config - Open Watcom v1.4 and later, 16-bit targets.
33 #
4444 TOOL_OPENWATCOM-16_COMPILE_AS_DEPORD =
4545 TOOL_OPENWATCOM-16_COMPILE_AS_OUTPUT = $(obj).err
4646 define TOOL_OPENWATCOM-16_COMPILE_AS_CMDS
47 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AS) \
47 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AS) \
4848 $(flags) \
4949 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
5050 $(addprefix -d, $(defs)) \
5959 TOOL_OPENWATCOM-16_COMPILE_C_DEPORD =
6060 TOOL_OPENWATCOM-16_COMPILE_C_OUTPUT = $(obj).err
6161 define TOOL_OPENWATCOM-16_COMPILE_C_CMDS
62 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CC16) \
62 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CC16) \
6363 $(flags) \
6464 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
6565 $(addprefix -d, $(defs)) \
7474 TOOL_OPENWATCOM-16_COMPILE_CXX_DEPORD =
7575 TOOL_OPENWATCOM-16_COMPILE_CXX_OUTPUT = $(obj).err
7676 define TOOL_OPENWATCOM-16_COMPILE_CXX_CMDS
77 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CXX16) \
77 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CXX16) \
7878 $(flags) \
7979 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
8080 $(addprefix -d, $(defs)) \
103103 TOOL_OPENWATCOM-16_LINK_LIBRARY_DEPORD =
104104 define TOOL_OPENWATCOM-16_LINK_LIBRARY_CMDS
105105 $(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(call TOOL_OPENWATCOM_FIX_SLASHES,$(objs) $(othersrc)),'+"$(obj)"')
106 $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
106 $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
107107 endef
108108
109109 TOOL_OPENWATCOM-16_LINK_PROGRAM_OUTPUT = $(outbase).map
111111 TOOL_OPENWATCOM-16_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
112112 TOOL_OPENWATCOM-16_LINK_PROGRAM_DEPORD =
113113 define TOOL_OPENWATCOM-16_LINK_PROGRAM_CMDS
114 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
114 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
115115 $(TOOL_OPENWATCOM_LD16) \
116116 $(flags) \
117117 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
131131 TOOL_OPENWATCOM-16_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
132132 TOOL_OPENWATCOM-16_LINK_DLL_DEPORD =
133133 define TOOL_OPENWATCOM-16_LINK_DLL_CMDS
134 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
134 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
135135 $(TOOL_OPENWATCOM_LD16) \
136136 $(flags) \
137137 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
151151 TOOL_OPENWATCOM-16_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
152152 TOOL_OPENWATCOM-16_LINK_SYSMOD_DEPORD =
153153 define TOOL_OPENWATCOM-16_LINK_SYSMOD_CMDS
154 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
154 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
155155 $(TOOL_OPENWATCOM_LD16) \
156156 $(flags) \
157157 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
0 # $Id: OPENWATCOM-WL.kmk 2663 2012-10-15 13:13:45Z bird $
0 # $Id: OPENWATCOM-WL.kmk 2749 2015-01-23 01:01:02Z bird $
11 ## @file
22 # kBuild Tool Config - Open Watcom v1.4 and later, using wlink.
33 #
5353 $(foreach p,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(libpath)),'LIBPath $p') \
5454 $(foreach o,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(filter-out %.res,$(objs)) $(othersrc)),'$(if $(filter %.lib %.a,$l),LIB,)File $o') \
5555 $(foreach l,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(libs)),'Library $l')
56 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP) \
56 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD) \
5757 $(TOOL_OPENWATCOM_WLINK) @$(outbase).rsp
5858 $(if $(filter %.res,$(objs)), $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP) \
5959 $(TOOL_OPENWATCOM_RC) \
0 # $Id: OPENWATCOM.kmk 2732 2014-06-28 16:02:41Z bird $
0 # $Id: OPENWATCOM.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - Open Watcom v1.4 and later.
33 #
3434
3535 ifeq ($(PATH_TOOL_OPENWATCOM),)
3636 ifeq ($(PATH_TOOL_OPENWATCOM),)
37 PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_BLD)/openwatcom/v*)
37 PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_HST)/openwatcom/v*)
3838 endif
3939 ifeq ($(PATH_TOOL_OPENWATCOM),)
4040 PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_TRG)/openwatcom/v*)
146146
147147 endif
148148
149 if $(KBUILD_KMK_REVISION) >= 2747
150 TOOL_OPENWATCOM_ENV_SETUP_BD ?= $(call TOOL_OPENWATCOM_ENV_SETUP,$1,$2 --wcc-brain-damage)
151 else
152 TOOL_OPENWATCOM_ENV_SETUP_BD ?= $(call TOOL_OPENWATCOM_ENV_SETUP,$1,$2)
153 endif
154
155
149156 # Functions for changing slashes (SQ = single quoted).
150157 if1of ($(KBUILD_HOST), os2 win)
151158 TOOL_OPENWATCOM_FIX_SLASHES = $(subst /,\\,$1)
201208 TOOL_OPENWATCOM_COMPILE_AS_DEPORD =
202209 TOOL_OPENWATCOM_COMPILE_AS_OUTPUT = $(obj).err
203210 define TOOL_OPENWATCOM_COMPILE_AS_CMDS
204 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AS) \
211 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AS) \
205212 $(flags) \
206213 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
207214 $(addprefix -d, $(defs)) \
217224 TOOL_OPENWATCOM_COMPILE_C_DEPORD =
218225 TOOL_OPENWATCOM_COMPILE_C_OUTPUT = $(obj).err
219226 define TOOL_OPENWATCOM_COMPILE_C_CMDS
220 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CC) \
227 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CC) \
221228 $(flags) \
222229 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
223230 $(addprefix -d, $(defs)) \
232239 TOOL_OPENWATCOM_COMPILE_CXX_DEPORD =
233240 TOOL_OPENWATCOM_COMPILE_CXX_OUTPUT = $(obj).err
234241 define TOOL_OPENWATCOM_COMPILE_CXX_CMDS
235 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CXX) \
242 $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CXX) \
236243 $(flags) \
237244 $(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
238245 $(addprefix -d, $(defs)) \
271278 $(filter %.imp,$(othersrc)) \
272279 --append $(outbase).rsp \
273280 )
274 $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
281 $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
275282 endef
276283
277284 TOOL_OPENWATCOM_LINK_PROGRAM_OUTPUT = $(outbase).map
278285 TOOL_OPENWATCOM_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
279286 TOOL_OPENWATCOM_LINK_PROGRAM_DEPORD =
280287 define TOOL_OPENWATCOM_LINK_PROGRAM_CMDS
281 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
288 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
282289 $(TOOL_OPENWATCOM_LD) \
283290 $(flags) \
284291 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
297304 TOOL_OPENWATCOM_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
298305 TOOL_OPENWATCOM_LINK_DLL_DEPORD =
299306 define TOOL_OPENWATCOM_LINK_DLL_CMDS
300 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
307 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
301308 $(TOOL_OPENWATCOM_LD) \
302309 $(flags) \
303310 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
316323 TOOL_OPENWATCOM_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
317324 TOOL_OPENWATCOM_LINK_SYSMOD_DEPORD =
318325 define TOOL_OPENWATCOM_LINK_SYSMOD_CMDS
319 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
326 $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
320327 $(TOOL_OPENWATCOM_LD) \
321328 $(flags) \
322329 -fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
0 # $Id: TAR.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: TAR.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - tar unpacker.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_TAR_TAR
37 TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_BLD)/tar/v*/tar$(HOSTSUFF_EXE))
37 TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_HST)/tar/v*/tar$(HOSTSUFF_EXE))
3838 ifeq ($(TOOL_TAR_TAR),)
39 TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/tar$(HOSTSUFF_EXE))
39 TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/tar$(HOSTSUFF_EXE))
4040 endif
4141 ifneq ($(TOOL_TAR_TAR),)
4242 TOOL_TAR_TAR := $(lastword $(sort $(TOOL_TAR_TAR)))
0 # $Id: VAC308.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: VAC308.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - VisualAge for C++ v3.08.
33 #
3434
3535 # Determin VAC308 location.
3636 ifndef PATH_TOOL_VAC308
37 PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/vac/v3.0.8*)
37 PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_HST)/vac/v3.0.8*)
3838 ifeq ($(PATH_TOOL_VAC308),)
39 PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/vac/v308*)
39 PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_HST)/vac/v308*)
4040 endif
4141 ifeq ($(PATH_TOOL_VAC308),)
4242 PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_TRG)/vac/v3.0.8*)
0 # $Id: WATCOMC11C-16.kmk 2731 2014-06-28 14:58:12Z bird $
0 # $Id: WATCOMC11C-16.kmk 2749 2015-01-23 01:01:02Z bird $
11 ## @file
22 # kBuild Tool Config - Watcom C v11.0c, 16-bit targets.
33 #
4343 TOOL_WATCOMC11C-16_COMPILE_C_DEPORD =
4444 TOOL_WATCOMC11C-16_COMPILE_C_OUTPUT = $(obj).err
4545 define TOOL_WATCOMC11C-16_COMPILE_C_CMDS
46 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CC16) \
46 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CC16) \
4747 $(flags) \
4848 $(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
4949 $(addprefix -d, $(defs)) \
5858 TOOL_WATCOMC11C-16_COMPILE_CXX_DEPORD =
5959 TOOL_WATCOMC11C-16_COMPILE_CXX_OUTPUT = $(obj).err
6060 define TOOL_WATCOMC11C-16_COMPILE_CXX_CMDS
61 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CXX16) \
61 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CXX16) \
6262 $(flags) \
6363 $(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
6464 $(addprefix -d, $(defs)) \
8787 TOOL_WATCOMC11C-16_LINK_LIBRARY_DEPORD =
8888 define TOOL_WATCOMC11C-16_LINK_LIBRARY_CMDS
8989 $(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(subst /,\,$(objs) $(othersrc)),'+"$(obj)"')
90 $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
90 $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
9191 endef
9292
9393 TOOL_WATCOMC11C-16_LINK_PROGRAM_OUTPUT = $(outbase).map
9494 TOOL_WATCOMC11C-16_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
9595 TOOL_WATCOMC11C-16_LINK_PROGRAM_DEPORD =
9696 define TOOL_WATCOMC11C-16_LINK_PROGRAM_CMDS
97 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
97 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
9898 $(TOOL_WATCOMC11C_LD16) \
9999 $(flags) \
100100 -fe=$(subst /,\\,$(out)) \
113113 TOOL_WATCOMC11C-16_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
114114 TOOL_WATCOMC11C-16_LINK_DLL_DEPORD =
115115 define TOOL_WATCOMC11C-16_LINK_DLL_CMDS
116 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
116 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
117117 $(TOOL_WATCOMC11C_LD16) \
118118 $(flags) \
119119 -fe=$(subst /,\\,$(out)) \
132132 TOOL_WATCOMC11C-16_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
133133 TOOL_WATCOMC11C-16_LINK_SYSMOD_DEPORD =
134134 define TOOL_WATCOMC11C-16_LINK_SYSMOD_CMDS
135 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
135 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
136136 $(TOOL_WATCOMC11C_LD16) \
137137 $(flags) \
138138 -fe=$(subst /,\\,$(out)) \
0 # $Id: WATCOMC11C-WL.kmk 2413 2010-09-11 17:43:04Z bird $
0 # $Id: WATCOMC11C-WL.kmk 2749 2015-01-23 01:01:02Z bird $
11 ## @file
22 # kBuild Tool Config - Watcom C/C++ v11.0c, using wlink.
33 #
5252 $(foreach p,$(subst /,\,$(libpath)),'LIBPath $p') \
5353 $(foreach o,$(subst /,\,$(filter-out %.res,$(objs)) $(othersrc)),'$(if $(filter %.lib %.a,$l),LIB,)File $o') \
5454 $(foreach l,$(subst /,\,$(libs)),'Library $l')
55 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP) \
55 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD) \
5656 $(TOOL_WATCOMC11C_WLINK) @$(outbase).rsp
5757 $(if $(filter %.res,$(objs)), $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP) \
5858 $(TOOL_WATCOMC11C_RC) \
0 # $Id: WATCOMC11C.kmk 2731 2014-06-28 14:58:12Z bird $
0 # $Id: WATCOMC11C.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - Watcom C v11.0c
33 #
3434
3535 ifeq ($(PATH_TOOL_WATCOMC11C),)
3636 ifeq ($(PATH_TOOL_WATCOMC11C),)
37 PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_BLD)/watcom/v11.0c*)
37 PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_HST)/watcom/v11.0c*)
3838 endif
3939 ifeq ($(PATH_TOOL_WATCOMC11C),)
4040 PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_TRG)/watcom/v11.0c*)
112112
113113 endif
114114
115 if $(KBUILD_KMK_REVISION) >= 2747
116 TOOL_WATCOMC11C_ENV_SETUP_BD ?= $(call TOOL_WATCOMC11C_ENV_SETUP,$1,$2 --wcc-brain-damage)
117 else
118 TOOL_WATCOMC11C_ENV_SETUP_BD ?= $(call TOOL_WATCOMC11C_ENV_SETUP,$1,$2)
119 endif
120
121
115122 # General Properties used by kBuild
116123 TOOL_WATCOMC11C_COBJSUFF ?= .obj
117124 TOOL_WATCOMC11C_CFLAGS ?= -zq
150157 TOOL_WATCOMC11C_COMPILE_C_DEPORD =
151158 TOOL_WATCOMC11C_COMPILE_C_OUTPUT = $(obj).err
152159 define TOOL_WATCOMC11C_COMPILE_C_CMDS
153 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CC) \
160 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CC) \
154161 $(flags) \
155162 $(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
156163 $(addprefix -d, $(defs)) \
165172 TOOL_WATCOMC11C_COMPILE_CXX_DEPORD =
166173 TOOL_WATCOMC11C_COMPILE_CXX_OUTPUT = $(obj).err
167174 define TOOL_WATCOMC11C_COMPILE_CXX_CMDS
168 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CXX) \
175 $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CXX) \
169176 $(flags) \
170177 $(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
171178 $(addprefix -d, $(defs)) \
194201 TOOL_WATCOMC11C_LINK_LIBRARY_DEPORD =
195202 define TOOL_WATCOMC11C_LINK_LIBRARY_CMDS
196203 $(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(subst /,\,$(objs) $(othersrc)),'+"$(obj)"')
197 $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
204 $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
198205 endef
199206
200207 TOOL_WATCOMC11C_LINK_PROGRAM_OUTPUT = $(outbase).map
201208 TOOL_WATCOMC11C_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
202209 TOOL_WATCOMC11C_LINK_PROGRAM_DEPORD =
203210 define TOOL_WATCOMC11C_LINK_PROGRAM_CMDS
204 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
211 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
205212 $(TOOL_WATCOMC11C_LD) \
206213 $(flags) \
207214 -fe=$(subst /,\\,$(out)) \
220227 TOOL_WATCOMC11C_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
221228 TOOL_WATCOMC11C_LINK_DLL_DEPORD =
222229 define TOOL_WATCOMC11C_LINK_DLL_CMDS
223 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
230 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
224231 $(TOOL_WATCOMC11C_LD) \
225232 $(flags) \
226233 -fe=$(subst /,\\,$(out)) \
239246 TOOL_WATCOMC11C_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
240247 TOOL_WATCOMC11C_LINK_SYSMOD_DEPORD =
241248 define TOOL_WATCOMC11C_LINK_SYSMOD_CMDS
242 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
249 $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
243250 $(TOOL_WATCOMC11C_LD) \
244251 $(flags) \
245252 -fe=$(subst /,\\,$(out)) \
0 # $Id: WGET.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: WGET.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - wget fetchers.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_WGET_FETCH
37 TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_BLD)/wget/v*/wget$(HOSTSUFF_EXE))
37 TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_HST)/wget/v*/wget$(HOSTSUFF_EXE))
3838 ifneq ($(TOOL_WGET_FETCH),)
39 TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/wget$(HOSTSUFF_EXE))
39 TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/wget$(HOSTSUFF_EXE))
4040 endif
4141 ifneq ($(TOOL_WGET_FETCH),)
4242 TOOL_WGET_FETCH := $(lastword $(sort $(TOOL_WGET_FETCH)))
0 # $Id: XGCCAMD64LINUX.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: XGCCAMD64LINUX.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - GCC Cross compiler for AMD64+Linux.
33 #
4242 ifndef TOOL_XGCCAMD64LINUX_PREFIX
4343 TOOL_XGCCAMD64LINUX_PREFIX := x86_64-unknown-linux-gnu-
4444 ifndef PATH_TOOL_XGCCAMD64LINUX
45 PATH_TOOL_XGCCAMD64LINUX := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/x86_64-unknown-linux-gnu/*))
45 PATH_TOOL_XGCCAMD64LINUX := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/x86_64-unknown-linux-gnu/*))
4646 ifeq ($(PATH_TOOL_XGCCAMD64LINUX),)
4747 ifeq ($(filter-out win.amd64,$(KBUILD_HOST).$(KBUILD_HOST_ARCH)),) # these can use the windows build.
4848 TOOL_XGCCAMD64LINUX_EXEC_PREFIX ?= $(EXEC_X86_WIN32)
0 # $Id: YASM.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: YASM.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - YASM 0.4.0 or later.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef PATH_TOOL_YASM
37 PATH_TOOL_YASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/yasm/v*.*))
37 PATH_TOOL_YASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/yasm/v*.*))
3838 ifneq ($(PATH_TOOL_YASM),)
3939 PATH_TOOL_YASM := $(call lastword,$(PATH_TOOL_YASM))
4040 endif
0 # $Id: ZIP.kmk 2726 2014-02-26 23:23:54Z bird $
0 # $Id: ZIP.kmk 2750 2015-01-23 12:24:02Z bird $
11 ## @file
22 # kBuild Tool Config - The zip/unzip packer/unpacker.
33 #
3434
3535 # Tool Specific Properties
3636 ifndef TOOL_ZIP_UNPACK
37 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/unzip/v*/unzip$(HOSTSUFF_EXE))
37 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/unzip/v*/unzip$(HOSTSUFF_EXE))
3838 ifeq ($(TOOL_ZIP_UNPACK),)
39 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/zip/v*/unzip$(HOSTSUFF_EXE))
39 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/zip/v*/unzip$(HOSTSUFF_EXE))
4040 endif
4141 ifeq ($(TOOL_ZIP_UNPACK),)
42 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/unzip$(HOSTSUFF_EXE))
42 TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/unzip$(HOSTSUFF_EXE))
4343 endif
4444 ifneq ($(TOOL_ZIP_UNPACK),)
4545 TOOL_ZIP_UNPACK := $(lastword $(sort $(TOOL_ZIP_UNPACK)))
5050 TOOL_ZIP_UNPACK := $(TOOL_ZIP_UNPACK)
5151 endif
5252 #ifndef TOOL_ZIP_PACK
53 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/zip/v*/zip$(HOSTSUFF_EXE))
53 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/zip/v*/zip$(HOSTSUFF_EXE))
5454 # ifeq ($(TOOL_ZIP_PACK),)
55 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/unzip/v*/zip$(HOSTSUFF_EXE))
55 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/unzip/v*/zip$(HOSTSUFF_EXE))
5656 # endif
5757 # ifeq ($(TOOL_ZIP_PACK),)
58 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/zip$(HOSTSUFF_EXE))
58 # TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/zip$(HOSTSUFF_EXE))
5959 # endif
6060 # ifneq ($(TOOL_ZIP_PACK),)
6161 # TOOL_ZIP_PACK := $(lastword $(sort $(TOOL_ZIP_PACK)))
0 # $Id: Makefile.kmk 2719 2014-01-01 17:40:56Z bird $
0 # $Id: Makefile.kmk 2765 2015-01-30 00:27:51Z bird $
11 ## @file
22 # Sub-makefile for kmk / GNU Make.
33 #
191191 CONFIG_WITH_RDONLY_VARIABLE_VALUE \
192192 CONFIG_WITH_LAZY_DEPS_VARS \
193193 CONFIG_WITH_MEMORY_OPTIMIZATIONS \
194 CONFIG_WITH_COMPILER \
194195 \
195196 KBUILD_HOST=\"$(KBUILD_TARGET)\" \
196197 KBUILD_HOST_ARCH=\"$(KBUILD_TARGET_ARCH)\" \
199200 kmk_DEFS.amd64 = CONFIG_WITH_OPTIMIZATION_HACKS
200201 kmk_DEFS.win = CONFIG_NEW_WIN32_CTRL_EVENT CONFIG_WITH_FAST_IS_SPACE
201202 kmk_DEFS.debug = CONFIG_WITH_MAKE_STATS
203 ifdef CONFIG_WITH_MAKE_STATS
204 kmk_DEFS += CONFIG_WITH_MAKE_STATS
205 endif
202206
203207 kmk_SOURCES = \
204208 main.c \
205 kbuild.c \
206 kbuild-object.c \
207209 read.c \
208 expreval.c \
209 incdep.c \
210210 hash.c \
211211 strcache.c \
212 strcache2.c \
213212 variable.c \
214213 ar.c \
215214 arscan.c \
222221 implicit.c \
223222 job.c \
224223 misc.c \
225 alloccache.c \
226224 remake.c \
227225 rule.c \
228226 signame.c \
229227 version.c \
230228 vpath.c \
231 remote-stub.c
229 remote-stub.c \
230 \
231 alloccache.c \
232 expreval.c \
233 incdep.c \
234 strcache2.c \
235 kmk_cc_exec.c \
236 kbuild.c \
237 kbuild-object.c
232238
233239 kmk_DEFS.freebsd.x86 = CONFIG_WITHOUT_THREADS
234240
628628 }
629629 }
630630
631 #ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
632 /* This is for saving memory in func_commands. */
633 void
634 free_chopped_commands (struct commands *cmds)
635 {
636 if ( cmds
637 && cmds->command_lines != 0
638 && cmds->refs == 0)
639 {
640 unsigned idx = cmds->ncommand_lines;
641 while (idx-- > 0)
642 free (cmds->command_lines[idx]);
643 free (cmds->command_lines);
644 free (cmds->lines_flags);
645 cmds->command_lines = 0;
646 cmds->lines_flags = 0;
647 cmds->ncommand_lines = 0;
648 }
649 }
650
651 #endif /* CONFIG_WITH_MEMORY_OPTIMIZATIONS */
631652 /* Execute the commands to remake FILE. If they are currently executing,
632653 return or have already finished executing, just return. Otherwise,
633654 fork off a child process to run the first command line in the sequence. */
5555 void print_commands (const struct commands *cmds);
5656 void delete_child_targets (struct child *child);
5757 void chop_commands (struct commands *cmds);
58 #ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
59 void free_chopped_commands (struct commands *cmd);
60 #endif
5861 #if defined(CONFIG_WITH_COMMANDS_FUNC) || defined (CONFIG_WITH_DOT_MUST_MAKE)
5962 void set_file_variables (struct file *file, int called_early);
6063 #else
1414 You should have received a copy of the GNU General Public License along with
1515 GNU Make; see the file COPYING. If not, write to the Free Software
1616 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
17
18 #ifndef ___config_h_win
19 #define ___config_h_win
1720
1821 /* Suppress some Visual C++ warnings.
1922 Maybe after the code cleanup for ISO C we can remove some/all of these. */
217220 #define HAVE_STDARG_H 1
218221
219222 /* Define to 1 if you have the <stdint.h> header file. */
220 /*#define HAVE_STDINT_H 1*/
223 #if _MSC_VER >= 1600
224 # define HAVE_STDINT_H 1
225 #endif
221226
222227 /* Define to 1 if you have the <stdlib.h> header file. */
223228 #define HAVE_STDLIB_H 1
442447 #define uid_t int
443448
444449 /* Define uintmax_t if not defined in <stdint.h> or <inttypes.h>. */
445 #if 0
446 #define uintmax_t unsigned long
447 #else
448 #define uintmax_t unsigned __int64
450 #if _MSC_VER < 1600
451 # if 0
452 # define uintmax_t unsigned long
453 # else
454 # define uintmax_t unsigned __int64
455 # endif
449456 #endif
450457
451458 /* Define as `fork' if `vfork' does not work. */
532539 #define _DIRENT_HAVE_D_NAMLEN 1
533540 #define _DIRENT_HAVE_D_TYPE 1
534541
535
536 /* cygwin sucks to much in one end or the other. */
542 /* bird: Not sure if this is necessary any more... */
537543 #define BATCH_MODE_ONLY_SHELL
538544
539545 #include "inlined_memchr.h"
555561 extern char space_map[space_map_size];
556562 #endif
557563
564 /* bird: Include mscfakes.h to make sure we have all it's tricks applied. */
565 #ifndef ___mscfakes_h
566 # include "kmkbuiltin/mscfakes.h"
567 #endif
568
569 #endif /* bird */
570
13091309
13101310 /* Hooks for globbing. */
13111311
1312 #if defined(KMK) && !defined(__OS2__)
1313 # include "glob/glob.h"
1314 #else
13121315 #include <glob.h>
1316 #endif
13131317
13141318 /* Structure describing state of iterating through a directory hash table. */
13151319
2424 #include "commands.h"
2525 #include "variable.h"
2626 #include "rule.h"
27 #ifdef CONFIG_WITH_COMPILER
28 # include "kmk_cc_exec.h"
29 #endif
2730
2831 /* Initially, any errors reported when expanding strings will be reported
2932 against the file where the error appears. */
184187 value = allocated_variable_expand (v->value);
185188 #else /* CONFIG_WITH_VALUE_LENGTH */
186189 if (!v->append)
187 value = allocated_variable_expand_2 (v->value, v->value_length, value_lenp);
190 {
191 if (!IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
192 value = allocated_variable_expand_2 (v->value, v->value_length, value_lenp);
193 else
194 {
195 unsigned int len = v->value_length;
196 value = xmalloc (len + 2);
197 memcpy (value, v->value, len + 1);
198 value[len + 1] = '\0'; /* Extra terminator like allocated_variable_expand_2 returns. Why? */
199 if (value_lenp)
200 *value_lenp = len;
201 }
202 }
188203 else
189204 {
190205 value = allocated_variable_append (v);
206221 }
207222
208223 #ifdef CONFIG_WITH_VALUE_LENGTH
209 /* Static worker for reference_variable() that expands the recursive
224 /* Worker for reference_variable() and kmk_exec_* that expands the recursive
210225 variable V. The main difference between this and
211226 recursively_expand[_for_file] is that this worker avoids the temporary
212227 buffer and outputs directly into the current variable buffer (O). */
213 static char *
228 char *
214229 reference_recursive_variable (char *o, struct variable *v)
215230 {
216231 const struct floc *this_var;
245260
246261 v->expanding = 1;
247262 if (!v->append)
248 /* Expand directly into the variable buffer. */
249 variable_expand_string_2 (o, v->value, v->value_length, &o);
263 {
264 /* Expand directly into the variable buffer. */
265 # ifdef CONFIG_WITH_COMPILER
266 v->expand_count++;
267 if ( v->expandprog
268 || (v->expand_count == 3 && kmk_cc_compile_variable_for_expand (v)) )
269 o = kmk_exec_expand_to_var_buf (v, o);
270 else
271 variable_expand_string_2 (o, v->value, v->value_length, &o);
272 # else
273 MAKE_STATS_2 (v->expand_count++);
274 variable_expand_string_2 (o, v->value, v->value_length, &o);
275 # endif
276 }
250277 else
251278 {
252279 /* XXX: Feel free to optimize appending target variables as well. */
294321
295322 #ifdef CONFIG_WITH_VALUE_LENGTH
296323 assert (v->value_length == strlen (v->value));
297 if (!v->recursive)
324 if (!v->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
298325 o = variable_buffer_output (o, v->value, v->value_length);
299326 else
300327 o = reference_recursive_variable (o, v);
9861013 #endif
9871014
9881015 /* Either expand it or copy it, depending. */
989 if (! v->recursive)
1016 if (! v->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
9901017 #ifdef CONFIG_WITH_VALUE_LENGTH
9911018 return variable_buffer_output (buf, v->value, v->value_length);
9921019 #else
10571084 v->value = variable_buffer;
10581085 v->value_length = p - v->value;
10591086 v->value_alloc_len = variable_buffer_length;
1087 VARIABLE_CHANGED(v);
10601088
10611089 /* Restore the variable buffer, but without freeing the current. */
10621090 variable_buffer = NULL;
11941222 initialize_variable_output ();
11951223 }
11961224
1197 /* Restore a previously-saved variable_buffer setting (free the current one).
1198 */
1225 #ifdef CONFIG_WITH_COMPILER
1226 /* Same as install_variable_buffer, except we supply a size hint. */
1227
1228 char *
1229 install_variable_buffer_with_hint (char **bufp, unsigned int *lenp, unsigned int size_hint)
1230 {
1231 struct recycled_buffer *recycled;
1232 char *buf;
1233
1234 *bufp = variable_buffer;
1235 *lenp = variable_buffer_length;
1236
1237 recycled = recycled_head;
1238 if (recycled)
1239 {
1240 recycled_head = recycled->next;
1241 variable_buffer_length = recycled->length;
1242 variable_buffer = buf = (char *)recycled;
1243 }
1244 else
1245 {
1246 if (size_hint < 512)
1247 variable_buffer_length = (size_hint + 1 + 63) & ~(unsigned int)63;
1248 else if (size_hint < 4096)
1249 variable_buffer_length = (size_hint + 1 + 1023) & ~(unsigned int)1023;
1250 else
1251 variable_buffer_length = (size_hint + 1 + 4095) & ~(unsigned int)4095;
1252 variable_buffer = buf = xmalloc (variable_buffer_length);
1253 }
1254 buf[0] = '\0';
1255 return buf;
1256 }
1257 #endif /* CONFIG_WITH_COMPILER */
1258
1259 /* Restore a previously-saved variable_buffer setting (free the
1260 current one). */
11991261
12001262 void
12011263 restore_variable_buffer (char *buf, unsigned int len)
12101272 variable_buffer = buf;
12111273 variable_buffer_length = len;
12121274 }
1275
1276
1277 /* Used to make sure there is at least SIZE bytes of buffer space
1278 available starting at PTR. */
1279 char *
1280 ensure_variable_buffer_space(char *ptr, unsigned int size)
1281 {
1282 unsigned int offset = (unsigned int)(ptr - variable_buffer);
1283 assert(offset <= variable_buffer_length);
1284 if (variable_buffer_length - offset < size)
1285 {
1286 unsigned minlen = size + offset;
1287 variable_buffer_length *= 2;
1288 if (variable_buffer_length < minlen + 100)
1289 variable_buffer_length = (minlen + 100 + 63) & ~(unsigned int)63;
1290 variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
1291 ptr = variable_buffer + offset;
1292 }
1293 return ptr;
1294 }
1295
4141 # ifdef HAVE_LIMITS_H
4242 # include <limits.h>
4343 # endif
44 #endif
45 #ifdef CONFIG_WITH_COMPILER
46 # include "kmk_cc_exec.h"
4447 #endif
4548 #include <assert.h> /* bird */
4649
13481351 memcpy (var->value, p, len);
13491352 var->value[len] = '\0';
13501353 var->value_length = len;
1354 VARIABLE_CHANGED (var);
13511355
13521356 variable_expand_string_2 (o, body, body_len, &o);
13531357 o = variable_buffer_output (o, " ", 1);
17401744 wordi = 0;
17411745 while ((p = find_next_token (&t, &len)) != 0)
17421746 {
1743 ++t;
1747 if (*t != '\0') /* bird: Fixes access beyond end of string and overflowing words array. */
1748 ++t;
17441749 p[len] = '\0';
17451750 words[wordi++] = p;
17461751 }
20322037 int var_ctx;
20332038 size_t off;
20342039 const struct floc *reading_file_saved = reading_file;
2035
2036 /* Make a copy of the value to the variable buffer since
2037 eval_buffer will make changes to its input. */
2038
2039 off = o - variable_buffer;
2040 variable_buffer_output (o, v->value, v->value_length + 1);
2041 o = variable_buffer + off;
2042
2043 /* Eval the value. Pop the current variable buffer setting so that the
2044 eval'd code can use its own without conflicting. (really necessary?) */
2045
2046 install_variable_buffer (&buf, &len);
2040 # ifdef CONFIG_WITH_MAKE_STATS
2041 unsigned long long uStartTick = CURRENT_CLOCK_TICK();
2042 # ifndef CONFIG_WITH_COMPILER
2043 MAKE_STATS_2(v->evalval_count++);
2044 # endif
2045 # endif
2046
20472047 var_ctx = !strcmp (funcname, "evalvalctx");
20482048 if (var_ctx)
20492049 push_new_variable_scope ();
20502050 if (v->fileinfo.filenm)
20512051 reading_file = &v->fileinfo;
20522052
2053 assert (!o[v->value_length]);
2054 eval_buffer (o, o + v->value_length);
2053 # ifdef CONFIG_WITH_COMPILER
2054 /* If this variable has been evaluated more than a few times, it make
2055 sense to compile it to speed up the processing. */
2056
2057 v->evalval_count++;
2058 if ( v->evalprog
2059 || (v->evalval_count == 3 && kmk_cc_compile_variable_for_eval (v)))
2060 {
2061 install_variable_buffer (&buf, &len); /* Really necessary? */
2062 kmk_exec_evalval (v);
2063 restore_variable_buffer (buf, len);
2064 }
2065 else
2066 # endif
2067 {
2068 /* Make a copy of the value to the variable buffer first since
2069 eval_buffer will make changes to its input. */
2070
2071 off = o - variable_buffer;
2072 variable_buffer_output (o, v->value, v->value_length + 1);
2073 o = variable_buffer + off;
2074 assert (!o[v->value_length]);
2075
2076 install_variable_buffer (&buf, &len); /* Really necessary? */
2077 eval_buffer (o, o + v->value_length);
2078 restore_variable_buffer (buf, len);
2079 }
20552080
20562081 reading_file = reading_file_saved;
20572082 if (var_ctx)
20582083 pop_variable_scope ();
2059 restore_variable_buffer (buf, len);
2084
2085 MAKE_STATS_2(v->cTicksEvalVal += CURRENT_CLOCK_TICK() - uStartTick);
20602086 }
20612087
20622088 return o;
21252151 *dst = '\0';
21262152 v->value_length = dst - v->value;
21272153 }
2154
2155 VARIABLE_CHANGED (v);
2156
2157 # ifdef CONFIG_WITH_COMPILER
2158 /* Compile the variable for evalval, evalctx and expansion. */
2159
2160 if ( v->recursive
2161 && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
2162 kmk_cc_compile_variable_for_expand (v);
2163 kmk_cc_compile_variable_for_eval (v);
2164 # endif
21282165 }
21292166 else if (v)
21302167 error (NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
40664103 return variable_buffer_output (o, argv[2], strlen(argv[2]));
40674104 if (var1->value == var2->value)
40684105 return variable_buffer_output (o, "", 0); /* eq */
4069 if (!var1->recursive && !var2->recursive)
4106 if ( (!var1->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var1))
4107 && (!var2->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var2)) )
40704108 {
40714109 if ( var1->value_length == var2->value_length
40724110 && !memcmp (var1->value, var2->value, var1->value_length))
45964634 #ifdef CONFIG_WITH_VALUE_LENGTH
45974635 stack_var->value_length = lastitem - stack_var->value;
45984636 #endif
4637 VARIABLE_CHANGED (stack_var);
45994638 }
46004639 }
46014640 }
57545793 return handle_function2 (entry_p, op, stringp);
57555794 }
57565795 #endif /* CONFIG_WITH_VALUE_LENGTH */
5796
5797 #ifdef CONFIG_WITH_COMPILER
5798 /* Used by the "compiler" to get all info about potential functions. */
5799 make_function_ptr_t
5800 lookup_function_for_compiler (const char *name, unsigned int len,
5801 unsigned char *minargsp, unsigned char *maxargsp,
5802 char *expargsp, const char **funcnamep)
5803 {
5804 const struct function_table_entry *entry_p = lookup_function (name, len);
5805 if (!entry_p)
5806 return 0;
5807 *minargsp = entry_p->minimum_args;
5808 *maxargsp = entry_p->maximum_args;
5809 *expargsp = entry_p->expand_args;
5810 *funcnamep = entry_p->name;
5811 return entry_p->func_ptr;
5812 }
5813 #endif /* CONFIG_WITH_COMPILER */
57575814
57585815
57595816 /* User-defined functions. Expand the first argument as either a builtin
59285985 current_variable_set_list->set);
59295986 if (v && v->value_length)
59305987 {
5931 if (v->recursive)
5988 if (v->recursive && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
59325989 {
59335990 v->exp_count = EXP_COUNT_MAX;
59345991 variable_expand_string_2 (o, v->value, v->value_length, &o);
10091009
10101010 child->file->cmds->refs--;
10111011 if ( !child->file->intermediate
1012 && !child->file->pat_variables
1013 && child->file->cmds->refs == 0)
1014 {
1015 struct commands *cmds = child->file->cmds;
1016 unsigned int i;
1017
1018 for (i = 0; i < cmds->ncommand_lines; ++i)
1019 {
1020 free (cmds->command_lines[i]);
1021 cmds->command_lines[i] = 0;
1022 }
1023 free (cmds->command_lines);
1024 cmds->command_lines = 0;
1025 free (cmds->lines_flags);
1026 cmds->lines_flags = 0;
1027 cmds->ncommand_lines = 0;
1028 }
1012 && !child->file->pat_variables)
1013 free_chopped_commands(child->file->cmds);
10291014 #endif /* CONFIG_WITH_MEMORY_OPTIMIZATIONS */
10301015
10311016 free (child);
0 /* $Id: kbuild.c 2540 2011-08-02 20:13:24Z bird $ */
0 /* $Id: kbuild.c 2771 2015-02-01 20:48:36Z bird $ */
11 /** @file
22 * kBuild specific make functionality.
33 */
568568 pVar->value_alloc_len = value_len + 1;
569569 }
570570 pVar->recursive = 0;
571 VARIABLE_CHANGED(pVar);
571572 return pVar;
572573 }
573574
15721573 if (pVar) \
15731574 { \
15741575 paVars[iVar].pVar = pVar; \
1575 if ( !pVar->recursive \
1576 || !memchr(pVar->value, '$', pVar->value_length)) \
1576 if ( !pVar->recursive \
1577 || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar)) \
15771578 { \
15781579 paVars[iVar].pszExp = pVar->value; \
15791580 paVars[iVar].cchExp = pVar->value_length; \
26192620 off--;
26202621 pDefTemplate->value_length = off;
26212622 pDefTemplate->value[off] = '\0';
2623
2624 VARIABLE_CHANGED(pDefTemplate);
26222625 }
26232626
26242627 if (!pDefTemplate->value_length)
0 #ifdef CONFIG_WITH_COMPILER
1 /* $Id: kmk_cc_exec.c 2777 2015-02-03 21:06:31Z bird $ */
2 /** @file
3 * kmk_cc - Make "Compiler".
4 */
5
6 /*
7 * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
23 *
24 */
25
26
27 /*******************************************************************************
28 * Header Files *
29 *******************************************************************************/
30 #include "make.h"
31
32 #include "dep.h"
33 #include "variable.h"
34 #include "rule.h"
35 #include "debug.h"
36 #include "hash.h"
37 #include <ctype.h>
38 #ifdef HAVE_STDINT_H
39 # include <stdint.h>
40 #endif
41 #include <stdarg.h>
42 #include <assert.h>
43
44 /*******************************************************************************
45 * Defined Constants And Macros *
46 *******************************************************************************/
47 /** @def KMK_CC_WITH_STATS
48 * Enables the collection of extra statistics. */
49 #ifndef KMK_CC_WITH_STATS
50 # ifdef CONFIG_WITH_MAKE_STATS
51 # define KMK_CC_WITH_STATS
52 # endif
53 #endif
54
55 /** @def KMK_CC_STRICT
56 * Indicates whether assertions and other checks are enabled. */
57 #ifndef KMK_CC_STRICT
58 # ifndef NDEBUG
59 # define KMK_CC_STRICT
60 # endif
61 #endif
62
63 #ifdef KMK_CC_STRICT
64 # ifdef _MSC_VER
65 # define KMK_CC_ASSERT(a_TrueExpr) do { if (!(a_TrueExpr)) __debugbreak(); } while (0)
66 # else
67 # define KMK_CC_ASSERT(a_TrueExpr) assert(a_TrueExpr)
68 # endif
69 #else
70 # define KMK_CC_ASSERT(a_TrueExpr) do {} while (0)
71 #endif
72 #define KMK_CC_ASSERT_ALIGNED(a_uValue, a_uAlignment) \
73 KMK_CC_ASSERT( ((a_uValue) & ((a_uAlignment) - 1)) == 0 )
74
75
76 /*******************************************************************************
77 * Structures and Typedefs *
78 *******************************************************************************/
79 /**
80 * Block of expand instructions.
81 *
82 * To avoid wasting space on "next" pointers, as well as a lot of time walking
83 * these chains when destroying programs, we work with blocks of instructions.
84 */
85 typedef struct kmk_cc_block
86 {
87 /** The pointer to the next block (LIFO). */
88 struct kmk_cc_block *pNext;
89 /** The size of this block. */
90 uint32_t cbBlock;
91 /** The offset of the next free byte in the block. When set to cbBlock the
92 * block is 100% full. */
93 uint32_t offNext;
94 } KMKCCBLOCK;
95 typedef KMKCCBLOCK *PKMKCCBLOCK;
96
97 /**
98 * String expansion statistics.
99 */
100 typedef struct KMKCCEXPSTATS
101 {
102 /** Recent average size. */
103 uint32_t cchAvg;
104 } KMKCCEXPSTATS;
105 typedef KMKCCEXPSTATS *PKMKCCEXPSTATS;
106
107 /**
108 * Expansion instructions.
109 */
110 typedef enum KMKCCEXPINSTR
111 {
112 /** Copy a plain string. */
113 kKmkCcExpInstr_CopyString = 0,
114 /** Insert an expanded variable value, which name we already know. */
115 kKmkCcExpInstr_PlainVariable,
116 /** Insert an expanded variable value, the name is dynamic (sub prog). */
117 kKmkCcExpInstr_DynamicVariable,
118 /** Insert an expanded variable value, which name we already know, doing
119 * search an replace on a string. */
120 kKmkCcExpInstr_SearchAndReplacePlainVariable,
121 /** Insert the output of function that requires no argument expansion. */
122 kKmkCcExpInstr_PlainFunction,
123 /** Insert the output of function that requires dynamic expansion of one ore
124 * more arguments. (Dynamic is perhaps not such a great name, but whatever.) */
125 kKmkCcExpInstr_DynamicFunction,
126 /** Jump to a new instruction block. */
127 kKmkCcExpInstr_Jump,
128 /** We're done, return. Has no specific structure. */
129 kKmkCcExpInstr_Return,
130 /** The end of valid instructions (exclusive). */
131 kKmkCcExpInstr_End
132 } KMKCCEXPANDINSTR;
133
134 /** Instruction core. */
135 typedef struct kmk_cc_exp_core
136 {
137 /** The instruction opcode number (KMKCCEXPANDINSTR). */
138 KMKCCEXPANDINSTR enmOpCode;
139 } KMKCCEXPCORE;
140 typedef KMKCCEXPCORE *PKMKCCEXPCORE;
141
142 /**
143 * String expansion sub program.
144 */
145 typedef struct kmk_cc_exp_subprog
146 {
147 /** Pointer to the first instruction. */
148 PKMKCCEXPCORE pFirstInstr;
149 /** Statistics. */
150 KMKCCEXPSTATS Stats;
151 } KMKCCEXPSUBPROG;
152 typedef KMKCCEXPSUBPROG *PKMKCCEXPSUBPROG;
153
154 /**
155 * kKmkCcExpInstr_CopyString instruction format.
156 */
157 typedef struct kmk_cc_exp_copy_string
158 {
159 /** The core instruction. */
160 KMKCCEXPCORE Core;
161 /** The number of bytes to copy. */
162 uint32_t cchCopy;
163 /** Pointer to the source string (not terminated at cchCopy). */
164 const char *pachSrc;
165 } KMKCCEXPCOPYSTRING;
166 typedef KMKCCEXPCOPYSTRING *PKMKCCEXPCOPYSTRING;
167
168 /**
169 * kKmkCcExpInstr_PlainVariable instruction format.
170 */
171 typedef struct kmk_cc_exp_plain_variable
172 {
173 /** The core instruction. */
174 KMKCCEXPCORE Core;
175 /** The name of the variable (points into variable_strcache). */
176 const char *pszName;
177 } KMKCCEXPPLAINVAR;
178 typedef KMKCCEXPPLAINVAR *PKMKCCEXPPLAINVAR;
179
180 /**
181 * kKmkCcExpInstr_DynamicVariable instruction format.
182 */
183 typedef struct kmk_cc_exp_dynamic_variable
184 {
185 /** The core instruction. */
186 KMKCCEXPCORE Core;
187 /** Where to continue after this instruction. (This is necessary since the
188 * instructions of the subprogram are emitted after this instruction.) */
189 PKMKCCEXPCORE pNext;
190 /** The subprogram that will give us the variable name. */
191 KMKCCEXPSUBPROG SubProg;
192 } KMKCCEXPDYNVAR;
193 typedef KMKCCEXPDYNVAR *PKMKCCEXPDYNVAR;
194
195 /**
196 * kKmkCcExpInstr_SearchAndReplacePlainVariable instruction format.
197 */
198 typedef struct kmk_cc_exp_sr_plain_variable
199 {
200 /** The core instruction. */
201 KMKCCEXPCORE Core;
202 /** Where to continue after this instruction. (This is necessary since the
203 * instruction contains string data of variable size.) */
204 PKMKCCEXPCORE pNext;
205 /** The name of the variable (points into variable_strcache). */
206 const char *pszName;
207 /** Search pattern. */
208 const char *pszSearchPattern;
209 /** Replacement pattern. */
210 const char *pszReplacePattern;
211 /** Offset into pszSearchPattern of the significant '%' char. */
212 uint32_t offPctSearchPattern;
213 /** Offset into pszReplacePattern of the significant '%' char. */
214 uint32_t offPctReplacePattern;
215 } KMKCCEXPSRPLAINVAR;
216 typedef KMKCCEXPSRPLAINVAR *PKMKCCEXPSRPLAINVAR;
217
218 /**
219 * Instruction format parts common to both kKmkCcExpInstr_PlainFunction and
220 * kKmkCcExpInstr_DynamicFunction.
221 */
222 typedef struct kmk_cc_exp_function_core
223 {
224 /** The core instruction. */
225 KMKCCEXPCORE Core;
226 /** Number of arguments. */
227 uint32_t cArgs;
228 /** Set if the function could be modifying the input arguments. */
229 uint8_t fDirty;
230 /** Where to continue after this instruction. (This is necessary since the
231 * instructions are of variable size and may be followed by string data.) */
232 PKMKCCEXPCORE pNext;
233 /**
234 * Pointer to the function table entry.
235 *
236 * @returns New variable buffer position.
237 * @param pchDst Current variable buffer position.
238 * @param papszArgs Pointer to a NULL terminated array of argument strings.
239 * @param pszFuncName The name of the function being called.
240 */
241 char * (*pfnFunction)(char *pchDst, char **papszArgs, const char *pszFuncName);
242 /** Pointer to the function name in the variable string cache. */
243 const char *pszFuncName;
244 } KMKCCEXPFUNCCORE;
245 typedef KMKCCEXPFUNCCORE *PKMKCCEXPFUNCCORE;
246
247 /**
248 * Instruction format for kKmkCcExpInstr_PlainFunction.
249 */
250 typedef struct kmk_cc_exp_plain_function
251 {
252 /** The bits comment to both plain and dynamic functions. */
253 KMKCCEXPFUNCCORE Core;
254 /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
255 * The string pointers are to memory following this instruction, to memory in
256 * the next block or to memory in the variable / makefile we're working on
257 * (if zero terminated appropriately). */
258 const char *apszArgs[1];
259 } KMKCCEXPPLAINFUNC;
260 typedef KMKCCEXPPLAINFUNC *PKMKCCEXPPLAINFUNC;
261 /** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
262 #define KMKCCEXPPLAINFUNC_SIZE(a_cArgs) (sizeof(KMKCCEXPFUNCCORE) + (a_cArgs + 1) * sizeof(const char *))
263
264 /**
265 * Instruction format for kKmkCcExpInstr_DynamicFunction.
266 */
267 typedef struct kmk_cc_exp_dyn_function
268 {
269 /** The bits comment to both plain and dynamic functions. */
270 KMKCCEXPFUNCCORE Core;
271 /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
272 * The string pointers are to memory following this instruction, to memory in
273 * the next block or to memory in the variable / makefile we're working on
274 * (if zero terminated appropriately). */
275 struct
276 {
277 /** Set if plain string argument, clear if sub program. */
278 uint8_t fPlain;
279 union
280 {
281 /** Sub program for expanding this argument. */
282 KMKCCEXPSUBPROG SubProg;
283 struct
284 {
285 /** Pointer to the plain argument string.
286 * This is allocated in the same manner as the
287 * string pointed to by KMKCCEXPPLAINFUNC::apszArgs. */
288 const char *pszArg;
289 } Plain;
290 } u;
291 } aArgs[1];
292 } KMKCCEXPDYNFUNC;
293 typedef KMKCCEXPDYNFUNC *PKMKCCEXPDYNFUNC;
294 /** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
295 #define KMKCCEXPDYNFUNC_SIZE(a_cArgs) ( sizeof(KMKCCEXPFUNCCORE) \
296 + (a_cArgs) * sizeof(((PKMKCCEXPDYNFUNC)(uintptr_t)42)->aArgs[0]) )
297
298 /**
299 * Instruction format for kKmkCcExpInstr_Jump.
300 */
301 typedef struct kmk_cc_exp_jump
302 {
303 /** The core instruction. */
304 KMKCCEXPCORE Core;
305 /** Where to jump to (new instruction block, typically). */
306 PKMKCCEXPCORE pNext;
307 } KMKCCEXPJUMP;
308 typedef KMKCCEXPJUMP *PKMKCCEXPJUMP;
309
310 /**
311 * String expansion program.
312 */
313 typedef struct kmk_cc_expandprog
314 {
315 /** Pointer to the first instruction for this program. */
316 PKMKCCEXPCORE pFirstInstr;
317 /** List of blocks for this program (LIFO). */
318 PKMKCCBLOCK pBlockTail;
319 /** Statistics. */
320 KMKCCEXPSTATS Stats;
321 #ifdef KMK_CC_STRICT
322 /** The hash of the input string. Used to check that we get all the change
323 * notifications we require. */
324 uint32_t uInputHash;
325 #endif
326 /** Reference count. */
327 uint32_t volatile cRefs;
328 } KMKCCEXPPROG;
329 /** Pointer to a string expansion program. */
330 typedef KMKCCEXPPROG *PKMKCCEXPPROG;
331
332
333 /*******************************************************************************
334 * Global Variables *
335 *******************************************************************************/
336 static uint32_t g_cVarForExpandCompilations = 0;
337 static uint32_t g_cVarForExpandExecs = 0;
338 #ifdef KMK_CC_WITH_STATS
339 static uint32_t g_cBlockAllocated = 0;
340 static uint32_t g_cbAllocated = 0;
341 static uint32_t g_cBlocksAllocatedExpProgs = 0;
342 static uint32_t g_cbAllocatedExpProgs = 0;
343 static uint32_t g_cSingleBlockExpProgs = 0;
344 static uint32_t g_cTwoBlockExpProgs = 0;
345 static uint32_t g_cMultiBlockExpProgs = 0;
346 static uint32_t g_cbUnusedMemExpProgs = 0;
347 #endif
348
349
350 /*******************************************************************************
351 * Internal Functions *
352 *******************************************************************************/
353 static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg);
354 static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcch);
355
356
357 /**
358 * Initializes global variables for the 'compiler'.
359 */
360 void kmk_cc_init(void)
361 {
362 }
363
364
365 /**
366 * Prints stats (for kmk -p).
367 */
368 void kmk_cc_print_stats(void)
369 {
370 puts(_("\n# The kmk 'compiler' and kmk 'program executor':\n"));
371
372 printf(_("# Variables compiled for string expansion: %6u\n"), g_cVarForExpandCompilations);
373 printf(_("# Variables string expansion runs: %6u\n"), g_cVarForExpandExecs);
374 printf(_("# String expansion runs per compile: %6u\n"), g_cVarForExpandExecs / g_cVarForExpandExecs);
375 #ifdef KMK_CC_WITH_STATS
376 printf(_("# Single alloc block exp progs: %6u (%u%%)\n"
377 "# Two alloc block exp progs: %6u (%u%%)\n"
378 "# Three or more alloc block exp progs: %6u (%u%%)\n"
379 ),
380 g_cSingleBlockExpProgs, (uint32_t)((uint64_t)g_cSingleBlockExpProgs * 100 / g_cVarForExpandCompilations),
381 g_cTwoBlockExpProgs, (uint32_t)((uint64_t)g_cTwoBlockExpProgs * 100 / g_cVarForExpandCompilations),
382 g_cMultiBlockExpProgs, (uint32_t)((uint64_t)g_cMultiBlockExpProgs * 100 / g_cVarForExpandCompilations));
383 printf(_("# Total amount of memory for exp progs: %8u bytes\n"
384 "# in: %6u blocks\n"
385 "# avg block size: %6u bytes\n"
386 "# unused memory: %8u bytes (%u%%)\n"
387 "# avg unused memory per block: %6u bytes\n"
388 "\n"),
389 g_cbAllocatedExpProgs, g_cBlocksAllocatedExpProgs, g_cbAllocatedExpProgs / g_cBlocksAllocatedExpProgs,
390 g_cbUnusedMemExpProgs, (uint32_t)((uint64_t)g_cbUnusedMemExpProgs * 100 / g_cbAllocatedExpProgs),
391 g_cbUnusedMemExpProgs / g_cBlocksAllocatedExpProgs);
392
393 printf(_("# Total amount of block mem allocated: %8u bytes\n"), g_cbAllocated);
394 printf(_("# Total number of block allocated: %8u\n"), g_cBlockAllocated);
395 printf(_("# Average block size: %8u byte\n"), g_cbAllocated / g_cBlockAllocated);
396 #endif
397
398 puts("");
399 }
400
401
402 /*
403 *
404 * Various utility functions.
405 * Various utility functions.
406 * Various utility functions.
407 *
408 */
409
410 /**
411 * Counts the number of dollar chars in the string.
412 *
413 * @returns Number of dollar chars.
414 * @param pchStr The string to search (does not need to be zero
415 * terminated).
416 * @param cchStr The length of the string.
417 */
418 static uint32_t kmk_cc_count_dollars(const char *pchStr, uint32_t cchStr)
419 {
420 uint32_t cDollars = 0;
421 const char *pch;
422 while ((pch = memchr(pchStr, '$', cchStr)) != NULL)
423 {
424 cDollars++;
425 cchStr -= pch - pchStr + 1;
426 pchStr = pch + 1;
427 }
428 return cDollars;
429 }
430
431 #ifdef KMK_CC_STRICT
432 /**
433 * Used to check that function arguments are left alone.
434 * @returns Updated hash.
435 * @param uHash The current hash value.
436 * @param psz The string to hash.
437 */
438 static uint32_t kmk_cc_debug_string_hash(uint32_t uHash, const char *psz)
439 {
440 unsigned char ch;
441 while ((ch = *(unsigned char const *)psz++) != '\0')
442 uHash = (uHash << 6) + (uHash << 16) - uHash + (unsigned char)ch;
443 return uHash;
444 }
445
446 /**
447 * Used to check that function arguments are left alone.
448 * @returns Updated hash.
449 * @param uHash The current hash value.
450 * @param pch The string to hash, not terminated.
451 * @param cch The number of chars to hash.
452 */
453 static uint32_t kmk_cc_debug_string_hash_n(uint32_t uHash, const char *pch, uint32_t cch)
454 {
455 while (cch-- > 0)
456 {
457 unsigned char ch = *(unsigned char const *)pch++;
458 uHash = (uHash << 6) + (uHash << 16) - uHash + (unsigned char)ch;
459 }
460 return uHash;
461 }
462
463 #endif
464
465
466
467 /*
468 *
469 * The allocator.
470 * The allocator.
471 * The allocator.
472 *
473 */
474
475
476 /**
477 * For the first allocation using the block allocator.
478 *
479 * @returns Pointer to the first allocation (@a cbFirst in size).
480 * @param ppBlockTail Where to return the pointer to the first block.
481 * @param cbFirst The size of the first allocation.
482 * @param cbHint Hint about how much memory we might be needing.
483 */
484 static void *kmk_cc_block_alloc_first(PKMKCCBLOCK *ppBlockTail, size_t cbFirst, size_t cbHint)
485 {
486 uint32_t cbBlock;
487 PKMKCCBLOCK pNewBlock;
488
489 KMK_CC_ASSERT_ALIGNED(cbFirst, sizeof(void *));
490
491 /*
492 * Turn the hint into a block size.
493 */
494 if (cbHint <= 512)
495 {
496 if (cbHint <= 256)
497 cbBlock = 128;
498 else
499 cbBlock = 256;
500 }
501 else if (cbHint < 2048)
502 cbBlock = 1024;
503 else if (cbHint < 3072)
504 cbBlock = 2048;
505 else
506 cbBlock = 4096;
507
508 /*
509 * Allocate and initialize the first block.
510 */
511 pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
512 pNewBlock->cbBlock = cbBlock;
513 pNewBlock->offNext = sizeof(*pNewBlock) + cbFirst;
514 pNewBlock->pNext = NULL;
515 *ppBlockTail = pNewBlock;
516
517 #ifdef KMK_CC_WITH_STATS
518 g_cBlockAllocated++;
519 g_cbAllocated += cbBlock;
520 #endif
521
522 return pNewBlock + 1;
523 }
524
525
526 /**
527 * Used for getting the address of the next instruction.
528 *
529 * @returns Pointer to the next allocation.
530 * @param pBlockTail The allocator tail pointer.
531 */
532 static void *kmk_cc_block_get_next_ptr(PKMKCCBLOCK pBlockTail)
533 {
534 return (char *)pBlockTail + pBlockTail->offNext;
535 }
536
537
538 /**
539 * Realigns the allocator after doing byte or string allocations.
540 *
541 * @param ppBlockTail Pointer to the allocator tail pointer.
542 */
543 static void kmk_cc_block_realign(PKMKCCBLOCK *ppBlockTail)
544 {
545 PKMKCCBLOCK pBlockTail = *ppBlockTail;
546 if (pBlockTail->offNext & (sizeof(void *) - 1))
547 {
548 pBlockTail->offNext = (pBlockTail->offNext + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
549 KMK_CC_ASSERT(pBlockTail->cbBlock - pBlockTail->offNext >= sizeof(KMKCCEXPJUMP));
550 }
551 }
552
553
554 /**
555 * Grows the allocation with another block, byte allocator case.
556 *
557 * @returns Pointer to the byte allocation.
558 * @param ppBlockTail Pointer to the allocator tail pointer.
559 * @param cb The number of bytes to allocate.
560 */
561 static void *kmk_cc_block_byte_alloc_grow(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
562 {
563 PKMKCCBLOCK pOldBlock = *ppBlockTail;
564 PKMKCCBLOCK pPrevBlock = pOldBlock->pNext;
565 PKMKCCBLOCK pNewBlock;
566 uint32_t cbBlock;
567
568 /*
569 * Check if there accidentally is some space left in the previous block first.
570 */
571 if ( pPrevBlock
572 && pPrevBlock->cbBlock - pPrevBlock->offNext >= cb)
573 {
574 void *pvRet = (char *)pPrevBlock + pPrevBlock->offNext;
575 pPrevBlock->offNext += cb;
576 return pvRet;
577 }
578
579 /*
580 * Allocate a new block.
581 */
582
583 /* Figure the block size. */
584 cbBlock = pOldBlock->cbBlock;
585 while (cbBlock - sizeof(KMKCCEXPJUMP) - sizeof(*pNewBlock) < cb)
586 cbBlock *= 2;
587
588 /* Allocate and initialize the block it with the new instruction already accounted for. */
589 pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
590 pNewBlock->cbBlock = cbBlock;
591 pNewBlock->offNext = sizeof(*pNewBlock) + cb;
592 pNewBlock->pNext = pOldBlock;
593 *ppBlockTail = pNewBlock;
594
595 #ifdef KMK_CC_WITH_STATS
596 g_cBlockAllocated++;
597 g_cbAllocated += cbBlock;
598 #endif
599
600 return pNewBlock + 1;
601 }
602
603
604 /**
605 * Make a byte allocation.
606 *
607 * Must call kmk_cc_block_realign() when done doing byte and string allocations.
608 *
609 * @returns Pointer to the byte allocation (byte aligned).
610 * @param ppBlockTail Pointer to the allocator tail pointer.
611 * @param cb The number of bytes to allocate.
612 */
613 static void *kmk_cc_block_byte_alloc(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
614 {
615 PKMKCCBLOCK pBlockTail = *ppBlockTail;
616 uint32_t cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
617
618 KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
619 if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
620 {
621 void *pvRet = (char *)pBlockTail + pBlockTail->offNext;
622 pBlockTail->offNext += cb;
623 return pvRet;
624 }
625 return kmk_cc_block_byte_alloc_grow(ppBlockTail, cb);
626 }
627
628
629 /**
630 * Duplicates the given string in a byte allocation.
631 *
632 * Must call kmk_cc_block_realign() when done doing byte and string allocations.
633 *
634 * @returns Pointer to the byte allocation (byte aligned).
635 * @param ppBlockTail Pointer to the allocator tail pointer.
636 * @param cb The number of bytes to allocate.
637 */
638 static const char *kmk_cc_block_strdup(PKMKCCBLOCK *ppBlockTail, const char *pachStr, uint32_t cchStr)
639 {
640 char *pszCopy;
641 if (cchStr)
642 {
643 pszCopy = kmk_cc_block_byte_alloc(ppBlockTail, cchStr + 1);
644 memcpy(pszCopy, pachStr, cchStr);
645 pszCopy[cchStr] = '\0';
646 return pszCopy;
647 }
648 return "";
649 }
650
651
652 /**
653 * Grows the allocation with another block, string expansion program case.
654 *
655 * @returns Pointer to a string expansion instruction core.
656 * @param ppBlockTail Pointer to the allocator tail pointer.
657 * @param cb The number of bytes to allocate.
658 */
659 static PKMKCCEXPCORE kmk_cc_block_alloc_exp_grow(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
660 {
661 PKMKCCBLOCK pOldBlock = *ppBlockTail;
662 PKMKCCBLOCK pNewBlock;
663 PKMKCCEXPCORE pRet;
664 PKMKCCEXPJUMP pJump;
665
666 /* Figure the block size. */
667 uint32_t cbBlock = !pOldBlock->pNext ? 128 : pOldBlock->cbBlock;
668 while (cbBlock - sizeof(KMKCCEXPJUMP) - sizeof(*pNewBlock) < cb)
669 cbBlock *= 2;
670
671 /* Allocate and initialize the block it with the new instruction already accounted for. */
672 pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
673 pNewBlock->cbBlock = cbBlock;
674 pNewBlock->offNext = sizeof(*pNewBlock) + cb;
675 pNewBlock->pNext = pOldBlock;
676 *ppBlockTail = pNewBlock;
677
678 #ifdef KMK_CC_WITH_STATS
679 g_cBlockAllocated++;
680 g_cbAllocated += cbBlock;
681 #endif
682
683 pRet = (PKMKCCEXPCORE)(pNewBlock + 1);
684
685 /* Emit jump. */
686 pJump = (PKMKCCEXPJUMP)((char *)pOldBlock + pOldBlock->offNext);
687 pJump->Core.enmOpCode = kKmkCcExpInstr_Jump;
688 pJump->pNext = pRet;
689 pOldBlock->offNext += sizeof(*pJump);
690 KMK_CC_ASSERT(pOldBlock->offNext <= pOldBlock->cbBlock);
691
692 return pRet;
693 }
694
695
696 /**
697 * Allocates a string expansion instruction of size @a cb.
698 *
699 * @returns Pointer to a string expansion instruction core.
700 * @param ppBlockTail Pointer to the allocator tail pointer.
701 * @param cb The number of bytes to allocate.
702 */
703 static PKMKCCEXPCORE kmk_cc_block_alloc_exp(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
704 {
705 PKMKCCBLOCK pBlockTail = *ppBlockTail;
706 uint32_t cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
707
708 KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
709 KMK_CC_ASSERT( (cb & (sizeof(void *) - 1)) == 0 || cb == sizeof(KMKCCEXPCORE) /* final */ );
710
711 if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
712 {
713 PKMKCCEXPCORE pRet = (PKMKCCEXPCORE)((char *)pBlockTail + pBlockTail->offNext);
714 pBlockTail->offNext += cb;
715 return pRet;
716 }
717 return kmk_cc_block_alloc_exp_grow(ppBlockTail, cb);
718 }
719
720
721 /**
722 * Frees all memory used by an allocator.
723 *
724 * @param ppBlockTail The allocator tail pointer.
725 */
726 static void kmk_cc_block_free_list(PKMKCCBLOCK pBlockTail)
727 {
728 while (pBlockTail)
729 {
730 PKMKCCBLOCK pThis = pBlockTail;
731 pBlockTail = pBlockTail->pNext;
732 free(pThis);
733 }
734 }
735
736
737 /*
738 *
739 * The string expansion compiler.
740 * The string expansion compiler.
741 * The string expansion compiler.
742 *
743 */
744
745
746 /**
747 * Emits a kKmkCcExpInstr_Return.
748 *
749 * @param ppBlockTail Pointer to the allocator tail pointer.
750 */
751 static void kmk_cc_exp_emit_return(PKMKCCBLOCK *ppBlockTail)
752 {
753 PKMKCCEXPCORE pCore = kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pCore));
754 pCore->enmOpCode = kKmkCcExpInstr_Return;
755 }
756
757
758 /**
759 * Checks if a function is known to mess up the arguments its given.
760 *
761 * When executing calls to "dirty" functions, all arguments must be duplicated
762 * on the heap.
763 *
764 * @returns 1 if dirty, 0 if clean.
765 * @param pszFunction The function name.
766 */
767 static uint8_t kmk_cc_is_dirty_function(const char *pszFunction)
768 {
769 switch (pszFunction[0])
770 {
771 default:
772 return 0;
773
774 case 'e':
775 if (!strcmp(pszFunction, "eval"))
776 return 1;
777 if (!strcmp(pszFunction, "evalctx"))
778 return 1;
779 return 0;
780
781 case 'f':
782 if (!strcmp(pszFunction, "filter"))
783 return 1;
784 if (!strcmp(pszFunction, "filter-out"))
785 return 1;
786 if (!strcmp(pszFunction, "for"))
787 return 1;
788 return 0;
789
790 case 's':
791 if (!strcmp(pszFunction, "sort"))
792 return 1;
793 return 0;
794 }
795 }
796
797
798 /**
799 * Emits a function call instruction taking arguments that needs expanding.
800 *
801 * @returns 0 on success, non-zero on failure.
802 * @param ppBlockTail Pointer to the allocator tail pointer.
803 * @param pszFunction The function name (const string from function.c).
804 * @param pchArgs Pointer to the arguments expression string, leading
805 * any blanks has been stripped.
806 * @param cchArgs The length of the arguments expression string.
807 * @param cArgs Number of arguments found.
808 * @param chOpen The char used to open the function call.
809 * @param chClose The char used to close the function call.
810 * @param pfnFunction The function implementation.
811 * @param cMaxArgs Maximum number of arguments the function takes.
812 */
813 static int kmk_cc_exp_emit_dyn_function(PKMKCCBLOCK *ppBlockTail, const char *pszFunction,
814 const char *pchArgs, uint32_t cchArgs, uint32_t cArgs, char chOpen, char chClose,
815 make_function_ptr_t pfnFunction, unsigned char cMaxArgs)
816 {
817 uint32_t iArg;
818
819 /*
820 * The function instruction has variable size. The maximum argument count
821 * isn't quite like the minium one. Zero means no limit. While a non-zero
822 * value means that any commas beyond the max will be taken to be part of
823 * the final argument.
824 */
825 uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
826 PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPDYNFUNC_SIZE(cActualArgs));
827 pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
828 pInstr->Core.cArgs = cActualArgs;
829 pInstr->Core.pfnFunction = pfnFunction;
830 pInstr->Core.pszFuncName = pszFunction;
831 pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
832
833 /*
834 * Parse the arguments. Plain arguments gets duplicated in the program
835 * memory so that they are terminated and no extra processing is necessary
836 * later on. ASSUMES that the function implementations do NOT change
837 * argument memory. Other arguments the compiled into their own expansion
838 * sub programs.
839 */
840 iArg = 0;
841 for (;;)
842 {
843 /* Find the end of the argument. Check for $. */
844 char ch = '\0';
845 uint8_t fDollar = 0;
846 int32_t cDepth = 0;
847 uint32_t cchThisArg = 0;
848 while (cchThisArg < cchArgs)
849 {
850 ch = pchArgs[cchThisArg];
851 if (ch == chClose)
852 {
853 KMK_CC_ASSERT(cDepth > 0);
854 if (cDepth > 0)
855 cDepth--;
856 }
857 else if (ch == chOpen)
858 cDepth++;
859 else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
860 break;
861 else if (ch == '$')
862 fDollar = 1;
863 cchThisArg++;
864 }
865
866 pInstr->aArgs[iArg].fPlain = !fDollar;
867 if (fDollar)
868 {
869 /* Compile it. */
870 int rc;
871 kmk_cc_block_realign(ppBlockTail);
872 rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.SubProg);
873 if (rc != 0)
874 return rc;
875 }
876 else
877 {
878 /* Duplicate it. */
879 pInstr->aArgs[iArg].u.Plain.pszArg = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
880 }
881 iArg++;
882 if (ch != ',')
883 break;
884 pchArgs += cchThisArg + 1;
885 cchArgs -= cchThisArg + 1;
886 }
887 KMK_CC_ASSERT(iArg == cActualArgs);
888
889 /*
890 * Realign the allocator and take down the address of the next instruction.
891 */
892 kmk_cc_block_realign(ppBlockTail);
893 pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
894 return 0;
895 }
896
897
898 /**
899 * Emits a function call instruction taking plain arguments.
900 *
901 * @returns 0 on success, non-zero on failure.
902 * @param ppBlockTail Pointer to the allocator tail pointer.
903 * @param pszFunction The function name (const string from function.c).
904 * @param pchArgs Pointer to the arguments string, leading any blanks
905 * has been stripped.
906 * @param cchArgs The length of the arguments string.
907 * @param cArgs Number of arguments found.
908 * @param chOpen The char used to open the function call.
909 * @param chClose The char used to close the function call.
910 * @param pfnFunction The function implementation.
911 * @param cMaxArgs Maximum number of arguments the function takes.
912 */
913 static void kmk_cc_exp_emit_plain_function(PKMKCCBLOCK *ppBlockTail, const char *pszFunction,
914 const char *pchArgs, uint32_t cchArgs, uint32_t cArgs, char chOpen, char chClose,
915 make_function_ptr_t pfnFunction, unsigned char cMaxArgs)
916 {
917 uint32_t iArg;
918
919 /*
920 * The function instruction has variable size. The maximum argument count
921 * isn't quite like the minium one. Zero means no limit. While a non-zero
922 * value means that any commas beyond the max will be taken to be part of
923 * the final argument.
924 */
925 uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
926 PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPPLAINFUNC_SIZE(cActualArgs));
927 pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
928 pInstr->Core.cArgs = cActualArgs;
929 pInstr->Core.pfnFunction = pfnFunction;
930 pInstr->Core.pszFuncName = pszFunction;
931 pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
932
933 /*
934 * Parse the arguments. Plain arguments gets duplicated in the program
935 * memory so that they are terminated and no extra processing is necessary
936 * later on. ASSUMES that the function implementations do NOT change
937 * argument memory.
938 */
939 iArg = 0;
940 for (;;)
941 {
942 /* Find the end of the argument. */
943 char ch = '\0';
944 int32_t cDepth = 0;
945 uint32_t cchThisArg = 0;
946 while (cchThisArg < cchArgs)
947 {
948 ch = pchArgs[cchThisArg];
949 if (ch == chClose)
950 {
951 KMK_CC_ASSERT(cDepth > 0);
952 if (cDepth > 0)
953 cDepth--;
954 }
955 else if (ch == chOpen)
956 cDepth++;
957 else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
958 break;
959 cchThisArg++;
960 }
961
962 /* Duplicate it. */
963 pInstr->apszArgs[iArg++] = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
964 if (ch != ',')
965 break;
966 pchArgs += cchThisArg + 1;
967 cchArgs -= cchThisArg + 1;
968 }
969
970 KMK_CC_ASSERT(iArg == cActualArgs);
971 pInstr->apszArgs[iArg] = NULL;
972
973 /*
974 * Realign the allocator and take down the address of the next instruction.
975 */
976 kmk_cc_block_realign(ppBlockTail);
977 pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
978 }
979
980
981 /**
982 * Emits a kKmkCcExpInstr_DynamicVariable.
983 *
984 * @returns 0 on success, non-zero on failure.
985 * @param ppBlockTail Pointer to the allocator tail pointer.
986 * @param pchNameExpr The name of the variable (ASSUMED presistent
987 * thru-out the program life time).
988 * @param cchNameExpr The length of the variable name. If zero,
989 * nothing will be emitted.
990 */
991 static int kmk_cc_exp_emit_dyn_variable(PKMKCCBLOCK *ppBlockTail, const char *pchNameExpr, uint32_t cchNameExpr)
992 {
993 PKMKCCEXPDYNVAR pInstr;
994 int rc;
995 KMK_CC_ASSERT(cchNameExpr > 0);
996
997 pInstr = (PKMKCCEXPDYNVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
998 pInstr->Core.enmOpCode = kKmkCcExpInstr_DynamicVariable;
999
1000 rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->SubProg);
1001
1002 pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
1003 return rc;
1004 }
1005
1006
1007 /**
1008 * Emits either a kKmkCcExpInstr_PlainVariable or
1009 * kKmkCcExpInstr_SearchAndReplacePlainVariable instruction.
1010 *
1011 * @param ppBlockTail Pointer to the allocator tail pointer.
1012 * @param pchName The name of the variable. (Does not need to be
1013 * valid beyond the call.)
1014 * @param cchName The length of the variable name. If zero,
1015 * nothing will be emitted.
1016 */
1017 static void kmk_cc_exp_emit_plain_variable_maybe_sr(PKMKCCBLOCK *ppBlockTail, const char *pchName, uint32_t cchName)
1018 {
1019 if (cchName > 0)
1020 {
1021 /*
1022 * Hopefully, we're not expected to do any search and replace on the
1023 * expanded variable string later... Requires both ':' and '='.
1024 */
1025 const char *pchEqual;
1026 const char *pchColon = (const char *)memchr(pchName, ':', cchName);
1027 if ( pchColon == NULL
1028 || (pchEqual = (const char *)memchr(pchColon + 1, ':', cchName - (pchColon - pchName - 1))) == NULL
1029 || pchEqual == pchEqual + 1)
1030 {
1031 PKMKCCEXPPLAINVAR pInstr = (PKMKCCEXPPLAINVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
1032 pInstr->Core.enmOpCode = kKmkCcExpInstr_PlainVariable;
1033 pInstr->pszName = strcache2_add(&variable_strcache, pchName, cchName);
1034 }
1035 else if (pchColon != pchName)
1036 {
1037 /*
1038 * Okay, we need to do search and replace the variable value.
1039 * This is performed by patsubst_expand_pat using '%' patterns.
1040 */
1041 uint32_t cchName2 = (uint32_t)(pchColon - pchName);
1042 uint32_t cchSearch = (uint32_t)(pchEqual - pchColon - 1);
1043 uint32_t cchReplace = cchName - cchName2 - cchSearch - 2;
1044 const char *pchPct;
1045 char *psz;
1046 PKMKCCEXPSRPLAINVAR pInstr;
1047
1048 pInstr = (PKMKCCEXPSRPLAINVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
1049 pInstr->Core.enmOpCode = kKmkCcExpInstr_SearchAndReplacePlainVariable;
1050 pInstr->pszName = strcache2_add(&variable_strcache, pchName, cchName2);
1051
1052 /* Figure out the search pattern, unquoting percent chars.. */
1053 psz = (char *)kmk_cc_block_byte_alloc(ppBlockTail, cchSearch + 2);
1054 psz[0] = '%';
1055 memcpy(psz + 1, pchColon + 1, cchSearch);
1056 psz[1 + cchSearch] = '\0';
1057 pchPct = find_percent(psz + 1); /* also performs unquoting */
1058 if (pchPct)
1059 {
1060 pInstr->pszSearchPattern = psz + 1;
1061 pInstr->offPctSearchPattern = (uint32_t)(pchPct - psz - 1);
1062 }
1063 else
1064 {
1065 pInstr->pszSearchPattern = psz;
1066 pInstr->offPctSearchPattern = 0;
1067 }
1068
1069 /* Figure out the replacement pattern, unquoting percent chars.. */
1070 if (cchReplace == 0)
1071 {
1072 pInstr->pszReplacePattern = "%";
1073 pInstr->offPctReplacePattern = 0;
1074 }
1075 else
1076 {
1077 psz = (char *)kmk_cc_block_byte_alloc(ppBlockTail, cchReplace + 2);
1078 psz[0] = '%';
1079 memcpy(psz + 1, pchEqual + 1, cchReplace);
1080 psz[1 + cchReplace] = '\0';
1081 pchPct = find_percent(psz + 1); /* also performs unquoting */
1082 if (pchPct)
1083 {
1084 pInstr->pszReplacePattern = psz + 1;
1085 pInstr->offPctReplacePattern = (uint32_t)(pchPct - psz - 1);
1086 }
1087 else
1088 {
1089 pInstr->pszReplacePattern = psz;
1090 pInstr->offPctReplacePattern = 0;
1091 }
1092 }
1093
1094 /* Note down where the next instruction is after realigning the allocator. */
1095 kmk_cc_block_realign(ppBlockTail);
1096 pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
1097 }
1098 }
1099 }
1100
1101
1102 /**
1103 * Emits a kKmkCcExpInstr_CopyString.
1104 *
1105 * @param ppBlockTail Pointer to the allocator tail pointer.
1106 * @param pchStr The string to emit (ASSUMED presistent thru-out
1107 * the program life time).
1108 * @param cchStr The number of chars to copy. If zero, nothing
1109 * will be emitted.
1110 */
1111 static void kmk_cc_exp_emit_copy_string(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr)
1112 {
1113 if (cchStr > 0)
1114 {
1115 PKMKCCEXPCOPYSTRING pInstr = (PKMKCCEXPCOPYSTRING)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
1116 pInstr->Core.enmOpCode = kKmkCcExpInstr_CopyString;
1117 pInstr->cchCopy = cchStr;
1118 pInstr->pachSrc = pchStr;
1119 }
1120 }
1121
1122
1123 /**
1124 * String expansion compilation function common to both normal and sub programs.
1125 *
1126 * @returns 0 on success, non-zero on failure.
1127 * @param ppBlockTail Pointer to the allocator tail pointer.
1128 * @param pchStr The expression to compile.
1129 * @param cchStr The length of the expression to compile.
1130 */
1131 static int kmk_cc_exp_compile_common(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr)
1132 {
1133 /*
1134 * Process the string.
1135 */
1136 while (cchStr > 0)
1137 {
1138 /* Look for dollar sign, marks variable expansion or dollar-escape. */
1139 int rc;
1140 const char *pchDollar = memchr(pchStr, '$', cchStr);
1141 if (pchDollar)
1142 {
1143 /*
1144 * Check for multiple dollar chars.
1145 */
1146 uint32_t offDollar = (uint32_t)(pchDollar - pchStr);
1147 uint32_t cDollars = 1;
1148 while ( offDollar + cDollars < cchStr
1149 && pchStr[offDollar + cDollars] == '$')
1150 cDollars++;
1151
1152 /*
1153 * Emit a string copy for any preceeding stuff, including half of
1154 * the dollars we found (dollar escape: $$ -> $).
1155 * (kmk_cc_exp_emit_copy_string ignore zero length strings).
1156 */
1157 kmk_cc_exp_emit_copy_string(ppBlockTail, pchStr, offDollar + cDollars / 2);
1158 pchStr += offDollar + cDollars;
1159 cchStr -= offDollar + cDollars;
1160
1161 /*
1162 * Odd number of dollar chars means there is a variable to expand
1163 * or function to call.
1164 */
1165 if (cDollars & 1)
1166 {
1167 if (cchStr > 0)
1168 {
1169 char const chOpen = *pchStr;
1170 if (chOpen == '(' || chOpen == '{')
1171 {
1172 /* There are several alternative ways of finding the ending
1173 parenthesis / braces.
1174
1175 GNU make does one thing for functions and variable containing
1176 any '$' chars before the first closing char. While for
1177 variables where a closing char comes before any '$' char, a
1178 simplified approach is taken. This means that for example:
1179
1180 Given VAR=var, the expressions "$(var())" and
1181 "$($(VAR)())" would be expanded differently.
1182 In the first case the variable "var(" would be
1183 used and in the second "var()".
1184
1185 This code will not duplicate this weird behavior, but work
1186 the same regardless of whether there is a '$' char before
1187 the first closing char. */
1188 make_function_ptr_t pfnFunction;
1189 const char *pszFunction;
1190 unsigned char cMaxArgs;
1191 unsigned char cMinArgs;
1192 char fExpandArgs;
1193 char const chClose = chOpen == '(' ? ')' : '}';
1194 char ch = 0;
1195 uint32_t cchName = 0;
1196 uint32_t cDepth = 1;
1197 uint32_t cMaxDepth = 1;
1198 cDollars = 0;
1199
1200 pchStr++;
1201 cchStr--;
1202
1203 /* First loop: Identify potential function calls and dynamic expansion. */
1204 KMK_CC_ASSERT(!func_char_map[chOpen]);
1205 KMK_CC_ASSERT(!func_char_map[chClose]);
1206 KMK_CC_ASSERT(!func_char_map['$']);
1207 while (cchName < cchStr)
1208 {
1209 ch = pchStr[cchName];
1210 if (!func_char_map[(int)ch])
1211 break;
1212 cchName++;
1213 }
1214
1215 if ( cchName >= MIN_FUNCTION_LENGTH
1216 && cchName <= MAX_FUNCTION_LENGTH
1217 && (isblank(ch) || ch == chClose || cchName == cchStr)
1218 && (pfnFunction = lookup_function_for_compiler(pchStr, cchName, &cMinArgs, &cMaxArgs,
1219 &fExpandArgs, &pszFunction)) != NULL)
1220 {
1221 /*
1222 * It's a function invocation, we should count parameters while
1223 * looking for the end.
1224 * Note! We use cchName for the length of the argument list.
1225 */
1226 uint32_t cArgs = 1;
1227 if (ch != chClose)
1228 {
1229 /* Skip leading spaces before the first arg. */
1230 cchName++;
1231 while (cchName < cchStr && isblank((unsigned char)pchStr[cchName]))
1232 cchName++;
1233
1234 pchStr += cchName;
1235 cchStr -= cchName;
1236 cchName = 0;
1237
1238 while (cchName < cchStr)
1239 {
1240 ch = pchStr[cchName];
1241 if (ch == ',')
1242 {
1243 if (cDepth == 1)
1244 cArgs++;
1245 }
1246 else if (ch == chClose)
1247 {
1248 if (!--cDepth)
1249 break;
1250 }
1251 else if (ch == chOpen)
1252 {
1253 if (++cDepth > cMaxDepth)
1254 cMaxDepth = cDepth;
1255 }
1256 else if (ch == '$')
1257 cDollars++;
1258 cchName++;
1259 }
1260 }
1261 else
1262 {
1263 pchStr += cchName;
1264 cchStr -= cchName;
1265 cchName = 0;
1266 }
1267 if (cArgs < cMinArgs)
1268 {
1269 fatal(NULL, _("Function '%.*s' takes a minimum of %d arguments: %d given"),
1270 pszFunction, (int)cMinArgs, (int)cArgs);
1271 return -1; /* not reached */
1272 }
1273 if (cDepth != 0)
1274 {
1275 fatal(NULL, chOpen == '('
1276 ? _("Missing closing parenthesis calling '%s'") : _("Missing closing braces calling '%s'"),
1277 pszFunction);
1278 return -1; /* not reached */
1279 }
1280 if (cMaxDepth > 16 && fExpandArgs)
1281 {
1282 fatal(NULL, _("Too many levels of nested function arguments expansions: %s"), pszFunction);
1283 return -1; /* not reached */
1284 }
1285 if (!fExpandArgs || cDollars == 0)
1286 kmk_cc_exp_emit_plain_function(ppBlockTail, pszFunction, pchStr, cchName,
1287 cArgs, chOpen, chClose, pfnFunction, cMaxArgs);
1288 else
1289 {
1290 rc = kmk_cc_exp_emit_dyn_function(ppBlockTail, pszFunction, pchStr, cchName,
1291 cArgs, chOpen, chClose, pfnFunction, cMaxArgs);
1292 if (rc != 0)
1293 return rc;
1294 }
1295 }
1296 else
1297 {
1298 /*
1299 * Variable, find the end while checking whether anything needs expanding.
1300 */
1301 if (ch == chClose)
1302 cDepth = 0;
1303 else if (cchName < cchStr)
1304 {
1305 if (ch != '$')
1306 {
1307 /* Second loop: Look for things that needs expanding. */
1308 while (cchName < cchStr)
1309 {
1310 ch = pchStr[cchName];
1311 if (ch == chClose)
1312 {
1313 if (!--cDepth)
1314 break;
1315 }
1316 else if (ch == chOpen)
1317 {
1318 if (++cDepth > cMaxDepth)
1319 cMaxDepth = cDepth;
1320 }
1321 else if (ch == '$')
1322 break;
1323 cchName++;
1324 }
1325 }
1326 if (ch == '$')
1327 {
1328 /* Third loop: Something needs expanding, just find the end. */
1329 cDollars = 1;
1330 cchName++;
1331 while (cchName < cchStr)
1332 {
1333 ch = pchStr[cchName];
1334 if (ch == chClose)
1335 {
1336 if (!--cDepth)
1337 break;
1338 }
1339 else if (ch == chOpen)
1340 {
1341 if (++cDepth > cMaxDepth)
1342 cMaxDepth = cDepth;
1343 }
1344 cchName++;
1345 }
1346 }
1347 }
1348 if (cDepth > 0) /* After warning, we just assume they're all there. */
1349 error(NULL, chOpen == '(' ? _("Missing closing parenthesis ") : _("Missing closing braces"));
1350 if (cMaxDepth >= 16)
1351 {
1352 fatal(NULL, _("Too many levels of nested variable expansions: '%.*s'"), (int)cchName + 2, pchStr - 1);
1353 return -1; /* not reached */
1354 }
1355 if (cDollars == 0)
1356 kmk_cc_exp_emit_plain_variable_maybe_sr(ppBlockTail, pchStr, cchName);
1357 else
1358 {
1359 rc = kmk_cc_exp_emit_dyn_variable(ppBlockTail, pchStr, cchName);
1360 if (rc != 0)
1361 return rc;
1362 }
1363 }
1364 pchStr += cchName + 1;
1365 cchStr -= cchName + (cDepth == 0);
1366 }
1367 else
1368 {
1369 /* Single character variable name. */
1370 kmk_cc_exp_emit_plain_variable_maybe_sr(ppBlockTail, pchStr, 1);
1371 pchStr++;
1372 cchStr--;
1373 }
1374 }
1375 else
1376 {
1377 error(NULL, _("Unexpected end of string after $"));
1378 break;
1379 }
1380 }
1381 }
1382 else
1383 {
1384 /*
1385 * Nothing more to expand, the remainder is a simple string copy.
1386 */
1387 kmk_cc_exp_emit_copy_string(ppBlockTail, pchStr, cchStr);
1388 break;
1389 }
1390 }
1391
1392 /*
1393 * Emit final instruction.
1394 */
1395 kmk_cc_exp_emit_return(ppBlockTail);
1396 return 0;
1397 }
1398
1399
1400 /**
1401 * Initializes string expansion program statistics.
1402 * @param pStats Pointer to the statistics structure to init.
1403 */
1404 static void kmk_cc_exp_stats_init(PKMKCCEXPSTATS pStats)
1405 {
1406 pStats->cchAvg = 0;
1407 }
1408
1409
1410 /**
1411 * Compiles a string expansion sub program.
1412 *
1413 * The caller typically make a call to kmk_cc_block_get_next_ptr after this
1414 * function returns to figure out where to continue executing.
1415 *
1416 * @returns 0 on success, non-zero on failure.
1417 * @param ppBlockTail Pointer to the allocator tail pointer.
1418 * @param pchStr Pointer to the string to compile an expansion
1419 * program for (ASSUMED to be valid for the
1420 * lifetime of the program).
1421 * @param cchStr The length of the string to compile. Expected to
1422 * be at least on char long.
1423 * @param pSubProg The sub program structure to initialize.
1424 */
1425 static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg)
1426 {
1427 KMK_CC_ASSERT(cchStr > 0);
1428 pSubProg->pFirstInstr = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
1429 kmk_cc_exp_stats_init(&pSubProg->Stats);
1430 return kmk_cc_exp_compile_common(ppBlockTail, pchStr, cchStr);
1431 }
1432
1433
1434 /**
1435 * Compiles a string expansion program.
1436 *
1437 * @returns Pointer to the program on success, NULL on failure.
1438 * @param pchStr Pointer to the string to compile an expansion
1439 * program for (ASSUMED to be valid for the
1440 * lifetime of the program).
1441 * @param cchStr The length of the string to compile. Expected to
1442 * be at least on char long.
1443 */
1444 static PKMKCCEXPPROG kmk_cc_exp_compile(const char *pchStr, uint32_t cchStr)
1445 {
1446 /*
1447 * Estimate block size, allocate one and initialize it.
1448 */
1449 PKMKCCEXPPROG pProg;
1450 PKMKCCBLOCK pBlock;
1451 pProg = kmk_cc_block_alloc_first(&pBlock, sizeof(*pProg),
1452 (kmk_cc_count_dollars(pchStr, cchStr) + 4) * 8);
1453 if (pProg)
1454 {
1455 int rc = 0;
1456
1457 pProg->pBlockTail = pBlock;
1458 pProg->pFirstInstr = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(pBlock);
1459 kmk_cc_exp_stats_init(&pProg->Stats);
1460 pProg->cRefs = 1;
1461 #ifdef KMK_CC_STRICT
1462 pProg->uInputHash = kmk_cc_debug_string_hash_n(0, pchStr, cchStr);
1463 #endif
1464
1465 /*
1466 * Join forces with the sub program compilation code.
1467 */
1468 if (kmk_cc_exp_compile_common(&pProg->pBlockTail, pchStr, cchStr) == 0)
1469 {
1470 #ifdef KMK_CC_WITH_STATS
1471 pBlock = pProg->pBlockTail;
1472 if (!pBlock->pNext)
1473 g_cSingleBlockExpProgs++;
1474 else if (!pBlock->pNext->pNext)
1475 g_cTwoBlockExpProgs++;
1476 else
1477 g_cMultiBlockExpProgs++;
1478 for (; pBlock; pBlock = pBlock->pNext)
1479 {
1480 g_cBlocksAllocatedExpProgs++;
1481 g_cbAllocatedExpProgs += pBlock->cbBlock;
1482 g_cbUnusedMemExpProgs += pBlock->cbBlock - pBlock->offNext;
1483 }
1484 #endif
1485 return pProg;
1486 }
1487 kmk_cc_block_free_list(pProg->pBlockTail);
1488 }
1489 return NULL;
1490 }
1491
1492
1493 /**
1494 * Compiles a variable direct evaluation as is, setting v->evalprog on success.
1495 *
1496 * @returns Pointer to the program on success, NULL if no program was created.
1497 * @param pVar Pointer to the variable.
1498 */
1499 struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar)
1500 {
1501 return NULL;
1502 }
1503
1504
1505 /**
1506 * Updates the recursive_without_dollar member of a variable structure.
1507 *
1508 * This avoid compiling string expansion programs without only a CopyString
1509 * instruction. By setting recursive_without_dollar to 1, code calling
1510 * kmk_cc_compile_variable_for_expand and kmk_exec_expand_to_var_buf will
1511 * instead treat start treating it as a simple variable, which is faster.
1512 *
1513 * @returns The updated recursive_without_dollar value.
1514 * @param pVar Pointer to the variable.
1515 */
1516 static int kmk_cc_update_variable_recursive_without_dollar(struct variable *pVar)
1517 {
1518 int fValue;
1519 KMK_CC_ASSERT(pVar->recursive_without_dollar == 0);
1520
1521 if (memchr(pVar->value, '$', pVar->value_length))
1522 fValue = -1;
1523 else
1524 fValue = 1;
1525 pVar->recursive_without_dollar = fValue;
1526
1527 return fValue;
1528 }
1529
1530
1531 /**
1532 * Compiles a variable for string expansion.
1533 *
1534 * @returns Pointer to the string expansion program on success, NULL if no
1535 * program was created.
1536 * @param pVar Pointer to the variable.
1537 */
1538 struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar)
1539 {
1540 KMK_CC_ASSERT(strlen(pVar->value) == pVar->value_length);
1541 KMK_CC_ASSERT(!pVar->expandprog);
1542 KMK_CC_ASSERT(pVar->recursive_without_dollar <= 0);
1543
1544 if ( !pVar->expandprog
1545 && pVar->recursive)
1546 {
1547 if ( pVar->recursive_without_dollar < 0
1548 || ( pVar->recursive_without_dollar == 0
1549 && kmk_cc_update_variable_recursive_without_dollar(pVar) < 0) )
1550 {
1551 pVar->expandprog = kmk_cc_exp_compile(pVar->value, pVar->value_length);
1552 g_cVarForExpandCompilations++;
1553 }
1554 }
1555 return pVar->expandprog;
1556 }
1557
1558
1559 /**
1560 * String expansion execution worker for outputting a variable.
1561 *
1562 * @returns The new variable buffer position.
1563 * @param pVar The variable to reference.
1564 * @param pchDst The current variable buffer position.
1565 */
1566 static char *kmk_exec_expand_worker_reference_variable(struct variable *pVar, char *pchDst)
1567 {
1568 if (pVar->value_length > 0)
1569 {
1570 if (!pVar->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar))
1571 pchDst = variable_buffer_output(pchDst, pVar->value, pVar->value_length);
1572 else
1573 pchDst = reference_recursive_variable(pchDst, pVar);
1574 }
1575 else if (pVar->append)
1576 pchDst = reference_recursive_variable(pchDst, pVar);
1577 return pchDst;
1578 }
1579
1580
1581 /**
1582 * Executes a stream string expansion instructions, outputting to the current
1583 * varaible buffer.
1584 *
1585 * @returns The new variable buffer position.
1586 * @param pInstrCore The instruction to start executing at.
1587 * @param pchDst The current variable buffer position.
1588 */
1589 static char *kmk_exec_expand_instruction_stream_to_var_buf(PKMKCCEXPCORE pInstrCore, char *pchDst)
1590 {
1591 for (;;)
1592 {
1593 switch (pInstrCore->enmOpCode)
1594 {
1595 case kKmkCcExpInstr_CopyString:
1596 {
1597 PKMKCCEXPCOPYSTRING pInstr = (PKMKCCEXPCOPYSTRING)pInstrCore;
1598 pchDst = variable_buffer_output(pchDst, pInstr->pachSrc, pInstr->cchCopy);
1599
1600 pInstrCore = &(pInstr + 1)->Core;
1601 break;
1602 }
1603
1604 case kKmkCcExpInstr_PlainVariable:
1605 {
1606 PKMKCCEXPPLAINVAR pInstr = (PKMKCCEXPPLAINVAR)pInstrCore;
1607 struct variable *pVar = lookup_variable_strcached(pInstr->pszName);
1608 if (pVar)
1609 pchDst = kmk_exec_expand_worker_reference_variable(pVar, pchDst);
1610 else
1611 warn_undefined(pInstr->pszName, strcache2_get_len(&variable_strcache, pInstr->pszName));
1612
1613 pInstrCore = &(pInstr + 1)->Core;
1614 break;
1615 }
1616
1617 case kKmkCcExpInstr_DynamicVariable:
1618 {
1619 PKMKCCEXPDYNVAR pInstr = (PKMKCCEXPDYNVAR)pInstrCore;
1620 struct variable *pVar;
1621 uint32_t cchName;
1622 char *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->SubProg, &cchName);
1623 char *pszColon = (char *)memchr(pszName, ':', cchName);
1624 char *pszEqual;
1625 if ( pszColon == NULL
1626 || (pszEqual = (char *)memchr(pszColon + 1, '=', &pszName[cchName] - pszColon - 1)) == NULL
1627 || pszEqual == pszColon + 1)
1628 {
1629 pVar = lookup_variable(pszName, cchName);
1630 if (pVar)
1631 pchDst = kmk_exec_expand_worker_reference_variable(pVar, pchDst);
1632 else
1633 warn_undefined(pszName, cchName);
1634 }
1635 else if (pszColon != pszName)
1636 {
1637 /*
1638 * Oh, we have to do search and replace. How tedious.
1639 * Since the variable name is a temporary buffer, we can transform
1640 * the strings into proper search and replacement patterns directly.
1641 */
1642 pVar = lookup_variable(pszName, pszColon - pszName);
1643 if (pVar)
1644 {
1645 char const *pszExpandedVarValue = pVar->recursive ? recursively_expand(pVar) : pVar->value;
1646 char *pszSearchPat = pszColon + 1;
1647 char *pszReplacePat = pszEqual + 1;
1648 const char *pchPctSearchPat;
1649 const char *pchPctReplacePat;
1650
1651 *pszEqual = '\0';
1652 pchPctSearchPat = find_percent(pszSearchPat);
1653 pchPctReplacePat = find_percent(pszReplacePat);
1654
1655 if (!pchPctReplacePat)
1656 {
1657 if (pszReplacePat[-2] != '\0') /* On the offchance that a pct was unquoted by find_percent. */
1658 {
1659 memmove(pszName + 1, pszSearchPat, pszReplacePat - pszSearchPat);
1660 if (pchPctSearchPat)
1661 pchPctSearchPat -= pszSearchPat - &pszName[1];
1662 pszSearchPat = &pszName[1];
1663 }
1664 pchPctReplacePat = --pszReplacePat;
1665 *pszReplacePat = '%';
1666 }
1667
1668 if (!pchPctSearchPat)
1669 {
1670 pchPctSearchPat = --pszSearchPat;
1671 *pszSearchPat = '%';
1672 }
1673
1674 pchDst = patsubst_expand_pat(pchDst, pszExpandedVarValue,
1675 pszSearchPat, pszReplacePat,
1676 pchPctSearchPat, pchPctReplacePat);
1677
1678 if (pVar->recursive)
1679 free((void *)pszExpandedVarValue);
1680 }
1681 else
1682 warn_undefined(pszName, pszColon - pszName);
1683 }
1684 free(pszName);
1685
1686 pInstrCore = pInstr->pNext;
1687 break;
1688 }
1689
1690
1691 case kKmkCcExpInstr_SearchAndReplacePlainVariable:
1692 {
1693 PKMKCCEXPSRPLAINVAR pInstr = (PKMKCCEXPSRPLAINVAR)pInstrCore;
1694 struct variable *pVar = lookup_variable_strcached(pInstr->pszName);
1695 if (pVar)
1696 {
1697 char const *pszExpandedVarValue = pVar->recursive ? recursively_expand(pVar) : pVar->value;
1698 pchDst = patsubst_expand_pat(pchDst,
1699 pszExpandedVarValue,
1700 pInstr->pszSearchPattern,
1701 pInstr->pszReplacePattern,
1702 &pInstr->pszSearchPattern[pInstr->offPctSearchPattern],
1703 &pInstr->pszReplacePattern[pInstr->offPctReplacePattern]);
1704 if (pVar->recursive)
1705 free((void *)pszExpandedVarValue);
1706 }
1707 else
1708 warn_undefined(pInstr->pszName, strcache2_get_len(&variable_strcache, pInstr->pszName));
1709
1710 pInstrCore = pInstr->pNext;
1711 break;
1712 }
1713
1714 case kKmkCcExpInstr_PlainFunction:
1715 {
1716 PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)pInstrCore;
1717 uint32_t iArg;
1718 if (!pInstr->Core.fDirty)
1719 {
1720 #ifdef KMK_CC_STRICT
1721 uint32_t uCrcBefore = 0;
1722 uint32_t uCrcAfter = 0;
1723 iArg = pInstr->Core.cArgs;
1724 while (iArg-- > 0)
1725 uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
1726 #endif
1727
1728 pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
1729
1730 #ifdef KMK_CC_STRICT
1731 iArg = pInstr->Core.cArgs;
1732 while (iArg-- > 0)
1733 uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
1734 KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
1735 #endif
1736 }
1737 else
1738 {
1739 char **papszShadowArgs = xmalloc((pInstr->Core.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
1740 char **papszArgs = &papszShadowArgs[pInstr->Core.cArgs];
1741
1742 iArg = pInstr->Core.cArgs;
1743 papszArgs[iArg] = NULL;
1744 while (iArg-- > 0)
1745 papszArgs[iArg] = papszShadowArgs[iArg] = xstrdup(pInstr->apszArgs[iArg]);
1746
1747 pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
1748
1749 iArg = pInstr->Core.cArgs;
1750 while (iArg-- > 0)
1751 free(papszShadowArgs[iArg]);
1752 free(papszShadowArgs);
1753 }
1754
1755 pInstrCore = pInstr->Core.pNext;
1756 break;
1757 }
1758
1759 case kKmkCcExpInstr_DynamicFunction:
1760 {
1761 PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)pInstrCore;
1762 char **papszArgsShadow = xmalloc( (pInstr->Core.cArgs * 2 + 1) * sizeof(char *));
1763 char **papszArgs = &papszArgsShadow[pInstr->Core.cArgs];
1764 uint32_t iArg;
1765
1766 if (!pInstr->Core.fDirty)
1767 {
1768 #ifdef KMK_CC_STRICT
1769 uint32_t uCrcBefore = 0;
1770 uint32_t uCrcAfter = 0;
1771 #endif
1772 iArg = pInstr->Core.cArgs;
1773 papszArgs[iArg] = NULL;
1774 while (iArg-- > 0)
1775 {
1776 char *pszArg;
1777 if (!pInstr->aArgs[iArg].fPlain)
1778 pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
1779 else
1780 pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
1781 papszArgsShadow[iArg] = pszArg;
1782 papszArgs[iArg] = pszArg;
1783 #ifdef KMK_CC_STRICT
1784 uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pszArg);
1785 #endif
1786 }
1787 pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
1788
1789 iArg = pInstr->Core.cArgs;
1790 while (iArg-- > 0)
1791 {
1792 #ifdef KMK_CC_STRICT
1793 KMK_CC_ASSERT(papszArgsShadow[iArg] == papszArgs[iArg]);
1794 uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
1795 #endif
1796 if (!pInstr->aArgs[iArg].fPlain)
1797 free(papszArgsShadow[iArg]);
1798 }
1799 KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
1800 }
1801 else
1802 {
1803 iArg = pInstr->Core.cArgs;
1804 papszArgs[iArg] = NULL;
1805 while (iArg-- > 0)
1806 {
1807 char *pszArg;
1808 if (!pInstr->aArgs[iArg].fPlain)
1809 pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
1810 else
1811 pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.pszArg);
1812 papszArgsShadow[iArg] = pszArg;
1813 papszArgs[iArg] = pszArg;
1814 }
1815
1816 pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
1817
1818 iArg = pInstr->Core.cArgs;
1819 while (iArg-- > 0)
1820 free(papszArgsShadow[iArg]);
1821 }
1822 free(papszArgsShadow);
1823
1824 pInstrCore = pInstr->Core.pNext;
1825 break;
1826 }
1827
1828 case kKmkCcExpInstr_Jump:
1829 {
1830 PKMKCCEXPJUMP pInstr = (PKMKCCEXPJUMP)pInstrCore;
1831 pInstrCore = pInstr->pNext;
1832 break;
1833 }
1834
1835 case kKmkCcExpInstr_Return:
1836 return pchDst;
1837
1838 default:
1839 fatal(NULL, _("Unknown string expansion opcode: %d (%#x)"),
1840 (int)pInstrCore->enmOpCode, (int)pInstrCore->enmOpCode);
1841 return NULL;
1842 }
1843 }
1844 }
1845
1846
1847 /**
1848 * Updates the string expansion statistics.
1849 *
1850 * @param pStats The statistics structure to update.
1851 * @param cchResult The result lenght.
1852 */
1853 void kmk_cc_exp_stats_update(PKMKCCEXPSTATS pStats, uint32_t cchResult)
1854 {
1855 /*
1856 * The average is simplified and not an exact average for every
1857 * expansion that has taken place.
1858 */
1859 pStats->cchAvg = (pStats->cchAvg * 7 + cchResult) / 8;
1860 }
1861
1862
1863 /**
1864 * Execute a string expansion sub-program, outputting to a new heap buffer.
1865 *
1866 * @returns Pointer to the output buffer (hand to free when done).
1867 * @param pSubProg The sub-program to execute.
1868 * @param pcchResult Where to return the size of the result. Optional.
1869 */
1870 static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcchResult)
1871 {
1872 char *pchOldVarBuf;
1873 unsigned int cbOldVarBuf;
1874 char *pchDst;
1875 char *pszResult;
1876 uint32_t cchResult;
1877
1878 /*
1879 * Temporarily replace the variable buffer while executing the instruction
1880 * stream for this sub program.
1881 */
1882 pchDst = install_variable_buffer_with_hint(&pchOldVarBuf, &cbOldVarBuf,
1883 pSubProg->Stats.cchAvg ? pSubProg->Stats.cchAvg + 32 : 256);
1884
1885 pchDst = kmk_exec_expand_instruction_stream_to_var_buf(pSubProg->pFirstInstr, pchDst);
1886
1887 /* Ensure that it's terminated. */
1888 pchDst = variable_buffer_output(pchDst, "\0", 1) - 1;
1889
1890 /* Grab the result buffer before restoring the previous one. */
1891 pszResult = variable_buffer;
1892 cchResult = (uint32_t)(pchDst - pszResult);
1893 if (pcchResult)
1894 *pcchResult = cchResult;
1895 kmk_cc_exp_stats_update(&pSubProg->Stats, cchResult);
1896
1897 variable_buffer = pchOldVarBuf;
1898 variable_buffer_length = cbOldVarBuf;
1899
1900 return pszResult;
1901 }
1902
1903
1904 /**
1905 * Execute a string expansion program, outputting to the current variable
1906 * buffer.
1907 *
1908 * @returns New variable buffer position.
1909 * @param pProg The program to execute.
1910 * @param pchDst The current varaible buffer position.
1911 */
1912 static char *kmk_exec_expand_prog_to_var_buf(PKMKCCEXPPROG pProg, char *pchDst)
1913 {
1914 uint32_t cchResult;
1915 uint32_t offStart = (uint32_t)(pchDst - variable_buffer);
1916
1917 if (pProg->Stats.cchAvg >= variable_buffer_length - offStart)
1918 pchDst = ensure_variable_buffer_space(pchDst, offStart + pProg->Stats.cchAvg + 32);
1919
1920 KMK_CC_ASSERT(pProg->cRefs > 0);
1921 pProg->cRefs++;
1922
1923 pchDst = kmk_exec_expand_instruction_stream_to_var_buf(pProg->pFirstInstr, pchDst);
1924
1925 pProg->cRefs--;
1926 KMK_CC_ASSERT(pProg->cRefs > 0);
1927
1928 cchResult = (uint32_t)(pchDst - variable_buffer);
1929 KMK_CC_ASSERT(cchResult >= offStart);
1930 cchResult -= offStart;
1931 kmk_cc_exp_stats_update(&pProg->Stats, cchResult);
1932 g_cVarForExpandExecs++;
1933
1934 return pchDst;
1935 }
1936
1937
1938 /**
1939 * Equivalent of eval_buffer, only it's using the evalprog of the variable.
1940 *
1941 * @param pVar Pointer to the variable. Must have a program.
1942 */
1943 void kmk_exec_evalval(struct variable *pVar)
1944 {
1945 KMK_CC_ASSERT(pVar->evalprog);
1946 assert(0);
1947 }
1948
1949
1950 /**
1951 * Expands a variable into a variable buffer using its expandprog.
1952 *
1953 * @returns The new variable buffer position.
1954 * @param pVar Pointer to the variable. Must have a program.
1955 * @param pchDst Pointer to the current variable buffer position.
1956 */
1957 char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst)
1958 {
1959 KMK_CC_ASSERT(pVar->expandprog);
1960 KMK_CC_ASSERT(pVar->expandprog->uInputHash == kmk_cc_debug_string_hash(0, pVar->value));
1961 return kmk_exec_expand_prog_to_var_buf(pVar->expandprog, pchDst);
1962 }
1963
1964
1965 /**
1966 * Called when a variable with expandprog or/and evalprog changes.
1967 *
1968 * @param pVar Pointer to the variable.
1969 */
1970 void kmk_cc_variable_changed(struct variable *pVar)
1971 {
1972 PKMKCCEXPPROG pProg = pVar->expandprog;
1973
1974 KMK_CC_ASSERT(pVar->evalprog || pProg);
1975
1976 #if 0
1977 if (pVar->evalprog)
1978 {
1979 kmk_cc_block_free_list(pVar->evalprog->pBlockTail);
1980 pVar->evalprog = NULL;
1981 }
1982 #endif
1983
1984 if (pProg)
1985 {
1986 if (pProg->cRefs == 1)
1987 kmk_cc_block_free_list(pProg->pBlockTail);
1988 else
1989 fatal(NULL, _("Modifying a variable (%s) while its expansion program is running is not supported"), pVar->name);
1990 pVar->expandprog = NULL;
1991 }
1992 }
1993
1994
1995 /**
1996 * Called when a variable with expandprog or/and evalprog is deleted.
1997 *
1998 * @param pVar Pointer to the variable.
1999 */
2000 void kmk_cc_variable_deleted(struct variable *pVar)
2001 {
2002 PKMKCCEXPPROG pProg = pVar->expandprog;
2003
2004 KMK_CC_ASSERT(pVar->evalprog || pProg);
2005
2006 #if 0
2007 if (pVar->evalprog)
2008 {
2009 kmk_cc_block_free_list(pVar->evalprog->pBlockTail);
2010 pVar->evalprog = NULL;
2011 }
2012 #endif
2013
2014 if (pProg)
2015 {
2016 if (pProg->cRefs == 1)
2017 kmk_cc_block_free_list(pProg->pBlockTail);
2018 else
2019 fatal(NULL, _("Deleting a variable (%s) while its expansion program is running is not supported"), pVar->name);
2020 pVar->expandprog = NULL;
2021 }
2022 }
2023
2024
2025 #endif /* CONFIG_WITH_COMPILER */
2026
0 /* $Id: kmk_cc_exec.h 2773 2015-02-03 12:59:54Z bird $ */
1 /** @file
2 * kmk_cc - Make "Compiler".
3 */
4
5 /*
6 * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx@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 3 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, see <http://www.gnu.org/licenses/>
22 *
23 */
24
25 #ifndef ___kmk_cc_and_exech
26 #define ___kmk_cc_and_exech
27 #ifdef CONFIG_WITH_COMPILER
28
29
30
31 void kmk_cc_init(void);
32 void kmk_cc_print_stats(void);
33
34 struct variable;
35 extern struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar);
36 extern struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar);
37 extern char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst);
38 extern void kmk_exec_evalval(struct variable *pVar);
39 extern void kmk_cc_variable_changed(struct variable *pVar);
40 extern void kmk_cc_variable_deleted(struct variable *pVar);
41
42
43 #endif /* CONFIG_WITH_COMPILER */
44 #endif
0 /* $Id: append.c 2466 2011-07-12 09:52:39Z bird $ */
0 /* $Id: append.c 2771 2015-02-01 20:48:36Z bird $ */
11 /** @file
22 * kMk Builtin command - append text to file.
33 */
216216 struct variable *pVar = lookup_variable(psz, cch);
217217 if (!pVar)
218218 continue;
219 if ( pVar->recursive
220 && memchr(pVar->value, '$', pVar->value_length))
219 if ( !pVar->recursive
220 || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar))
221 fwrite(pVar->value, 1, pVar->value_length, pFile);
222 else
221223 {
222224 char *pszExpanded = allocated_variable_expand(pVar->value);
223225 fwrite(pszExpanded, 1, strlen(pszExpanded), pFile);
224226 free(pszExpanded);
225227 }
226 else
227 fwrite(pVar->value, 1, pVar->value_length, pFile);
228228 }
229229 else
230230 #endif
7171 errexit(const char *prog, const char *reason)
7272 {
7373 char *errstr = strerror(errno);
74 #ifdef _MSC_VER
75 int doserrno = _doserrno;
76 char szDosErr[48];
77 sprintf(szDosErr, " (doserrno=%d)", doserrno);
78 #endif
7479 write(STDERR_FILENO, prog, strlen(prog));
7580 write(STDERR_FILENO, ": ", 2);
7681 write(STDERR_FILENO, reason, strlen(reason));
7782 write(STDERR_FILENO, ": ", 2);
7883 write(STDERR_FILENO, errstr, strlen(errstr));
84 #ifdef _MSC_VER
85 write(STDERR_FILENO, szDosErr, strlen(szDosErr));
86 #endif
7987 write(STDERR_FILENO, "\n", 1);
8088 }
8189
0 /* $Id: kDepObj.c 2591 2012-06-17 20:45:31Z bird $ */
0 /* $Id: kDepObj.c 2759 2015-01-28 16:14:00Z bird $ */
11 /** @file
22 * kDepObj - Extract dependency information from an object file.
33 */
2525 /*******************************************************************************
2626 * Header Files *
2727 *******************************************************************************/
28 #define MSCFAKES_NO_WINDOWS_H
2829 #include "config.h"
2930 #include <stdio.h>
3031 #include <stdlib.h>
0 /* $Id: mscfakes.c 2733 2014-10-16 18:29:41Z bird $ */
0 /* $Id: mscfakes.c 2759 2015-01-28 16:14:00Z bird $ */
11 /** @file
22 * Fake Unix stuff for MSC.
33 */
44
55 /*
6 * Copyright (c) 2005-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
6 * Copyright (c) 2005-2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
77 *
88 * This file is part of kBuild.
99 *
2626 * Header Files *
2727 *******************************************************************************/
2828 #include "config.h"
29 #include <assert.h>
2930 #include <stdarg.h>
3031 #include <stdio.h>
3132 #include <stdlib.h>
4041 #define timeval windows_timeval
4142 #include <Windows.h>
4243 #undef timeval
44
45 /*******************************************************************************
46 * Internal Functions *
47 *******************************************************************************/
48 static BOOL isPipeFd(int fd);
4349
4450
4551 /**
459465 }
460466
461467
462 int writev(int fd, const struct iovec *vector, int count)
468 /* We override the libc write function (in our modules only, unfortunately) so
469 we can kludge our way around a ENOSPC problem observed on build servers
470 capturing STDOUT and STDERR via pipes. Apparently this may happen when the
471 pipe buffer is full, even with the mscfake_init hack in place.
472
473 XXX: Probably need to hook into fwrite as well. */
474 ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc)
475 {
476 ssize_t cbRet;
477 if (cbSrc < UINT_MAX / 4)
478 {
479 #ifndef MSC_WRITE_TEST
480 cbRet = _write(fd, pvSrc, (unsigned int)cbSrc);
481 #else
482 cbRet = -1; errno = ENOSPC;
483 #endif
484 if (cbRet < 0)
485 {
486 /* ENOSPC on pipe kludge. */
487 int cbLimit;
488 int cSinceLastSuccess;
489
490 if (cbSrc == 0)
491 return 0;
492 if (errno != ENOSPC)
493 return -1;
494 #ifndef MSC_WRITE_TEST
495 if (!isPipeFd(fd))
496 {
497 errno = ENOSPC;
498 return -1;
499 }
500 #endif
501
502 /* Likely a full pipe buffer, try write smaller amounts and do some
503 sleeping inbetween each unsuccessful one. */
504 cbLimit = cbSrc / 4;
505 if (cbLimit < 4)
506 cbLimit = 4;
507 else if (cbLimit > 512)
508 cbLimit = 512;
509 cSinceLastSuccess = 0;
510 cbRet = 0;
511 #ifdef MSC_WRITE_TEST
512 cbLimit = 4;
513 #endif
514
515 while (cbSrc > 0)
516 {
517 unsigned int cbAttempt = cbSrc > cbLimit ? (int)cbLimit : (int)cbSrc;
518 ssize_t cbActual = _write(fd, pvSrc, cbAttempt);
519 if (cbActual > 0)
520 {
521 assert(cbActual <= (ssize_t)cbAttempt);
522 pvSrc = (char *)pvSrc + cbActual;
523 cbSrc -= cbActual;
524 cbRet += cbActual;
525 #ifndef MSC_WRITE_TEST
526 if (cbLimit < 32)
527 cbLimit = 32;
528 #endif
529 cSinceLastSuccess = 0;
530 }
531 else if (errno != ENOSPC)
532 return -1;
533 else
534 {
535 /* Delay for about 30 seconds, then just give up. */
536 cSinceLastSuccess++;
537 if (cSinceLastSuccess > 1860)
538 return -1;
539 if (cSinceLastSuccess <= 2)
540 Sleep(0);
541 else if (cSinceLastSuccess <= 66)
542 {
543 if (cbLimit >= 8)
544 cbLimit /= 2; /* Just in case the pipe buffer is very very small. */
545 Sleep(1);
546 }
547 else
548 Sleep(16);
549 }
550 }
551 }
552 }
553 else
554 {
555 /*
556 * Type limit exceeded. Split the job up.
557 */
558 cbRet = 0;
559 while (cbSrc > 0)
560 {
561 size_t cbToWrite = cbSrc > UINT_MAX / 4 ? UINT_MAX / 4 : cbSrc;
562 ssize_t cbWritten = msc_write(fd, pvSrc, cbToWrite);
563 if (cbWritten > 0)
564 {
565 pvSrc = (char *)pvSrc + (size_t)cbWritten;
566 cbSrc -= (size_t)cbWritten;
567 cbRet += (size_t)cbWritten;
568 }
569 else if (cbWritten == 0 || cbRet > 0)
570 break;
571 else
572 return -1;
573 }
574 }
575 return cbRet;
576 }
577
578 ssize_t writev(int fd, const struct iovec *vector, int count)
463579 {
464580 int size = 0;
465581 int i;
466582 for (i = 0; i < count; i++)
467583 {
468 int cb = (int)write(fd, vector[i].iov_base, (int)vector[i].iov_len);
584 int cb = msc_write(fd, vector[i].iov_base, (int)vector[i].iov_len);
469585 if (cb < 0)
470 return -1;
586 return cb;
471587 size += cb;
472588 }
473589 return size;
534650
535651
536652 /**
653 * Checks if the given file descriptor is a pipe or not.
654 *
655 * @returns TRUE if pipe, FALSE if not.
656 * @param fd The libc file descriptor number.
657 */
658 static BOOL isPipeFd(int fd)
659 {
660 /* Is pipe? */
661 HANDLE hFile = (HANDLE)_get_osfhandle(fd);
662 if (hFile != INVALID_HANDLE_VALUE)
663 {
664 DWORD fType = GetFileType(hFile);
665 fType &= ~FILE_TYPE_REMOTE;
666 if (fType == FILE_TYPE_PIPE)
667 return TRUE;
668 }
669 return FALSE;
670 }
671
672
673 /**
537674 * This is a kludge to make pipe handles blocking.
538675 *
539676 * @returns TRUE if it's now blocking, FALSE if not a pipe or we failed to fix
542679 */
543680 static BOOL makePipeBlocking(int fd)
544681 {
545 /* Is pipe? */
546 HANDLE hFile = (HANDLE)_get_osfhandle(fd);
547 if (hFile != INVALID_HANDLE_VALUE)
548 {
549 DWORD fType = GetFileType(hFile);
550 fType &= ~FILE_TYPE_REMOTE;
551 if (fType == FILE_TYPE_PIPE)
552 {
553 /* Try fix it. */
554 DWORD fState = 0;
555 if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL, 0))
556 {
557 fState &= ~PIPE_NOWAIT;
558 fState |= PIPE_WAIT;
559 if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
560 return TRUE;
561 }
682 if (isPipeFd(fd))
683 {
684 /* Try fix it. */
685 HANDLE hFile = (HANDLE)_get_osfhandle(fd);
686 DWORD fState = 0;
687 if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL, 0))
688 {
689 fState &= ~PIPE_NOWAIT;
690 fState |= PIPE_WAIT;
691 if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
692 return TRUE;
562693 }
563694 }
564695 return FALSE;
0 /* $Id: mscfakes.h 2713 2013-11-21 21:11:00Z bird $ */
0 /* $Id: mscfakes.h 2766 2015-01-30 03:32:38Z bird $ */
11 /** @file
22 * Unix fakes for MSC.
33 */
2626 #define ___mscfakes_h
2727 #ifdef _MSC_VER
2828
29 /* Include the config file (kmk's) so we don't need to duplicate stuff from it here. */
30 #include "config.h"
31
2932 #include <io.h>
3033 #include <direct.h>
3134 #include <time.h>
3235 #include <stdarg.h>
3336 #include <malloc.h>
3437 #include "getopt.h"
38 #ifndef MSCFAKES_NO_WINDOWS_H
39 # include <Windows.h>
40 #endif
3541
36 /* Note: Duplicated it config.h.win */
3742 #include <sys/stat.h>
3843 #include <io.h>
3944 #include <direct.h>
7782 typedef unsigned short uid_t;
7883 typedef unsigned short gid_t;
7984 #endif
85 #if defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64) || defined(_WIN64)
86 typedef __int64 ssize_t;
87 #else
8088 typedef long ssize_t;
89 #endif
8190 typedef unsigned long u_long;
8291 typedef unsigned int u_int;
8392 typedef unsigned short u_short;
8493
85 #ifndef timerisset
94 #if _MSC_VER >= 1600
95 # include <stdint.h>
96 #else
97 typedef unsigned char uint8_t;
98 typedef unsigned short uint16_t;
99 typedef unsigned int uint32_t;
100 typedef signed char int8_t;
101 typedef signed short int16_t;
102 typedef signed int int32_t;
103 #endif
104
105 #if !defined(timerisset) && defined(MSCFAKES_NO_WINDOWS_H)
86106 struct timeval
87107 {
88108 long tv_sec;
136156 #endif
137157 int symlink(const char *pszDst, const char *pszLink);
138158 int utimes(const char *pszPath, const struct timeval *paTimes);
139 int writev(int fd, const struct iovec *vector, int count);
159 ssize_t writev(int fd, const struct iovec *vector, int count);
140160
141
161 /* bird write ENOSPC hacks. */
162 #undef write
163 #define write msc_write
164 ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc);
142165
143166 /*
144167 * MSC fake internals / helpers.
0 /* $Id: redirect.c 2728 2014-03-05 13:09:47Z bird $ */
0 /* $Id: redirect.c 2779 2015-02-24 03:50:12Z bird $ */
11 /** @file
22 * kmk_redirect - Do simple program <-> file redirection (++).
33 */
5858 * For details on how MSC parses the command line, see "Parsing C Command-Line
5959 * Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
6060 *
61 * @param argc The argument count.
62 * @param argv The argument vector.
61 * @param argc The argument count.
62 * @param argv The argument vector.
63 * @param fWatcomBrainDamage Set if we're catering for wcc, wcc386 or similar
64 * OpenWatcom tools. They seem to follow some
65 * ancient or home made quoting convention.
6366 */
64 static void quoteArguments(int argc, char **argv)
67 static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage)
6568 {
6669 int i;
6770 for (i = 0; i < argc; i++)
6972 const char *pszOrg = argv[i];
7073 size_t cchOrg = strlen(pszOrg);
7174 const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg);
75 const char *pszProblem = NULL;
7276 if ( pszQuotes
7377 || cchOrg == 0
74 || memchr(pszOrg, ' ', cchOrg)
75 || memchr(pszOrg, '\t', cchOrg)
76 || memchr(pszOrg, '\n', cchOrg)
77 || memchr(pszOrg, '\r', cchOrg)
78 || memchr(pszOrg, '&', cchOrg)
79 || memchr(pszOrg, '>', cchOrg)
80 || memchr(pszOrg, '<', cchOrg)
81 || memchr(pszOrg, '|', cchOrg)
82 || memchr(pszOrg, '%', cchOrg)
83 || memchr(pszOrg, '\'', cchOrg)
84 || memchr(pszOrg, '=', cchOrg)
78 || (pszProblem = (const char *)memchr(pszOrg, ' ', cchOrg)) != NULL
79 || (pszProblem = (const char *)memchr(pszOrg, '\t', cchOrg)) != NULL
80 || (pszProblem = (const char *)memchr(pszOrg, '\n', cchOrg)) != NULL
81 || (pszProblem = (const char *)memchr(pszOrg, '\r', cchOrg)) != NULL
82 || (pszProblem = (const char *)memchr(pszOrg, '&', cchOrg)) != NULL
83 || (pszProblem = (const char *)memchr(pszOrg, '>', cchOrg)) != NULL
84 || (pszProblem = (const char *)memchr(pszOrg, '<', cchOrg)) != NULL
85 || (pszProblem = (const char *)memchr(pszOrg, '|', cchOrg)) != NULL
86 || (pszProblem = (const char *)memchr(pszOrg, '%', cchOrg)) != NULL
87 || (pszProblem = (const char *)memchr(pszOrg, '\'', cchOrg)) != NULL
88 || ( !fWatcomBrainDamage
89 && (pszProblem = (const char *)memchr(pszOrg, '=', cchOrg)) != NULL)
8590 )
8691 {
8792 char ch;
9095 char *pszNew = (char *)malloc(cchNew + 1);
9196
9297 argv[i] = pszNew;
98
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. */
101 if (fWatcomBrainDamage)
102 {
103 size_t cchUnquoted = 0;
104 if (pszOrg[0] == '@') /* Response file quoting: @"file name.rsp" */
105 cchUnquoted = 1;
106 else if (pszOrg[0] == '-' || pszOrg[0] == '/') /* Switch quoting. */
107 {
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;
112 else
113 pszNeedQuoting++;
114 cchUnquoted = pszNeedQuoting - pszOrg;
115 }
116 if (cchUnquoted)
117 {
118 memcpy(pszNew, pszOrg, cchUnquoted);
119 pszNew += cchUnquoted;
120 pszOrg += cchUnquoted;
121 cchOrg -= cchUnquoted;
122 }
123 }
93124
94125 *pszNew++ = '"';
95126 if (fComplicated)
186217 static int usage(FILE *pOut, const char *argv0)
187218 {
188219 fprintf(pOut,
189 "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] -- <program> [args]\n"
220 "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] -- <program> [args]\n"
190221 " or: %s --help\n"
191222 " or: %s --version\n"
192223 "\n"
206237 "The -C switch is for changing the current directory. This takes immediate\n"
207238 "effect, so be careful where you put it.\n"
208239 "\n"
240 "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n"
241 "not following normal quoting conventions on Windows, OS/2, and DOS.\n"
242 "\n"
209243 "This command was originally just a quick hack to avoid invoking the shell\n"
210244 "on Windows (cygwin) where forking is very expensive and has exhibited\n"
211245 "stability issues on SMP machines. It has since grown into something like\n"
224258 #endif
225259 FILE *pStdErr = stderr;
226260 FILE *pStdOut = stdout;
261 int fWatcomBrainDamage = 0;
227262
228263 /*
229264 * Parse arguments.
260295 psz = "Z";
261296 else if (!strcmp(psz, "-close"))
262297 psz = "c";
298 else if (!strcmp(psz, "-wcc-brain-damage"))
299 {
300 fWatcomBrainDamage = 1;
301 continue;
302 }
263303 }
264304
265305 /*
708748 }
709749
710750 /* MSC is a PITA since it refuses to quote the arguments... */
711 quoteArguments(argc - i, &argv[i]);
751 quoteArguments(argc - i, &argv[i], fWatcomBrainDamage);
712752 rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);
713753 if (rc == -1 && pStdErr)
714754 {
4444 #endif
4545 #ifdef HAVE_FCNTL_H
4646 # include <fcntl.h>
47 #endif
48 #ifdef CONFIG_WITH_COMPILER
49 # include "kmk_cc_exec.h"
4750 #endif
4851
4952 #ifdef KMK /* for get_online_cpu_count */
11591162 HANDLE hThread;
11601163 CONTEXT Ctx;
11611164
1165 /*fprintf(stderr, "dbg: ctrl_event sig=%d\n", sig);*/
11621166 #ifndef _M_IX86
11631167 /* only once. */
11641168 if (InterlockedExchange(&g_lTriggered, 1))
11911195 Ctx.Eip = (uintptr_t)&dispatch_stub;
11921196 #else
11931197 g_Ctx = Ctx;
1194 Ctx.Rsp -= 0x20;
1198 Ctx.Rsp -= 0x80;
11951199 Ctx.Rsp &= ~(uintptr_t)0xf;
1196 Ctx.Rip = (uintptr_t)&dispatch_stub;
1200 Ctx.Rsp += 8; /* (Stack aligned before call instruction, not after.) */
1201 Ctx.Rip = (uintptr_t)&dispatch_stub;
11971202 #endif
11981203
11991204 SetThreadContext(hThread, &Ctx);
13621367 struct dep *read_makefiles;
13631368 PATH_VAR (current_directory);
13641369 unsigned int restarts = 0;
1370 #ifdef CONFIG_WITH_MAKE_STATS
1371 unsigned long long uStartTick = CURRENT_CLOCK_TICK();
1372 #endif
13651373 #ifdef WINDOWS32
13661374 char *unix_path = NULL;
13671375 char *windows32_path = NULL;
15741582 /* Set up to access user data (files). */
15751583 user_access ();
15761584
1585 # ifdef CONFIG_WITH_COMPILER
1586 kmk_cc_init ();
1587 # endif
15771588 #ifdef CONFIG_WITH_ALLOC_CACHES
15781589 initialize_global_alloc_caches ();
15791590 #endif
29162927 error (NILF,
29172928 _("warning: Clock skew detected. Your build may be incomplete."));
29182929
2930 MAKE_STATS_2(if (uStartTick) printf("main ticks elapsed: %ull\n", (unsigned long long)(CURRENT_CLOCK_TICK() - uStartTick)) );
29192931 /* Exit. */
29202932 die (status);
29212933 }
38113823 #ifdef CONFIG_WITH_ALLOC_CACHES
38123824 alloccache_print_all ();
38133825 #endif
3826 #ifdef CONFIG_WITH_COMPILER
3827 kmk_cc_print_stats ();
3828 #endif
38143829
38153830 when = time ((time_t *) 0);
38163831 printf (_("\n# Finished Make data base on %s\n"), ctime (&when));
236236 #endif
237237
238238 /* bird - start */
239 #ifdef _MSC_VER
240 # include <intrin.h>
241 # define CURRENT_CLOCK_TICK() __rdtsc()
242 #else
243 # define CURRENT_CLOCK_TICK() 0
244 #endif
245
239246 #define COMMA ,
240247 #ifdef CONFIG_WITH_VALUE_LENGTH
241248 # define IF_WITH_VALUE_LENGTH(a_Expr) a_Expr
22862286 assert (v != 0);
22872287
22882288 v->origin = origin;
2289 #ifndef CONFIG_WITH_VALUE_LENGTH
22892290 if (v->flavor == f_simple)
22902291 v->value = allocated_variable_expand (v->value);
22912292 else
22922293 v->value = xstrdup (v->value);
2294 #else
2295 v->value_length = strlen (v->value);
2296 if (v->flavor == f_simple)
2297 v->value = allocated_variable_expand_2 (v->value, v->value_length, &v->value_length);
2298 else
2299 v->value = (char *)memcpy (xmalloc (v->value_length + 1), v->value, v->value_length + 1);
2300 v->value_alloc_len = v->value_length + 1;
2301 #endif
22932302
22942303 fname = p->target;
22952304 }
23602369 v->origin = gv->origin;
23612370 v->recursive = gv->recursive;
23622371 v->append = 0;
2372 VARIABLE_CHANGED (v);
23632373 }
23642374 }
23652375 }
13211321 So mark it now as "succeeded". */
13221322 file->update_status = 0;
13231323 #endif
1324
1325 #ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
1326 /* We're done with this command, so free the memory held by the chopped
1327 command lines. Saves heap for the compilers & linkers. */
1328 if (file->cmds && file->cmds->command_lines)
1329 free_chopped_commands (file->cmds);
1330 #endif
13241331 }
13251332
13261333 /* Check whether another file (whose mtime is THIS_MTIME) needs updating on
3939 #endif
4040 #ifdef CONFIG_WITH_STRCACHE2
4141 # include <stddef.h>
42 #endif
43 #ifdef CONFIG_WITH_COMPILER
44 # include "kmk_cc_exec.h"
4245 #endif
4346
4447 #ifdef KMK
379382 v->fileinfo.filenm = 0;
380383 v->origin = origin;
381384 v->recursive = recursive;
382 MAKE_STATS_2(v->changes++);
385 VARIABLE_CHANGED (v);
383386 }
384387 return v;
385388 }
441444 v->aliased = 0;
442445 #endif
443446 v->export = v_default;
447 #ifdef CONFIG_WITH_COMPILER
448 v->recursive_without_dollar = 0;
449 v->evalprog = 0;
450 v->expandprog = 0;
451 v->evalval_count = 0;
452 v->expand_count = 0;
453 #else
454 MAKE_STATS_2(v->expand_count = 0);
455 MAKE_STATS_2(v->evalval_count = 0);
456 #endif
444457 MAKE_STATS_2(v->changes = 0);
445458 MAKE_STATS_2(v->reallocs = 0);
459 MAKE_STATS_2(v->references = 0);
460 MAKE_STATS_2(v->cTicksEvalVal = 0);
446461
447462 v->exportable = 1;
448463 if (*name != '_' && (*name < 'A' || *name > 'Z')
580595
581596 if (v->value != 0 && !v->rdonly_val)
582597 free (v->value);
583 MAKE_STATS_2(v->changes++);
598 VARIABLE_CHANGED (v);
584599 }
585600 else
586601 {
597612 v->private_var = 0;
598613 v->aliased = 0;
599614 v->export = v_default;
615 #ifdef CONFIG_WITH_COMPILER
616 v->recursive_without_dollar = 0;
617 v->evalprog = 0;
618 v->expandprog = 0;
619 v->evalval_count = 0;
620 v->expand_count = 0;
621 #else
622 MAKE_STATS_2(v->expand_count = 0);
623 MAKE_STATS_2(v->evalval_count = 0);
624 #endif
600625 MAKE_STATS_2(v->changes = 0);
601626 MAKE_STATS_2(v->reallocs = 0);
627 MAKE_STATS_2(v->references = 0);
628 MAKE_STATS_2(v->cTicksEvalVal = 0);
602629 v->exportable = 1;
603630 if (*name != '_' && (*name < 'A' || *name > 'Z')
604631 && (*name < 'a' || *name > 'z'))
726753 var->value_length = p - var->value - 1;
727754 var->value_alloc_len = max;
728755 #endif
756 VARIABLE_CHANGED (var);
729757
730758 /* Remember how many variables are in our current count. Since we never
731759 remove variables from the list, this is a reliable way to know whether
886914 {
887915 struct variable *v = lookup_kbuild_object_variable_accessor(name, length);
888916 if (v != VAR_NOT_KBUILD_ACCESSOR)
889 return v;
917 {
918 MAKE_STATS_2 (v->references++);
919 return v;
920 }
890921 }
891922 # endif
892923
919950 # ifdef KMK
920951 RESOLVE_ALIAS_VARIABLE(v);
921952 # endif
922 return v->special ? lookup_special_var (v) : v;
953 MAKE_STATS_2 (v->references++);
954 return v->special ? lookup_special_var (v) : v;
923955 }
924956
925957 is_parent |= setlist->next_is_parent;
9921024
9931025 return 0;
9941026 }
1027
1028 #ifdef CONFIG_WITH_STRCACHE2
1029 /* Alternative version of lookup_variable that takes a name that's already in
1030 the variable string cache. */
1031 struct variable *
1032 lookup_variable_strcached (const char *name)
1033 {
1034 struct variable *v;
1035 #if 1 /*FIX THIS - ndef KMK*/
1036 const struct variable_set_list *setlist;
1037 struct variable var_key;
1038 #endif /* KMK */
1039 int is_parent = 0;
1040
1041 #ifndef NDEBUG
1042 strcache2_verify_entry (&variable_strcache, name);
1043 #endif
1044
1045 #ifdef KMK
1046 /* Check for kBuild-define- local variable accesses and handle these first. */
1047 if (strcache2_get_len(&variable_strcache, name) > 3 && name[0] == '[')
1048 {
1049 v = lookup_kbuild_object_variable_accessor(name, strcache2_get_len(&variable_strcache, name));
1050 if (v != VAR_NOT_KBUILD_ACCESSOR)
1051 {
1052 MAKE_STATS_2 (v->references++);
1053 return v;
1054 }
1055 }
1056 #endif
1057
1058 #if 1 /*FIX THIS - ndef KMK */
1059
1060 var_key.name = (char *) name;
1061 var_key.length = strcache2_get_len(&variable_strcache, name);
1062
1063 for (setlist = current_variable_set_list;
1064 setlist != 0; setlist = setlist->next)
1065 {
1066 const struct variable_set *set = setlist->set;
1067
1068 v = (struct variable *) hash_find_item_strcached ((struct hash_table *) &set->table, &var_key);
1069 if (v && (!is_parent || !v->private_var))
1070 {
1071 # ifdef KMK
1072 RESOLVE_ALIAS_VARIABLE(v);
1073 # endif
1074 MAKE_STATS_2 (v->references++);
1075 return v->special ? lookup_special_var (v) : v;
1076 }
1077
1078 is_parent |= setlist->next_is_parent;
1079 }
1080
1081 #else /* KMK - need for speed */
1082
1083 v = lookup_cached_variable (name);
1084 assert (lookup_variable_for_assert(name, length) == v);
1085 #ifdef VMS
1086 if (v)
1087 #endif
1088 return v;
1089 #endif /* KMK - need for speed */
1090 #ifdef VMS
1091 # error "Port me (split out the relevant code from lookup_varaible and call it)"
1092 #endif
1093 return 0;
1094 }
1095 #endif
1096
9951097
9961098 /* Lookup a variable whose name is a string starting at NAME
9971099 and with LENGTH chars in set SET. NAME need not be null-terminated.
10031105 const struct variable_set *set)
10041106 {
10051107 struct variable var_key;
1006 struct variable *v;
10071108 #ifndef CONFIG_WITH_STRCACHE2
10081109 var_key.name = (char *) name;
10091110 var_key.length = length;
10111112 return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
10121113 #else /* CONFIG_WITH_STRCACHE2 */
10131114 const char *cached_name;
1115 struct variable *v;
10141116
10151117 # ifdef KMK
10161118 /* Check for kBuild-define- local variable accesses and handle these first. */
10201122 if (v != VAR_NOT_KBUILD_ACCESSOR)
10211123 {
10221124 RESOLVE_ALIAS_VARIABLE(v);
1125 MAKE_STATS_2 (v->references++);
10231126 return v;
10241127 }
10251128 }
10471150 # ifdef KMK
10481151 RESOLVE_ALIAS_VARIABLE(v);
10491152 # endif
1153 MAKE_STATS_2 (if (v) v->references++);
10501154 return v;
10511155 #endif /* CONFIG_WITH_STRCACHE2 */
10521156 }
12211325 struct variable *v = (struct variable *) item;
12221326 #ifndef CONFIG_WITH_STRCACHE2
12231327 free (v->name);
1328 #endif
1329 #ifdef CONFIG_WITH_COMPILER
1330 if (v->evalprog || v->expandprog)
1331 kmk_cc_variable_deleted (v);
12241332 #endif
12251333 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
12261334 if (!v->rdonly_val)
13401448 fatal(NULL, ("Attempting to delete aliased variable '%s'"), from_var->name);
13411449 if (from_var->alias)
13421450 fatal(NULL, ("Attempting to delete variable aliased '%s'"), from_var->name);
1451 #endif
1452 #ifdef CONFIG_WITH_COMPILER
1453 if (from_var->evalprog || from_var->expandprog)
1454 kmk_cc_variable_deleted (from_var);
13431455 #endif
13441456 #ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
13451457 if (!from_var->rdonly_val)
20942206 else
20952207 memcpy (v->value, value, value_len + 1);
20962208 v->value_length = new_value_len;
2209 VARIABLE_CHANGED (v);
20972210 }
20982211
20992212 struct variable *
23062419 # endif
23072420 if (free_value)
23082421 free (free_value);
2309 MAKE_STATS_2(v->changes++);
23102422 return v;
23112423 #else /* !CONFIG_WITH_VALUE_LENGTH */
23122424
27332845 return vp;
27342846 }
27352847
2848 #if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
2849 static unsigned long var_stats_evalvals, var_stats_evalvaled;
2850 static unsigned long var_stats_expands, var_stats_expanded;
2851 #endif
2852 #ifdef CONFIG_WITH_COMPILER
2853 static unsigned long var_stats_expandprogs, var_stats_evalprogs;
2854 #endif
27362855 #ifdef CONFIG_WITH_MAKE_STATS
27372856 static unsigned long var_stats_changes, var_stats_changed;
27382857 static unsigned long var_stats_reallocs, var_stats_realloced;
2858 static unsigned long var_stats_references, var_stats_referenced;
27392859 static unsigned long var_stats_val_len, var_stats_val_alloc_len;
27402860 static unsigned long var_stats_val_rdonly_len;
27412861 #endif
28032923 printf (_(", alias for '%s'"), v->name);
28042924 #endif /* KMK */
28052925
2926 #if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
2927 if (v->evalval_count != 0)
2928 {
2929 # ifdef CONFIG_WITH_MAKE_STATS
2930 printf (_(", %u evalvals (%llu ticks)"), v->evalval_count, v->cTicksEvalVal);
2931 # else
2932 printf (_(", %u evalvals"), v->evalval_count);
2933 # endif
2934 var_stats_evalvaled++;
2935 }
2936 var_stats_evalvals += v->evalval_count;
2937
2938 if (v->expand_count != 0)
2939 {
2940 printf (_(", %u expands"), v->expand_count);
2941 var_stats_expanded++;
2942 }
2943 var_stats_expands += v->expand_count;
2944
2945 # ifdef CONFIG_WITH_COMPILER
2946 if (v->evalprog != 0)
2947 {
2948 printf (_(", evalprog"));
2949 var_stats_evalprogs++;
2950 }
2951 if (v->expandprog != 0)
2952 {
2953 printf (_(", expandprog"));
2954 var_stats_expandprogs++;
2955 }
2956 # endif
2957 #endif
2958
28062959 #ifdef CONFIG_WITH_MAKE_STATS
28072960 if (v->changes != 0)
2961 {
28082962 printf (_(", %u changes"), v->changes);
2963 var_stats_changed++;
2964 }
28092965 var_stats_changes += v->changes;
2810 var_stats_changed += (v->changes != 0);
2966
28112967 if (v->reallocs != 0)
2968 {
28122969 printf (_(", %u reallocs"), v->reallocs);
2970 var_stats_realloced++;
2971 }
28132972 var_stats_reallocs += v->reallocs;
2814 var_stats_realloced += (v->reallocs != 0);
2973
2974 if (v->references != 0)
2975 {
2976 printf (_(", %u references"), v->references);
2977 var_stats_referenced++;
2978 }
2979 var_stats_references += v->references;
2980
28152981 var_stats_val_len += v->value_length;
28162982 if (v->value_alloc_len)
28172983 var_stats_val_alloc_len += v->value_alloc_len;
28663032 void
28673033 print_variable_set (struct variable_set *set, char *prefix)
28683034 {
3035 #if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
3036 var_stats_expands = var_stats_expanded = var_stats_evalvals
3037 = var_stats_evalvaled = 0;
3038 #endif
3039 #ifdef CONFIG_WITH_COMPILER
3040 var_stats_expandprogs = var_stats_evalprogs = 0;
3041 #endif
28693042 #ifdef CONFIG_WITH_MAKE_STATS
28703043 var_stats_changes = var_stats_changed = var_stats_reallocs
2871 = var_stats_realloced = var_stats_val_len = var_stats_val_alloc_len
2872 = var_stats_val_rdonly_len = 0;
3044 = var_stats_realloced = var_stats_references = var_stats_referenced
3045 = var_stats_val_len = var_stats_val_alloc_len
3046 = var_stats_val_rdonly_len = 0;
3047 #endif
28733048
28743049 hash_map_arg (&set->table, print_variable, prefix);
28753050
28763051 if (set->table.ht_fill)
28773052 {
3053 #ifdef CONFIG_WITH_MAKE_STATS
28783054 unsigned long fragmentation;
28793055
28803056 fragmentation = var_stats_val_alloc_len - (var_stats_val_len - var_stats_val_rdonly_len);
28983074 var_stats_realloced,
28993075 (unsigned int)((100.0 * var_stats_realloced) / set->table.ht_fill),
29003076 var_stats_reallocs);
3077
3078 if (var_stats_referenced)
3079 printf(_("# referenced %5lu (%2u%%), references %6lu\n"),
3080 var_stats_referenced,
3081 (unsigned int)((100.0 * var_stats_referenced) / set->table.ht_fill),
3082 var_stats_references);
3083 #endif
3084 #if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
3085 if (var_stats_evalvals)
3086 printf(_("# evalvaled %5lu (%2u%%), evalval calls %6lu\n"),
3087 var_stats_evalvaled,
3088 (unsigned int)((100.0 * var_stats_evalvaled) / set->table.ht_fill),
3089 var_stats_evalvals);
3090 if (var_stats_expands)
3091 printf(_("# expanded %5lu (%2u%%), expands %6lu\n"),
3092 var_stats_expanded,
3093 (unsigned int)((100.0 * var_stats_expanded) / set->table.ht_fill),
3094 var_stats_expands);
3095 #endif
3096 #ifdef CONFIG_WITH_COMPILER
3097 if (var_stats_expandprogs || var_stats_evalprogs)
3098 printf(_("# eval progs %5lu (%2u%%), expand progs %6lu (%2u%%)\n"),
3099 var_stats_evalprogs,
3100 (unsigned int)((100.0 * var_stats_evalprogs) / set->table.ht_fill),
3101 var_stats_expandprogs,
3102 (unsigned int)((100.0 * var_stats_expandprogs) / set->table.ht_fill));
3103 #endif
29013104 }
2902 #else
2903 hash_map_arg (&set->table, print_variable, prefix);
2904 #endif
29053105
29063106 fputs (_("# variable set hash-table stats:\n"), stdout);
29073107 fputs ("# ", stdout);
1616 this program. If not, see <http://www.gnu.org/licenses/>. */
1717
1818 #include "hash.h"
19 #ifdef CONFIG_WITH_COMPILER
20 # include "kmk_cc_exec.h"
21 #endif
1922
2023 /* Codes in a variable definition saying where the definition came from.
2124 Increasing numeric values signify less-overridable definitions. */
107110 v_ifset, /* Export it if it has a non-default value. */
108111 v_default /* Decide in target_environment. */
109112 } export ENUM_BITFIELD (2);
113 #ifdef CONFIG_WITH_COMPILER
114 int recursive_without_dollar : 2; /* 0 if undetermined, 1 if value has no '$' chars, -1 if it has. */
115 #endif
110116 #ifdef CONFIG_WITH_MAKE_STATS
111 unsigned int changes;
112 unsigned int reallocs;
117 unsigned int changes; /* Variable modification count. */
118 unsigned int reallocs; /* Realloc on value count. */
119 unsigned int references; /* Lookup count. */
120 unsigned long long cTicksEvalVal; /* Number of ticks spend in cEvalVal. */
121 #endif
122 #if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
123 unsigned int evalval_count; /* Times used with $(evalval ) or $(evalctx ) since last change. */
124 unsigned int expand_count; /* Times expanded since last change (not to be confused with exp_count). */
125 #endif
126 #ifdef CONFIG_WITH_COMPILER
127 struct kmk_cc_evalprog *evalprog; /* Pointer to evalval/evalctx "program". */
128 struct kmk_cc_expandprog *expandprog; /* Pointer to variable expand "program". */
113129 #endif
114130 };
131
132 /* Update statistics and invalidates optimizations when a variable changes. */
133 #ifdef CONFIG_WITH_COMPILER
134 # define VARIABLE_CHANGED(v) \
135 do { \
136 MAKE_STATS_2((v)->changes++); \
137 if ((v)->evalprog || (v)->expandprog) kmk_cc_variable_changed(v); \
138 (v)->expand_count = 0; \
139 (v)->evalval_count = 0; \
140 (v)->recursive_without_dollar = 0; \
141 } while (0)
142 #else
143 # define VARIABLE_CHANGED(v) MAKE_STATS_2((v)->changes++)
144 #endif
145
146 /* Macro that avoids a lot of CONFIG_WITH_COMPILER checks when
147 accessing recursive_without_dollar. */
148 #ifdef CONFIG_WITH_COMPILER
149 # define IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(v) ((v)->recursive_without_dollar > 0)
150 #else
151 # define IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(v) 0
152 #endif
153
154
115155
116156 /* Structure that represents a variable set. */
117157
232272 }
233273 #endif /* CONFIG_WITH_VALUE_LENGTH */
234274 void install_variable_buffer (char **bufp, unsigned int *lenp);
275 char *install_variable_buffer_with_hint (char **bufp, unsigned int *lenp, unsigned int size_hint);
235276 void restore_variable_buffer (char *buf, unsigned int len);
277 char *ensure_variable_buffer_space(char *ptr, unsigned int size);
236278 #ifdef CONFIG_WITH_VALUE_LENGTH
237279 void append_expanded_string_to_variable (struct variable *v, const char *value,
238280 unsigned int value_len, int append);
243285 int handle_function (char **op, const char **stringp);
244286 #else
245287 int handle_function (char **op, const char **stringp, const char *nameend, const char *eol);
288 #endif
289 #ifdef CONFIG_WITH_COMPILER
290 typedef char *(*make_function_ptr_t) (char *, char **, const char *);
291 make_function_ptr_t lookup_function_for_compiler (const char *name, unsigned int len,
292 unsigned char *minargsp, unsigned char *maxargsp,
293 char *expargsp, const char **funcnamep);
246294 #endif
247295 int pattern_matches (const char *pattern, const char *percent, const char *str);
248296 char *subst_expand (char *o, const char *text, const char *subst,
307355 char *recursively_expand_for_file (struct variable *v, struct file *file,
308356 unsigned int *value_lenp);
309357 #define recursively_expand(v) recursively_expand_for_file (v, NULL, NULL)
358 #endif
359 #ifdef CONFIG_WITH_COMPILER
360 char *reference_recursive_variable (char *o, struct variable *v);
310361 #endif
311362
312363 /* variable.c */
351402 struct variable *lookup_variable (const char *name, unsigned int length);
352403 struct variable *lookup_variable_in_set (const char *name, unsigned int length,
353404 const struct variable_set *set);
405 #ifdef CONFIG_WITH_STRCACHE2
406 struct variable *lookup_variable_strcached (const char *name);
407 #endif
354408
355409 #ifdef CONFIG_WITH_VALUE_LENGTH
356410 void append_string_to_variable (struct variable *v, const char *value,