[Pkg-virtualbox-commits] [kbuild] 01/03: Imported Upstream version 0.1.9998svn2780+dfsg
Gianfranco Costamagna
locutusofborg-guest at moszumanska.debian.org
Tue Apr 28 19:01:23 UTC 2015
This is an automated email from the git hooks/post-receive script.
locutusofborg-guest pushed a commit to branch master
in repository kbuild.
commit 98ec982ba2a4ca945cb58d5ad187b936b5aff8e6
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date: Mon Apr 27 00:27:04 2015 +0200
Imported Upstream version 0.1.9998svn2780+dfsg
---
kBuild/footer-pass1.kmk | 42 +-
kBuild/footer-pass2-compiling-targets.kmk | 32 +-
kBuild/header.kmk | 30 +-
kBuild/subfooter.kmk | 26 +-
kBuild/subheader.kmk | 25 +-
kBuild/tools/ALP.kmk | 4 +-
kBuild/tools/GCC3.kmk | 26 +-
kBuild/tools/GCC32.kmk | 26 +-
kBuild/tools/GCC3OMF.kmk | 40 +-
kBuild/tools/GCC64.kmk | 20 +-
kBuild/tools/GXX3.kmk | 26 +-
kBuild/tools/GXX32.kmk | 26 +-
kBuild/tools/GXX3OMF.kmk | 42 +-
kBuild/tools/GXX64.kmk | 20 +-
kBuild/tools/JWASM.kmk | 6 +-
kBuild/tools/MASM510.kmk | 4 +-
kBuild/tools/MASM600.kmk | 4 +-
kBuild/tools/MASM610.kmk | 4 +-
kBuild/tools/MASM6PLUS.kmk | 6 +-
kBuild/tools/MASM710.kmk | 4 +-
kBuild/tools/MINGW32.kmk | 4 +-
kBuild/tools/MINGWW64.kmk | 4 +-
kBuild/tools/NASM.kmk | 4 +-
kBuild/tools/OPENWATCOM-16.kmk | 16 +-
kBuild/tools/OPENWATCOM-WL.kmk | 4 +-
kBuild/tools/OPENWATCOM.kmk | 25 +-
kBuild/tools/TAR.kmk | 6 +-
kBuild/tools/VAC308.kmk | 6 +-
kBuild/tools/WATCOMC11C-16.kmk | 14 +-
kBuild/tools/WATCOMC11C-WL.kmk | 4 +-
kBuild/tools/WATCOMC11C.kmk | 23 +-
kBuild/tools/WGET.kmk | 6 +-
kBuild/tools/XGCCAMD64LINUX.kmk | 4 +-
kBuild/tools/YASM.kmk | 4 +-
kBuild/tools/ZIP.kmk | 14 +-
src/kmk/Makefile.kmk | 22 +-
src/kmk/commands.c | 21 +
src/kmk/commands.h | 3 +
src/kmk/config.h.win | 27 +-
src/kmk/dir.c | 4 +
src/kmk/expand.c | 101 +-
src/kmk/function.c | 91 +-
src/kmk/job.c | 19 +-
src/kmk/kbuild.c | 9 +-
src/kmk/kmk_cc_exec.c | 2027 +++++++++++++++++++++++++++++
src/kmk/kmk_cc_exec.h | 45 +
src/kmk/kmkbuiltin/append.c | 10 +-
src/kmk/kmkbuiltin/echo.c | 8 +
src/kmk/kmkbuiltin/kDepObj.c | 3 +-
src/kmk/kmkbuiltin/mscfakes.c | 167 ++-
src/kmk/kmkbuiltin/mscfakes.h | 33 +-
src/kmk/kmkbuiltin/redirect.c | 74 +-
src/kmk/main.c | 19 +-
src/kmk/make.h | 7 +
src/kmk/read.c | 10 +
src/kmk/remake.c | 7 +
src/kmk/variable.c | 226 +++-
src/kmk/variable.h | 58 +-
58 files changed, 3172 insertions(+), 370 deletions(-)
diff --git a/kBuild/footer-pass1.kmk b/kBuild/footer-pass1.kmk
index d77c59e..141e618 100644
--- a/kBuild/footer-pass1.kmk
+++ b/kBuild/footer-pass1.kmk
@@ -1,4 +1,4 @@
-# $Id: footer-pass1.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: footer-pass1.kmk 2764 2015-01-28 18:51:46Z bird $
## @file
# kBuild - Footer - Target lists - Pass 1.
#
@@ -107,13 +107,9 @@ ifeq ($(insttype),)
local insttype := both
endif
endif
-ifn1of ($(insttype), none both stage)
- $(error kBuild: Unknown value '$(insttype)' for '$(target)_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
-endif
$(target)_1_INSTTYPE := $(insttype)
-if1of ($(insttype), stage both)
- local inst := $(strip $(firstdefined \
+local inst := $(strip $(firstdefined \
$(target)_INST.$(bld_trg).$(bld_trg_arch).$(bld_type) \
$(target)_INST.$(bld_trg).$(bld_trg_arch) \
$(target)_INST.$(bld_trg).$(bld_type) \
@@ -124,7 +120,7 @@ if1of ($(insttype), stage both)
$(target)_INST \
definst \
,value))
- local stage := $(strip $(firstdefined \
+local stage := $(strip $(firstdefined \
$(target)_STAGE.$(bld_trg).$(bld_trg_arch).$(bld_type) \
$(target)_STAGE.$(bld_trg).$(bld_trg_arch) \
$(target)_STAGE.$(bld_trg).$(bld_type) \
@@ -135,6 +131,7 @@ if1of ($(insttype), stage both)
$(target)_STAGE \
inst \
,value))
+if1of ($(insttype), stage both)
$(target)_1_STAGE := $(stage)
if "$(substr $(stage),-1,1)" == "/" # Multicast support requires addprefix/suffix.
$(target)_1_STAGE_TARGET := $(addprefix $(PATH_STAGE)/,$(addsuffix $(notdir $(out)),$(stage)))
@@ -143,9 +140,11 @@ if1of ($(insttype), stage both)
else
$(target)_1_STAGE_TARGET := $(addprefix $(PATH_STAGE)/,$(stage))
endif
-else
+else if1of ($(insttype), none)
$(target)_1_STAGE :=
$(target)_1_STAGE_TARGET :=
+else
+ $(error kBuild: Unknown value '$(insttype)' for '$(target)_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
endif
INSTARGET_$(target) := $($(target)_1_STAGE_TARGET)
@@ -174,9 +173,6 @@ local debug_insttype := $(firstword \
$($(target)_DEBUG_INSTTYPE.$(bld_type)) \
$($(target)_DEBUG_INSTTYPE) \
$(insttype) )
-ifn1of ($(debug_insttype), none both stage)
- $(error kBuild: Unknown value '$(debug_insttype)' for '$(target)_DEBUG_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
-endif
$(target)_1_DEBUG_INSTTYPE := $(debug_insttype)
if1of ($(debug_insttype), stage both)
@@ -205,8 +201,10 @@ if1of ($(debug_insttype), stage both)
ifndef $(target)_1_DEBUG_STAGE
$(target)_1_DEBUG_STAGE := ./
endif
-else
+else if1of ($(debug_insttype), none)
$(target)_1_DEBUG_STAGE :=
+else
+ $(error kBuild: Unknown value '$(debug_insttype)' for '$(target)_DEBUG_INSTTYPE'. Valid values are 'none', 'both' and 'stage'.)
endif
if1of ($(debug_insttype), both)
@@ -244,7 +242,7 @@ define def_pass1_bldprog
ifndef $(target)_INST
$(target)_INSTTYPE := none
endif
-$(evalval def_pass1_link_common)
+$(evalvalctx def_pass1_link_common)
endef
EXT := EXE
@@ -253,7 +251,7 @@ definst := $(INST_BIN)
tool_prefix := LD
bld_trg_base_var := PLATFORM
$(foreach target, $(_ALL_BLDPROGS), \
- $(evalval def_pass1_bldprog))
+ $(evalvalctx def_pass1_bldprog))
#
@@ -265,7 +263,7 @@ definst := $(INST_LIB)
tool_prefix := AR
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_LIBRARIES), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
#
@@ -277,7 +275,7 @@ definst := $(INST_DLL)
tool_prefix := LD
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_DLLS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
#
@@ -293,7 +291,7 @@ if1of ($(KBUILD_TARGET), nt os2 win win64 win32)
tool_prefix := AR
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_IMPORT_LIBS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
else
EXT := DLL
EXTPRE :=
@@ -301,7 +299,7 @@ else
tool_prefix := LD
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_IMPORT_LIBS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
endif
@@ -314,7 +312,7 @@ definst := $(INST_BIN)
tool_prefix := LD
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_PROGRAMS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
#
@@ -326,7 +324,7 @@ definst := $(INST_SYS)
tool_prefix := LD
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_SYSMODS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
#
@@ -338,7 +336,7 @@ definst := $(INST_BIN)
tool_prefix := LD
bld_trg_base_var := TARGET
$(foreach target, $(_ALL_MISCBINS), \
- $(evalval def_pass1_link_common))
+ $(evalvalctx def_pass1_link_common))
#
@@ -452,7 +450,7 @@ endef # def_pass1_install
$(eval-opt-var def_pass1_install)
$(foreach target, $(_ALL_INSTALLS), \
- $(evalval def_pass1_install))
+ $(evalvalctx def_pass1_install))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done pass 1)
diff --git a/kBuild/footer-pass2-compiling-targets.kmk b/kBuild/footer-pass2-compiling-targets.kmk
index 98f2866..23a5337 100644
--- a/kBuild/footer-pass2-compiling-targets.kmk
+++ b/kBuild/footer-pass2-compiling-targets.kmk
@@ -1,4 +1,4 @@
-# $Id: footer-pass2-compiling-targets.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: footer-pass2-compiling-targets.kmk 2762 2015-01-28 18:17:54Z bird $
## @file
# kBuild - Footer - Target lists - Pass 2 - Compiling Targets.
#
@@ -270,7 +270,7 @@ $(foreach source,\
$($(target)_SOURCES.$(bld_trg_arch))\
$($(target)_SOURCES.$(bld_trg_cpu))\
$($(target)_SOURCES.$(bld_type))\
- ,$(evalval def_src_handler_one) )
+ ,$(evalvalctx def_src_handler_one) )
$(foreach source,\
$($(target)_GEN_SOURCES_)\
@@ -281,7 +281,7 @@ $(foreach source,\
$($(target)_GEN_SOURCES_.$(bld_trg_arch))\
$($(target)_GEN_SOURCES_.$(bld_trg_cpu))\
$($(target)_GEN_SOURCES_.$(bld_type))\
- ,$(evalval def_src_handler_one) )
+ ,$(evalvalctx def_src_handler_one) )
endef # def_target_sources
$(eval-opt-var def_target_sources)
@@ -406,18 +406,18 @@ if ( defined($(target)_2_OUTPUT_DEBUG_DIRS) \
local debug_inst_path := $(PATH_INS)
local debug_install_cmd := $(INSTALL)
local debug_var := INSTALL
- $(foreach debug_inst, $($(target)_1_DEBUG_INST), $(evalval def_target_install_only_debug))
+ $(foreach debug_inst, $($(target)_1_DEBUG_INST), $(evalvalctx def_target_install_only_debug))
endif
local debug_inst_path := $(PATH_STAGE)
local debug_install_cmd := $(INSTALL_STAGING)
local debug_var := STAGE
if1of ($($(target)_1_DEBUG_INSTTYPE), stage both)
- $(foreach debug_inst, $($(target)_1_DEBUG_STAGE), $(evalval def_target_install_only_debug))
+ $(foreach debug_inst, $($(target)_1_DEBUG_STAGE), $(evalvalctx def_target_install_only_debug))
endif
if1of ($($(target)_1_INSTTYPE), stage both)
ifndef debug_nostage
- $(foreach debug_inst,$($(target)_1_STAGE), $(evalval def_target_install_only_debug))
+ $(foreach debug_inst,$($(target)_1_STAGE), $(evalvalctx def_target_install_only_debug))
endif
endif
@@ -488,7 +488,7 @@ local units := \
$($(target)_USES.$(bld_trg))\
$($(target)_USES.$(bld_type))\
$($(target)_USES)
-$(foreach unit,$(units),$(evalval def_unit_$(unit)_target_pre))
+$(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
# source -> object
$(evalval def_target_sources)
@@ -628,7 +628,7 @@ $(eval-opt-var def_lib)
typevar := _LIBS
tool_do := LINK_LIBRARY
mode := 0644
-$(foreach target, $(_ALL_LIBRARIES), $(evalval def_lib))
+$(foreach target, $(_ALL_LIBRARIES), $(evalvalctx def_lib))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done library targets)
@@ -691,7 +691,7 @@ local units := \
$($(target)_USES.$(bld_trg))\
$($(target)_USES.$(bld_type))\
$($(target)_USES)
-$(foreach unit,$(units),$(evalval def_unit_$(unit)_target_pre))
+$(foreach unit,$(units),$(evalvalctx def_unit_$(unit)_target_pre))
# source -> object
$(evalval def_target_sources)
@@ -967,7 +967,7 @@ tool_do := LINK_PROGRAM
typevar := _BLDPROGS
mode := 0755
bld_trg_base_var := PLATFORM
-$(foreach target, $(_ALL_BLDPROGS), $(evalval def_link_common))
+$(foreach target, $(_ALL_BLDPROGS), $(evalvalctx def_link_common))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done build program targets)
@@ -985,7 +985,7 @@ tool_do := LINK_DLL
typevar := _DLLS
mode := 0644
bld_trg_base_var := TARGET
-$(foreach target, $(_ALL_DLLS), $(evalval def_link_common))
+$(foreach target, $(_ALL_DLLS), $(evalvalctx def_link_common))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done dll targets)
@@ -1005,11 +1005,11 @@ bld_trg_base_var := TARGET
ifeq ($(filter-out nt os2 win win64 win32,$(KBUILD_TARGET)),)
EXT := LIB
tool_do := LINK_LIBRARY
- $(foreach target, $(_ALL_IMPORT_LIBS), $(evalval def_lib))
+ $(foreach target, $(_ALL_IMPORT_LIBS), $(evalvalctx def_lib))
else
EXT := DLL
tool_do := LINK_DLL
- $(foreach target, $(_ALL_IMPORT_LIBS), $(evalval def_link_common))
+ $(foreach target, $(_ALL_IMPORT_LIBS), $(evalvalctx def_link_common))
endif
ifdef KBUILD_PROFILE_SELF
@@ -1028,7 +1028,7 @@ tool_do := LINK_PROGRAM
typevar := _PROGRAMS
mode := 0755
bld_trg_base_var := TARGET
-$(foreach target, $(_ALL_PROGRAMS), $(evalval def_link_common))
+$(foreach target, $(_ALL_PROGRAMS), $(evalvalctx def_link_common))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done program targets)
@@ -1046,7 +1046,7 @@ tool_do := LINK_SYSMOD
typevar := _SYSMODS
mode := 0644
bld_trg_base_var := TARGET
-$(foreach target, $(_ALL_SYSMODS), $(evalval def_link_common))
+$(foreach target, $(_ALL_SYSMODS), $(evalvalctx def_link_common))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done sysmod targets)
@@ -1064,7 +1064,7 @@ tool_do := LINK_MISCBIN
typevar := _MISCBINS
mode := 0644
bld_trg_base_var := TARGET
-$(foreach target, $(_ALL_MISCBINS), $(evalval def_link_common))
+$(foreach target, $(_ALL_MISCBINS), $(evalvalctx def_link_common))
ifdef KBUILD_PROFILE_SELF
$(evalcall def_profile_self, done misc binary targets)
diff --git a/kBuild/header.kmk b/kBuild/header.kmk
index d2774f1..4d0f1f0 100644
--- a/kBuild/header.kmk
+++ b/kBuild/header.kmk
@@ -1,10 +1,10 @@
-# $Id: header.kmk 2729 2014-03-16 00:21:49Z bird $
+# $Id: header.kmk 2763 2015-01-28 18:25:31Z bird $
## @file
# kBuild - File included at top of a makefile.
#
#
-# Copyright (c) 2004-2014 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+# Copyright (c) 2004-2015 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
#
# This file is part of kBuild.
#
@@ -79,7 +79,7 @@ endif
# The revision in which this file was last modified.
# This can be useful when using development versions of kBuild.
#
-KMK_REVISION := $(patsubst %:,, $Rev: 2729 $ )
+KMK_REVISION := $(patsubst %:,, $Rev: 2763 $ )
#
@@ -516,6 +516,7 @@ endif
# Deprecated legacy names.
PATH_DEVTOOLS ?= $(KBUILD_DEVTOOLS)
PATH_DEVTOOLS_TRG ?= $(KBUILD_DEVTOOLS_TRG)
+PATH_DEVTOOLS_BLD ?= $(KBUILD_DEVTOOLS_TRG)
PATH_DEVTOOLS_TRG_ALT ?= $(KBUILD_DEVTOOLS_TRG_ALT)
PATH_DEVTOOLS_HST ?= $(KBUILD_DEVTOOLS_HST)
PATH_DEVTOOLS_HST_ALT ?= $(KBUILD_DEVTOOLS_HST_ALT)
@@ -1565,6 +1566,29 @@ endif
#
+# An internal define used by subheader.kmk and subfooter.kmk.
+# We keep them here to avoid redefining them for each sub-makefile.
+#
+define def_subfooter_header_target_pass
+ ifndef $(target)_PATH
+ ifndef $(target)_DEFPATH
+ $(target)_DEFPATH := $(PATH_SUB_CURRENT)
+ endif
+ $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH), $(target)_DEFPATH)
+ else ifndef $(target)_DEFPATH
+ $(target)_DEFPATH := $($(target)_PATH)
+ endif
+ ifndef $(target)_MAKEFILE
+ $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
+ endif
+ ifndef $(target)_0_OUTDIR
+ $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
+ $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR), $(target)_0_OUTDIR)
+ endif
+endef
+
+
+#
# Validate any KBUILD_BLD_TYPES additions and finally the KBUILD_TYPE.
#
if1of ($(KBUILD_BLD_TYPES), $(KBUILD_OSES))
diff --git a/kBuild/subfooter.kmk b/kBuild/subfooter.kmk
index c87dfd0..baf1a03 100644
--- a/kBuild/subfooter.kmk
+++ b/kBuild/subfooter.kmk
@@ -1,10 +1,10 @@
-# $Id: subfooter.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: subfooter.kmk 2763 2015-01-28 18:25:31Z bird $
## @file
# kBuild - File included at bottom of a makefile or sub-makefile.
#
#
-# Copyright (c) 2006-2014 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+# Copyright (c) 2006-2015 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
#
# This file is part of kBuild.
#
@@ -41,24 +41,7 @@ endif
#
# Set the default path for all new targets.
#
-define def_subheader
- ifndef $(target)_PATH
- ifndef $(target)_DEFPATH
- $(target)_DEFPATH := $(PATH_SUB_CURRENT)
- endif
- $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH),$(target)_DEFPATH)
- else ifndef $(target)_DEFPATH
- $(target)_DEFPATH := $($(target)_PATH)
- endif
- ifndef $(target)_MAKEFILE
- $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
- endif
- ifndef $(target)_0_OUTDIR
- $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
- $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR),$(target)_0_OUTDIR)
- endif
-endef
-
+## @todo Wish there was an easy way of only enumerating only new targets...
$(foreach target,\
$(ALL_TARGETS) \
$(FETCHES) $(FETCHES.$(KBUILD_TARGET)) $(FETCHES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_CPU)) $(FETCHES.$(KBUILD_TYPE)) \
@@ -72,8 +55,7 @@ $(foreach target,\
$(MISCBINS) $(MISCBINS.$(KBUILD_TARGET)) $(MISCBINS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_CPU)) $(MISCBINS.$(KBUILD_TYPE)) \
$(INSTALLS) $(INSTALLS.$(KBUILD_TARGET)) $(INSTALLS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_CPU)) $(INSTALLS.$(KBUILD_TYPE)) \
$(OTHERS) $(OTHERS.$(KBUILD_TARGET)) $(OTHERS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_CPU)) $(OTHERS.$(KBUILD_TYPE)) \
-,$(evalval def_subheader))
-
+,$(if-expr defined($(target)_0_OUTDIR),,$(evalval def_subfooter_header_target_pass)))
ifneq ($(_SUB_MAKEFILE_STACK),)
diff --git a/kBuild/subheader.kmk b/kBuild/subheader.kmk
index 830e3ce..91d1059 100644
--- a/kBuild/subheader.kmk
+++ b/kBuild/subheader.kmk
@@ -1,10 +1,10 @@
-# $Id: subheader.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: subheader.kmk 2763 2015-01-28 18:25:31Z bird $
## @file
# kBuild - File included at top of a makefile or sub-makefile.
#
#
-# Copyright (c) 2006-2014 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+# Copyright (c) 2006-2015 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
#
# This file is part of kBuild.
#
@@ -52,24 +52,7 @@ else
#
# Set the default path and makefile for all new targets.
#
- define def_subfooter
- ifndef $(target)_PATH
- ifndef $(target)_DEFPATH
- $(target)_DEFPATH := $(PATH_SUB_CURRENT)
- endif
- $(call KB_FN_ASSIGN_DEPRECATED,$(target)_PATH,$($(target)_DEFPATH), $(target)_DEFPATH)
- else ifndef $(target)_DEFPATH
- $(target)_DEFPATH := $($(target)_PATH)
- endif
- ifndef $(target)_MAKEFILE
- $(target)_MAKEFILE := $(MAKEFILE_CURRENT)
- endif
- ifndef $(target)_0_OUTDIR
- $(target)_0_OUTDIR := $(call TARGET_PATH,$(target))
- $(call KB_FN_ASSIGN_DEPRECATED,PATH_$(target),$($(target)_0_OUTDIR), $(target)_0_OUTDIR)
- endif
- endef
-
+ ## @todo Wish there was an easy way of only enumerating only new targets...
$(foreach target,\
$(ALL_TARGETS) \
$(FETCHES) $(FETCHES.$(KBUILD_TARGET)) $(FETCHES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_ARCH)) $(FETCHES.$(KBUILD_TARGET_CPU)) $(FETCHES.$(KBUILD_TYPE)) \
@@ -83,7 +66,7 @@ else
$(MISCBINS) $(MISCBINS.$(KBUILD_TARGET)) $(MISCBINS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_ARCH)) $(MISCBINS.$(KBUILD_TARGET_CPU)) $(MISCBINS.$(KBUILD_TYPE)) \
$(INSTALLS) $(INSTALLS.$(KBUILD_TARGET)) $(INSTALLS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_ARCH)) $(INSTALLS.$(KBUILD_TARGET_CPU)) $(INSTALLS.$(KBUILD_TYPE)) \
$(OTHERS) $(OTHERS.$(KBUILD_TARGET)) $(OTHERS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_ARCH)) $(OTHERS.$(KBUILD_TARGET_CPU)) $(OTHERS.$(KBUILD_TYPE)) \
- ,$(evalval def_subfooter))
+ ,$(if-expr defined($(target)_0_OUTDIR),,$(evalval def_subfooter_header_target_pass)))
#
diff --git a/kBuild/tools/ALP.kmk b/kBuild/tools/ALP.kmk
index 82971cd..42ef67d 100644
--- a/kBuild/tools/ALP.kmk
+++ b/kBuild/tools/ALP.kmk
@@ -1,4 +1,4 @@
-# $Id: ALP.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: ALP.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - ALP or later.
#
@@ -35,7 +35,7 @@ TOOL_ALP := The IBM Assembly Language Processor
# Tool Specific Properties
ifndef PATH_TOOL_ALP
- PATH_TOOL_ALP := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/alp/v*.*))
+ PATH_TOOL_ALP := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/alp/v*.*))
ifneq ($(PATH_TOOL_ALP),)
PATH_TOOL_ALP := $(call lastword,$(PATH_TOOL_ALP))
endif
diff --git a/kBuild/tools/GCC3.kmk b/kBuild/tools/GCC3.kmk
index 4142bda..fd6c6b8 100644
--- a/kBuild/tools/GCC3.kmk
+++ b/kBuild/tools/GCC3.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC3.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GCC3.kmk 2775 2015-02-03 20:00:15Z bird $
## @file
# kBuild Tool Config - Generic GCC v3.2.x or later Using The System GCC and Binutils.
#
@@ -237,9 +237,9 @@ define TOOL_GCC3_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
$(QUIET)$(APPEND) -n $(out).ar-script \
$(foreach o,$(objs), 'ADDMOD $(o)') \
- $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(TOOL_GCC3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
+ $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(TOOL_GCC3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
$(QUIET)$(APPEND) $(out).ar-script 'SAVE'
$(QUIET)$(APPEND) $(out).ar-script 'END'
@@ -274,9 +274,9 @@ define TOOL_GCC3_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC3_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -310,9 +310,9 @@ define TOOL_GCC3_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC3_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -344,9 +344,9 @@ define TOOL_GCC3_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC3_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/GCC32.kmk b/kBuild/tools/GCC32.kmk
index cf3ed32..595e78a 100644
--- a/kBuild/tools/GCC32.kmk
+++ b/kBuild/tools/GCC32.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC32.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GCC32.kmk 2775 2015-02-03 20:00:15Z bird $
## @file
# kBuild Tool Config - Generic 32-bit GCC v3.2.x or later Using The System GCC.
#
@@ -232,9 +232,9 @@ define TOOL_GCC32_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
$(QUIET)$(APPEND) -n $(out).ar-script \
$(foreach o,$(objs), 'ADDMOD $(o)') \
- $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(TOOL_GCC32_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
+ $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(TOOL_GCC32_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
$(QUIET)$(APPEND) $(out).ar-script 'SAVE'
$(QUIET)$(APPEND) $(out).ar-script 'END'
@@ -268,9 +268,9 @@ define TOOL_GCC32_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC32_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -303,9 +303,9 @@ define TOOL_GCC32_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC32_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -337,9 +337,9 @@ define TOOL_GCC32_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC32_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/GCC3OMF.kmk b/kBuild/tools/GCC3OMF.kmk
index eb86dfd..e7a97e8 100644
--- a/kBuild/tools/GCC3OMF.kmk
+++ b/kBuild/tools/GCC3OMF.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC3OMF.kmk 2545 2011-09-13 19:09:05Z bird $
+# $Id: GCC3OMF.kmk 2776 2015-02-03 20:38:12Z bird $
## @file
# kBuild Tool Config - GCC v3 targeting OS/2 OMF.
#
@@ -49,6 +49,7 @@ endif
TOOL_GCC3OMF_LDFLAGS.sysmod ?= -nostdlib
TOOL_GCC3OMF_LD_MAP ?= -Zmap=$(1)
TOOL_GCC3OMF_LD_SYSMOD_MAP ?= -Zmap=$(1)
+TOOL_GCC3OMF_RC = rc$(HOSTSUFF_EXE)
ifdef SLKRUNS
TOOL_GCC3OMF_CC += -fmessage-length=0
@@ -78,6 +79,11 @@ TOOL_GCC3OMF_ASFLAGS.debug ?= -g
TOOL_GCC3OMF_ASFLAGS.profile ?= -g
TOOL_GCC3OMF_ASOBJSUFF ?= .obj
+TOOL_GCC3OMF_RCOBJSUFF ?= .res
+TOOL_GCC3OMF_RCFLAGS ?= -n
+TOOL_GCC3OMF_RCINCS ?= $(shell $(TOOL_GCC3OMF_CXX) -E -x c++ - 2>&1 < /dev/null \
+ | $(SED_EXT) -e "/search starts here/,/[Ee]nd of search list/!d" -e "/^ /!d")
+
TOOL_GCC3OMF_ARFLAGS ?= cr
TOOL_GCC3OMF_ARLIBSUFF ?= .lib
@@ -202,6 +208,28 @@ define TOOL_GCC3OMF_COMPILE_AS_CMDS
endef
+## Compile resource source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_GCC3OMF_COMPILE_RC_OUTPUT =
+TOOL_GCC3OMF_COMPILE_RC_DEPEND =
+TOOL_GCC3OMF_COMPILE_RC_DEPORD =
+define TOOL_GCC3OMF_COMPILE_RC_CMDS
+ $(QUIET)$(REDIRECT) -E 'INCLUDE=' -- $(TOOL_GCC3OMF_RC) -r \
+ $(flags) $(addprefix -i, $(subst /,\\,$(subst /@unixroot,$(UNIXROOT),$(incs)))) $(addprefix -d, $(defs))\
+ $(subst /,\\,$(abspath $(source))) \
+ $(obj)
+endef
## Link library
# @param $(target) Normalized main target name.
# @param $(out) Library name.
@@ -216,12 +244,12 @@ TOOL_GCC3OMF_LINK_LIBRARY_OUTPUT = $(outbase).rsp
TOOL_GCC3OMF_LINK_LIBRARY_DEPEND = $(othersrc)
TOOL_GCC3OMF_LINK_LIBRARY_DEPORD =
define TOOL_GCC3OMF_LINK_LIBRARY_CMDS
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp,$(othersrc))\
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(QUIET)$(TOOL_GCC3OMF_AR_IMP) -o $(out) @$(outbase).rsp\
$(NL)$(TAB)$(QUIET)$(RM) -f $(outbase).rsp)
- $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp,$(othersrc))
- $(TOOL_GCC3OMF_AR) @$(outbase).rsp
+ $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp %.dll,$(othersrc))
+ $(QUIET)$(TOOL_GCC3OMF_AR) @$(outbase).rsp
endef
@@ -282,7 +310,7 @@ define TOOL_GCC3OMF_LINK_DLL_CMDS
$(othersrc)\
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
-Zmap=$(outbase).map
- $(TOOL_GCC3OMF_LD) @$(outbase).rsp
+ $(QUIET)$(TOOL_GCC3OMF_LD) @$(outbase).rsp
endef
diff --git a/kBuild/tools/GCC64.kmk b/kBuild/tools/GCC64.kmk
index d2a8b27..586f737 100644
--- a/kBuild/tools/GCC64.kmk
+++ b/kBuild/tools/GCC64.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC64.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GCC64.kmk 2774 2015-02-03 19:56:24Z bird $
## @file
# kBuild Tool Config - Generic 64-bit GCC v3.2.x or later Using The System GCC.
#
@@ -263,9 +263,9 @@ define TOOL_GCC64_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC64_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -297,9 +297,9 @@ define TOOL_GCC64_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC64_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -329,9 +329,9 @@ define TOOL_GCC64_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GCC64_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GCC64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/GXX3.kmk b/kBuild/tools/GXX3.kmk
index b1e3fa4..64cbd1d 100644
--- a/kBuild/tools/GXX3.kmk
+++ b/kBuild/tools/GXX3.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX3.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GXX3.kmk 2775 2015-02-03 20:00:15Z bird $
## @file
# kBuild Tool Config - Generic GCC v3.2.x using the system GCC and Binutils, for building C++ code.
#
@@ -237,9 +237,9 @@ define TOOL_GXX3_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
$(QUIET)$(APPEND) -n $(out).ar-script \
$(foreach o,$(objs), 'ADDMOD $(o)') \
- $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
+ $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
$(QUIET)$(APPEND) $(out).ar-script 'SAVE'
$(QUIET)$(APPEND) $(out).ar-script 'END'
@@ -274,9 +274,9 @@ define TOOL_GXX3_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX3_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -310,9 +310,9 @@ define TOOL_GXX3_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX3_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -344,9 +344,9 @@ define TOOL_GXX3_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX3_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX3_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/GXX32.kmk b/kBuild/tools/GXX32.kmk
index 6c5b82e..49463d2 100644
--- a/kBuild/tools/GXX32.kmk
+++ b/kBuild/tools/GXX32.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX32.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GXX32.kmk 2775 2015-02-03 20:00:15Z bird $
## @file
# kBuild Tool Config - Generic 32-bit GCC v3.2.x or later using the system GCC, for building C++ code.
#
@@ -231,9 +231,9 @@ define TOOL_GXX32_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) $(out).ar-script 'CREATE $(out)'
$(QUIET)$(APPEND) -n $(out).ar-script \
$(foreach o,$(objs), 'ADDMOD $(o)') \
- $(foreach o,$(filter-out %.def %.imp,$(othersrc)), 'ADDLIB $(o)')
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp,$(othersrc))\
+ $(foreach o,$(filter-out %.def %.imp %.dll,$(othersrc)), 'ADDLIB $(o)')
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(TOOL_GXX3_AR_IMP) -o $(outbase).imp.a $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(APPEND) $(out).ar-script 'ADDLIB $(outbase).imp.a')
$(QUIET)$(APPEND) $(out).ar-script 'SAVE'
$(QUIET)$(APPEND) $(out).ar-script 'END'
@@ -267,9 +267,9 @@ define TOOL_GXX32_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX32_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -302,9 +302,9 @@ define TOOL_GXX32_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX32_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -336,9 +336,9 @@ define TOOL_GXX32_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX32_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX32_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/GXX3OMF.kmk b/kBuild/tools/GXX3OMF.kmk
index bb38527..f54b775 100644
--- a/kBuild/tools/GXX3OMF.kmk
+++ b/kBuild/tools/GXX3OMF.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX3OMF.kmk 2545 2011-09-13 19:09:05Z bird $
+# $Id: GXX3OMF.kmk 2776 2015-02-03 20:38:12Z bird $
## @file
# kBuild Tool Config - GCC v3 targeting OS/2 OMF, for building C++ code.
#
@@ -49,6 +49,7 @@ endif
TOOL_GXX3OMF_LDFLAGS.sysmod ?= -nostdlib
TOOL_GXX3OMF_LD_MAP ?= -Zmap=$(1)
TOOL_GXX3OMF_LD_SYSMOD_MAP ?= -Zmap=$(1)
+TOOL_GXX3OMF_RC = rc$(HOSTSUFF_EXE)
ifdef SLKRUNS
TOOL_GXX3OMF_CC += -fmessage-length=0
@@ -78,6 +79,11 @@ TOOL_GXX3OMF_ASFLAGS.debug ?= -g
TOOL_GXX3OMF_ASFLAGS.profile ?= -g
TOOL_GXX3OMF_ASOBJSUFF ?= .obj
+TOOL_GXX3OMF_RCOBJSUFF ?= .res
+TOOL_GXX3OMF_RCFLAGS ?= -n
+TOOL_GXX3OMF_RCINCS ?= $(shell $(TOOL_GXX3OMF_CXX) -E -x c++ - 2>&1 < /dev/null \
+ | $(SED_EXT) -e "/search starts here/,/[Ee]nd of search list/!d" -e "/^ /!d")
+
TOOL_GXX3OMF_ARFLAGS ?= cr
TOOL_GXX3OMF_ARLIBSUFF ?= .lib
@@ -202,6 +208,30 @@ define TOOL_GXX3OMF_COMPILE_AS_CMDS
endef
+## Compile resource source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_GXX3OMF_COMPILE_RC_OUTPUT =
+TOOL_GXX3OMF_COMPILE_RC_DEPEND =
+TOOL_GXX3OMF_COMPILE_RC_DEPORD =
+define TOOL_GXX3OMF_COMPILE_RC_CMDS
+ $(QUIET)$(REDIRECT) -E 'INCLUDE=' -- $(TOOL_GXX3OMF_RC) -r \
+ $(flags) $(addprefix -i, $(subst /,\\,$(subst /@unixroot,$(UNIXROOT),$(incs)))) $(addprefix -d, $(defs))\
+ $(subst /,\\,$(abspath $(source))) \
+ $(obj)
+endef
+
+
## Link library
# @param $(target) Normalized main target name.
# @param $(out) Library name.
@@ -216,12 +246,12 @@ TOOL_GXX3OMF_LINK_LIBRARY_OUTPUT = $(outbase).rsp
TOOL_GXX3OMF_LINK_LIBRARY_DEPEND = $(othersrc)
TOOL_GXX3OMF_LINK_LIBRARY_DEPORD =
define TOOL_GXX3OMF_LINK_LIBRARY_CMDS
- $(if $(filter %.def %.imp,$(othersrc))\
- ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp,$(othersrc))\
+ $(if $(filter %.def %.imp %.dll,$(othersrc))\
+ ,$(QUIET)$(APPEND) -n $(outbase).rsp $(filter %.def %.imp %.dll,$(othersrc))\
$(NL)$(TAB)$(QUIET)$(QUIET)$(TOOL_GXX3OMF_AR_IMP) -o $(out) @$(outbase).rsp\
$(NL)$(TAB)$(QUIET)$(RM) -f $(outbase).rsp)
- $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp,$(othersrc))
- $(TOOL_GXX3OMF_AR) @$(outbase).rsp
+ $(QUIET)$(APPEND) -n $(outbase).rsp $(flags) $(out) $(objs) $(filter-out %.def %.imp %.dll,$(othersrc))
+ $(QUIET)$(TOOL_GXX3OMF_AR) @$(outbase).rsp
endef
@@ -282,7 +312,7 @@ define TOOL_GXX3OMF_LINK_DLL_CMDS
$(othersrc)\
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
-Zmap=$(outbase).map
- $(TOOL_GXX3OMF_LD) @$(outbase).rsp
+ $(QUIET)$(TOOL_GXX3OMF_LD) @$(outbase).rsp
endef
diff --git a/kBuild/tools/GXX64.kmk b/kBuild/tools/GXX64.kmk
index 35cabfc..03973fc 100644
--- a/kBuild/tools/GXX64.kmk
+++ b/kBuild/tools/GXX64.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX64.kmk 2541 2011-08-03 09:51:30Z bird $
+# $Id: GXX64.kmk 2774 2015-02-03 19:56:24Z bird $
## @file
# kBuild Tool Config - Generic 64-bit GCC v3.2.x or later using the system GCC, for building C++ code.
#
@@ -263,9 +263,9 @@ define TOOL_GXX64_LINK_PROGRAM_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX64_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -297,9 +297,9 @@ define TOOL_GXX64_LINK_DLL_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX64_LD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
@@ -329,9 +329,9 @@ define TOOL_GXX64_LINK_SYSMOD_CMDS
$(foreach lib,$(libs), $(if $(findstring $(lib),$(subst /,x,$(lib))), -l$(patsubst lib%,%,$(lib)), $(lib)))\
$(call TOOL_GXX64_LD_SYSMOD_MAP,$(outbase).map)
ifeq ($(ld_debug),split)
- $(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
- $(CHMOD) a-x $(outbase).debug
- $(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --only-keep-debug $(out) $(outbase).debug
+ $(QUIET)$(CHMOD) a-x $(outbase).debug
+ $(QUIET)$(TOOL_GXX64_OBJCOPY) --strip-debug --strip-unneeded --add-gnu-debuglink=$(outbase).debug $(out)
endif
endef
diff --git a/kBuild/tools/JWASM.kmk b/kBuild/tools/JWASM.kmk
index 5e99194..fb8ab22 100644
--- a/kBuild/tools/JWASM.kmk
+++ b/kBuild/tools/JWASM.kmk
@@ -1,4 +1,4 @@
-# $Id: JWASM.kmk 2730 2014-03-16 20:30:59Z bird $
+# $Id: JWASM.kmk 2774 2015-02-03 19:56:24Z bird $
## @file
# kBuild Tool Config - JWasm
#
@@ -36,7 +36,7 @@ TOOL_JWASM := JWasm - MASM clone based on the Open Watcom assembler.
# Tool Specific Properties
ifndef TOOL_JWASM_AS
- TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
+ TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
ifeq ($(TOOL_JWASM_AS),)
TOOL_JWASM_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/jwasm/*/jwasm$(HOSTSUFF_EXE))))
endif
@@ -52,7 +52,7 @@ TOOL_JWASM_COMPILE_AS_OUTPUT = $(outbase).lst
TOOL_JWASM_COMPILE_AS_DEPEND =
TOOL_JWASM_COMPILE_AS_DEPORD =
define TOOL_JWASM_COMPILE_AS_CMDS
- $(TOOL_JWASM_AS) -c \
+ $(QUIET)$(TOOL_JWASM_AS) -c \
$(strip $(flags)) \
$(addprefix -D,$(defs)) \
$(addprefix -I,$(incs)) \
diff --git a/kBuild/tools/MASM510.kmk b/kBuild/tools/MASM510.kmk
index 91778e8..bd00786 100644
--- a/kBuild/tools/MASM510.kmk
+++ b/kBuild/tools/MASM510.kmk
@@ -1,4 +1,4 @@
-# $Id: MASM510.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MASM510.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MASM v5.10
#
@@ -35,7 +35,7 @@ TOOL_MASM510 := Microsoft Macro Assembler v5.10
# Tool Specific Properties
ifndef TOOL_MASM510_AS
- TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
+ TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
ifeq ($(TOOL_MASM510_AS),)
TOOL_MASM510_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v5.10*/masm$(HOSTSUFF_EXE))))
endif
diff --git a/kBuild/tools/MASM600.kmk b/kBuild/tools/MASM600.kmk
index d8ea283..e1a300c 100644
--- a/kBuild/tools/MASM600.kmk
+++ b/kBuild/tools/MASM600.kmk
@@ -1,4 +1,4 @@
-# $Id: MASM600.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MASM600.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MASM v6.00
#
@@ -35,7 +35,7 @@ TOOL_MASM600 := Microsoft Macro Assembler v6.00
# Tool Specific Properties
ifndef TOOL_MASM600_AS
- TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
+ TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
ifeq ($(TOOL_MASM600_AS),)
TOOL_MASM600_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v6.00*/binp/ml$(HOSTSUFF_EXE))))
endif
diff --git a/kBuild/tools/MASM610.kmk b/kBuild/tools/MASM610.kmk
index d07636f..e920bda 100644
--- a/kBuild/tools/MASM610.kmk
+++ b/kBuild/tools/MASM610.kmk
@@ -1,4 +1,4 @@
-# $Id: MASM610.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MASM610.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MASM v6.10
#
@@ -35,7 +35,7 @@ TOOL_MASM610 := Microsoft Macro Assembler v6.10
# Tool Specific Properties
ifndef TOOL_MASM610_AS
- TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
+ TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
ifeq ($(TOOL_MASM610_AS),)
TOOL_MASM610_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v6.10*/binp/ml$(HOSTSUFF_EXE))))
endif
diff --git a/kBuild/tools/MASM6PLUS.kmk b/kBuild/tools/MASM6PLUS.kmk
index a155876..b6023f2 100644
--- a/kBuild/tools/MASM6PLUS.kmk
+++ b/kBuild/tools/MASM6PLUS.kmk
@@ -1,4 +1,4 @@
-# $Id: MASM6PLUS.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MASM6PLUS.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MASM v6 and later.
#
@@ -36,11 +36,11 @@ TOOL_MASM6PLUS := Microsoft Macro Assembler v6 and later.
# Tool Specific Properties
ifndef TOOL_MASM6PLUS_AS
TOOL_MASM6PLUS_AS := $(firstword $(rsort $(wildcard \
- $(KBUILD_DEVTOOLS_BLD)/masm/*/bin$(if $(eq $(KBUILD_HOST),os2),p,)/ml$(HOSTSUFF_EXE)\
+ $(KBUILD_DEVTOOLS_HST)/masm/*/bin$(if $(eq $(KBUILD_HOST),os2),p,)/ml$(HOSTSUFF_EXE)\
)))
ifeq ($(TOOL_MASM6PLUS_AS),)
TOOL_MASM6PLUS_AS := $(firstword $(rsort $(wildcard \
- $(KBUILD_DEVTOOLS_BLD)/vcc/*/bin/ml$(HOSTSUFF_EXE) \
+ $(KBUILD_DEVTOOLS_HST)/vcc/*/bin/ml$(HOSTSUFF_EXE) \
)))
endif
ifeq ($(TOOL_MASM6PLUS_AS),)
diff --git a/kBuild/tools/MASM710.kmk b/kBuild/tools/MASM710.kmk
index 877c38e..812a8ae 100644
--- a/kBuild/tools/MASM710.kmk
+++ b/kBuild/tools/MASM710.kmk
@@ -1,4 +1,4 @@
-# $Id: MASM710.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MASM710.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MASM v7.10
#
@@ -35,7 +35,7 @@ TOOL_MASM710 := Microsoft Macro Assembler v7.10
# Tool Specific Properties
ifndef TOOL_MASM710_AS
- TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_BLD)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
+ TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
ifeq ($(TOOL_MASM710_AS),)
TOOL_MASM710_AS := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS_TRG)/masm/v7.10*/binp/ml$(HOSTSUFF_EXE))))
endif
diff --git a/kBuild/tools/MINGW32.kmk b/kBuild/tools/MINGW32.kmk
index e28e0f3..e9b32a3 100644
--- a/kBuild/tools/MINGW32.kmk
+++ b/kBuild/tools/MINGW32.kmk
@@ -1,4 +1,4 @@
-# $Id: MINGW32.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MINGW32.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MinGW32 GCC v3.3+.
#
@@ -38,7 +38,7 @@ TOOL_MINGW32 := MinGW32 GCC v3.3+.
# Tool Specific Properties
ifndef PATH_TOOL_MINGW32
- PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/mingw32/v*.*)
+ PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS_HST)/mingw32/v*.*)
ifeq ($(PATH_TOOL_MINGW32),)
PATH_TOOL_MINGW32 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/mingw32/v*.*)
endif
diff --git a/kBuild/tools/MINGWW64.kmk b/kBuild/tools/MINGWW64.kmk
index c6143fe..b14f673 100644
--- a/kBuild/tools/MINGWW64.kmk
+++ b/kBuild/tools/MINGWW64.kmk
@@ -1,4 +1,4 @@
-# $Id: MINGWW64.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: MINGWW64.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - MinGW-W64.
#
@@ -38,7 +38,7 @@ TOOL_MINGWW64 := MinGW-W64 - The incomprehensible 64-bit GCC port to Windows.
# Tool Specific Properties
ifndef PATH_TOOL_MINGWW64
- PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/mingw-w64/r*)
+ PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS_HST)/mingw-w64/r*)
ifeq ($(PATH_TOOL_MINGWW64),)
PATH_TOOL_MINGWW64 := $(wildcard $(KBUILD_DEVTOOLS)/win.amd64/mingw-w64/r*)
endif
diff --git a/kBuild/tools/NASM.kmk b/kBuild/tools/NASM.kmk
index 660ce59..41e4512 100644
--- a/kBuild/tools/NASM.kmk
+++ b/kBuild/tools/NASM.kmk
@@ -1,4 +1,4 @@
-# $Id: NASM.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: NASM.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - Netwide Assembler v0.98+.
#
@@ -35,7 +35,7 @@ TOOL_NASM := Netwide Assembler v0.98+
# Tool Specific Properties
ifndef PATH_TOOL_NASM
- PATH_TOOL_NASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/nasm/v*.*))
+ PATH_TOOL_NASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/nasm/v*.*))
ifneq ($(PATH_TOOL_NASM),)
PATH_TOOL_NASM := $(call lastword,$(PATH_TOOL_NASM))
endif
diff --git a/kBuild/tools/OPENWATCOM-16.kmk b/kBuild/tools/OPENWATCOM-16.kmk
index 830a760..153b871 100644
--- a/kBuild/tools/OPENWATCOM-16.kmk
+++ b/kBuild/tools/OPENWATCOM-16.kmk
@@ -1,4 +1,4 @@
-# $Id: OPENWATCOM-16.kmk 2731 2014-06-28 14:58:12Z bird $
+# $Id: OPENWATCOM-16.kmk 2749 2015-01-23 01:01:02Z bird $
## @file
# kBuild Tool Config - Open Watcom v1.4 and later, 16-bit targets.
#
@@ -45,7 +45,7 @@ TOOL_OPENWATCOM-16_COMPILE_AS_DEPEND =
TOOL_OPENWATCOM-16_COMPILE_AS_DEPORD =
TOOL_OPENWATCOM-16_COMPILE_AS_OUTPUT = $(obj).err
define TOOL_OPENWATCOM-16_COMPILE_AS_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AS) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AS) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -60,7 +60,7 @@ TOOL_OPENWATCOM-16_COMPILE_C_DEPEND =
TOOL_OPENWATCOM-16_COMPILE_C_DEPORD =
TOOL_OPENWATCOM-16_COMPILE_C_OUTPUT = $(obj).err
define TOOL_OPENWATCOM-16_COMPILE_C_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CC16) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CC16) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -75,7 +75,7 @@ TOOL_OPENWATCOM-16_COMPILE_CXX_DEPEND =
TOOL_OPENWATCOM-16_COMPILE_CXX_DEPORD =
TOOL_OPENWATCOM-16_COMPILE_CXX_OUTPUT = $(obj).err
define TOOL_OPENWATCOM-16_COMPILE_CXX_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CXX16) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CXX16) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -104,7 +104,7 @@ TOOL_OPENWATCOM-16_LINK_LIBRARY_DEPEND = $(othersrc)
TOOL_OPENWATCOM-16_LINK_LIBRARY_DEPORD =
define TOOL_OPENWATCOM-16_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(call TOOL_OPENWATCOM_FIX_SLASHES,$(objs) $(othersrc)),'+"$(obj)"')
- $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
+ $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
endef
TOOL_OPENWATCOM-16_LINK_PROGRAM_OUTPUT = $(outbase).map
@@ -112,7 +112,7 @@ TOOL_OPENWATCOM-16_LINK_PROGRAM_OUTPUT_MAYBE = $(outbase).sym
TOOL_OPENWATCOM-16_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM-16_LINK_PROGRAM_DEPORD =
define TOOL_OPENWATCOM-16_LINK_PROGRAM_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD16) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
@@ -132,7 +132,7 @@ TOOL_OPENWATCOM-16_LINK_DLL_OUTPUT_MAYBE = $(outbase).sym
TOOL_OPENWATCOM-16_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM-16_LINK_DLL_DEPORD =
define TOOL_OPENWATCOM-16_LINK_DLL_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD16) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
@@ -152,7 +152,7 @@ TOOL_OPENWATCOM-16_LINK_SYSMOD_OUTPUT_MAYBE = $(outbase).sym
TOOL_OPENWATCOM-16_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM-16_LINK_SYSMOD_DEPORD =
define TOOL_OPENWATCOM-16_LINK_SYSMOD_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD16) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
diff --git a/kBuild/tools/OPENWATCOM-WL.kmk b/kBuild/tools/OPENWATCOM-WL.kmk
index 7d28629..22fa44f 100644
--- a/kBuild/tools/OPENWATCOM-WL.kmk
+++ b/kBuild/tools/OPENWATCOM-WL.kmk
@@ -1,4 +1,4 @@
-# $Id: OPENWATCOM-WL.kmk 2663 2012-10-15 13:13:45Z bird $
+# $Id: OPENWATCOM-WL.kmk 2749 2015-01-23 01:01:02Z bird $
## @file
# kBuild Tool Config - Open Watcom v1.4 and later, using wlink.
#
@@ -54,7 +54,7 @@ define TOOL_OPENWATCOM-WL_LINK_PROGRAM_CMDS
$(foreach p,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(libpath)),'LIBPath $p') \
$(foreach o,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(filter-out %.res,$(objs)) $(othersrc)),'$(if $(filter %.lib %.a,$l),LIB,)File $o') \
$(foreach l,$(call TOOL_OPENWATCOM_FIX_SLASHES_SQ,$(libs)),'Library $l')
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD) \
$(TOOL_OPENWATCOM_WLINK) @$(outbase).rsp
$(if $(filter %.res,$(objs)), $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP) \
$(TOOL_OPENWATCOM_RC) \
diff --git a/kBuild/tools/OPENWATCOM.kmk b/kBuild/tools/OPENWATCOM.kmk
index 2ced379..26fb276 100644
--- a/kBuild/tools/OPENWATCOM.kmk
+++ b/kBuild/tools/OPENWATCOM.kmk
@@ -1,4 +1,4 @@
-# $Id: OPENWATCOM.kmk 2732 2014-06-28 16:02:41Z bird $
+# $Id: OPENWATCOM.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - Open Watcom v1.4 and later.
#
@@ -35,7 +35,7 @@ TOOL_OPENWATCOM = Open Watcom v1.4 and later (generic)
ifeq ($(PATH_TOOL_OPENWATCOM),)
ifeq ($(PATH_TOOL_OPENWATCOM),)
- PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_BLD)/openwatcom/v*)
+ PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_HST)/openwatcom/v*)
endif
ifeq ($(PATH_TOOL_OPENWATCOM),)
PATH_TOOL_OPENWATCOM := $(wildcard $(KBUILD_DEVTOOLS_TRG)/openwatcom/v*)
@@ -147,6 +147,13 @@ else
endif
+if $(KBUILD_KMK_REVISION) >= 2747
+ TOOL_OPENWATCOM_ENV_SETUP_BD ?= $(call TOOL_OPENWATCOM_ENV_SETUP,$1,$2 --wcc-brain-damage)
+else
+ TOOL_OPENWATCOM_ENV_SETUP_BD ?= $(call TOOL_OPENWATCOM_ENV_SETUP,$1,$2)
+endif
+
+
# Functions for changing slashes (SQ = single quoted).
if1of ($(KBUILD_HOST), os2 win)
TOOL_OPENWATCOM_FIX_SLASHES = $(subst /,\\,$1)
@@ -202,7 +209,7 @@ TOOL_OPENWATCOM_COMPILE_AS_DEPEND =
TOOL_OPENWATCOM_COMPILE_AS_DEPORD =
TOOL_OPENWATCOM_COMPILE_AS_OUTPUT = $(obj).err
define TOOL_OPENWATCOM_COMPILE_AS_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AS) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AS) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -218,7 +225,7 @@ TOOL_OPENWATCOM_COMPILE_C_DEPEND =
TOOL_OPENWATCOM_COMPILE_C_DEPORD =
TOOL_OPENWATCOM_COMPILE_C_OUTPUT = $(obj).err
define TOOL_OPENWATCOM_COMPILE_C_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CC) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CC) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -233,7 +240,7 @@ TOOL_OPENWATCOM_COMPILE_CXX_DEPEND =
TOOL_OPENWATCOM_COMPILE_CXX_DEPORD =
TOOL_OPENWATCOM_COMPILE_CXX_OUTPUT = $(obj).err
define TOOL_OPENWATCOM_COMPILE_CXX_CMDS
- $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_CXX) \
+ $(QUIET) $(call TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_CXX) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(call TOOL_OPENWATCOM_FIX_SLASHES,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -272,14 +279,14 @@ define TOOL_OPENWATCOM_LINK_LIBRARY_CMDS
$(filter %.imp,$(othersrc)) \
--append $(outbase).rsp \
)
- $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
+ $(QUIET)$(TOOL_OPENWATCOM_ENV_SETUP_BD) $(TOOL_OPENWATCOM_AR) $(flags) $(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) @$(outbase).rsp
endef
TOOL_OPENWATCOM_LINK_PROGRAM_OUTPUT = $(outbase).map
TOOL_OPENWATCOM_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM_LINK_PROGRAM_DEPORD =
define TOOL_OPENWATCOM_LINK_PROGRAM_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
@@ -298,7 +305,7 @@ TOOL_OPENWATCOM_LINK_DLL_OUTPUT = $(outbase).map
TOOL_OPENWATCOM_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM_LINK_DLL_DEPORD =
define TOOL_OPENWATCOM_LINK_DLL_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
@@ -317,7 +324,7 @@ TOOL_OPENWATCOM_LINK_SYSMOD_OUTPUT = $(outbase).map
TOOL_OPENWATCOM_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_OPENWATCOM_LINK_SYSMOD_DEPORD =
define TOOL_OPENWATCOM_LINK_SYSMOD_CMDS
- $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_OPENWATCOM_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_OPENWATCOM_LD) \
$(flags) \
-fe=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(out)) \
diff --git a/kBuild/tools/TAR.kmk b/kBuild/tools/TAR.kmk
index 825daed..cde01cf 100644
--- a/kBuild/tools/TAR.kmk
+++ b/kBuild/tools/TAR.kmk
@@ -1,4 +1,4 @@
-# $Id: TAR.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: TAR.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - tar unpacker.
#
@@ -35,9 +35,9 @@ TOOL_TAR := tar unpacker.
# Tool Specific Properties
ifndef TOOL_TAR_TAR
- TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_BLD)/tar/v*/tar$(HOSTSUFF_EXE))
+ TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_HST)/tar/v*/tar$(HOSTSUFF_EXE))
ifeq ($(TOOL_TAR_TAR),)
- TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/tar$(HOSTSUFF_EXE))
+ TOOL_TAR_TAR := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/tar$(HOSTSUFF_EXE))
endif
ifneq ($(TOOL_TAR_TAR),)
TOOL_TAR_TAR := $(lastword $(sort $(TOOL_TAR_TAR)))
diff --git a/kBuild/tools/VAC308.kmk b/kBuild/tools/VAC308.kmk
index fad15b2..8a12242 100644
--- a/kBuild/tools/VAC308.kmk
+++ b/kBuild/tools/VAC308.kmk
@@ -1,4 +1,4 @@
-# $Id: VAC308.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: VAC308.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - VisualAge for C++ v3.08.
#
@@ -35,9 +35,9 @@ TOOL_VAC308 := VisualAge for C++ v3.08
# Determin VAC308 location.
ifndef PATH_TOOL_VAC308
- PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/vac/v3.0.8*)
+ PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_HST)/vac/v3.0.8*)
ifeq ($(PATH_TOOL_VAC308),)
- PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_BLD)/vac/v308*)
+ PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_HST)/vac/v308*)
endif
ifeq ($(PATH_TOOL_VAC308),)
PATH_TOOL_VAC308 := $(wildcard $(KBUILD_DEVTOOLS_TRG)/vac/v3.0.8*)
diff --git a/kBuild/tools/WATCOMC11C-16.kmk b/kBuild/tools/WATCOMC11C-16.kmk
index be907ec..a024628 100644
--- a/kBuild/tools/WATCOMC11C-16.kmk
+++ b/kBuild/tools/WATCOMC11C-16.kmk
@@ -1,4 +1,4 @@
-# $Id: WATCOMC11C-16.kmk 2731 2014-06-28 14:58:12Z bird $
+# $Id: WATCOMC11C-16.kmk 2749 2015-01-23 01:01:02Z bird $
## @file
# kBuild Tool Config - Watcom C v11.0c, 16-bit targets.
#
@@ -44,7 +44,7 @@ TOOL_WATCOMC11C-16_COMPILE_C_DEPEND =
TOOL_WATCOMC11C-16_COMPILE_C_DEPORD =
TOOL_WATCOMC11C-16_COMPILE_C_OUTPUT = $(obj).err
define TOOL_WATCOMC11C-16_COMPILE_C_CMDS
- $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CC16) \
+ $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CC16) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -59,7 +59,7 @@ TOOL_WATCOMC11C-16_COMPILE_CXX_DEPEND =
TOOL_WATCOMC11C-16_COMPILE_CXX_DEPORD =
TOOL_WATCOMC11C-16_COMPILE_CXX_OUTPUT = $(obj).err
define TOOL_WATCOMC11C-16_COMPILE_CXX_CMDS
- $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CXX16) \
+ $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CXX16) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -88,14 +88,14 @@ TOOL_WATCOMC11C-16_LINK_LIBRARY_DEPEND = $(othersrc)
TOOL_WATCOMC11C-16_LINK_LIBRARY_DEPORD =
define TOOL_WATCOMC11C-16_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(subst /,\,$(objs) $(othersrc)),'+"$(obj)"')
- $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
+ $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
endef
TOOL_WATCOMC11C-16_LINK_PROGRAM_OUTPUT = $(outbase).map
TOOL_WATCOMC11C-16_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C-16_LINK_PROGRAM_DEPORD =
define TOOL_WATCOMC11C-16_LINK_PROGRAM_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD16) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
@@ -114,7 +114,7 @@ TOOL_WATCOMC11C-16_LINK_DLL_OUTPUT = $(outbase).map
TOOL_WATCOMC11C-16_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C-16_LINK_DLL_DEPORD =
define TOOL_WATCOMC11C-16_LINK_DLL_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD16) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
@@ -133,7 +133,7 @@ TOOL_WATCOMC11C-16_LINK_SYSMOD_OUTPUT = $(outbase).map
TOOL_WATCOMC11C-16_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C-16_LINK_SYSMOD_DEPORD =
define TOOL_WATCOMC11C-16_LINK_SYSMOD_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD16) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
diff --git a/kBuild/tools/WATCOMC11C-WL.kmk b/kBuild/tools/WATCOMC11C-WL.kmk
index e494af5..34919e3 100644
--- a/kBuild/tools/WATCOMC11C-WL.kmk
+++ b/kBuild/tools/WATCOMC11C-WL.kmk
@@ -1,4 +1,4 @@
-# $Id: WATCOMC11C-WL.kmk 2413 2010-09-11 17:43:04Z bird $
+# $Id: WATCOMC11C-WL.kmk 2749 2015-01-23 01:01:02Z bird $
## @file
# kBuild Tool Config - Watcom C/C++ v11.0c, using wlink.
#
@@ -53,7 +53,7 @@ define TOOL_WATCOMC11C-WL_LINK_PROGRAM_CMDS
$(foreach p,$(subst /,\,$(libpath)),'LIBPath $p') \
$(foreach o,$(subst /,\,$(filter-out %.res,$(objs)) $(othersrc)),'$(if $(filter %.lib %.a,$l),LIB,)File $o') \
$(foreach l,$(subst /,\,$(libs)),'Library $l')
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD) \
$(TOOL_WATCOMC11C_WLINK) @$(outbase).rsp
$(if $(filter %.res,$(objs)), $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP) \
$(TOOL_WATCOMC11C_RC) \
diff --git a/kBuild/tools/WATCOMC11C.kmk b/kBuild/tools/WATCOMC11C.kmk
index 44bb885..f33dd6b 100644
--- a/kBuild/tools/WATCOMC11C.kmk
+++ b/kBuild/tools/WATCOMC11C.kmk
@@ -1,4 +1,4 @@
-# $Id: WATCOMC11C.kmk 2731 2014-06-28 14:58:12Z bird $
+# $Id: WATCOMC11C.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - Watcom C v11.0c
#
@@ -35,7 +35,7 @@ TOOL_WATCOMC11C = Watcom C/C++ v11.0c (generic)
ifeq ($(PATH_TOOL_WATCOMC11C),)
ifeq ($(PATH_TOOL_WATCOMC11C),)
- PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_BLD)/watcom/v11.0c*)
+ PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_HST)/watcom/v11.0c*)
endif
ifeq ($(PATH_TOOL_WATCOMC11C),)
PATH_TOOL_WATCOMC11C := $(wildcard $(KBUILD_DEVTOOLS_TRG)/watcom/v11.0c*)
@@ -113,6 +113,13 @@ else
endif
+if $(KBUILD_KMK_REVISION) >= 2747
+ TOOL_WATCOMC11C_ENV_SETUP_BD ?= $(call TOOL_WATCOMC11C_ENV_SETUP,$1,$2 --wcc-brain-damage)
+else
+ TOOL_WATCOMC11C_ENV_SETUP_BD ?= $(call TOOL_WATCOMC11C_ENV_SETUP,$1,$2)
+endif
+
+
# General Properties used by kBuild
TOOL_WATCOMC11C_COBJSUFF ?= .obj
TOOL_WATCOMC11C_CFLAGS ?= -zq
@@ -151,7 +158,7 @@ TOOL_WATCOMC11C_COMPILE_C_DEPEND =
TOOL_WATCOMC11C_COMPILE_C_DEPORD =
TOOL_WATCOMC11C_COMPILE_C_OUTPUT = $(obj).err
define TOOL_WATCOMC11C_COMPILE_C_CMDS
- $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CC) \
+ $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CC) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -166,7 +173,7 @@ TOOL_WATCOMC11C_COMPILE_CXX_DEPEND =
TOOL_WATCOMC11C_COMPILE_CXX_DEPORD =
TOOL_WATCOMC11C_COMPILE_CXX_OUTPUT = $(obj).err
define TOOL_WATCOMC11C_COMPILE_CXX_CMDS
- $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_CXX) \
+ $(QUIET) $(call TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_CXX) \
$(flags) \
$(addsuffix , $(addprefix -i=, $(subst /,\\,$(incs)))) \
$(addprefix -d, $(defs)) \
@@ -195,14 +202,14 @@ TOOL_WATCOMC11C_LINK_LIBRARY_DEPEND = $(othersrc)
TOOL_WATCOMC11C_LINK_LIBRARY_DEPORD =
define TOOL_WATCOMC11C_LINK_LIBRARY_CMDS
$(QUIET)$(APPEND) -tn $(outbase).rsp $(foreach obj,$(subst /,\,$(objs) $(othersrc)),'+"$(obj)"')
- $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
+ $(QUIET)$(TOOL_WATCOMC11C_ENV_SETUP_BD) $(TOOL_WATCOMC11C_AR) $(flags) $(subst /,\\,$(out)) @$(outbase).rsp
endef
TOOL_WATCOMC11C_LINK_PROGRAM_OUTPUT = $(outbase).map
TOOL_WATCOMC11C_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C_LINK_PROGRAM_DEPORD =
define TOOL_WATCOMC11C_LINK_PROGRAM_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
@@ -221,7 +228,7 @@ TOOL_WATCOMC11C_LINK_DLL_OUTPUT = $(outbase).map
TOOL_WATCOMC11C_LINK_DLL_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C_LINK_DLL_DEPORD =
define TOOL_WATCOMC11C_LINK_DLL_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
@@ -240,7 +247,7 @@ TOOL_WATCOMC11C_LINK_SYSMOD_OUTPUT = $(outbase).map
TOOL_WATCOMC11C_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
TOOL_WATCOMC11C_LINK_SYSMOD_DEPORD =
define TOOL_WATCOMC11C_LINK_SYSMOD_CMDS
- $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
+ $(QUIET)$(call TOOL_WATCOMC11C_ENV_SETUP_BD,$(subst $(SP),,$(addsuffix ;,$(libpath))),-C $(dir $(out))) \
$(TOOL_WATCOMC11C_LD) \
$(flags) \
-fe=$(subst /,\\,$(out)) \
diff --git a/kBuild/tools/WGET.kmk b/kBuild/tools/WGET.kmk
index 2bd0670..c644c36 100644
--- a/kBuild/tools/WGET.kmk
+++ b/kBuild/tools/WGET.kmk
@@ -1,4 +1,4 @@
-# $Id: WGET.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: WGET.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - wget fetchers.
#
@@ -35,9 +35,9 @@ TOOL_WGET := wget fetcher.
# Tool Specific Properties
ifndef TOOL_WGET_FETCH
- TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_BLD)/wget/v*/wget$(HOSTSUFF_EXE))
+ TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_HST)/wget/v*/wget$(HOSTSUFF_EXE))
ifneq ($(TOOL_WGET_FETCH),)
- TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/wget$(HOSTSUFF_EXE))
+ TOOL_WGET_FETCH := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/wget$(HOSTSUFF_EXE))
endif
ifneq ($(TOOL_WGET_FETCH),)
TOOL_WGET_FETCH := $(lastword $(sort $(TOOL_WGET_FETCH)))
diff --git a/kBuild/tools/XGCCAMD64LINUX.kmk b/kBuild/tools/XGCCAMD64LINUX.kmk
index 2430a8b..4b81f42 100644
--- a/kBuild/tools/XGCCAMD64LINUX.kmk
+++ b/kBuild/tools/XGCCAMD64LINUX.kmk
@@ -1,4 +1,4 @@
-# $Id: XGCCAMD64LINUX.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: XGCCAMD64LINUX.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - GCC Cross compiler for AMD64+Linux.
#
@@ -43,7 +43,7 @@ else # x-compile:
ifndef TOOL_XGCCAMD64LINUX_PREFIX
TOOL_XGCCAMD64LINUX_PREFIX := x86_64-unknown-linux-gnu-
ifndef PATH_TOOL_XGCCAMD64LINUX
- PATH_TOOL_XGCCAMD64LINUX := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/x86_64-unknown-linux-gnu/*))
+ PATH_TOOL_XGCCAMD64LINUX := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/x86_64-unknown-linux-gnu/*))
ifeq ($(PATH_TOOL_XGCCAMD64LINUX),)
ifeq ($(filter-out win.amd64,$(KBUILD_HOST).$(KBUILD_HOST_ARCH)),) # these can use the windows build.
TOOL_XGCCAMD64LINUX_EXEC_PREFIX ?= $(EXEC_X86_WIN32)
diff --git a/kBuild/tools/YASM.kmk b/kBuild/tools/YASM.kmk
index 24a2041..725402c 100644
--- a/kBuild/tools/YASM.kmk
+++ b/kBuild/tools/YASM.kmk
@@ -1,4 +1,4 @@
-# $Id: YASM.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: YASM.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - YASM 0.4.0 or later.
#
@@ -35,7 +35,7 @@ TOOL_YASM := YASM v0.4.0+
# Tool Specific Properties
ifndef PATH_TOOL_YASM
- PATH_TOOL_YASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_BLD)/yasm/v*.*))
+ PATH_TOOL_YASM := $(sort $(wildcard $(KBUILD_DEVTOOLS_HST)/yasm/v*.*))
ifneq ($(PATH_TOOL_YASM),)
PATH_TOOL_YASM := $(call lastword,$(PATH_TOOL_YASM))
endif
diff --git a/kBuild/tools/ZIP.kmk b/kBuild/tools/ZIP.kmk
index b84f2a4..d5a0217 100644
--- a/kBuild/tools/ZIP.kmk
+++ b/kBuild/tools/ZIP.kmk
@@ -1,4 +1,4 @@
-# $Id: ZIP.kmk 2726 2014-02-26 23:23:54Z bird $
+# $Id: ZIP.kmk 2750 2015-01-23 12:24:02Z bird $
## @file
# kBuild Tool Config - The zip/unzip packer/unpacker.
#
@@ -35,12 +35,12 @@ TOOL_ZIP := The zip/unzip packer/unpacker.
# Tool Specific Properties
ifndef TOOL_ZIP_UNPACK
- TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/unzip/v*/unzip$(HOSTSUFF_EXE))
+ TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/unzip/v*/unzip$(HOSTSUFF_EXE))
ifeq ($(TOOL_ZIP_UNPACK),)
- TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/zip/v*/unzip$(HOSTSUFF_EXE))
+ TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/zip/v*/unzip$(HOSTSUFF_EXE))
endif
ifeq ($(TOOL_ZIP_UNPACK),)
- TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/unzip$(HOSTSUFF_EXE))
+ TOOL_ZIP_UNPACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/unzip$(HOSTSUFF_EXE))
endif
ifneq ($(TOOL_ZIP_UNPACK),)
TOOL_ZIP_UNPACK := $(lastword $(sort $(TOOL_ZIP_UNPACK)))
@@ -51,12 +51,12 @@ else
TOOL_ZIP_UNPACK := $(TOOL_ZIP_UNPACK)
endif
#ifndef TOOL_ZIP_PACK
-# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/zip/v*/zip$(HOSTSUFF_EXE))
+# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/zip/v*/zip$(HOSTSUFF_EXE))
# ifeq ($(TOOL_ZIP_PACK),)
-# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/unzip/v*/zip$(HOSTSUFF_EXE))
+# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/unzip/v*/zip$(HOSTSUFF_EXE))
# endif
# ifeq ($(TOOL_ZIP_PACK),)
-# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_BLD)/bin/zip$(HOSTSUFF_EXE))
+# TOOL_ZIP_PACK := $(wildcard $(KBUILD_DEVTOOLS_HST)/bin/zip$(HOSTSUFF_EXE))
# endif
# ifneq ($(TOOL_ZIP_PACK),)
# TOOL_ZIP_PACK := $(lastword $(sort $(TOOL_ZIP_PACK)))
diff --git a/src/kmk/Makefile.kmk b/src/kmk/Makefile.kmk
index 7b7e11c..83efb22 100644
--- a/src/kmk/Makefile.kmk
+++ b/src/kmk/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2719 2014-01-01 17:40:56Z bird $
+# $Id: Makefile.kmk 2765 2015-01-30 00:27:51Z bird $
## @file
# Sub-makefile for kmk / GNU Make.
#
@@ -192,6 +192,7 @@ kmk_DEFS = \
CONFIG_WITH_RDONLY_VARIABLE_VALUE \
CONFIG_WITH_LAZY_DEPS_VARS \
CONFIG_WITH_MEMORY_OPTIMIZATIONS \
+ CONFIG_WITH_COMPILER \
\
KBUILD_HOST=\"$(KBUILD_TARGET)\" \
KBUILD_HOST_ARCH=\"$(KBUILD_TARGET_ARCH)\" \
@@ -200,17 +201,15 @@ kmk_DEFS.x86 = CONFIG_WITH_OPTIMIZATION_HACKS
kmk_DEFS.amd64 = CONFIG_WITH_OPTIMIZATION_HACKS
kmk_DEFS.win = CONFIG_NEW_WIN32_CTRL_EVENT CONFIG_WITH_FAST_IS_SPACE
kmk_DEFS.debug = CONFIG_WITH_MAKE_STATS
+ifdef CONFIG_WITH_MAKE_STATS
+ kmk_DEFS += CONFIG_WITH_MAKE_STATS
+endif
kmk_SOURCES = \
main.c \
- kbuild.c \
- kbuild-object.c \
read.c \
- expreval.c \
- incdep.c \
hash.c \
strcache.c \
- strcache2.c \
variable.c \
ar.c \
arscan.c \
@@ -223,13 +222,20 @@ kmk_SOURCES = \
implicit.c \
job.c \
misc.c \
- alloccache.c \
remake.c \
rule.c \
signame.c \
version.c \
vpath.c \
- remote-stub.c
+ remote-stub.c \
+ \
+ alloccache.c \
+ expreval.c \
+ incdep.c \
+ strcache2.c \
+ kmk_cc_exec.c \
+ kbuild.c \
+ kbuild-object.c
kmk_DEFS.freebsd.x86 = CONFIG_WITHOUT_THREADS
diff --git a/src/kmk/commands.c b/src/kmk/commands.c
index bc74e18..6e4bd21 100644
--- a/src/kmk/commands.c
+++ b/src/kmk/commands.c
@@ -629,6 +629,27 @@ chop_commands (struct commands *cmds)
}
}
+#ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
+/* This is for saving memory in func_commands. */
+void
+free_chopped_commands (struct commands *cmds)
+{
+ if ( cmds
+ && cmds->command_lines != 0
+ && cmds->refs == 0)
+ {
+ unsigned idx = cmds->ncommand_lines;
+ while (idx-- > 0)
+ free (cmds->command_lines[idx]);
+ free (cmds->command_lines);
+ free (cmds->lines_flags);
+ cmds->command_lines = 0;
+ cmds->lines_flags = 0;
+ cmds->ncommand_lines = 0;
+ }
+}
+
+#endif /* CONFIG_WITH_MEMORY_OPTIMIZATIONS */
/* Execute the commands to remake FILE. If they are currently executing,
return or have already finished executing, just return. Otherwise,
fork off a child process to run the first command line in the sequence. */
diff --git a/src/kmk/commands.h b/src/kmk/commands.h
index df4ab4c..581713d 100644
--- a/src/kmk/commands.h
+++ b/src/kmk/commands.h
@@ -56,6 +56,9 @@ void execute_file_commands (struct file *file);
void print_commands (const struct commands *cmds);
void delete_child_targets (struct child *child);
void chop_commands (struct commands *cmds);
+#ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
+void free_chopped_commands (struct commands *cmd);
+#endif
#if defined(CONFIG_WITH_COMMANDS_FUNC) || defined (CONFIG_WITH_DOT_MUST_MAKE)
void set_file_variables (struct file *file, int called_early);
#else
diff --git a/src/kmk/config.h.win b/src/kmk/config.h.win
index 4cb172a..64e42d7 100644
--- a/src/kmk/config.h.win
+++ b/src/kmk/config.h.win
@@ -16,6 +16,9 @@ You should have received a copy of the GNU General Public License along with
GNU Make; see the file COPYING. If not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
+#ifndef ___config_h_win
+#define ___config_h_win
+
/* Suppress some Visual C++ warnings.
Maybe after the code cleanup for ISO C we can remove some/all of these. */
#if _MSC_VER > 1000
@@ -218,7 +221,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
-/*#define HAVE_STDINT_H 1*/
+#if _MSC_VER >= 1600
+# define HAVE_STDINT_H 1
+#endif
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@@ -443,10 +448,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
#define uid_t int
/* Define uintmax_t if not defined in <stdint.h> or <inttypes.h>. */
-#if 0
-#define uintmax_t unsigned long
-#else
-#define uintmax_t unsigned __int64
+#if _MSC_VER < 1600
+# if 0
+# define uintmax_t unsigned long
+# else
+# define uintmax_t unsigned __int64
+# endif
#endif
/* Define as `fork' if `vfork' does not work. */
@@ -533,8 +540,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
#define _DIRENT_HAVE_D_NAMLEN 1
#define _DIRENT_HAVE_D_TYPE 1
-
-/* cygwin sucks to much in one end or the other. */
+/* bird: Not sure if this is necessary any more... */
#define BATCH_MODE_ONLY_SHELL
#include "inlined_memchr.h"
@@ -556,3 +562,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
extern char space_map[space_map_size];
#endif
+/* bird: Include mscfakes.h to make sure we have all it's tricks applied. */
+#ifndef ___mscfakes_h
+# include "kmkbuiltin/mscfakes.h"
+#endif
+
+#endif /* bird */
+
diff --git a/src/kmk/dir.c b/src/kmk/dir.c
index 335c2f8..2bef610 100644
--- a/src/kmk/dir.c
+++ b/src/kmk/dir.c
@@ -1310,7 +1310,11 @@ print_dir_data_base (void)
/* Hooks for globbing. */
+#if defined(KMK) && !defined(__OS2__)
+# include "glob/glob.h"
+#else
#include <glob.h>
+#endif
/* Structure describing state of iterating through a directory hash table. */
diff --git a/src/kmk/expand.c b/src/kmk/expand.c
index c93e197..7deeb99 100644
--- a/src/kmk/expand.c
+++ b/src/kmk/expand.c
@@ -25,6 +25,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "commands.h"
#include "variable.h"
#include "rule.h"
+#ifdef CONFIG_WITH_COMPILER
+# include "kmk_cc_exec.h"
+#endif
/* Initially, any errors reported when expanding strings will be reported
against the file where the error appears. */
@@ -185,7 +188,19 @@ recursively_expand_for_file (struct variable *v, struct file *file,
value = allocated_variable_expand (v->value);
#else /* CONFIG_WITH_VALUE_LENGTH */
if (!v->append)
- value = allocated_variable_expand_2 (v->value, v->value_length, value_lenp);
+ {
+ if (!IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
+ value = allocated_variable_expand_2 (v->value, v->value_length, value_lenp);
+ else
+ {
+ unsigned int len = v->value_length;
+ value = xmalloc (len + 2);
+ memcpy (value, v->value, len + 1);
+ value[len + 1] = '\0'; /* Extra terminator like allocated_variable_expand_2 returns. Why? */
+ if (value_lenp)
+ *value_lenp = len;
+ }
+ }
else
{
value = allocated_variable_append (v);
@@ -207,11 +222,11 @@ recursively_expand_for_file (struct variable *v, struct file *file,
}
#ifdef CONFIG_WITH_VALUE_LENGTH
-/* Static worker for reference_variable() that expands the recursive
+/* Worker for reference_variable() and kmk_exec_* that expands the recursive
variable V. The main difference between this and
recursively_expand[_for_file] is that this worker avoids the temporary
buffer and outputs directly into the current variable buffer (O). */
-static char *
+char *
reference_recursive_variable (char *o, struct variable *v)
{
const struct floc *this_var;
@@ -246,8 +261,20 @@ reference_recursive_variable (char *o, struct variable *v)
v->expanding = 1;
if (!v->append)
- /* Expand directly into the variable buffer. */
- variable_expand_string_2 (o, v->value, v->value_length, &o);
+ {
+ /* Expand directly into the variable buffer. */
+# ifdef CONFIG_WITH_COMPILER
+ v->expand_count++;
+ if ( v->expandprog
+ || (v->expand_count == 3 && kmk_cc_compile_variable_for_expand (v)) )
+ o = kmk_exec_expand_to_var_buf (v, o);
+ else
+ variable_expand_string_2 (o, v->value, v->value_length, &o);
+# else
+ MAKE_STATS_2 (v->expand_count++);
+ variable_expand_string_2 (o, v->value, v->value_length, &o);
+# endif
+ }
else
{
/* XXX: Feel free to optimize appending target variables as well. */
@@ -295,7 +322,7 @@ reference_variable (char *o, const char *name, unsigned int length)
#ifdef CONFIG_WITH_VALUE_LENGTH
assert (v->value_length == strlen (v->value));
- if (!v->recursive)
+ if (!v->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
o = variable_buffer_output (o, v->value, v->value_length);
else
o = reference_recursive_variable (o, v);
@@ -987,7 +1014,7 @@ variable_append (const char *name, unsigned int length,
#endif
/* Either expand it or copy it, depending. */
- if (! v->recursive)
+ if (! v->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
#ifdef CONFIG_WITH_VALUE_LENGTH
return variable_buffer_output (buf, v->value, v->value_length);
#else
@@ -1058,6 +1085,7 @@ append_expanded_string_to_variable (struct variable *v, const char *value,
v->value = variable_buffer;
v->value_length = p - v->value;
v->value_alloc_len = variable_buffer_length;
+ VARIABLE_CHANGED(v);
/* Restore the variable buffer, but without freeing the current. */
variable_buffer = NULL;
@@ -1195,8 +1223,42 @@ install_variable_buffer (char **bufp, unsigned int *lenp)
initialize_variable_output ();
}
-/* Restore a previously-saved variable_buffer setting (free the current one).
- */
+#ifdef CONFIG_WITH_COMPILER
+/* Same as install_variable_buffer, except we supply a size hint. */
+
+char *
+install_variable_buffer_with_hint (char **bufp, unsigned int *lenp, unsigned int size_hint)
+{
+ struct recycled_buffer *recycled;
+ char *buf;
+
+ *bufp = variable_buffer;
+ *lenp = variable_buffer_length;
+
+ recycled = recycled_head;
+ if (recycled)
+ {
+ recycled_head = recycled->next;
+ variable_buffer_length = recycled->length;
+ variable_buffer = buf = (char *)recycled;
+ }
+ else
+ {
+ if (size_hint < 512)
+ variable_buffer_length = (size_hint + 1 + 63) & ~(unsigned int)63;
+ else if (size_hint < 4096)
+ variable_buffer_length = (size_hint + 1 + 1023) & ~(unsigned int)1023;
+ else
+ variable_buffer_length = (size_hint + 1 + 4095) & ~(unsigned int)4095;
+ variable_buffer = buf = xmalloc (variable_buffer_length);
+ }
+ buf[0] = '\0';
+ return buf;
+}
+#endif /* CONFIG_WITH_COMPILER */
+
+/* Restore a previously-saved variable_buffer setting (free the
+ current one). */
void
restore_variable_buffer (char *buf, unsigned int len)
@@ -1211,3 +1273,24 @@ restore_variable_buffer (char *buf, unsigned int len)
variable_buffer = buf;
variable_buffer_length = len;
}
+
+
+/* Used to make sure there is at least SIZE bytes of buffer space
+ available starting at PTR. */
+char *
+ensure_variable_buffer_space(char *ptr, unsigned int size)
+{
+ unsigned int offset = (unsigned int)(ptr - variable_buffer);
+ assert(offset <= variable_buffer_length);
+ if (variable_buffer_length - offset < size)
+ {
+ unsigned minlen = size + offset;
+ variable_buffer_length *= 2;
+ if (variable_buffer_length < minlen + 100)
+ variable_buffer_length = (minlen + 100 + 63) & ~(unsigned int)63;
+ variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
+ ptr = variable_buffer + offset;
+ }
+ return ptr;
+}
+
diff --git a/src/kmk/function.c b/src/kmk/function.c
index 68409f7..6852a84 100644
--- a/src/kmk/function.c
+++ b/src/kmk/function.c
@@ -43,6 +43,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# include <limits.h>
# endif
#endif
+#ifdef CONFIG_WITH_COMPILER
+# include "kmk_cc_exec.h"
+#endif
#include <assert.h> /* bird */
#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE) /* bird */
@@ -1349,6 +1352,7 @@ func_foreach (char *o, char **argv, const char *funcname UNUSED)
memcpy (var->value, p, len);
var->value[len] = '\0';
var->value_length = len;
+ VARIABLE_CHANGED (var);
variable_expand_string_2 (o, body, body_len, &o);
o = variable_buffer_output (o, " ", 1);
@@ -1741,7 +1745,8 @@ func_sort (char *o, char **argv, const char *funcname UNUSED)
wordi = 0;
while ((p = find_next_token (&t, &len)) != 0)
{
- ++t;
+ if (*t != '\0') /* bird: Fixes access beyond end of string and overflowing words array. */
+ ++t;
p[len] = '\0';
words[wordi++] = p;
}
@@ -2033,31 +2038,52 @@ func_evalval (char *o, char **argv, const char *funcname)
int var_ctx;
size_t off;
const struct floc *reading_file_saved = reading_file;
+# ifdef CONFIG_WITH_MAKE_STATS
+ unsigned long long uStartTick = CURRENT_CLOCK_TICK();
+# ifndef CONFIG_WITH_COMPILER
+ MAKE_STATS_2(v->evalval_count++);
+# endif
+# endif
- /* Make a copy of the value to the variable buffer since
- eval_buffer will make changes to its input. */
-
- off = o - variable_buffer;
- variable_buffer_output (o, v->value, v->value_length + 1);
- o = variable_buffer + off;
-
- /* Eval the value. Pop the current variable buffer setting so that the
- eval'd code can use its own without conflicting. (really necessary?) */
-
- install_variable_buffer (&buf, &len);
var_ctx = !strcmp (funcname, "evalvalctx");
if (var_ctx)
push_new_variable_scope ();
if (v->fileinfo.filenm)
reading_file = &v->fileinfo;
- assert (!o[v->value_length]);
- eval_buffer (o, o + v->value_length);
+# ifdef CONFIG_WITH_COMPILER
+ /* If this variable has been evaluated more than a few times, it make
+ sense to compile it to speed up the processing. */
+
+ v->evalval_count++;
+ if ( v->evalprog
+ || (v->evalval_count == 3 && kmk_cc_compile_variable_for_eval (v)))
+ {
+ install_variable_buffer (&buf, &len); /* Really necessary? */
+ kmk_exec_evalval (v);
+ restore_variable_buffer (buf, len);
+ }
+ else
+# endif
+ {
+ /* Make a copy of the value to the variable buffer first since
+ eval_buffer will make changes to its input. */
+
+ off = o - variable_buffer;
+ variable_buffer_output (o, v->value, v->value_length + 1);
+ o = variable_buffer + off;
+ assert (!o[v->value_length]);
+
+ install_variable_buffer (&buf, &len); /* Really necessary? */
+ eval_buffer (o, o + v->value_length);
+ restore_variable_buffer (buf, len);
+ }
reading_file = reading_file_saved;
if (var_ctx)
pop_variable_scope ();
- restore_variable_buffer (buf, len);
+
+ MAKE_STATS_2(v->cTicksEvalVal += CURRENT_CLOCK_TICK() - uStartTick);
}
return o;
@@ -2126,6 +2152,17 @@ func_eval_optimize_variable (char *o, char **argv, const char *funcname)
*dst = '\0';
v->value_length = dst - v->value;
}
+
+ VARIABLE_CHANGED (v);
+
+# ifdef CONFIG_WITH_COMPILER
+ /* Compile the variable for evalval, evalctx and expansion. */
+
+ if ( v->recursive
+ && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
+ kmk_cc_compile_variable_for_expand (v);
+ kmk_cc_compile_variable_for_eval (v);
+# endif
}
else if (v)
error (NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
@@ -4067,7 +4104,8 @@ func_comp_vars (char *o, char **argv, const char *funcname)
return variable_buffer_output (o, argv[2], strlen(argv[2]));
if (var1->value == var2->value)
return variable_buffer_output (o, "", 0); /* eq */
- if (!var1->recursive && !var2->recursive)
+ if ( (!var1->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var1))
+ && (!var2->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var2)) )
{
if ( var1->value_length == var2->value_length
&& !memcmp (var1->value, var2->value, var1->value_length))
@@ -4597,6 +4635,7 @@ func_stack_pop_top (char *o, char **argv, const char *funcname)
#ifdef CONFIG_WITH_VALUE_LENGTH
stack_var->value_length = lastitem - stack_var->value;
#endif
+ VARIABLE_CHANGED (stack_var);
}
}
}
@@ -5755,6 +5794,24 @@ handle_function (char **op, const char **stringp, const char *nameend, const cha
return handle_function2 (entry_p, op, stringp);
}
#endif /* CONFIG_WITH_VALUE_LENGTH */
+
+#ifdef CONFIG_WITH_COMPILER
+/* Used by the "compiler" to get all info about potential functions. */
+make_function_ptr_t
+lookup_function_for_compiler (const char *name, unsigned int len,
+ unsigned char *minargsp, unsigned char *maxargsp,
+ char *expargsp, const char **funcnamep)
+{
+ const struct function_table_entry *entry_p = lookup_function (name, len);
+ if (!entry_p)
+ return 0;
+ *minargsp = entry_p->minimum_args;
+ *maxargsp = entry_p->maximum_args;
+ *expargsp = entry_p->expand_args;
+ *funcnamep = entry_p->name;
+ return entry_p->func_ptr;
+}
+#endif /* CONFIG_WITH_COMPILER */
/* User-defined functions. Expand the first argument as either a builtin
@@ -5929,7 +5986,7 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
current_variable_set_list->set);
if (v && v->value_length)
{
- if (v->recursive)
+ if (v->recursive && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
{
v->exp_count = EXP_COUNT_MAX;
variable_expand_string_2 (o, v->value, v->value_length, &o);
diff --git a/src/kmk/job.c b/src/kmk/job.c
index 46c5939..340420e 100644
--- a/src/kmk/job.c
+++ b/src/kmk/job.c
@@ -1010,23 +1010,8 @@ free_child (struct child *child)
child->file->cmds->refs--;
if ( !child->file->intermediate
- && !child->file->pat_variables
- && child->file->cmds->refs == 0)
- {
- struct commands *cmds = child->file->cmds;
- unsigned int i;
-
- for (i = 0; i < cmds->ncommand_lines; ++i)
- {
- free (cmds->command_lines[i]);
- cmds->command_lines[i] = 0;
- }
- free (cmds->command_lines);
- cmds->command_lines = 0;
- free (cmds->lines_flags);
- cmds->lines_flags = 0;
- cmds->ncommand_lines = 0;
- }
+ && !child->file->pat_variables)
+ free_chopped_commands(child->file->cmds);
#endif /* CONFIG_WITH_MEMORY_OPTIMIZATIONS */
free (child);
diff --git a/src/kmk/kbuild.c b/src/kmk/kbuild.c
index 28a24cb..5dcd397 100644
--- a/src/kmk/kbuild.c
+++ b/src/kmk/kbuild.c
@@ -1,4 +1,4 @@
-/* $Id: kbuild.c 2540 2011-08-02 20:13:24Z bird $ */
+/* $Id: kbuild.c 2771 2015-02-01 20:48:36Z bird $ */
/** @file
* kBuild specific make functionality.
*/
@@ -569,6 +569,7 @@ kbuild_simplify_variable(struct variable *pVar)
pVar->value_alloc_len = value_len + 1;
}
pVar->recursive = 0;
+ VARIABLE_CHANGED(pVar);
return pVar;
}
@@ -1573,8 +1574,8 @@ kbuild_collect_source_prop(struct variable *pTarget, struct variable *pSource,
if (pVar) \
{ \
paVars[iVar].pVar = pVar; \
- if ( !pVar->recursive \
- || !memchr(pVar->value, '$', pVar->value_length)) \
+ if ( !pVar->recursive \
+ || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar)) \
{ \
paVars[iVar].pszExp = pVar->value; \
paVars[iVar].cchExp = pVar->value_length; \
@@ -2620,6 +2621,8 @@ func_kbuild_expand_template(char *o, char **argv, const char *pszFuncName)
off--;
pDefTemplate->value_length = off;
pDefTemplate->value[off] = '\0';
+
+ VARIABLE_CHANGED(pDefTemplate);
}
if (!pDefTemplate->value_length)
diff --git a/src/kmk/kmk_cc_exec.c b/src/kmk/kmk_cc_exec.c
new file mode 100644
index 0000000..f49951d
--- /dev/null
+++ b/src/kmk/kmk_cc_exec.c
@@ -0,0 +1,2027 @@
+#ifdef CONFIG_WITH_COMPILER
+/* $Id: kmk_cc_exec.c 2777 2015-02-03 21:06:31Z bird $ */
+/** @file
+ * kmk_cc - Make "Compiler".
+ */
+
+/*
+ * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * kBuild is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with kBuild. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "make.h"
+
+#include "dep.h"
+#include "variable.h"
+#include "rule.h"
+#include "debug.h"
+#include "hash.h"
+#include <ctype.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <stdarg.h>
+#include <assert.h>
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** @def KMK_CC_WITH_STATS
+ * Enables the collection of extra statistics. */
+#ifndef KMK_CC_WITH_STATS
+# ifdef CONFIG_WITH_MAKE_STATS
+# define KMK_CC_WITH_STATS
+# endif
+#endif
+
+/** @def KMK_CC_STRICT
+ * Indicates whether assertions and other checks are enabled. */
+#ifndef KMK_CC_STRICT
+# ifndef NDEBUG
+# define KMK_CC_STRICT
+# endif
+#endif
+
+#ifdef KMK_CC_STRICT
+# ifdef _MSC_VER
+# define KMK_CC_ASSERT(a_TrueExpr) do { if (!(a_TrueExpr)) __debugbreak(); } while (0)
+# else
+# define KMK_CC_ASSERT(a_TrueExpr) assert(a_TrueExpr)
+# endif
+#else
+# define KMK_CC_ASSERT(a_TrueExpr) do {} while (0)
+#endif
+#define KMK_CC_ASSERT_ALIGNED(a_uValue, a_uAlignment) \
+ KMK_CC_ASSERT( ((a_uValue) & ((a_uAlignment) - 1)) == 0 )
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * Block of expand instructions.
+ *
+ * To avoid wasting space on "next" pointers, as well as a lot of time walking
+ * these chains when destroying programs, we work with blocks of instructions.
+ */
+typedef struct kmk_cc_block
+{
+ /** The pointer to the next block (LIFO). */
+ struct kmk_cc_block *pNext;
+ /** The size of this block. */
+ uint32_t cbBlock;
+ /** The offset of the next free byte in the block. When set to cbBlock the
+ * block is 100% full. */
+ uint32_t offNext;
+} KMKCCBLOCK;
+typedef KMKCCBLOCK *PKMKCCBLOCK;
+
+/**
+ * String expansion statistics.
+ */
+typedef struct KMKCCEXPSTATS
+{
+ /** Recent average size. */
+ uint32_t cchAvg;
+} KMKCCEXPSTATS;
+typedef KMKCCEXPSTATS *PKMKCCEXPSTATS;
+
+/**
+ * Expansion instructions.
+ */
+typedef enum KMKCCEXPINSTR
+{
+ /** Copy a plain string. */
+ kKmkCcExpInstr_CopyString = 0,
+ /** Insert an expanded variable value, which name we already know. */
+ kKmkCcExpInstr_PlainVariable,
+ /** Insert an expanded variable value, the name is dynamic (sub prog). */
+ kKmkCcExpInstr_DynamicVariable,
+ /** Insert an expanded variable value, which name we already know, doing
+ * search an replace on a string. */
+ kKmkCcExpInstr_SearchAndReplacePlainVariable,
+ /** Insert the output of function that requires no argument expansion. */
+ kKmkCcExpInstr_PlainFunction,
+ /** Insert the output of function that requires dynamic expansion of one ore
+ * more arguments. (Dynamic is perhaps not such a great name, but whatever.) */
+ kKmkCcExpInstr_DynamicFunction,
+ /** Jump to a new instruction block. */
+ kKmkCcExpInstr_Jump,
+ /** We're done, return. Has no specific structure. */
+ kKmkCcExpInstr_Return,
+ /** The end of valid instructions (exclusive). */
+ kKmkCcExpInstr_End
+} KMKCCEXPANDINSTR;
+
+/** Instruction core. */
+typedef struct kmk_cc_exp_core
+{
+ /** The instruction opcode number (KMKCCEXPANDINSTR). */
+ KMKCCEXPANDINSTR enmOpCode;
+} KMKCCEXPCORE;
+typedef KMKCCEXPCORE *PKMKCCEXPCORE;
+
+/**
+ * String expansion sub program.
+ */
+typedef struct kmk_cc_exp_subprog
+{
+ /** Pointer to the first instruction. */
+ PKMKCCEXPCORE pFirstInstr;
+ /** Statistics. */
+ KMKCCEXPSTATS Stats;
+} KMKCCEXPSUBPROG;
+typedef KMKCCEXPSUBPROG *PKMKCCEXPSUBPROG;
+
+/**
+ * kKmkCcExpInstr_CopyString instruction format.
+ */
+typedef struct kmk_cc_exp_copy_string
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** The number of bytes to copy. */
+ uint32_t cchCopy;
+ /** Pointer to the source string (not terminated at cchCopy). */
+ const char *pachSrc;
+} KMKCCEXPCOPYSTRING;
+typedef KMKCCEXPCOPYSTRING *PKMKCCEXPCOPYSTRING;
+
+/**
+ * kKmkCcExpInstr_PlainVariable instruction format.
+ */
+typedef struct kmk_cc_exp_plain_variable
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** The name of the variable (points into variable_strcache). */
+ const char *pszName;
+} KMKCCEXPPLAINVAR;
+typedef KMKCCEXPPLAINVAR *PKMKCCEXPPLAINVAR;
+
+/**
+ * kKmkCcExpInstr_DynamicVariable instruction format.
+ */
+typedef struct kmk_cc_exp_dynamic_variable
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** Where to continue after this instruction. (This is necessary since the
+ * instructions of the subprogram are emitted after this instruction.) */
+ PKMKCCEXPCORE pNext;
+ /** The subprogram that will give us the variable name. */
+ KMKCCEXPSUBPROG SubProg;
+} KMKCCEXPDYNVAR;
+typedef KMKCCEXPDYNVAR *PKMKCCEXPDYNVAR;
+
+/**
+ * kKmkCcExpInstr_SearchAndReplacePlainVariable instruction format.
+ */
+typedef struct kmk_cc_exp_sr_plain_variable
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** Where to continue after this instruction. (This is necessary since the
+ * instruction contains string data of variable size.) */
+ PKMKCCEXPCORE pNext;
+ /** The name of the variable (points into variable_strcache). */
+ const char *pszName;
+ /** Search pattern. */
+ const char *pszSearchPattern;
+ /** Replacement pattern. */
+ const char *pszReplacePattern;
+ /** Offset into pszSearchPattern of the significant '%' char. */
+ uint32_t offPctSearchPattern;
+ /** Offset into pszReplacePattern of the significant '%' char. */
+ uint32_t offPctReplacePattern;
+} KMKCCEXPSRPLAINVAR;
+typedef KMKCCEXPSRPLAINVAR *PKMKCCEXPSRPLAINVAR;
+
+/**
+ * Instruction format parts common to both kKmkCcExpInstr_PlainFunction and
+ * kKmkCcExpInstr_DynamicFunction.
+ */
+typedef struct kmk_cc_exp_function_core
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** Number of arguments. */
+ uint32_t cArgs;
+ /** Set if the function could be modifying the input arguments. */
+ uint8_t fDirty;
+ /** Where to continue after this instruction. (This is necessary since the
+ * instructions are of variable size and may be followed by string data.) */
+ PKMKCCEXPCORE pNext;
+ /**
+ * Pointer to the function table entry.
+ *
+ * @returns New variable buffer position.
+ * @param pchDst Current variable buffer position.
+ * @param papszArgs Pointer to a NULL terminated array of argument strings.
+ * @param pszFuncName The name of the function being called.
+ */
+ char * (*pfnFunction)(char *pchDst, char **papszArgs, const char *pszFuncName);
+ /** Pointer to the function name in the variable string cache. */
+ const char *pszFuncName;
+} KMKCCEXPFUNCCORE;
+typedef KMKCCEXPFUNCCORE *PKMKCCEXPFUNCCORE;
+
+/**
+ * Instruction format for kKmkCcExpInstr_PlainFunction.
+ */
+typedef struct kmk_cc_exp_plain_function
+{
+ /** The bits comment to both plain and dynamic functions. */
+ KMKCCEXPFUNCCORE Core;
+ /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
+ * The string pointers are to memory following this instruction, to memory in
+ * the next block or to memory in the variable / makefile we're working on
+ * (if zero terminated appropriately). */
+ const char *apszArgs[1];
+} KMKCCEXPPLAINFUNC;
+typedef KMKCCEXPPLAINFUNC *PKMKCCEXPPLAINFUNC;
+/** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
+#define KMKCCEXPPLAINFUNC_SIZE(a_cArgs) (sizeof(KMKCCEXPFUNCCORE) + (a_cArgs + 1) * sizeof(const char *))
+
+/**
+ * Instruction format for kKmkCcExpInstr_DynamicFunction.
+ */
+typedef struct kmk_cc_exp_dyn_function
+{
+ /** The bits comment to both plain and dynamic functions. */
+ KMKCCEXPFUNCCORE Core;
+ /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
+ * The string pointers are to memory following this instruction, to memory in
+ * the next block or to memory in the variable / makefile we're working on
+ * (if zero terminated appropriately). */
+ struct
+ {
+ /** Set if plain string argument, clear if sub program. */
+ uint8_t fPlain;
+ union
+ {
+ /** Sub program for expanding this argument. */
+ KMKCCEXPSUBPROG SubProg;
+ struct
+ {
+ /** Pointer to the plain argument string.
+ * This is allocated in the same manner as the
+ * string pointed to by KMKCCEXPPLAINFUNC::apszArgs. */
+ const char *pszArg;
+ } Plain;
+ } u;
+ } aArgs[1];
+} KMKCCEXPDYNFUNC;
+typedef KMKCCEXPDYNFUNC *PKMKCCEXPDYNFUNC;
+/** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
+#define KMKCCEXPDYNFUNC_SIZE(a_cArgs) ( sizeof(KMKCCEXPFUNCCORE) \
+ + (a_cArgs) * sizeof(((PKMKCCEXPDYNFUNC)(uintptr_t)42)->aArgs[0]) )
+
+/**
+ * Instruction format for kKmkCcExpInstr_Jump.
+ */
+typedef struct kmk_cc_exp_jump
+{
+ /** The core instruction. */
+ KMKCCEXPCORE Core;
+ /** Where to jump to (new instruction block, typically). */
+ PKMKCCEXPCORE pNext;
+} KMKCCEXPJUMP;
+typedef KMKCCEXPJUMP *PKMKCCEXPJUMP;
+
+/**
+ * String expansion program.
+ */
+typedef struct kmk_cc_expandprog
+{
+ /** Pointer to the first instruction for this program. */
+ PKMKCCEXPCORE pFirstInstr;
+ /** List of blocks for this program (LIFO). */
+ PKMKCCBLOCK pBlockTail;
+ /** Statistics. */
+ KMKCCEXPSTATS Stats;
+#ifdef KMK_CC_STRICT
+ /** The hash of the input string. Used to check that we get all the change
+ * notifications we require. */
+ uint32_t uInputHash;
+#endif
+ /** Reference count. */
+ uint32_t volatile cRefs;
+} KMKCCEXPPROG;
+/** Pointer to a string expansion program. */
+typedef KMKCCEXPPROG *PKMKCCEXPPROG;
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+static uint32_t g_cVarForExpandCompilations = 0;
+static uint32_t g_cVarForExpandExecs = 0;
+#ifdef KMK_CC_WITH_STATS
+static uint32_t g_cBlockAllocated = 0;
+static uint32_t g_cbAllocated = 0;
+static uint32_t g_cBlocksAllocatedExpProgs = 0;
+static uint32_t g_cbAllocatedExpProgs = 0;
+static uint32_t g_cSingleBlockExpProgs = 0;
+static uint32_t g_cTwoBlockExpProgs = 0;
+static uint32_t g_cMultiBlockExpProgs = 0;
+static uint32_t g_cbUnusedMemExpProgs = 0;
+#endif
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg);
+static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcch);
+
+
+/**
+ * Initializes global variables for the 'compiler'.
+ */
+void kmk_cc_init(void)
+{
+}
+
+
+/**
+ * Prints stats (for kmk -p).
+ */
+void kmk_cc_print_stats(void)
+{
+ puts(_("\n# The kmk 'compiler' and kmk 'program executor':\n"));
+
+ printf(_("# Variables compiled for string expansion: %6u\n"), g_cVarForExpandCompilations);
+ printf(_("# Variables string expansion runs: %6u\n"), g_cVarForExpandExecs);
+ printf(_("# String expansion runs per compile: %6u\n"), g_cVarForExpandExecs / g_cVarForExpandExecs);
+#ifdef KMK_CC_WITH_STATS
+ printf(_("# Single alloc block exp progs: %6u (%u%%)\n"
+ "# Two alloc block exp progs: %6u (%u%%)\n"
+ "# Three or more alloc block exp progs: %6u (%u%%)\n"
+ ),
+ g_cSingleBlockExpProgs, (uint32_t)((uint64_t)g_cSingleBlockExpProgs * 100 / g_cVarForExpandCompilations),
+ g_cTwoBlockExpProgs, (uint32_t)((uint64_t)g_cTwoBlockExpProgs * 100 / g_cVarForExpandCompilations),
+ g_cMultiBlockExpProgs, (uint32_t)((uint64_t)g_cMultiBlockExpProgs * 100 / g_cVarForExpandCompilations));
+ printf(_("# Total amount of memory for exp progs: %8u bytes\n"
+ "# in: %6u blocks\n"
+ "# avg block size: %6u bytes\n"
+ "# unused memory: %8u bytes (%u%%)\n"
+ "# avg unused memory per block: %6u bytes\n"
+ "\n"),
+ g_cbAllocatedExpProgs, g_cBlocksAllocatedExpProgs, g_cbAllocatedExpProgs / g_cBlocksAllocatedExpProgs,
+ g_cbUnusedMemExpProgs, (uint32_t)((uint64_t)g_cbUnusedMemExpProgs * 100 / g_cbAllocatedExpProgs),
+ g_cbUnusedMemExpProgs / g_cBlocksAllocatedExpProgs);
+
+ printf(_("# Total amount of block mem allocated: %8u bytes\n"), g_cbAllocated);
+ printf(_("# Total number of block allocated: %8u\n"), g_cBlockAllocated);
+ printf(_("# Average block size: %8u byte\n"), g_cbAllocated / g_cBlockAllocated);
+#endif
+
+ puts("");
+}
+
+
+/*
+ *
+ * Various utility functions.
+ * Various utility functions.
+ * Various utility functions.
+ *
+ */
+
+/**
+ * Counts the number of dollar chars in the string.
+ *
+ * @returns Number of dollar chars.
+ * @param pchStr The string to search (does not need to be zero
+ * terminated).
+ * @param cchStr The length of the string.
+ */
+static uint32_t kmk_cc_count_dollars(const char *pchStr, uint32_t cchStr)
+{
+ uint32_t cDollars = 0;
+ const char *pch;
+ while ((pch = memchr(pchStr, '$', cchStr)) != NULL)
+ {
+ cDollars++;
+ cchStr -= pch - pchStr + 1;
+ pchStr = pch + 1;
+ }
+ return cDollars;
+}
+
+#ifdef KMK_CC_STRICT
+/**
+ * Used to check that function arguments are left alone.
+ * @returns Updated hash.
+ * @param uHash The current hash value.
+ * @param psz The string to hash.
+ */
+static uint32_t kmk_cc_debug_string_hash(uint32_t uHash, const char *psz)
+{
+ unsigned char ch;
+ while ((ch = *(unsigned char const *)psz++) != '\0')
+ uHash = (uHash << 6) + (uHash << 16) - uHash + (unsigned char)ch;
+ return uHash;
+}
+
+/**
+ * Used to check that function arguments are left alone.
+ * @returns Updated hash.
+ * @param uHash The current hash value.
+ * @param pch The string to hash, not terminated.
+ * @param cch The number of chars to hash.
+ */
+static uint32_t kmk_cc_debug_string_hash_n(uint32_t uHash, const char *pch, uint32_t cch)
+{
+ while (cch-- > 0)
+ {
+ unsigned char ch = *(unsigned char const *)pch++;
+ uHash = (uHash << 6) + (uHash << 16) - uHash + (unsigned char)ch;
+ }
+ return uHash;
+}
+
+#endif
+
+
+
+/*
+ *
+ * The allocator.
+ * The allocator.
+ * The allocator.
+ *
+ */
+
+
+/**
+ * For the first allocation using the block allocator.
+ *
+ * @returns Pointer to the first allocation (@a cbFirst in size).
+ * @param ppBlockTail Where to return the pointer to the first block.
+ * @param cbFirst The size of the first allocation.
+ * @param cbHint Hint about how much memory we might be needing.
+ */
+static void *kmk_cc_block_alloc_first(PKMKCCBLOCK *ppBlockTail, size_t cbFirst, size_t cbHint)
+{
+ uint32_t cbBlock;
+ PKMKCCBLOCK pNewBlock;
+
+ KMK_CC_ASSERT_ALIGNED(cbFirst, sizeof(void *));
+
+ /*
+ * Turn the hint into a block size.
+ */
+ if (cbHint <= 512)
+ {
+ if (cbHint <= 256)
+ cbBlock = 128;
+ else
+ cbBlock = 256;
+ }
+ else if (cbHint < 2048)
+ cbBlock = 1024;
+ else if (cbHint < 3072)
+ cbBlock = 2048;
+ else
+ cbBlock = 4096;
+
+ /*
+ * Allocate and initialize the first block.
+ */
+ pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
+ pNewBlock->cbBlock = cbBlock;
+ pNewBlock->offNext = sizeof(*pNewBlock) + cbFirst;
+ pNewBlock->pNext = NULL;
+ *ppBlockTail = pNewBlock;
+
+#ifdef KMK_CC_WITH_STATS
+ g_cBlockAllocated++;
+ g_cbAllocated += cbBlock;
+#endif
+
+ return pNewBlock + 1;
+}
+
+
+/**
+ * Used for getting the address of the next instruction.
+ *
+ * @returns Pointer to the next allocation.
+ * @param pBlockTail The allocator tail pointer.
+ */
+static void *kmk_cc_block_get_next_ptr(PKMKCCBLOCK pBlockTail)
+{
+ return (char *)pBlockTail + pBlockTail->offNext;
+}
+
+
+/**
+ * Realigns the allocator after doing byte or string allocations.
+ *
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ */
+static void kmk_cc_block_realign(PKMKCCBLOCK *ppBlockTail)
+{
+ PKMKCCBLOCK pBlockTail = *ppBlockTail;
+ if (pBlockTail->offNext & (sizeof(void *) - 1))
+ {
+ pBlockTail->offNext = (pBlockTail->offNext + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+ KMK_CC_ASSERT(pBlockTail->cbBlock - pBlockTail->offNext >= sizeof(KMKCCEXPJUMP));
+ }
+}
+
+
+/**
+ * Grows the allocation with another block, byte allocator case.
+ *
+ * @returns Pointer to the byte allocation.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param cb The number of bytes to allocate.
+ */
+static void *kmk_cc_block_byte_alloc_grow(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
+{
+ PKMKCCBLOCK pOldBlock = *ppBlockTail;
+ PKMKCCBLOCK pPrevBlock = pOldBlock->pNext;
+ PKMKCCBLOCK pNewBlock;
+ uint32_t cbBlock;
+
+ /*
+ * Check if there accidentally is some space left in the previous block first.
+ */
+ if ( pPrevBlock
+ && pPrevBlock->cbBlock - pPrevBlock->offNext >= cb)
+ {
+ void *pvRet = (char *)pPrevBlock + pPrevBlock->offNext;
+ pPrevBlock->offNext += cb;
+ return pvRet;
+ }
+
+ /*
+ * Allocate a new block.
+ */
+
+ /* Figure the block size. */
+ cbBlock = pOldBlock->cbBlock;
+ while (cbBlock - sizeof(KMKCCEXPJUMP) - sizeof(*pNewBlock) < cb)
+ cbBlock *= 2;
+
+ /* Allocate and initialize the block it with the new instruction already accounted for. */
+ pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
+ pNewBlock->cbBlock = cbBlock;
+ pNewBlock->offNext = sizeof(*pNewBlock) + cb;
+ pNewBlock->pNext = pOldBlock;
+ *ppBlockTail = pNewBlock;
+
+#ifdef KMK_CC_WITH_STATS
+ g_cBlockAllocated++;
+ g_cbAllocated += cbBlock;
+#endif
+
+ return pNewBlock + 1;
+}
+
+
+/**
+ * Make a byte allocation.
+ *
+ * Must call kmk_cc_block_realign() when done doing byte and string allocations.
+ *
+ * @returns Pointer to the byte allocation (byte aligned).
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param cb The number of bytes to allocate.
+ */
+static void *kmk_cc_block_byte_alloc(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
+{
+ PKMKCCBLOCK pBlockTail = *ppBlockTail;
+ uint32_t cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
+
+ KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
+ if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
+ {
+ void *pvRet = (char *)pBlockTail + pBlockTail->offNext;
+ pBlockTail->offNext += cb;
+ return pvRet;
+ }
+ return kmk_cc_block_byte_alloc_grow(ppBlockTail, cb);
+}
+
+
+/**
+ * Duplicates the given string in a byte allocation.
+ *
+ * Must call kmk_cc_block_realign() when done doing byte and string allocations.
+ *
+ * @returns Pointer to the byte allocation (byte aligned).
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param cb The number of bytes to allocate.
+ */
+static const char *kmk_cc_block_strdup(PKMKCCBLOCK *ppBlockTail, const char *pachStr, uint32_t cchStr)
+{
+ char *pszCopy;
+ if (cchStr)
+ {
+ pszCopy = kmk_cc_block_byte_alloc(ppBlockTail, cchStr + 1);
+ memcpy(pszCopy, pachStr, cchStr);
+ pszCopy[cchStr] = '\0';
+ return pszCopy;
+ }
+ return "";
+}
+
+
+/**
+ * Grows the allocation with another block, string expansion program case.
+ *
+ * @returns Pointer to a string expansion instruction core.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param cb The number of bytes to allocate.
+ */
+static PKMKCCEXPCORE kmk_cc_block_alloc_exp_grow(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
+{
+ PKMKCCBLOCK pOldBlock = *ppBlockTail;
+ PKMKCCBLOCK pNewBlock;
+ PKMKCCEXPCORE pRet;
+ PKMKCCEXPJUMP pJump;
+
+ /* Figure the block size. */
+ uint32_t cbBlock = !pOldBlock->pNext ? 128 : pOldBlock->cbBlock;
+ while (cbBlock - sizeof(KMKCCEXPJUMP) - sizeof(*pNewBlock) < cb)
+ cbBlock *= 2;
+
+ /* Allocate and initialize the block it with the new instruction already accounted for. */
+ pNewBlock = (PKMKCCBLOCK)xmalloc(cbBlock);
+ pNewBlock->cbBlock = cbBlock;
+ pNewBlock->offNext = sizeof(*pNewBlock) + cb;
+ pNewBlock->pNext = pOldBlock;
+ *ppBlockTail = pNewBlock;
+
+#ifdef KMK_CC_WITH_STATS
+ g_cBlockAllocated++;
+ g_cbAllocated += cbBlock;
+#endif
+
+ pRet = (PKMKCCEXPCORE)(pNewBlock + 1);
+
+ /* Emit jump. */
+ pJump = (PKMKCCEXPJUMP)((char *)pOldBlock + pOldBlock->offNext);
+ pJump->Core.enmOpCode = kKmkCcExpInstr_Jump;
+ pJump->pNext = pRet;
+ pOldBlock->offNext += sizeof(*pJump);
+ KMK_CC_ASSERT(pOldBlock->offNext <= pOldBlock->cbBlock);
+
+ return pRet;
+}
+
+
+/**
+ * Allocates a string expansion instruction of size @a cb.
+ *
+ * @returns Pointer to a string expansion instruction core.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param cb The number of bytes to allocate.
+ */
+static PKMKCCEXPCORE kmk_cc_block_alloc_exp(PKMKCCBLOCK *ppBlockTail, uint32_t cb)
+{
+ PKMKCCBLOCK pBlockTail = *ppBlockTail;
+ uint32_t cbLeft = pBlockTail->cbBlock - pBlockTail->offNext;
+
+ KMK_CC_ASSERT(cbLeft >= sizeof(KMKCCEXPJUMP));
+ KMK_CC_ASSERT( (cb & (sizeof(void *) - 1)) == 0 || cb == sizeof(KMKCCEXPCORE) /* final */ );
+
+ if (cbLeft >= cb + sizeof(KMKCCEXPJUMP))
+ {
+ PKMKCCEXPCORE pRet = (PKMKCCEXPCORE)((char *)pBlockTail + pBlockTail->offNext);
+ pBlockTail->offNext += cb;
+ return pRet;
+ }
+ return kmk_cc_block_alloc_exp_grow(ppBlockTail, cb);
+}
+
+
+/**
+ * Frees all memory used by an allocator.
+ *
+ * @param ppBlockTail The allocator tail pointer.
+ */
+static void kmk_cc_block_free_list(PKMKCCBLOCK pBlockTail)
+{
+ while (pBlockTail)
+ {
+ PKMKCCBLOCK pThis = pBlockTail;
+ pBlockTail = pBlockTail->pNext;
+ free(pThis);
+ }
+}
+
+
+/*
+ *
+ * The string expansion compiler.
+ * The string expansion compiler.
+ * The string expansion compiler.
+ *
+ */
+
+
+/**
+ * Emits a kKmkCcExpInstr_Return.
+ *
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ */
+static void kmk_cc_exp_emit_return(PKMKCCBLOCK *ppBlockTail)
+{
+ PKMKCCEXPCORE pCore = kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pCore));
+ pCore->enmOpCode = kKmkCcExpInstr_Return;
+}
+
+
+/**
+ * Checks if a function is known to mess up the arguments its given.
+ *
+ * When executing calls to "dirty" functions, all arguments must be duplicated
+ * on the heap.
+ *
+ * @returns 1 if dirty, 0 if clean.
+ * @param pszFunction The function name.
+ */
+static uint8_t kmk_cc_is_dirty_function(const char *pszFunction)
+{
+ switch (pszFunction[0])
+ {
+ default:
+ return 0;
+
+ case 'e':
+ if (!strcmp(pszFunction, "eval"))
+ return 1;
+ if (!strcmp(pszFunction, "evalctx"))
+ return 1;
+ return 0;
+
+ case 'f':
+ if (!strcmp(pszFunction, "filter"))
+ return 1;
+ if (!strcmp(pszFunction, "filter-out"))
+ return 1;
+ if (!strcmp(pszFunction, "for"))
+ return 1;
+ return 0;
+
+ case 's':
+ if (!strcmp(pszFunction, "sort"))
+ return 1;
+ return 0;
+ }
+}
+
+
+/**
+ * Emits a function call instruction taking arguments that needs expanding.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pszFunction The function name (const string from function.c).
+ * @param pchArgs Pointer to the arguments expression string, leading
+ * any blanks has been stripped.
+ * @param cchArgs The length of the arguments expression string.
+ * @param cArgs Number of arguments found.
+ * @param chOpen The char used to open the function call.
+ * @param chClose The char used to close the function call.
+ * @param pfnFunction The function implementation.
+ * @param cMaxArgs Maximum number of arguments the function takes.
+ */
+static int kmk_cc_exp_emit_dyn_function(PKMKCCBLOCK *ppBlockTail, const char *pszFunction,
+ const char *pchArgs, uint32_t cchArgs, uint32_t cArgs, char chOpen, char chClose,
+ make_function_ptr_t pfnFunction, unsigned char cMaxArgs)
+{
+ uint32_t iArg;
+
+ /*
+ * The function instruction has variable size. The maximum argument count
+ * isn't quite like the minium one. Zero means no limit. While a non-zero
+ * value means that any commas beyond the max will be taken to be part of
+ * the final argument.
+ */
+ uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
+ PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPDYNFUNC_SIZE(cActualArgs));
+ pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
+ pInstr->Core.cArgs = cActualArgs;
+ pInstr->Core.pfnFunction = pfnFunction;
+ pInstr->Core.pszFuncName = pszFunction;
+ pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
+
+ /*
+ * Parse the arguments. Plain arguments gets duplicated in the program
+ * memory so that they are terminated and no extra processing is necessary
+ * later on. ASSUMES that the function implementations do NOT change
+ * argument memory. Other arguments the compiled into their own expansion
+ * sub programs.
+ */
+ iArg = 0;
+ for (;;)
+ {
+ /* Find the end of the argument. Check for $. */
+ char ch = '\0';
+ uint8_t fDollar = 0;
+ int32_t cDepth = 0;
+ uint32_t cchThisArg = 0;
+ while (cchThisArg < cchArgs)
+ {
+ ch = pchArgs[cchThisArg];
+ if (ch == chClose)
+ {
+ KMK_CC_ASSERT(cDepth > 0);
+ if (cDepth > 0)
+ cDepth--;
+ }
+ else if (ch == chOpen)
+ cDepth++;
+ else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
+ break;
+ else if (ch == '$')
+ fDollar = 1;
+ cchThisArg++;
+ }
+
+ pInstr->aArgs[iArg].fPlain = !fDollar;
+ if (fDollar)
+ {
+ /* Compile it. */
+ int rc;
+ kmk_cc_block_realign(ppBlockTail);
+ rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.SubProg);
+ if (rc != 0)
+ return rc;
+ }
+ else
+ {
+ /* Duplicate it. */
+ pInstr->aArgs[iArg].u.Plain.pszArg = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
+ }
+ iArg++;
+ if (ch != ',')
+ break;
+ pchArgs += cchThisArg + 1;
+ cchArgs -= cchThisArg + 1;
+ }
+ KMK_CC_ASSERT(iArg == cActualArgs);
+
+ /*
+ * Realign the allocator and take down the address of the next instruction.
+ */
+ kmk_cc_block_realign(ppBlockTail);
+ pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
+ return 0;
+}
+
+
+/**
+ * Emits a function call instruction taking plain arguments.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pszFunction The function name (const string from function.c).
+ * @param pchArgs Pointer to the arguments string, leading any blanks
+ * has been stripped.
+ * @param cchArgs The length of the arguments string.
+ * @param cArgs Number of arguments found.
+ * @param chOpen The char used to open the function call.
+ * @param chClose The char used to close the function call.
+ * @param pfnFunction The function implementation.
+ * @param cMaxArgs Maximum number of arguments the function takes.
+ */
+static void kmk_cc_exp_emit_plain_function(PKMKCCBLOCK *ppBlockTail, const char *pszFunction,
+ const char *pchArgs, uint32_t cchArgs, uint32_t cArgs, char chOpen, char chClose,
+ make_function_ptr_t pfnFunction, unsigned char cMaxArgs)
+{
+ uint32_t iArg;
+
+ /*
+ * The function instruction has variable size. The maximum argument count
+ * isn't quite like the minium one. Zero means no limit. While a non-zero
+ * value means that any commas beyond the max will be taken to be part of
+ * the final argument.
+ */
+ uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
+ PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPPLAINFUNC_SIZE(cActualArgs));
+ pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
+ pInstr->Core.cArgs = cActualArgs;
+ pInstr->Core.pfnFunction = pfnFunction;
+ pInstr->Core.pszFuncName = pszFunction;
+ pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
+
+ /*
+ * Parse the arguments. Plain arguments gets duplicated in the program
+ * memory so that they are terminated and no extra processing is necessary
+ * later on. ASSUMES that the function implementations do NOT change
+ * argument memory.
+ */
+ iArg = 0;
+ for (;;)
+ {
+ /* Find the end of the argument. */
+ char ch = '\0';
+ int32_t cDepth = 0;
+ uint32_t cchThisArg = 0;
+ while (cchThisArg < cchArgs)
+ {
+ ch = pchArgs[cchThisArg];
+ if (ch == chClose)
+ {
+ KMK_CC_ASSERT(cDepth > 0);
+ if (cDepth > 0)
+ cDepth--;
+ }
+ else if (ch == chOpen)
+ cDepth++;
+ else if (ch == ',' && cDepth == 0 && iArg + 1 < cActualArgs)
+ break;
+ cchThisArg++;
+ }
+
+ /* Duplicate it. */
+ pInstr->apszArgs[iArg++] = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
+ if (ch != ',')
+ break;
+ pchArgs += cchThisArg + 1;
+ cchArgs -= cchThisArg + 1;
+ }
+
+ KMK_CC_ASSERT(iArg == cActualArgs);
+ pInstr->apszArgs[iArg] = NULL;
+
+ /*
+ * Realign the allocator and take down the address of the next instruction.
+ */
+ kmk_cc_block_realign(ppBlockTail);
+ pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
+}
+
+
+/**
+ * Emits a kKmkCcExpInstr_DynamicVariable.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pchNameExpr The name of the variable (ASSUMED presistent
+ * thru-out the program life time).
+ * @param cchNameExpr The length of the variable name. If zero,
+ * nothing will be emitted.
+ */
+static int kmk_cc_exp_emit_dyn_variable(PKMKCCBLOCK *ppBlockTail, const char *pchNameExpr, uint32_t cchNameExpr)
+{
+ PKMKCCEXPDYNVAR pInstr;
+ int rc;
+ KMK_CC_ASSERT(cchNameExpr > 0);
+
+ pInstr = (PKMKCCEXPDYNVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
+ pInstr->Core.enmOpCode = kKmkCcExpInstr_DynamicVariable;
+
+ rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->SubProg);
+
+ pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
+ return rc;
+}
+
+
+/**
+ * Emits either a kKmkCcExpInstr_PlainVariable or
+ * kKmkCcExpInstr_SearchAndReplacePlainVariable instruction.
+ *
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pchName The name of the variable. (Does not need to be
+ * valid beyond the call.)
+ * @param cchName The length of the variable name. If zero,
+ * nothing will be emitted.
+ */
+static void kmk_cc_exp_emit_plain_variable_maybe_sr(PKMKCCBLOCK *ppBlockTail, const char *pchName, uint32_t cchName)
+{
+ if (cchName > 0)
+ {
+ /*
+ * Hopefully, we're not expected to do any search and replace on the
+ * expanded variable string later... Requires both ':' and '='.
+ */
+ const char *pchEqual;
+ const char *pchColon = (const char *)memchr(pchName, ':', cchName);
+ if ( pchColon == NULL
+ || (pchEqual = (const char *)memchr(pchColon + 1, ':', cchName - (pchColon - pchName - 1))) == NULL
+ || pchEqual == pchEqual + 1)
+ {
+ PKMKCCEXPPLAINVAR pInstr = (PKMKCCEXPPLAINVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
+ pInstr->Core.enmOpCode = kKmkCcExpInstr_PlainVariable;
+ pInstr->pszName = strcache2_add(&variable_strcache, pchName, cchName);
+ }
+ else if (pchColon != pchName)
+ {
+ /*
+ * Okay, we need to do search and replace the variable value.
+ * This is performed by patsubst_expand_pat using '%' patterns.
+ */
+ uint32_t cchName2 = (uint32_t)(pchColon - pchName);
+ uint32_t cchSearch = (uint32_t)(pchEqual - pchColon - 1);
+ uint32_t cchReplace = cchName - cchName2 - cchSearch - 2;
+ const char *pchPct;
+ char *psz;
+ PKMKCCEXPSRPLAINVAR pInstr;
+
+ pInstr = (PKMKCCEXPSRPLAINVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
+ pInstr->Core.enmOpCode = kKmkCcExpInstr_SearchAndReplacePlainVariable;
+ pInstr->pszName = strcache2_add(&variable_strcache, pchName, cchName2);
+
+ /* Figure out the search pattern, unquoting percent chars.. */
+ psz = (char *)kmk_cc_block_byte_alloc(ppBlockTail, cchSearch + 2);
+ psz[0] = '%';
+ memcpy(psz + 1, pchColon + 1, cchSearch);
+ psz[1 + cchSearch] = '\0';
+ pchPct = find_percent(psz + 1); /* also performs unquoting */
+ if (pchPct)
+ {
+ pInstr->pszSearchPattern = psz + 1;
+ pInstr->offPctSearchPattern = (uint32_t)(pchPct - psz - 1);
+ }
+ else
+ {
+ pInstr->pszSearchPattern = psz;
+ pInstr->offPctSearchPattern = 0;
+ }
+
+ /* Figure out the replacement pattern, unquoting percent chars.. */
+ if (cchReplace == 0)
+ {
+ pInstr->pszReplacePattern = "%";
+ pInstr->offPctReplacePattern = 0;
+ }
+ else
+ {
+ psz = (char *)kmk_cc_block_byte_alloc(ppBlockTail, cchReplace + 2);
+ psz[0] = '%';
+ memcpy(psz + 1, pchEqual + 1, cchReplace);
+ psz[1 + cchReplace] = '\0';
+ pchPct = find_percent(psz + 1); /* also performs unquoting */
+ if (pchPct)
+ {
+ pInstr->pszReplacePattern = psz + 1;
+ pInstr->offPctReplacePattern = (uint32_t)(pchPct - psz - 1);
+ }
+ else
+ {
+ pInstr->pszReplacePattern = psz;
+ pInstr->offPctReplacePattern = 0;
+ }
+ }
+
+ /* Note down where the next instruction is after realigning the allocator. */
+ kmk_cc_block_realign(ppBlockTail);
+ pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
+ }
+ }
+}
+
+
+/**
+ * Emits a kKmkCcExpInstr_CopyString.
+ *
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pchStr The string to emit (ASSUMED presistent thru-out
+ * the program life time).
+ * @param cchStr The number of chars to copy. If zero, nothing
+ * will be emitted.
+ */
+static void kmk_cc_exp_emit_copy_string(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr)
+{
+ if (cchStr > 0)
+ {
+ PKMKCCEXPCOPYSTRING pInstr = (PKMKCCEXPCOPYSTRING)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
+ pInstr->Core.enmOpCode = kKmkCcExpInstr_CopyString;
+ pInstr->cchCopy = cchStr;
+ pInstr->pachSrc = pchStr;
+ }
+}
+
+
+/**
+ * String expansion compilation function common to both normal and sub programs.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pchStr The expression to compile.
+ * @param cchStr The length of the expression to compile.
+ */
+static int kmk_cc_exp_compile_common(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr)
+{
+ /*
+ * Process the string.
+ */
+ while (cchStr > 0)
+ {
+ /* Look for dollar sign, marks variable expansion or dollar-escape. */
+ int rc;
+ const char *pchDollar = memchr(pchStr, '$', cchStr);
+ if (pchDollar)
+ {
+ /*
+ * Check for multiple dollar chars.
+ */
+ uint32_t offDollar = (uint32_t)(pchDollar - pchStr);
+ uint32_t cDollars = 1;
+ while ( offDollar + cDollars < cchStr
+ && pchStr[offDollar + cDollars] == '$')
+ cDollars++;
+
+ /*
+ * Emit a string copy for any preceeding stuff, including half of
+ * the dollars we found (dollar escape: $$ -> $).
+ * (kmk_cc_exp_emit_copy_string ignore zero length strings).
+ */
+ kmk_cc_exp_emit_copy_string(ppBlockTail, pchStr, offDollar + cDollars / 2);
+ pchStr += offDollar + cDollars;
+ cchStr -= offDollar + cDollars;
+
+ /*
+ * Odd number of dollar chars means there is a variable to expand
+ * or function to call.
+ */
+ if (cDollars & 1)
+ {
+ if (cchStr > 0)
+ {
+ char const chOpen = *pchStr;
+ if (chOpen == '(' || chOpen == '{')
+ {
+ /* There are several alternative ways of finding the ending
+ parenthesis / braces.
+
+ GNU make does one thing for functions and variable containing
+ any '$' chars before the first closing char. While for
+ variables where a closing char comes before any '$' char, a
+ simplified approach is taken. This means that for example:
+
+ Given VAR=var, the expressions "$(var())" and
+ "$($(VAR)())" would be expanded differently.
+ In the first case the variable "var(" would be
+ used and in the second "var()".
+
+ This code will not duplicate this weird behavior, but work
+ the same regardless of whether there is a '$' char before
+ the first closing char. */
+ make_function_ptr_t pfnFunction;
+ const char *pszFunction;
+ unsigned char cMaxArgs;
+ unsigned char cMinArgs;
+ char fExpandArgs;
+ char const chClose = chOpen == '(' ? ')' : '}';
+ char ch = 0;
+ uint32_t cchName = 0;
+ uint32_t cDepth = 1;
+ uint32_t cMaxDepth = 1;
+ cDollars = 0;
+
+ pchStr++;
+ cchStr--;
+
+ /* First loop: Identify potential function calls and dynamic expansion. */
+ KMK_CC_ASSERT(!func_char_map[chOpen]);
+ KMK_CC_ASSERT(!func_char_map[chClose]);
+ KMK_CC_ASSERT(!func_char_map['$']);
+ while (cchName < cchStr)
+ {
+ ch = pchStr[cchName];
+ if (!func_char_map[(int)ch])
+ break;
+ cchName++;
+ }
+
+ if ( cchName >= MIN_FUNCTION_LENGTH
+ && cchName <= MAX_FUNCTION_LENGTH
+ && (isblank(ch) || ch == chClose || cchName == cchStr)
+ && (pfnFunction = lookup_function_for_compiler(pchStr, cchName, &cMinArgs, &cMaxArgs,
+ &fExpandArgs, &pszFunction)) != NULL)
+ {
+ /*
+ * It's a function invocation, we should count parameters while
+ * looking for the end.
+ * Note! We use cchName for the length of the argument list.
+ */
+ uint32_t cArgs = 1;
+ if (ch != chClose)
+ {
+ /* Skip leading spaces before the first arg. */
+ cchName++;
+ while (cchName < cchStr && isblank((unsigned char)pchStr[cchName]))
+ cchName++;
+
+ pchStr += cchName;
+ cchStr -= cchName;
+ cchName = 0;
+
+ while (cchName < cchStr)
+ {
+ ch = pchStr[cchName];
+ if (ch == ',')
+ {
+ if (cDepth == 1)
+ cArgs++;
+ }
+ else if (ch == chClose)
+ {
+ if (!--cDepth)
+ break;
+ }
+ else if (ch == chOpen)
+ {
+ if (++cDepth > cMaxDepth)
+ cMaxDepth = cDepth;
+ }
+ else if (ch == '$')
+ cDollars++;
+ cchName++;
+ }
+ }
+ else
+ {
+ pchStr += cchName;
+ cchStr -= cchName;
+ cchName = 0;
+ }
+ if (cArgs < cMinArgs)
+ {
+ fatal(NULL, _("Function '%.*s' takes a minimum of %d arguments: %d given"),
+ pszFunction, (int)cMinArgs, (int)cArgs);
+ return -1; /* not reached */
+ }
+ if (cDepth != 0)
+ {
+ fatal(NULL, chOpen == '('
+ ? _("Missing closing parenthesis calling '%s'") : _("Missing closing braces calling '%s'"),
+ pszFunction);
+ return -1; /* not reached */
+ }
+ if (cMaxDepth > 16 && fExpandArgs)
+ {
+ fatal(NULL, _("Too many levels of nested function arguments expansions: %s"), pszFunction);
+ return -1; /* not reached */
+ }
+ if (!fExpandArgs || cDollars == 0)
+ kmk_cc_exp_emit_plain_function(ppBlockTail, pszFunction, pchStr, cchName,
+ cArgs, chOpen, chClose, pfnFunction, cMaxArgs);
+ else
+ {
+ rc = kmk_cc_exp_emit_dyn_function(ppBlockTail, pszFunction, pchStr, cchName,
+ cArgs, chOpen, chClose, pfnFunction, cMaxArgs);
+ if (rc != 0)
+ return rc;
+ }
+ }
+ else
+ {
+ /*
+ * Variable, find the end while checking whether anything needs expanding.
+ */
+ if (ch == chClose)
+ cDepth = 0;
+ else if (cchName < cchStr)
+ {
+ if (ch != '$')
+ {
+ /* Second loop: Look for things that needs expanding. */
+ while (cchName < cchStr)
+ {
+ ch = pchStr[cchName];
+ if (ch == chClose)
+ {
+ if (!--cDepth)
+ break;
+ }
+ else if (ch == chOpen)
+ {
+ if (++cDepth > cMaxDepth)
+ cMaxDepth = cDepth;
+ }
+ else if (ch == '$')
+ break;
+ cchName++;
+ }
+ }
+ if (ch == '$')
+ {
+ /* Third loop: Something needs expanding, just find the end. */
+ cDollars = 1;
+ cchName++;
+ while (cchName < cchStr)
+ {
+ ch = pchStr[cchName];
+ if (ch == chClose)
+ {
+ if (!--cDepth)
+ break;
+ }
+ else if (ch == chOpen)
+ {
+ if (++cDepth > cMaxDepth)
+ cMaxDepth = cDepth;
+ }
+ cchName++;
+ }
+ }
+ }
+ if (cDepth > 0) /* After warning, we just assume they're all there. */
+ error(NULL, chOpen == '(' ? _("Missing closing parenthesis ") : _("Missing closing braces"));
+ if (cMaxDepth >= 16)
+ {
+ fatal(NULL, _("Too many levels of nested variable expansions: '%.*s'"), (int)cchName + 2, pchStr - 1);
+ return -1; /* not reached */
+ }
+ if (cDollars == 0)
+ kmk_cc_exp_emit_plain_variable_maybe_sr(ppBlockTail, pchStr, cchName);
+ else
+ {
+ rc = kmk_cc_exp_emit_dyn_variable(ppBlockTail, pchStr, cchName);
+ if (rc != 0)
+ return rc;
+ }
+ }
+ pchStr += cchName + 1;
+ cchStr -= cchName + (cDepth == 0);
+ }
+ else
+ {
+ /* Single character variable name. */
+ kmk_cc_exp_emit_plain_variable_maybe_sr(ppBlockTail, pchStr, 1);
+ pchStr++;
+ cchStr--;
+ }
+ }
+ else
+ {
+ error(NULL, _("Unexpected end of string after $"));
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Nothing more to expand, the remainder is a simple string copy.
+ */
+ kmk_cc_exp_emit_copy_string(ppBlockTail, pchStr, cchStr);
+ break;
+ }
+ }
+
+ /*
+ * Emit final instruction.
+ */
+ kmk_cc_exp_emit_return(ppBlockTail);
+ return 0;
+}
+
+
+/**
+ * Initializes string expansion program statistics.
+ * @param pStats Pointer to the statistics structure to init.
+ */
+static void kmk_cc_exp_stats_init(PKMKCCEXPSTATS pStats)
+{
+ pStats->cchAvg = 0;
+}
+
+
+/**
+ * Compiles a string expansion sub program.
+ *
+ * The caller typically make a call to kmk_cc_block_get_next_ptr after this
+ * function returns to figure out where to continue executing.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param ppBlockTail Pointer to the allocator tail pointer.
+ * @param pchStr Pointer to the string to compile an expansion
+ * program for (ASSUMED to be valid for the
+ * lifetime of the program).
+ * @param cchStr The length of the string to compile. Expected to
+ * be at least on char long.
+ * @param pSubProg The sub program structure to initialize.
+ */
+static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg)
+{
+ KMK_CC_ASSERT(cchStr > 0);
+ pSubProg->pFirstInstr = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
+ kmk_cc_exp_stats_init(&pSubProg->Stats);
+ return kmk_cc_exp_compile_common(ppBlockTail, pchStr, cchStr);
+}
+
+
+/**
+ * Compiles a string expansion program.
+ *
+ * @returns Pointer to the program on success, NULL on failure.
+ * @param pchStr Pointer to the string to compile an expansion
+ * program for (ASSUMED to be valid for the
+ * lifetime of the program).
+ * @param cchStr The length of the string to compile. Expected to
+ * be at least on char long.
+ */
+static PKMKCCEXPPROG kmk_cc_exp_compile(const char *pchStr, uint32_t cchStr)
+{
+ /*
+ * Estimate block size, allocate one and initialize it.
+ */
+ PKMKCCEXPPROG pProg;
+ PKMKCCBLOCK pBlock;
+ pProg = kmk_cc_block_alloc_first(&pBlock, sizeof(*pProg),
+ (kmk_cc_count_dollars(pchStr, cchStr) + 4) * 8);
+ if (pProg)
+ {
+ int rc = 0;
+
+ pProg->pBlockTail = pBlock;
+ pProg->pFirstInstr = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(pBlock);
+ kmk_cc_exp_stats_init(&pProg->Stats);
+ pProg->cRefs = 1;
+#ifdef KMK_CC_STRICT
+ pProg->uInputHash = kmk_cc_debug_string_hash_n(0, pchStr, cchStr);
+#endif
+
+ /*
+ * Join forces with the sub program compilation code.
+ */
+ if (kmk_cc_exp_compile_common(&pProg->pBlockTail, pchStr, cchStr) == 0)
+ {
+#ifdef KMK_CC_WITH_STATS
+ pBlock = pProg->pBlockTail;
+ if (!pBlock->pNext)
+ g_cSingleBlockExpProgs++;
+ else if (!pBlock->pNext->pNext)
+ g_cTwoBlockExpProgs++;
+ else
+ g_cMultiBlockExpProgs++;
+ for (; pBlock; pBlock = pBlock->pNext)
+ {
+ g_cBlocksAllocatedExpProgs++;
+ g_cbAllocatedExpProgs += pBlock->cbBlock;
+ g_cbUnusedMemExpProgs += pBlock->cbBlock - pBlock->offNext;
+ }
+#endif
+ return pProg;
+ }
+ kmk_cc_block_free_list(pProg->pBlockTail);
+ }
+ return NULL;
+}
+
+
+/**
+ * Compiles a variable direct evaluation as is, setting v->evalprog on success.
+ *
+ * @returns Pointer to the program on success, NULL if no program was created.
+ * @param pVar Pointer to the variable.
+ */
+struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar)
+{
+ return NULL;
+}
+
+
+/**
+ * Updates the recursive_without_dollar member of a variable structure.
+ *
+ * This avoid compiling string expansion programs without only a CopyString
+ * instruction. By setting recursive_without_dollar to 1, code calling
+ * kmk_cc_compile_variable_for_expand and kmk_exec_expand_to_var_buf will
+ * instead treat start treating it as a simple variable, which is faster.
+ *
+ * @returns The updated recursive_without_dollar value.
+ * @param pVar Pointer to the variable.
+ */
+static int kmk_cc_update_variable_recursive_without_dollar(struct variable *pVar)
+{
+ int fValue;
+ KMK_CC_ASSERT(pVar->recursive_without_dollar == 0);
+
+ if (memchr(pVar->value, '$', pVar->value_length))
+ fValue = -1;
+ else
+ fValue = 1;
+ pVar->recursive_without_dollar = fValue;
+
+ return fValue;
+}
+
+
+/**
+ * Compiles a variable for string expansion.
+ *
+ * @returns Pointer to the string expansion program on success, NULL if no
+ * program was created.
+ * @param pVar Pointer to the variable.
+ */
+struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar)
+{
+ KMK_CC_ASSERT(strlen(pVar->value) == pVar->value_length);
+ KMK_CC_ASSERT(!pVar->expandprog);
+ KMK_CC_ASSERT(pVar->recursive_without_dollar <= 0);
+
+ if ( !pVar->expandprog
+ && pVar->recursive)
+ {
+ if ( pVar->recursive_without_dollar < 0
+ || ( pVar->recursive_without_dollar == 0
+ && kmk_cc_update_variable_recursive_without_dollar(pVar) < 0) )
+ {
+ pVar->expandprog = kmk_cc_exp_compile(pVar->value, pVar->value_length);
+ g_cVarForExpandCompilations++;
+ }
+ }
+ return pVar->expandprog;
+}
+
+
+/**
+ * String expansion execution worker for outputting a variable.
+ *
+ * @returns The new variable buffer position.
+ * @param pVar The variable to reference.
+ * @param pchDst The current variable buffer position.
+ */
+static char *kmk_exec_expand_worker_reference_variable(struct variable *pVar, char *pchDst)
+{
+ if (pVar->value_length > 0)
+ {
+ if (!pVar->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar))
+ pchDst = variable_buffer_output(pchDst, pVar->value, pVar->value_length);
+ else
+ pchDst = reference_recursive_variable(pchDst, pVar);
+ }
+ else if (pVar->append)
+ pchDst = reference_recursive_variable(pchDst, pVar);
+ return pchDst;
+}
+
+
+/**
+ * Executes a stream string expansion instructions, outputting to the current
+ * varaible buffer.
+ *
+ * @returns The new variable buffer position.
+ * @param pInstrCore The instruction to start executing at.
+ * @param pchDst The current variable buffer position.
+ */
+static char *kmk_exec_expand_instruction_stream_to_var_buf(PKMKCCEXPCORE pInstrCore, char *pchDst)
+{
+ for (;;)
+ {
+ switch (pInstrCore->enmOpCode)
+ {
+ case kKmkCcExpInstr_CopyString:
+ {
+ PKMKCCEXPCOPYSTRING pInstr = (PKMKCCEXPCOPYSTRING)pInstrCore;
+ pchDst = variable_buffer_output(pchDst, pInstr->pachSrc, pInstr->cchCopy);
+
+ pInstrCore = &(pInstr + 1)->Core;
+ break;
+ }
+
+ case kKmkCcExpInstr_PlainVariable:
+ {
+ PKMKCCEXPPLAINVAR pInstr = (PKMKCCEXPPLAINVAR)pInstrCore;
+ struct variable *pVar = lookup_variable_strcached(pInstr->pszName);
+ if (pVar)
+ pchDst = kmk_exec_expand_worker_reference_variable(pVar, pchDst);
+ else
+ warn_undefined(pInstr->pszName, strcache2_get_len(&variable_strcache, pInstr->pszName));
+
+ pInstrCore = &(pInstr + 1)->Core;
+ break;
+ }
+
+ case kKmkCcExpInstr_DynamicVariable:
+ {
+ PKMKCCEXPDYNVAR pInstr = (PKMKCCEXPDYNVAR)pInstrCore;
+ struct variable *pVar;
+ uint32_t cchName;
+ char *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->SubProg, &cchName);
+ char *pszColon = (char *)memchr(pszName, ':', cchName);
+ char *pszEqual;
+ if ( pszColon == NULL
+ || (pszEqual = (char *)memchr(pszColon + 1, '=', &pszName[cchName] - pszColon - 1)) == NULL
+ || pszEqual == pszColon + 1)
+ {
+ pVar = lookup_variable(pszName, cchName);
+ if (pVar)
+ pchDst = kmk_exec_expand_worker_reference_variable(pVar, pchDst);
+ else
+ warn_undefined(pszName, cchName);
+ }
+ else if (pszColon != pszName)
+ {
+ /*
+ * Oh, we have to do search and replace. How tedious.
+ * Since the variable name is a temporary buffer, we can transform
+ * the strings into proper search and replacement patterns directly.
+ */
+ pVar = lookup_variable(pszName, pszColon - pszName);
+ if (pVar)
+ {
+ char const *pszExpandedVarValue = pVar->recursive ? recursively_expand(pVar) : pVar->value;
+ char *pszSearchPat = pszColon + 1;
+ char *pszReplacePat = pszEqual + 1;
+ const char *pchPctSearchPat;
+ const char *pchPctReplacePat;
+
+ *pszEqual = '\0';
+ pchPctSearchPat = find_percent(pszSearchPat);
+ pchPctReplacePat = find_percent(pszReplacePat);
+
+ if (!pchPctReplacePat)
+ {
+ if (pszReplacePat[-2] != '\0') /* On the offchance that a pct was unquoted by find_percent. */
+ {
+ memmove(pszName + 1, pszSearchPat, pszReplacePat - pszSearchPat);
+ if (pchPctSearchPat)
+ pchPctSearchPat -= pszSearchPat - &pszName[1];
+ pszSearchPat = &pszName[1];
+ }
+ pchPctReplacePat = --pszReplacePat;
+ *pszReplacePat = '%';
+ }
+
+ if (!pchPctSearchPat)
+ {
+ pchPctSearchPat = --pszSearchPat;
+ *pszSearchPat = '%';
+ }
+
+ pchDst = patsubst_expand_pat(pchDst, pszExpandedVarValue,
+ pszSearchPat, pszReplacePat,
+ pchPctSearchPat, pchPctReplacePat);
+
+ if (pVar->recursive)
+ free((void *)pszExpandedVarValue);
+ }
+ else
+ warn_undefined(pszName, pszColon - pszName);
+ }
+ free(pszName);
+
+ pInstrCore = pInstr->pNext;
+ break;
+ }
+
+
+ case kKmkCcExpInstr_SearchAndReplacePlainVariable:
+ {
+ PKMKCCEXPSRPLAINVAR pInstr = (PKMKCCEXPSRPLAINVAR)pInstrCore;
+ struct variable *pVar = lookup_variable_strcached(pInstr->pszName);
+ if (pVar)
+ {
+ char const *pszExpandedVarValue = pVar->recursive ? recursively_expand(pVar) : pVar->value;
+ pchDst = patsubst_expand_pat(pchDst,
+ pszExpandedVarValue,
+ pInstr->pszSearchPattern,
+ pInstr->pszReplacePattern,
+ &pInstr->pszSearchPattern[pInstr->offPctSearchPattern],
+ &pInstr->pszReplacePattern[pInstr->offPctReplacePattern]);
+ if (pVar->recursive)
+ free((void *)pszExpandedVarValue);
+ }
+ else
+ warn_undefined(pInstr->pszName, strcache2_get_len(&variable_strcache, pInstr->pszName));
+
+ pInstrCore = pInstr->pNext;
+ break;
+ }
+
+ case kKmkCcExpInstr_PlainFunction:
+ {
+ PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)pInstrCore;
+ uint32_t iArg;
+ if (!pInstr->Core.fDirty)
+ {
+#ifdef KMK_CC_STRICT
+ uint32_t uCrcBefore = 0;
+ uint32_t uCrcAfter = 0;
+ iArg = pInstr->Core.cArgs;
+ while (iArg-- > 0)
+ uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
+#endif
+
+ pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
+
+#ifdef KMK_CC_STRICT
+ iArg = pInstr->Core.cArgs;
+ while (iArg-- > 0)
+ uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
+ KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
+#endif
+ }
+ else
+ {
+ char **papszShadowArgs = xmalloc((pInstr->Core.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
+ char **papszArgs = &papszShadowArgs[pInstr->Core.cArgs];
+
+ iArg = pInstr->Core.cArgs;
+ papszArgs[iArg] = NULL;
+ while (iArg-- > 0)
+ papszArgs[iArg] = papszShadowArgs[iArg] = xstrdup(pInstr->apszArgs[iArg]);
+
+ pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
+
+ iArg = pInstr->Core.cArgs;
+ while (iArg-- > 0)
+ free(papszShadowArgs[iArg]);
+ free(papszShadowArgs);
+ }
+
+ pInstrCore = pInstr->Core.pNext;
+ break;
+ }
+
+ case kKmkCcExpInstr_DynamicFunction:
+ {
+ PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)pInstrCore;
+ char **papszArgsShadow = xmalloc( (pInstr->Core.cArgs * 2 + 1) * sizeof(char *));
+ char **papszArgs = &papszArgsShadow[pInstr->Core.cArgs];
+ uint32_t iArg;
+
+ if (!pInstr->Core.fDirty)
+ {
+#ifdef KMK_CC_STRICT
+ uint32_t uCrcBefore = 0;
+ uint32_t uCrcAfter = 0;
+#endif
+ iArg = pInstr->Core.cArgs;
+ papszArgs[iArg] = NULL;
+ while (iArg-- > 0)
+ {
+ char *pszArg;
+ if (!pInstr->aArgs[iArg].fPlain)
+ pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
+ else
+ pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
+ papszArgsShadow[iArg] = pszArg;
+ papszArgs[iArg] = pszArg;
+#ifdef KMK_CC_STRICT
+ uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pszArg);
+#endif
+ }
+ pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
+
+ iArg = pInstr->Core.cArgs;
+ while (iArg-- > 0)
+ {
+#ifdef KMK_CC_STRICT
+ KMK_CC_ASSERT(papszArgsShadow[iArg] == papszArgs[iArg]);
+ uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
+#endif
+ if (!pInstr->aArgs[iArg].fPlain)
+ free(papszArgsShadow[iArg]);
+ }
+ KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
+ }
+ else
+ {
+ iArg = pInstr->Core.cArgs;
+ papszArgs[iArg] = NULL;
+ while (iArg-- > 0)
+ {
+ char *pszArg;
+ if (!pInstr->aArgs[iArg].fPlain)
+ pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
+ else
+ pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.pszArg);
+ papszArgsShadow[iArg] = pszArg;
+ papszArgs[iArg] = pszArg;
+ }
+
+ pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
+
+ iArg = pInstr->Core.cArgs;
+ while (iArg-- > 0)
+ free(papszArgsShadow[iArg]);
+ }
+ free(papszArgsShadow);
+
+ pInstrCore = pInstr->Core.pNext;
+ break;
+ }
+
+ case kKmkCcExpInstr_Jump:
+ {
+ PKMKCCEXPJUMP pInstr = (PKMKCCEXPJUMP)pInstrCore;
+ pInstrCore = pInstr->pNext;
+ break;
+ }
+
+ case kKmkCcExpInstr_Return:
+ return pchDst;
+
+ default:
+ fatal(NULL, _("Unknown string expansion opcode: %d (%#x)"),
+ (int)pInstrCore->enmOpCode, (int)pInstrCore->enmOpCode);
+ return NULL;
+ }
+ }
+}
+
+
+/**
+ * Updates the string expansion statistics.
+ *
+ * @param pStats The statistics structure to update.
+ * @param cchResult The result lenght.
+ */
+void kmk_cc_exp_stats_update(PKMKCCEXPSTATS pStats, uint32_t cchResult)
+{
+ /*
+ * The average is simplified and not an exact average for every
+ * expansion that has taken place.
+ */
+ pStats->cchAvg = (pStats->cchAvg * 7 + cchResult) / 8;
+}
+
+
+/**
+ * Execute a string expansion sub-program, outputting to a new heap buffer.
+ *
+ * @returns Pointer to the output buffer (hand to free when done).
+ * @param pSubProg The sub-program to execute.
+ * @param pcchResult Where to return the size of the result. Optional.
+ */
+static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcchResult)
+{
+ char *pchOldVarBuf;
+ unsigned int cbOldVarBuf;
+ char *pchDst;
+ char *pszResult;
+ uint32_t cchResult;
+
+ /*
+ * Temporarily replace the variable buffer while executing the instruction
+ * stream for this sub program.
+ */
+ pchDst = install_variable_buffer_with_hint(&pchOldVarBuf, &cbOldVarBuf,
+ pSubProg->Stats.cchAvg ? pSubProg->Stats.cchAvg + 32 : 256);
+
+ pchDst = kmk_exec_expand_instruction_stream_to_var_buf(pSubProg->pFirstInstr, pchDst);
+
+ /* Ensure that it's terminated. */
+ pchDst = variable_buffer_output(pchDst, "\0", 1) - 1;
+
+ /* Grab the result buffer before restoring the previous one. */
+ pszResult = variable_buffer;
+ cchResult = (uint32_t)(pchDst - pszResult);
+ if (pcchResult)
+ *pcchResult = cchResult;
+ kmk_cc_exp_stats_update(&pSubProg->Stats, cchResult);
+
+ variable_buffer = pchOldVarBuf;
+ variable_buffer_length = cbOldVarBuf;
+
+ return pszResult;
+}
+
+
+/**
+ * Execute a string expansion program, outputting to the current variable
+ * buffer.
+ *
+ * @returns New variable buffer position.
+ * @param pProg The program to execute.
+ * @param pchDst The current varaible buffer position.
+ */
+static char *kmk_exec_expand_prog_to_var_buf(PKMKCCEXPPROG pProg, char *pchDst)
+{
+ uint32_t cchResult;
+ uint32_t offStart = (uint32_t)(pchDst - variable_buffer);
+
+ if (pProg->Stats.cchAvg >= variable_buffer_length - offStart)
+ pchDst = ensure_variable_buffer_space(pchDst, offStart + pProg->Stats.cchAvg + 32);
+
+ KMK_CC_ASSERT(pProg->cRefs > 0);
+ pProg->cRefs++;
+
+ pchDst = kmk_exec_expand_instruction_stream_to_var_buf(pProg->pFirstInstr, pchDst);
+
+ pProg->cRefs--;
+ KMK_CC_ASSERT(pProg->cRefs > 0);
+
+ cchResult = (uint32_t)(pchDst - variable_buffer);
+ KMK_CC_ASSERT(cchResult >= offStart);
+ cchResult -= offStart;
+ kmk_cc_exp_stats_update(&pProg->Stats, cchResult);
+ g_cVarForExpandExecs++;
+
+ return pchDst;
+}
+
+
+/**
+ * Equivalent of eval_buffer, only it's using the evalprog of the variable.
+ *
+ * @param pVar Pointer to the variable. Must have a program.
+ */
+void kmk_exec_evalval(struct variable *pVar)
+{
+ KMK_CC_ASSERT(pVar->evalprog);
+ assert(0);
+}
+
+
+/**
+ * Expands a variable into a variable buffer using its expandprog.
+ *
+ * @returns The new variable buffer position.
+ * @param pVar Pointer to the variable. Must have a program.
+ * @param pchDst Pointer to the current variable buffer position.
+ */
+char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst)
+{
+ KMK_CC_ASSERT(pVar->expandprog);
+ KMK_CC_ASSERT(pVar->expandprog->uInputHash == kmk_cc_debug_string_hash(0, pVar->value));
+ return kmk_exec_expand_prog_to_var_buf(pVar->expandprog, pchDst);
+}
+
+
+/**
+ * Called when a variable with expandprog or/and evalprog changes.
+ *
+ * @param pVar Pointer to the variable.
+ */
+void kmk_cc_variable_changed(struct variable *pVar)
+{
+ PKMKCCEXPPROG pProg = pVar->expandprog;
+
+ KMK_CC_ASSERT(pVar->evalprog || pProg);
+
+#if 0
+ if (pVar->evalprog)
+ {
+ kmk_cc_block_free_list(pVar->evalprog->pBlockTail);
+ pVar->evalprog = NULL;
+ }
+#endif
+
+ if (pProg)
+ {
+ if (pProg->cRefs == 1)
+ kmk_cc_block_free_list(pProg->pBlockTail);
+ else
+ fatal(NULL, _("Modifying a variable (%s) while its expansion program is running is not supported"), pVar->name);
+ pVar->expandprog = NULL;
+ }
+}
+
+
+/**
+ * Called when a variable with expandprog or/and evalprog is deleted.
+ *
+ * @param pVar Pointer to the variable.
+ */
+void kmk_cc_variable_deleted(struct variable *pVar)
+{
+ PKMKCCEXPPROG pProg = pVar->expandprog;
+
+ KMK_CC_ASSERT(pVar->evalprog || pProg);
+
+#if 0
+ if (pVar->evalprog)
+ {
+ kmk_cc_block_free_list(pVar->evalprog->pBlockTail);
+ pVar->evalprog = NULL;
+ }
+#endif
+
+ if (pProg)
+ {
+ if (pProg->cRefs == 1)
+ kmk_cc_block_free_list(pProg->pBlockTail);
+ else
+ fatal(NULL, _("Deleting a variable (%s) while its expansion program is running is not supported"), pVar->name);
+ pVar->expandprog = NULL;
+ }
+}
+
+
+#endif /* CONFIG_WITH_COMPILER */
+
diff --git a/src/kmk/kmk_cc_exec.h b/src/kmk/kmk_cc_exec.h
new file mode 100644
index 0000000..846d90f
--- /dev/null
+++ b/src/kmk/kmk_cc_exec.h
@@ -0,0 +1,45 @@
+/* $Id: kmk_cc_exec.h 2773 2015-02-03 12:59:54Z bird $ */
+/** @file
+ * kmk_cc - Make "Compiler".
+ */
+
+/*
+ * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * kBuild is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with kBuild. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef ___kmk_cc_and_exech
+#define ___kmk_cc_and_exech
+#ifdef CONFIG_WITH_COMPILER
+
+
+
+void kmk_cc_init(void);
+void kmk_cc_print_stats(void);
+
+struct variable;
+extern struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar);
+extern struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar);
+extern char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst);
+extern void kmk_exec_evalval(struct variable *pVar);
+extern void kmk_cc_variable_changed(struct variable *pVar);
+extern void kmk_cc_variable_deleted(struct variable *pVar);
+
+
+#endif /* CONFIG_WITH_COMPILER */
+#endif
diff --git a/src/kmk/kmkbuiltin/append.c b/src/kmk/kmkbuiltin/append.c
index aac2e5b..d88c92f 100644
--- a/src/kmk/kmkbuiltin/append.c
+++ b/src/kmk/kmkbuiltin/append.c
@@ -1,4 +1,4 @@
-/* $Id: append.c 2466 2011-07-12 09:52:39Z bird $ */
+/* $Id: append.c 2771 2015-02-01 20:48:36Z bird $ */
/** @file
* kMk Builtin command - append text to file.
*/
@@ -217,15 +217,15 @@ int kmk_builtin_append(int argc, char **argv, char **envp)
struct variable *pVar = lookup_variable(psz, cch);
if (!pVar)
continue;
- if ( pVar->recursive
- && memchr(pVar->value, '$', pVar->value_length))
+ if ( !pVar->recursive
+ || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(pVar))
+ fwrite(pVar->value, 1, pVar->value_length, pFile);
+ else
{
char *pszExpanded = allocated_variable_expand(pVar->value);
fwrite(pszExpanded, 1, strlen(pszExpanded), pFile);
free(pszExpanded);
}
- else
- fwrite(pVar->value, 1, pVar->value_length, pFile);
}
else
#endif
diff --git a/src/kmk/kmkbuiltin/echo.c b/src/kmk/kmkbuiltin/echo.c
index 77591fe..dff8cb2 100644
--- a/src/kmk/kmkbuiltin/echo.c
+++ b/src/kmk/kmkbuiltin/echo.c
@@ -72,11 +72,19 @@ static void
errexit(const char *prog, const char *reason)
{
char *errstr = strerror(errno);
+#ifdef _MSC_VER
+ int doserrno = _doserrno;
+ char szDosErr[48];
+ sprintf(szDosErr, " (doserrno=%d)", doserrno);
+#endif
write(STDERR_FILENO, prog, strlen(prog));
write(STDERR_FILENO, ": ", 2);
write(STDERR_FILENO, reason, strlen(reason));
write(STDERR_FILENO, ": ", 2);
write(STDERR_FILENO, errstr, strlen(errstr));
+#ifdef _MSC_VER
+ write(STDERR_FILENO, szDosErr, strlen(szDosErr));
+#endif
write(STDERR_FILENO, "\n", 1);
}
diff --git a/src/kmk/kmkbuiltin/kDepObj.c b/src/kmk/kmkbuiltin/kDepObj.c
index 649d9e7..7b42a59 100644
--- a/src/kmk/kmkbuiltin/kDepObj.c
+++ b/src/kmk/kmkbuiltin/kDepObj.c
@@ -1,4 +1,4 @@
-/* $Id: kDepObj.c 2591 2012-06-17 20:45:31Z bird $ */
+/* $Id: kDepObj.c 2759 2015-01-28 16:14:00Z bird $ */
/** @file
* kDepObj - Extract dependency information from an object file.
*/
@@ -26,6 +26,7 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
+#define MSCFAKES_NO_WINDOWS_H
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/kmk/kmkbuiltin/mscfakes.c b/src/kmk/kmkbuiltin/mscfakes.c
index 444943e..b8e33c7 100644
--- a/src/kmk/kmkbuiltin/mscfakes.c
+++ b/src/kmk/kmkbuiltin/mscfakes.c
@@ -1,10 +1,10 @@
-/* $Id: mscfakes.c 2733 2014-10-16 18:29:41Z bird $ */
+/* $Id: mscfakes.c 2759 2015-01-28 16:14:00Z bird $ */
/** @file
* Fake Unix stuff for MSC.
*/
/*
- * Copyright (c) 2005-2010 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ * Copyright (c) 2005-2015 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
*
* This file is part of kBuild.
*
@@ -27,6 +27,7 @@
* Header Files *
*******************************************************************************/
#include "config.h"
+#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -42,6 +43,11 @@
#include <Windows.h>
#undef timeval
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static BOOL isPipeFd(int fd);
+
/**
* Makes corrections to a directory path that ends with a trailing slash.
@@ -460,15 +466,125 @@ int utimes(const char *pszPath, const struct timeval *paTimes)
}
-int writev(int fd, const struct iovec *vector, int count)
+/* We override the libc write function (in our modules only, unfortunately) so
+ we can kludge our way around a ENOSPC problem observed on build servers
+ capturing STDOUT and STDERR via pipes. Apparently this may happen when the
+ pipe buffer is full, even with the mscfake_init hack in place.
+
+ XXX: Probably need to hook into fwrite as well. */
+ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc)
+{
+ ssize_t cbRet;
+ if (cbSrc < UINT_MAX / 4)
+ {
+#ifndef MSC_WRITE_TEST
+ cbRet = _write(fd, pvSrc, (unsigned int)cbSrc);
+#else
+ cbRet = -1; errno = ENOSPC;
+#endif
+ if (cbRet < 0)
+ {
+ /* ENOSPC on pipe kludge. */
+ int cbLimit;
+ int cSinceLastSuccess;
+
+ if (cbSrc == 0)
+ return 0;
+ if (errno != ENOSPC)
+ return -1;
+#ifndef MSC_WRITE_TEST
+ if (!isPipeFd(fd))
+ {
+ errno = ENOSPC;
+ return -1;
+ }
+#endif
+
+ /* Likely a full pipe buffer, try write smaller amounts and do some
+ sleeping inbetween each unsuccessful one. */
+ cbLimit = cbSrc / 4;
+ if (cbLimit < 4)
+ cbLimit = 4;
+ else if (cbLimit > 512)
+ cbLimit = 512;
+ cSinceLastSuccess = 0;
+ cbRet = 0;
+#ifdef MSC_WRITE_TEST
+ cbLimit = 4;
+#endif
+
+ while (cbSrc > 0)
+ {
+ unsigned int cbAttempt = cbSrc > cbLimit ? (int)cbLimit : (int)cbSrc;
+ ssize_t cbActual = _write(fd, pvSrc, cbAttempt);
+ if (cbActual > 0)
+ {
+ assert(cbActual <= (ssize_t)cbAttempt);
+ pvSrc = (char *)pvSrc + cbActual;
+ cbSrc -= cbActual;
+ cbRet += cbActual;
+#ifndef MSC_WRITE_TEST
+ if (cbLimit < 32)
+ cbLimit = 32;
+#endif
+ cSinceLastSuccess = 0;
+ }
+ else if (errno != ENOSPC)
+ return -1;
+ else
+ {
+ /* Delay for about 30 seconds, then just give up. */
+ cSinceLastSuccess++;
+ if (cSinceLastSuccess > 1860)
+ return -1;
+ if (cSinceLastSuccess <= 2)
+ Sleep(0);
+ else if (cSinceLastSuccess <= 66)
+ {
+ if (cbLimit >= 8)
+ cbLimit /= 2; /* Just in case the pipe buffer is very very small. */
+ Sleep(1);
+ }
+ else
+ Sleep(16);
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Type limit exceeded. Split the job up.
+ */
+ cbRet = 0;
+ while (cbSrc > 0)
+ {
+ size_t cbToWrite = cbSrc > UINT_MAX / 4 ? UINT_MAX / 4 : cbSrc;
+ ssize_t cbWritten = msc_write(fd, pvSrc, cbToWrite);
+ if (cbWritten > 0)
+ {
+ pvSrc = (char *)pvSrc + (size_t)cbWritten;
+ cbSrc -= (size_t)cbWritten;
+ cbRet += (size_t)cbWritten;
+ }
+ else if (cbWritten == 0 || cbRet > 0)
+ break;
+ else
+ return -1;
+ }
+ }
+ return cbRet;
+}
+
+ssize_t writev(int fd, const struct iovec *vector, int count)
{
int size = 0;
int i;
for (i = 0; i < count; i++)
{
- int cb = (int)write(fd, vector[i].iov_base, (int)vector[i].iov_len);
+ int cb = msc_write(fd, vector[i].iov_base, (int)vector[i].iov_len);
if (cb < 0)
- return -1;
+ return cb;
size += cb;
}
return size;
@@ -535,13 +651,12 @@ int vasprintf(char **strp, const char *fmt, va_list va)
/**
- * This is a kludge to make pipe handles blocking.
+ * Checks if the given file descriptor is a pipe or not.
*
- * @returns TRUE if it's now blocking, FALSE if not a pipe or we failed to fix
- * the blocking mode.
+ * @returns TRUE if pipe, FALSE if not.
* @param fd The libc file descriptor number.
*/
-static BOOL makePipeBlocking(int fd)
+static BOOL isPipeFd(int fd)
{
/* Is pipe? */
HANDLE hFile = (HANDLE)_get_osfhandle(fd);
@@ -550,16 +665,32 @@ static BOOL makePipeBlocking(int fd)
DWORD fType = GetFileType(hFile);
fType &= ~FILE_TYPE_REMOTE;
if (fType == FILE_TYPE_PIPE)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ * This is a kludge to make pipe handles blocking.
+ *
+ * @returns TRUE if it's now blocking, FALSE if not a pipe or we failed to fix
+ * the blocking mode.
+ * @param fd The libc file descriptor number.
+ */
+static BOOL makePipeBlocking(int fd)
+{
+ if (isPipeFd(fd))
+ {
+ /* Try fix it. */
+ HANDLE hFile = (HANDLE)_get_osfhandle(fd);
+ DWORD fState = 0;
+ if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL, 0))
{
- /* Try fix it. */
- DWORD fState = 0;
- if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL, 0))
- {
- fState &= ~PIPE_NOWAIT;
- fState |= PIPE_WAIT;
- if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
- return TRUE;
- }
+ fState &= ~PIPE_NOWAIT;
+ fState |= PIPE_WAIT;
+ if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
+ return TRUE;
}
}
return FALSE;
diff --git a/src/kmk/kmkbuiltin/mscfakes.h b/src/kmk/kmkbuiltin/mscfakes.h
index e5a2e99..379875a 100644
--- a/src/kmk/kmkbuiltin/mscfakes.h
+++ b/src/kmk/kmkbuiltin/mscfakes.h
@@ -1,4 +1,4 @@
-/* $Id: mscfakes.h 2713 2013-11-21 21:11:00Z bird $ */
+/* $Id: mscfakes.h 2766 2015-01-30 03:32:38Z bird $ */
/** @file
* Unix fakes for MSC.
*/
@@ -27,14 +27,19 @@
#define ___mscfakes_h
#ifdef _MSC_VER
+/* Include the config file (kmk's) so we don't need to duplicate stuff from it here. */
+#include "config.h"
+
#include <io.h>
#include <direct.h>
#include <time.h>
#include <stdarg.h>
#include <malloc.h>
#include "getopt.h"
+#ifndef MSCFAKES_NO_WINDOWS_H
+# include <Windows.h>
+#endif
-/* Note: Duplicated it config.h.win */
#include <sys/stat.h>
#include <io.h>
#include <direct.h>
@@ -78,12 +83,27 @@ typedef unsigned short nlink_t;
typedef unsigned short uid_t;
typedef unsigned short gid_t;
#endif
+#if defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64) || defined(_WIN64)
+typedef __int64 ssize_t;
+#else
typedef long ssize_t;
+#endif
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
-#ifndef timerisset
+#if _MSC_VER >= 1600
+# include <stdint.h>
+#else
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+#endif
+
+#if !defined(timerisset) && defined(MSCFAKES_NO_WINDOWS_H)
struct timeval
{
long tv_sec;
@@ -137,9 +157,12 @@ int snprintf(char *buf, size_t size, const char *fmt, ...);
#endif
int symlink(const char *pszDst, const char *pszLink);
int utimes(const char *pszPath, const struct timeval *paTimes);
-int writev(int fd, const struct iovec *vector, int count);
-
+ssize_t writev(int fd, const struct iovec *vector, int count);
+/* bird write ENOSPC hacks. */
+#undef write
+#define write msc_write
+ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc);
/*
* MSC fake internals / helpers.
diff --git a/src/kmk/kmkbuiltin/redirect.c b/src/kmk/kmkbuiltin/redirect.c
index cbcbb18..b928215 100644
--- a/src/kmk/kmkbuiltin/redirect.c
+++ b/src/kmk/kmkbuiltin/redirect.c
@@ -1,4 +1,4 @@
-/* $Id: redirect.c 2728 2014-03-05 13:09:47Z bird $ */
+/* $Id: redirect.c 2779 2015-02-24 03:50:12Z bird $ */
/** @file
* kmk_redirect - Do simple program <-> file redirection (++).
*/
@@ -59,10 +59,13 @@
* For details on how MSC parses the command line, see "Parsing C Command-Line
* Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
*
- * @param argc The argument count.
- * @param argv The argument vector.
+ * @param argc The argument count.
+ * @param argv The argument vector.
+ * @param fWatcomBrainDamage Set if we're catering for wcc, wcc386 or similar
+ * OpenWatcom tools. They seem to follow some
+ * ancient or home made quoting convention.
*/
-static void quoteArguments(int argc, char **argv)
+static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage)
{
int i;
for (i = 0; i < argc; i++)
@@ -70,19 +73,21 @@ static void quoteArguments(int argc, char **argv)
const char *pszOrg = argv[i];
size_t cchOrg = strlen(pszOrg);
const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg);
+ const char *pszProblem = NULL;
if ( pszQuotes
|| cchOrg == 0
- || memchr(pszOrg, ' ', cchOrg)
- || memchr(pszOrg, '\t', cchOrg)
- || memchr(pszOrg, '\n', cchOrg)
- || memchr(pszOrg, '\r', cchOrg)
- || memchr(pszOrg, '&', cchOrg)
- || memchr(pszOrg, '>', cchOrg)
- || memchr(pszOrg, '<', cchOrg)
- || memchr(pszOrg, '|', cchOrg)
- || memchr(pszOrg, '%', cchOrg)
- || memchr(pszOrg, '\'', cchOrg)
- || memchr(pszOrg, '=', cchOrg)
+ || (pszProblem = (const char *)memchr(pszOrg, ' ', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '\t', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '\n', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '\r', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '&', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '>', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '<', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '|', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '%', cchOrg)) != NULL
+ || (pszProblem = (const char *)memchr(pszOrg, '\'', cchOrg)) != NULL
+ || ( !fWatcomBrainDamage
+ && (pszProblem = (const char *)memchr(pszOrg, '=', cchOrg)) != NULL)
)
{
char ch;
@@ -92,6 +97,32 @@ static void quoteArguments(int argc, char **argv)
argv[i] = pszNew;
+ /* Watcom does not grok "-i=c:\program files\watcom\h", it thing
+ it's a source specification. The quote must follow the equal. */
+ if (fWatcomBrainDamage)
+ {
+ size_t cchUnquoted = 0;
+ if (pszOrg[0] == '@') /* Response file quoting: @"file name.rsp" */
+ cchUnquoted = 1;
+ else if (pszOrg[0] == '-' || pszOrg[0] == '/') /* Switch quoting. */
+ {
+ const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg);
+ if ( pszNeedQuoting == NULL
+ || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes))
+ pszNeedQuoting = pszProblem ? pszProblem : pszQuotes;
+ else
+ pszNeedQuoting++;
+ cchUnquoted = pszNeedQuoting - pszOrg;
+ }
+ if (cchUnquoted)
+ {
+ memcpy(pszNew, pszOrg, cchUnquoted);
+ pszNew += cchUnquoted;
+ pszOrg += cchUnquoted;
+ cchOrg -= cchUnquoted;
+ }
+ }
+
*pszNew++ = '"';
if (fComplicated)
{
@@ -187,7 +218,7 @@ static const char *name(const char *pszName)
static int usage(FILE *pOut, const char *argv0)
{
fprintf(pOut,
- "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] -- <program> [args]\n"
+ "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] -- <program> [args]\n"
" or: %s --help\n"
" or: %s --version\n"
"\n"
@@ -207,6 +238,9 @@ static int usage(FILE *pOut, const char *argv0)
"The -C switch is for changing the current directory. This takes immediate\n"
"effect, so be careful where you put it.\n"
"\n"
+ "The --wcc-brain-damage switch is to work around wcc and wcc386 (Open Watcom)\n"
+ "not following normal quoting conventions on Windows, OS/2, and DOS.\n"
+ "\n"
"This command was originally just a quick hack to avoid invoking the shell\n"
"on Windows (cygwin) where forking is very expensive and has exhibited\n"
"stability issues on SMP machines. It has since grown into something like\n"
@@ -225,6 +259,7 @@ int main(int argc, char **argv, char **envp)
#endif
FILE *pStdErr = stderr;
FILE *pStdOut = stdout;
+ int fWatcomBrainDamage = 0;
/*
* Parse arguments.
@@ -261,6 +296,11 @@ int main(int argc, char **argv, char **envp)
psz = "Z";
else if (!strcmp(psz, "-close"))
psz = "c";
+ else if (!strcmp(psz, "-wcc-brain-damage"))
+ {
+ fWatcomBrainDamage = 1;
+ continue;
+ }
}
/*
@@ -709,7 +749,7 @@ int main(int argc, char **argv, char **envp)
}
/* MSC is a PITA since it refuses to quote the arguments... */
- quoteArguments(argc - i, &argv[i]);
+ quoteArguments(argc - i, &argv[i], fWatcomBrainDamage);
rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);
if (rc == -1 && pStdErr)
{
diff --git a/src/kmk/main.c b/src/kmk/main.c
index 06a6cc0..a748da4 100644
--- a/src/kmk/main.c
+++ b/src/kmk/main.c
@@ -46,6 +46,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
+#ifdef CONFIG_WITH_COMPILER
+# include "kmk_cc_exec.h"
+#endif
#ifdef KMK /* for get_online_cpu_count */
# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
@@ -1160,6 +1163,7 @@ static BOOL WINAPI ctrl_event(DWORD CtrlType)
HANDLE hThread;
CONTEXT Ctx;
+ /*fprintf(stderr, "dbg: ctrl_event sig=%d\n", sig);*/
#ifndef _M_IX86
/* only once. */
if (InterlockedExchange(&g_lTriggered, 1))
@@ -1192,9 +1196,10 @@ static BOOL WINAPI ctrl_event(DWORD CtrlType)
Ctx.Eip = (uintptr_t)&dispatch_stub;
#else
g_Ctx = Ctx;
- Ctx.Rsp -= 0x20;
+ Ctx.Rsp -= 0x80;
Ctx.Rsp &= ~(uintptr_t)0xf;
- Ctx.Rip = (uintptr_t)&dispatch_stub;
+ Ctx.Rsp += 8; /* (Stack aligned before call instruction, not after.) */
+ Ctx.Rip = (uintptr_t)&dispatch_stub;
#endif
SetThreadContext(hThread, &Ctx);
@@ -1363,6 +1368,9 @@ main (int argc, char **argv, char **envp)
struct dep *read_makefiles;
PATH_VAR (current_directory);
unsigned int restarts = 0;
+#ifdef CONFIG_WITH_MAKE_STATS
+ unsigned long long uStartTick = CURRENT_CLOCK_TICK();
+#endif
#ifdef WINDOWS32
char *unix_path = NULL;
char *windows32_path = NULL;
@@ -1575,6 +1583,9 @@ main (int argc, char **argv, char **envp)
/* Set up to access user data (files). */
user_access ();
+# ifdef CONFIG_WITH_COMPILER
+ kmk_cc_init ();
+# endif
#ifdef CONFIG_WITH_ALLOC_CACHES
initialize_global_alloc_caches ();
#endif
@@ -2917,6 +2928,7 @@ main (int argc, char **argv, char **envp)
error (NILF,
_("warning: Clock skew detected. Your build may be incomplete."));
+ MAKE_STATS_2(if (uStartTick) printf("main ticks elapsed: %ull\n", (unsigned long long)(CURRENT_CLOCK_TICK() - uStartTick)) );
/* Exit. */
die (status);
}
@@ -3812,6 +3824,9 @@ print_data_base ()
#ifdef CONFIG_WITH_ALLOC_CACHES
alloccache_print_all ();
#endif
+#ifdef CONFIG_WITH_COMPILER
+ kmk_cc_print_stats ();
+#endif
when = time ((time_t *) 0);
printf (_("\n# Finished Make data base on %s\n"), ctime (&when));
diff --git a/src/kmk/make.h b/src/kmk/make.h
index 14c5ceb..60e1e54 100644
--- a/src/kmk/make.h
+++ b/src/kmk/make.h
@@ -237,6 +237,13 @@ extern unsigned long make_stats_ht_collisions;
#endif
/* bird - start */
+#ifdef _MSC_VER
+# include <intrin.h>
+# define CURRENT_CLOCK_TICK() __rdtsc()
+#else
+# define CURRENT_CLOCK_TICK() 0
+#endif
+
#define COMMA ,
#ifdef CONFIG_WITH_VALUE_LENGTH
# define IF_WITH_VALUE_LENGTH(a_Expr) a_Expr
diff --git a/src/kmk/read.c b/src/kmk/read.c
index 413df56..86a3544 100644
--- a/src/kmk/read.c
+++ b/src/kmk/read.c
@@ -2287,10 +2287,19 @@ record_target_var (struct nameseq *filenames, char *defn,
assert (v != 0);
v->origin = origin;
+#ifndef CONFIG_WITH_VALUE_LENGTH
if (v->flavor == f_simple)
v->value = allocated_variable_expand (v->value);
else
v->value = xstrdup (v->value);
+#else
+ v->value_length = strlen (v->value);
+ if (v->flavor == f_simple)
+ v->value = allocated_variable_expand_2 (v->value, v->value_length, &v->value_length);
+ else
+ v->value = (char *)memcpy (xmalloc (v->value_length + 1), v->value, v->value_length + 1);
+ v->value_alloc_len = v->value_length + 1;
+#endif
fname = p->target;
}
@@ -2361,6 +2370,7 @@ record_target_var (struct nameseq *filenames, char *defn,
v->origin = gv->origin;
v->recursive = gv->recursive;
v->append = 0;
+ VARIABLE_CHANGED (v);
}
}
}
diff --git a/src/kmk/remake.c b/src/kmk/remake.c
index f42cfa4..bc14311 100644
--- a/src/kmk/remake.c
+++ b/src/kmk/remake.c
@@ -1322,6 +1322,13 @@ notice_finished_file (struct file *file)
So mark it now as "succeeded". */
file->update_status = 0;
#endif
+
+#ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS
+ /* We're done with this command, so free the memory held by the chopped
+ command lines. Saves heap for the compilers & linkers. */
+ if (file->cmds && file->cmds->command_lines)
+ free_chopped_commands (file->cmds);
+#endif
}
/* Check whether another file (whose mtime is THIS_MTIME) needs updating on
diff --git a/src/kmk/variable.c b/src/kmk/variable.c
index 247556e..16e6a0f 100644
--- a/src/kmk/variable.c
+++ b/src/kmk/variable.c
@@ -41,6 +41,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef CONFIG_WITH_STRCACHE2
# include <stddef.h>
#endif
+#ifdef CONFIG_WITH_COMPILER
+# include "kmk_cc_exec.h"
+#endif
#ifdef KMK
/** Gets the real variable if alias. For use when looking up variables. */
@@ -380,7 +383,7 @@ define_variable_in_set (const char *name, unsigned int length,
v->fileinfo.filenm = 0;
v->origin = origin;
v->recursive = recursive;
- MAKE_STATS_2(v->changes++);
+ VARIABLE_CHANGED (v);
}
return v;
}
@@ -442,8 +445,20 @@ define_variable_in_set (const char *name, unsigned int length,
v->aliased = 0;
#endif
v->export = v_default;
+#ifdef CONFIG_WITH_COMPILER
+ v->recursive_without_dollar = 0;
+ v->evalprog = 0;
+ v->expandprog = 0;
+ v->evalval_count = 0;
+ v->expand_count = 0;
+#else
+ MAKE_STATS_2(v->expand_count = 0);
+ MAKE_STATS_2(v->evalval_count = 0);
+#endif
MAKE_STATS_2(v->changes = 0);
MAKE_STATS_2(v->reallocs = 0);
+ MAKE_STATS_2(v->references = 0);
+ MAKE_STATS_2(v->cTicksEvalVal = 0);
v->exportable = 1;
if (*name != '_' && (*name < 'A' || *name > 'Z')
@@ -581,7 +596,7 @@ define_variable_alias_in_set (const char *name, unsigned int length,
if (v->value != 0 && !v->rdonly_val)
free (v->value);
- MAKE_STATS_2(v->changes++);
+ VARIABLE_CHANGED (v);
}
else
{
@@ -598,8 +613,20 @@ define_variable_alias_in_set (const char *name, unsigned int length,
v->private_var = 0;
v->aliased = 0;
v->export = v_default;
+#ifdef CONFIG_WITH_COMPILER
+ v->recursive_without_dollar = 0;
+ v->evalprog = 0;
+ v->expandprog = 0;
+ v->evalval_count = 0;
+ v->expand_count = 0;
+#else
+ MAKE_STATS_2(v->expand_count = 0);
+ MAKE_STATS_2(v->evalval_count = 0);
+#endif
MAKE_STATS_2(v->changes = 0);
MAKE_STATS_2(v->reallocs = 0);
+ MAKE_STATS_2(v->references = 0);
+ MAKE_STATS_2(v->cTicksEvalVal = 0);
v->exportable = 1;
if (*name != '_' && (*name < 'A' || *name > 'Z')
&& (*name < 'a' || *name > 'z'))
@@ -727,6 +754,7 @@ lookup_special_var (struct variable *var)
var->value_length = p - var->value - 1;
var->value_alloc_len = max;
#endif
+ VARIABLE_CHANGED (var);
/* Remember how many variables are in our current count. Since we never
remove variables from the list, this is a reliable way to know whether
@@ -887,7 +915,10 @@ lookup_variable (const char *name, unsigned int length)
{
struct variable *v = lookup_kbuild_object_variable_accessor(name, length);
if (v != VAR_NOT_KBUILD_ACCESSOR)
- return v;
+ {
+ MAKE_STATS_2 (v->references++);
+ return v;
+ }
}
# endif
@@ -920,7 +951,8 @@ lookup_variable (const char *name, unsigned int length)
# ifdef KMK
RESOLVE_ALIAS_VARIABLE(v);
# endif
- return v->special ? lookup_special_var (v) : v;
+ MAKE_STATS_2 (v->references++);
+ return v->special ? lookup_special_var (v) : v;
}
is_parent |= setlist->next_is_parent;
@@ -993,6 +1025,76 @@ lookup_variable (const char *name, unsigned int length)
return 0;
}
+
+#ifdef CONFIG_WITH_STRCACHE2
+/* Alternative version of lookup_variable that takes a name that's already in
+ the variable string cache. */
+struct variable *
+lookup_variable_strcached (const char *name)
+{
+ struct variable *v;
+#if 1 /*FIX THIS - ndef KMK*/
+ const struct variable_set_list *setlist;
+ struct variable var_key;
+#endif /* KMK */
+ int is_parent = 0;
+
+#ifndef NDEBUG
+ strcache2_verify_entry (&variable_strcache, name);
+#endif
+
+#ifdef KMK
+ /* Check for kBuild-define- local variable accesses and handle these first. */
+ if (strcache2_get_len(&variable_strcache, name) > 3 && name[0] == '[')
+ {
+ v = lookup_kbuild_object_variable_accessor(name, strcache2_get_len(&variable_strcache, name));
+ if (v != VAR_NOT_KBUILD_ACCESSOR)
+ {
+ MAKE_STATS_2 (v->references++);
+ return v;
+ }
+ }
+#endif
+
+#if 1 /*FIX THIS - ndef KMK */
+
+ var_key.name = (char *) name;
+ var_key.length = strcache2_get_len(&variable_strcache, name);
+
+ for (setlist = current_variable_set_list;
+ setlist != 0; setlist = setlist->next)
+ {
+ const struct variable_set *set = setlist->set;
+
+ v = (struct variable *) hash_find_item_strcached ((struct hash_table *) &set->table, &var_key);
+ if (v && (!is_parent || !v->private_var))
+ {
+# ifdef KMK
+ RESOLVE_ALIAS_VARIABLE(v);
+# endif
+ MAKE_STATS_2 (v->references++);
+ return v->special ? lookup_special_var (v) : v;
+ }
+
+ is_parent |= setlist->next_is_parent;
+ }
+
+#else /* KMK - need for speed */
+
+ v = lookup_cached_variable (name);
+ assert (lookup_variable_for_assert(name, length) == v);
+#ifdef VMS
+ if (v)
+#endif
+ return v;
+#endif /* KMK - need for speed */
+#ifdef VMS
+# error "Port me (split out the relevant code from lookup_varaible and call it)"
+#endif
+ return 0;
+}
+#endif
+
/* Lookup a variable whose name is a string starting at NAME
and with LENGTH chars in set SET. NAME need not be null-terminated.
@@ -1004,7 +1106,6 @@ lookup_variable_in_set (const char *name, unsigned int length,
const struct variable_set *set)
{
struct variable var_key;
- struct variable *v;
#ifndef CONFIG_WITH_STRCACHE2
var_key.name = (char *) name;
var_key.length = length;
@@ -1012,6 +1113,7 @@ lookup_variable_in_set (const char *name, unsigned int length,
return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
#else /* CONFIG_WITH_STRCACHE2 */
const char *cached_name;
+ struct variable *v;
# ifdef KMK
/* Check for kBuild-define- local variable accesses and handle these first. */
@@ -1021,6 +1123,7 @@ lookup_variable_in_set (const char *name, unsigned int length,
if (v != VAR_NOT_KBUILD_ACCESSOR)
{
RESOLVE_ALIAS_VARIABLE(v);
+ MAKE_STATS_2 (v->references++);
return v;
}
}
@@ -1048,6 +1151,7 @@ lookup_variable_in_set (const char *name, unsigned int length,
# ifdef KMK
RESOLVE_ALIAS_VARIABLE(v);
# endif
+ MAKE_STATS_2 (if (v) v->references++);
return v;
#endif /* CONFIG_WITH_STRCACHE2 */
}
@@ -1223,6 +1327,10 @@ free_variable_name_and_value (const void *item)
#ifndef CONFIG_WITH_STRCACHE2
free (v->name);
#endif
+#ifdef CONFIG_WITH_COMPILER
+ if (v->evalprog || v->expandprog)
+ kmk_cc_variable_deleted (v);
+#endif
#ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
if (!v->rdonly_val)
#endif
@@ -1342,6 +1450,10 @@ merge_variable_sets (struct variable_set *to_set,
if (from_var->alias)
fatal(NULL, ("Attempting to delete variable aliased '%s'"), from_var->name);
#endif
+#ifdef CONFIG_WITH_COMPILER
+ if (from_var->evalprog || from_var->expandprog)
+ kmk_cc_variable_deleted (from_var);
+#endif
#ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
if (!from_var->rdonly_val)
#endif
@@ -2095,6 +2207,7 @@ void append_string_to_variable (struct variable *v, const char *value, unsigned
else
memcpy (v->value, value, value_len + 1);
v->value_length = new_value_len;
+ VARIABLE_CHANGED (v);
}
struct variable *
@@ -2307,7 +2420,6 @@ do_variable_definition_2 (const struct floc *flocp,
# endif
if (free_value)
free (free_value);
- MAKE_STATS_2(v->changes++);
return v;
#else /* !CONFIG_WITH_VALUE_LENGTH */
@@ -2734,9 +2846,17 @@ try_variable_definition (const struct floc *flocp, char *line
return vp;
}
+#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
+static unsigned long var_stats_evalvals, var_stats_evalvaled;
+static unsigned long var_stats_expands, var_stats_expanded;
+#endif
+#ifdef CONFIG_WITH_COMPILER
+static unsigned long var_stats_expandprogs, var_stats_evalprogs;
+#endif
#ifdef CONFIG_WITH_MAKE_STATS
static unsigned long var_stats_changes, var_stats_changed;
static unsigned long var_stats_reallocs, var_stats_realloced;
+static unsigned long var_stats_references, var_stats_referenced;
static unsigned long var_stats_val_len, var_stats_val_alloc_len;
static unsigned long var_stats_val_rdonly_len;
#endif
@@ -2804,15 +2924,61 @@ print_variable (const void *item, void *arg)
printf (_(", alias for '%s'"), v->name);
#endif /* KMK */
+#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
+ if (v->evalval_count != 0)
+ {
+# ifdef CONFIG_WITH_MAKE_STATS
+ printf (_(", %u evalvals (%llu ticks)"), v->evalval_count, v->cTicksEvalVal);
+# else
+ printf (_(", %u evalvals"), v->evalval_count);
+# endif
+ var_stats_evalvaled++;
+ }
+ var_stats_evalvals += v->evalval_count;
+
+ if (v->expand_count != 0)
+ {
+ printf (_(", %u expands"), v->expand_count);
+ var_stats_expanded++;
+ }
+ var_stats_expands += v->expand_count;
+
+# ifdef CONFIG_WITH_COMPILER
+ if (v->evalprog != 0)
+ {
+ printf (_(", evalprog"));
+ var_stats_evalprogs++;
+ }
+ if (v->expandprog != 0)
+ {
+ printf (_(", expandprog"));
+ var_stats_expandprogs++;
+ }
+# endif
+#endif
+
#ifdef CONFIG_WITH_MAKE_STATS
if (v->changes != 0)
+ {
printf (_(", %u changes"), v->changes);
+ var_stats_changed++;
+ }
var_stats_changes += v->changes;
- var_stats_changed += (v->changes != 0);
+
if (v->reallocs != 0)
+ {
printf (_(", %u reallocs"), v->reallocs);
+ var_stats_realloced++;
+ }
var_stats_reallocs += v->reallocs;
- var_stats_realloced += (v->reallocs != 0);
+
+ if (v->references != 0)
+ {
+ printf (_(", %u references"), v->references);
+ var_stats_referenced++;
+ }
+ var_stats_references += v->references;
+
var_stats_val_len += v->value_length;
if (v->value_alloc_len)
var_stats_val_alloc_len += v->value_alloc_len;
@@ -2867,15 +3033,25 @@ print_variable (const void *item, void *arg)
void
print_variable_set (struct variable_set *set, char *prefix)
{
+#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
+ var_stats_expands = var_stats_expanded = var_stats_evalvals
+ = var_stats_evalvaled = 0;
+#endif
+#ifdef CONFIG_WITH_COMPILER
+ var_stats_expandprogs = var_stats_evalprogs = 0;
+#endif
#ifdef CONFIG_WITH_MAKE_STATS
var_stats_changes = var_stats_changed = var_stats_reallocs
- = var_stats_realloced = var_stats_val_len = var_stats_val_alloc_len
- = var_stats_val_rdonly_len = 0;
+ = var_stats_realloced = var_stats_references = var_stats_referenced
+ = var_stats_val_len = var_stats_val_alloc_len
+ = var_stats_val_rdonly_len = 0;
+#endif
hash_map_arg (&set->table, print_variable, prefix);
if (set->table.ht_fill)
{
+#ifdef CONFIG_WITH_MAKE_STATS
unsigned long fragmentation;
fragmentation = var_stats_val_alloc_len - (var_stats_val_len - var_stats_val_rdonly_len);
@@ -2899,10 +3075,34 @@ print_variable_set (struct variable_set *set, char *prefix)
var_stats_realloced,
(unsigned int)((100.0 * var_stats_realloced) / set->table.ht_fill),
var_stats_reallocs);
- }
-#else
- hash_map_arg (&set->table, print_variable, prefix);
+
+ if (var_stats_referenced)
+ printf(_("# referenced %5lu (%2u%%), references %6lu\n"),
+ var_stats_referenced,
+ (unsigned int)((100.0 * var_stats_referenced) / set->table.ht_fill),
+ var_stats_references);
+#endif
+#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
+ if (var_stats_evalvals)
+ printf(_("# evalvaled %5lu (%2u%%), evalval calls %6lu\n"),
+ var_stats_evalvaled,
+ (unsigned int)((100.0 * var_stats_evalvaled) / set->table.ht_fill),
+ var_stats_evalvals);
+ if (var_stats_expands)
+ printf(_("# expanded %5lu (%2u%%), expands %6lu\n"),
+ var_stats_expanded,
+ (unsigned int)((100.0 * var_stats_expanded) / set->table.ht_fill),
+ var_stats_expands);
+#endif
+#ifdef CONFIG_WITH_COMPILER
+ if (var_stats_expandprogs || var_stats_evalprogs)
+ printf(_("# eval progs %5lu (%2u%%), expand progs %6lu (%2u%%)\n"),
+ var_stats_evalprogs,
+ (unsigned int)((100.0 * var_stats_evalprogs) / set->table.ht_fill),
+ var_stats_expandprogs,
+ (unsigned int)((100.0 * var_stats_expandprogs) / set->table.ht_fill));
#endif
+ }
fputs (_("# variable set hash-table stats:\n"), stdout);
fputs ("# ", stdout);
diff --git a/src/kmk/variable.h b/src/kmk/variable.h
index 6c922dd..3238108 100644
--- a/src/kmk/variable.h
+++ b/src/kmk/variable.h
@@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "hash.h"
+#ifdef CONFIG_WITH_COMPILER
+# include "kmk_cc_exec.h"
+#endif
/* Codes in a variable definition saying where the definition came from.
Increasing numeric values signify less-overridable definitions. */
@@ -108,12 +111,49 @@ struct variable
v_ifset, /* Export it if it has a non-default value. */
v_default /* Decide in target_environment. */
} export ENUM_BITFIELD (2);
+#ifdef CONFIG_WITH_COMPILER
+ int recursive_without_dollar : 2; /* 0 if undetermined, 1 if value has no '$' chars, -1 if it has. */
+#endif
#ifdef CONFIG_WITH_MAKE_STATS
- unsigned int changes;
- unsigned int reallocs;
+ unsigned int changes; /* Variable modification count. */
+ unsigned int reallocs; /* Realloc on value count. */
+ unsigned int references; /* Lookup count. */
+ unsigned long long cTicksEvalVal; /* Number of ticks spend in cEvalVal. */
+#endif
+#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
+ unsigned int evalval_count; /* Times used with $(evalval ) or $(evalctx ) since last change. */
+ unsigned int expand_count; /* Times expanded since last change (not to be confused with exp_count). */
+#endif
+#ifdef CONFIG_WITH_COMPILER
+ struct kmk_cc_evalprog *evalprog; /* Pointer to evalval/evalctx "program". */
+ struct kmk_cc_expandprog *expandprog; /* Pointer to variable expand "program". */
#endif
};
+/* Update statistics and invalidates optimizations when a variable changes. */
+#ifdef CONFIG_WITH_COMPILER
+# define VARIABLE_CHANGED(v) \
+ do { \
+ MAKE_STATS_2((v)->changes++); \
+ if ((v)->evalprog || (v)->expandprog) kmk_cc_variable_changed(v); \
+ (v)->expand_count = 0; \
+ (v)->evalval_count = 0; \
+ (v)->recursive_without_dollar = 0; \
+ } while (0)
+#else
+# define VARIABLE_CHANGED(v) MAKE_STATS_2((v)->changes++)
+#endif
+
+/* Macro that avoids a lot of CONFIG_WITH_COMPILER checks when
+ accessing recursive_without_dollar. */
+#ifdef CONFIG_WITH_COMPILER
+# define IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(v) ((v)->recursive_without_dollar > 0)
+#else
+# define IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR(v) 0
+#endif
+
+
+
/* Structure that represents a variable set. */
struct variable_set
@@ -233,7 +273,9 @@ variable_expand_string (char *line, const char *string, long length)
}
#endif /* CONFIG_WITH_VALUE_LENGTH */
void install_variable_buffer (char **bufp, unsigned int *lenp);
+char *install_variable_buffer_with_hint (char **bufp, unsigned int *lenp, unsigned int size_hint);
void restore_variable_buffer (char *buf, unsigned int len);
+char *ensure_variable_buffer_space(char *ptr, unsigned int size);
#ifdef CONFIG_WITH_VALUE_LENGTH
void append_expanded_string_to_variable (struct variable *v, const char *value,
unsigned int value_len, int append);
@@ -245,6 +287,12 @@ int handle_function (char **op, const char **stringp);
#else
int handle_function (char **op, const char **stringp, const char *nameend, const char *eol);
#endif
+#ifdef CONFIG_WITH_COMPILER
+typedef char *(*make_function_ptr_t) (char *, char **, const char *);
+make_function_ptr_t lookup_function_for_compiler (const char *name, unsigned int len,
+ unsigned char *minargsp, unsigned char *maxargsp,
+ char *expargsp, const char **funcnamep);
+#endif
int pattern_matches (const char *pattern, const char *percent, const char *str);
char *subst_expand (char *o, const char *text, const char *subst,
const char *replace, unsigned int slen, unsigned int rlen,
@@ -309,6 +357,9 @@ char *recursively_expand_for_file (struct variable *v, struct file *file,
unsigned int *value_lenp);
#define recursively_expand(v) recursively_expand_for_file (v, NULL, NULL)
#endif
+#ifdef CONFIG_WITH_COMPILER
+char *reference_recursive_variable (char *o, struct variable *v);
+#endif
/* variable.c */
struct variable_set_list *create_new_variable_set (void);
@@ -352,6 +403,9 @@ void hash_init_function_table (void);
struct variable *lookup_variable (const char *name, unsigned int length);
struct variable *lookup_variable_in_set (const char *name, unsigned int length,
const struct variable_set *set);
+#ifdef CONFIG_WITH_STRCACHE2
+struct variable *lookup_variable_strcached (const char *name);
+#endif
#ifdef CONFIG_WITH_VALUE_LENGTH
void append_string_to_variable (struct variable *v, const char *value,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/kbuild.git
More information about the Pkg-virtualbox-commits
mailing list