From: Paolo Bonzini <pbonzini@redhat.com>
To: Fam Zheng <famz@redhat.com>, qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
mjt@tls.msk.ru, Micael Roth <mdroth@linux.vnet.ibm.com>,
Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH v2] rules.mak: Rewrite unnest-vars
Date: Fri, 23 May 2014 15:22:09 +0200 [thread overview]
Message-ID: <537F4B81.4050702@redhat.com> (raw)
In-Reply-To: <1399987445-6042-1-git-send-email-famz@redhat.com>
Just one question:
> +# fix-paths
> +# Usage: $(call fix-paths, obj_path, src_path, vars)
> +# Add prefix @obj_path to all objects in @vars, and add prefix @src_path to all
> +# directories in @vars.
> +define fix-paths
> + $(foreach v,$3,
> + $(foreach o,$($v),
> + $(if $($o-libs),
> + $(eval $1$o-libs := $(value $o-libs)))
> + $(if $($o-cflags),
> + $(eval $1$o-cflags := $(value $o-cflags)))
> + $(if $($o-objs),
> + $(eval $1$o-objs := $(addprefix $1,$(value $o-objs)))))
> + $(eval $v := $(addprefix $1,$(filter-out %/,$(value $v))) \
> + $(addprefix $2,$(filter %/,$(value $v)))))
Why $(value $v) here in? I think you need to expand the variable,
especially in the last assignment but possibly also in the others. For
example if you have
OBJECTS = foo1.o foo2.o
foo.mo-objs = $(OBJECTS)
the addprefix would set
foo.mo-objs = dir/$(OBJECTS)
which is wrong.
Paolo
> endef
>
> -define process-modules
> -$(foreach o,$(filter %.o,$($1)),
> - $(eval $(patsubst %.o,%.mo,$o): $o) \
> - $(eval $(patsubst %.o,%.mo,$o)-objs := $o))
> -$(foreach o,$(filter-out $(modules-m), $(patsubst %.o,%.mo,$($1))), \
> - $(eval $o-objs += module-common.o)
> - $(eval $o: $($o-objs))
> - $(eval modules-objs-m += $($o-objs))
> - $(eval modules-m += $o)
> - $(eval $o:; $$(call quiet-command,touch $$@," GEN $$(TARGET_DIR)$$@"))
> - $(if $(CONFIG_MODULES),$(eval modules: $(patsubst %.mo,%$(DSOSUF),$o)))) \
> -$(eval modules-objs-m := $(sort $(modules-objs-m)))
> -$(foreach o,$(modules-objs-m), \
> - $(if $(CONFIG_MODULES),$(eval $o-cflags := $(call maybe-add, $(DSO_CFLAGS), $($o-cflags)))))
> -$(eval $(patsubst %-m,%-$(call lnot,$(CONFIG_MODULES)),$1) += $($1))
> +# unnest-var-recursive
> +# Usage: $(call unnest-var-recursive, obj_prefix, vars, var)
> +#
> +# Unnest @var by including subdir Makefile.objs, while protect others in @vars
> +# unchanged.
> +#
> +# @obj_prefix is the starting point of object path prefix.
> +#
> +define unnest-var-recursive
> + $(eval dirs := $(sort $(filter %/,$($3))))
> + $(eval $3 := $(filter-out %/,$($3)))
> + $(foreach d,$(dirs:%/=%),
> + $(call save-vars,$2)
> + $(eval obj := $(if $1,$1/)$d)
> + $(eval -include $(SRC_PATH)/$d/Makefile.objs)
> + $(call fix-paths,$(if $1,$1/)$d/,$d/,$2)
> + $(call load-vars,$2,$3)
> + $(call unnest-var-recursive,$1,$2,$3))
> endef
>
> +# unnest-vars
> +# Usage: $(call unnest-vars, obj_prefix, vars)
> +#
> +# @obj_prefix: object path prefix, can be empty, or '..', etc. Don't include
> +# ending '/'.
> +#
> +# @vars: the list of variable names to unnest.
> +#
> +# This macro will scan subdirectories's Makefile.objs, include them, to build
> +# up each variable listed in @vars.
> +#
> +# Per object and per module cflags and libs are saved with relative path fixed
> +# as well, those variables include -libs, -cflags and -objs. Items in -objs are
> +# also fixed to relative path against SRC_PATH plus the prefix @obj_prefix.
> +#
> +# All nested variables postfixed by -m in names are treated as DSO variables,
> +# and will be built as modules, if enabled.
> +#
> +# A simple example of the unnest:
> +#
> +# obj_prefix = ..
> +# vars = hot cold
> +# hot = fire.o sun.o season/
> +# cold = snow.o water/ season/
> +#
> +# Unnest through a faked source directory structure:
> +#
> +# SRC_PATH
> +# ├── water
> +# │ └── Makefile.objs──────────────────┐
> +# │ │ hot += steam.o │
> +# │ │ cold += ice.mo │
> +# │ │ ice.mo-libs := -licemaker │
> +# │ │ ice.mo-objs := ice1.o ice2.o │
> +# │ └──────────────────────────────┘
> +# │
> +# └── season
> +# └── Makefile.objs──────┐
> +# │ hot += summer.o │
> +# │ cold += winter.o │
> +# └──────────────────┘
> +#
> +# In the end, the result will be:
> +#
> +# hot = ../fire.o ../sun.o ../season/summer.o
> +# cold = ../snow.o ../water/ice.mo ../season/winter.o
> +# ../water/ice.mo-libs = -licemaker
> +# ../water/ice.mo-objs = ../water/ice1.o ../water/ice2.o
> +#
> +# Note that 'hot' didn't include 'season/' in the input, so 'summer.o' is not
> +# included.
> +#
> define unnest-vars
> -$(eval obj := $1)
> -$(eval nested-vars := $2)
> -$(foreach v,$(nested-vars),$(call fix-obj-vars,$v,$(obj)))
> -$(eval old-nested-dirs := )
> -$(call unnest-vars-1)
> -$(if $1,$(foreach v,$(nested-vars),$(eval \
> - $v := $(addprefix $1/,$($v)))))
> -$(foreach var,$(nested-vars),$(eval $(var) := $(filter-out %/, $($(var)))))
> -$(shell mkdir -p $(sort $(foreach var,$(nested-vars),$(dir $($(var))))))
> -$(foreach var,$(nested-vars), $(eval \
> - -include $(addsuffix *.d, $(sort $(dir $($(var)))))))
> -$(foreach v,$(filter %-m,$(nested-vars)), \
> - $(call process-modules,$v))
> + # In the case of target build (i.e. $1 == ..), fix path for top level
> + # Makefile.objs objects
> + $(if $1,$(call fix-paths,$1/,,$2))
> +
> + # Descend and include every subdir Makefile.objs
> + $(foreach v, $2, $(call unnest-var-recursive,$1,$2,$v))
> +
> + $(foreach v,$(filter %-m,$2),
> + # All .o found in *-m variables are single object modules, create .mo
> + # for them
> + $(foreach o,$(filter %.o,$($v)),
> + $(eval $(o:%.o=%.mo)-objs := $o))
> + # Now unify .o in -m variable to .mo
> + $(eval $v := $($v:%.o=%.mo))
> +
> + $(eval modules: $($v:%.mo=%$(DSOSUF)))
> + $(eval modules-m += $($v:%.mo=%$(DSOSUF)))
> +
> + # For non-module build, add -m to -y
> + $(if $(CONFIG_MODULES),,$(eval $(patsubst %-m,%-y,$v) += $($v))))
> +
> + # .mo's are .PHONY targets
> + $(eval .PHONY: $(modules-m))
> + $(eval $(modules-m): module-common.o)
> +
> + # Post-process all the unnested vars
> + $(foreach v,$2,
> + $(foreach o, $(filter %.mo,$($v)),
> + # Find all the .mo objects in variables and add dependency rules
> + # according to .mo-objs. Report error if not set
> + $(if $($o-objs),
> + $(eval $o: $($o-objs)),
> + $(error $o added in $v but $o-objs is not set))
> + # Pass the .mo-cflags along to member objects
> + $(if $($o-cflags),
> + $(foreach p,$($o-objs),
> + $(eval $p-cflags := $($o-cflags)))))
> + $(shell mkdir -p ./ $(sort $(dir $($v))))
> + # Include all the .d files
> + $(eval -include $(addsuffix *.d, $(sort $(dir $($v)))))
> + $(eval $v := $(filter-out %/,$($v))))
> endef
>
next prev parent reply other threads:[~2014-05-23 13:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-13 13:24 [Qemu-devel] [PATCH v2] rules.mak: Rewrite unnest-vars Fam Zheng
2014-05-23 2:37 ` Fam Zheng
2014-05-23 13:22 ` Paolo Bonzini [this message]
2014-05-23 13:33 ` Fam Zheng
2014-05-23 13:56 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=537F4B81.4050702@redhat.com \
--to=pbonzini@redhat.com \
--cc=famz@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=mjt@tls.msk.ru \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.