Skip to content

Commit

Permalink
kbuild: Fix handling of backslashes in *.cmd files
Browse files Browse the repository at this point in the history
Commit c353acb ("kbuild: make: fix if_changed when command contains
backslashes") attempted to handle backslashes in *.cmd files, but it
only handled double backslashes for some reason. Changing make-cmd to also
handle single backslashes fixes rebuilds with dash, but it breaks bash
again. The reason is that the two shells disagree about the
interpretation of backslash sequences in the echo builtin. The way out
of this is to print the command with printf '%s\n'. While at it,
document what the individual parts of make-cmd do and why.

Reported-and-tested-by: Konstantin Khlebnikov <[email protected]>
Reviewed-by: Sam Ravnborg <[email protected]>
Signed-off-by: Michal Marek <[email protected]>
  • Loading branch information
michal42 committed Aug 7, 2014
1 parent 26ea6bb commit 164f0d2
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions scripts/Kbuild.include
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,13 @@ else
arg-check = $(if $(strip $(cmd_$@)),,1)
endif

# >'< substitution is for echo to work,
# >$< substitution to preserve $ when reloading .cmd file
# note: when using inline perl scripts [perl -e '...$$t=1;...']
# in $(cmd_xxx) double $$ your perl vars
make-cmd = $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))))
# Replace >$< with >$$< to preserve $ when reloading the .cmd file
# (needed for make)
# Replace >#< with >\#< to avoid starting a comment in the .cmd file
# (needed for make)
# Replace >'< with >'\''< to be able to enclose the whole string in '...'
# (needed for the shell)
make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1)))))

# Find any prerequisites that is newer than target or that does not exist.
# PHONY targets skipped in both cases.
Expand All @@ -230,7 +232,7 @@ any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)

# Execute the command and also postprocess generated .d dependencies file.
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
Expand Down

0 comments on commit 164f0d2

Please sign in to comment.