13364c5525
The bug is due to a stupid make misfeature. The article [1] contains much more information but in a nutshell, the following code: a b: c bla is equivalent to: a: c bla b: c bla This is bad because in parallel runs (make -j typically), "bla" can be run TWICE and even worse, twice in PARALLEL. Obviously the result will be completely unexpected. This is a real bummer because on the other hand, the following code: %.c %.h: %:in bla actually expresses the fact that bla produces two files. For some reasons, pattern rules work differently from implicit rules. This commit attempts to fix the problem with lang.h by rewriting (simplified): lang.c lang.h: lang.in genlang as lang.h: lang.in genlang lang.c: lang.h This works (it correctly expresses the dependency chain and ensures genlang runs once) but as one drawback: if one manually removes lang.c, then genlang will not re-run since the second rule does nothing. This is minor drawback since no one ever removes lang.c manually and "clean" removes lang.h which triggers a rebuild. [1]: https://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html Change-Id: Ic0bf7c7c203dc599b00fde457946d2316c70474e
54 lines
3 KiB
Makefile
54 lines
3 KiB
Makefile
# __________ __ ___.
|
|
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
# \/ \/ \/ \/ \/
|
|
# $Id$
|
|
#
|
|
|
|
LANGS := $(call preprocess, $(APPSDIR)/lang/SOURCES)
|
|
LANGOBJ := $(LANGS:$(ROOTDIR)/%.lang=$(BUILDDIR)/%.lng)
|
|
VOICEOBJ := $(LANGS:$(ROOTDIR)/%.lang=$(BUILDDIR)/%.vstrings)
|
|
LANG_O = $(BUILDDIR)/lang/lang_core.o
|
|
|
|
CLEANOBJS += $(BUILDDIR)/lang/max_language_size.h $(BUILDDIR)/lang/lang*
|
|
|
|
# $(BUILDDIR)/apps/lang must exist before we create dependencies on it,
|
|
# otherwise make will simply ignore those dependencies.
|
|
# Therefore we create it here.
|
|
#DUMMY := $(shell mkdir -p $(BUILDDIR)/apps/lang)
|
|
|
|
# Calculate the maximum language size. Currently based on the file size
|
|
# of the largest lng file. Subtract 10 due to HEADER_SIZE and
|
|
# SUBHEADER_SIZE.
|
|
# TODO: In the future generate this file within genlang or another script
|
|
# in order to only calculate the maximum size based on the core strings.
|
|
$(BUILDDIR)/lang/max_language_size.h: $(LANGOBJ) $(BUILDDIR)/apps/lang/voicestrings.zip
|
|
$(call PRINTS,GEN $(subst $(BUILDDIR)/,,$@))
|
|
$(SILENT)echo "#define MAX_LANGUAGE_SIZE `ls -ln $(BUILDDIR)/apps/lang/*.lng | awk '{print $$5-10}' | sort -n | tail -1`" > $@
|
|
|
|
$(BUILDDIR)/lang/lang_core.o: $(BUILDDIR)/lang/lang.h $(BUILDDIR)/lang/lang_core.c
|
|
$(call PRINTS,CC lang_core.c)$(CC) $(CFLAGS) -c $(BUILDDIR)/lang/lang_core.c -o $@
|
|
|
|
# genlang creates *both* lang.c and lang.h but in Make there is no wat to express this rule
|
|
# (multiple target rules DO NOT express that, they are a simple shortcut for multiple rules)
|
|
# instead we pretend that genlang create lang_core.c and that lang.c depends from lang.h
|
|
# it will work fine as long as one never manually removes lang.c and not lang.h, and it will avoid
|
|
# race conditions such as running genlang twice or worse in parallel with other things!
|
|
$(BUILDDIR)/lang/lang.h: $(APPSDIR)/lang/$(LANGUAGE).lang $(BUILDDIR)/apps/features
|
|
$(call PRINTS,GEN lang.h)
|
|
$(SILENT)for f in `cat $(BUILDDIR)/apps/features`; do feat="$$feat:$$f" ; done; \
|
|
perl -s $(TOOLSDIR)/genlang -p=$(BUILDDIR)/lang -t=$(MODELNAME)$$feat $<
|
|
$(BUILDDIR)/lang/lang_core.c: $(BUILDDIR)/lang/lang.h
|
|
|
|
# NOTE: for some weird reasons in GNU make, multi targets rules WITH patterns actually express
|
|
# the fact that the two files are created as the result of one invocation of the rule
|
|
$(BUILDDIR)/%.lng $(BUILDDIR)/%.vstrings: $(ROOTDIR)/%.lang $(BUILDDIR)/apps/genlang-features
|
|
$(call PRINTS,GENLANG $(subst $(ROOTDIR)/,,$<))
|
|
$(SILENT)mkdir -p $(dir $@)
|
|
$(SILENT)$(TOOLSDIR)/genlang -e=$(APPSDIR)/lang/english.lang -t=$(MODELNAME):`cat $(BUILDDIR)/apps/genlang-features` -i=$(TARGET_ID) -b=$*.lng -c=$*.vstrings $<
|
|
|
|
$(BUILDDIR)/apps/lang/voicestrings.zip: $(VOICEOBJ)
|
|
$(call PRINTS,ZIP $(subst $(BUILDDIR)/,,$@))
|
|
$(SILENT)zip -9 -q $@ $(subst $(BUILDDIR)/,,$^)
|