GNU RISCV GCC Makefile.in all target recipe - gcc

RISCV-GCC Makefile.in
# The target built for a native non-bootstrap build.
all:
#if gcc-bootstrap
[ -f stage_final ] || echo stage3 > stage_final
#r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(MAKE) $(RECURSE_FLAGS_TO_PASS) `cat stage_final`-bubble
#endif gcc-bootstrap
#: $(MAKE); $(unstage)
#r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
#if gcc-bootstrap
if [ -f stage_last ]; then \
TFLAGS="$(STAGE$(shell test ! -f stage_last || sed s,^stage,, stage_last)_TFLAGS)"; \
$(MAKE) $(TARGET_FLAGS_TO_PASS) all-host all-target; \
else \
#endif gcc-bootstrap
$(MAKE) $(RECURSE_FLAGS_TO_PASS) all-host all-target \
#if gcc-bootstrap
; \
fi \
#endif gcc-bootstrap
&& :
What does this statement, #: $(MAKE); $(unstage), do in this recipe for target all?
I have tried to remove other statements but this one, and make this Makefile, it does nothing. However, according to the mechanism of make, it should invoke the recipe for first target if without dependencies, therefore it will spawn a new shell process to call make in current directory, which may lead to a indefinitively recursive call. But it just does nothing and terminate.
I am confused about what that statement, #: $(MAKE); $(unstage) do, and why need it there in recipe.

Related

Behavior of parenthesis in the shell invoked from make

I'm building a Linux from scratch on my old Android phone in a chrooted environment (which can be part of the problem), on a mounted ext4 partition on the sd card. I managed to cross compile install most of the stuff I need to build locally there. I installed the latest release of everything.
And now time to make something in place without cross compilation.
I decided to make and install inetutils-1.9.4.
The configure runs just fine, but when I try to make, it just fails without saying a thing:
# make
make all-recursive
make[1]: Entering directory '/tmp/inetutils_build'
Making all in lib
make[1]: *** [Makefile:1491: all-recursive] Error 1
make[1]: Leaving directory '/tmp/inetutils_build'
make: *** [Makefile:1428: all] Error 2
So I looked at the generated makefile and it contains this rule:
$(am__recursive_targets):
#fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $# | sed s/-recursive//`; \
case "$#" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
After inserting some echos I have found that the line with the $(am__cd)... fails, and the ored expression runs which exits the script with failure. So I attempted to find out which command fails there, and inserted some echos within the parenthesis, like this:
(echo "1" && $(am__cd) $$subdir && echo "2" && $(MAKE) $(AM_MAKEFLAGS) $$local_target && echo "3") \
|| eval $$failcom; \
Now it prints:
make all-recursive
make[1]: Entering directory '/tmp/inetutils_build'
Making all in lib
1
make[1]: *** [Makefile:1491: all-recursive] Error 1
make[1]: Leaving directory '/tmp/inetutils_build'
make: *** [Makefile:1428: all] Error 2
However I wanted to make sure the echo doesn't fail, so I added another one.
(echo "1" && echo "1b" && $(am__cd) $$subdir && echo "2" && $(MAKE) $(AM_MAKEFLAGS) $$local_target && echo "3") \
|| eval $$failcom; \
When I tried it. It again prints just 1.
I didn't give it up just yet.
I wanted to make sure echo really fails within the script.
So I tried adding new statements into the script, before the problematic command:
(echo "A" && echo "B"); \
(echo "X" || echo "Y"); \
echo "N" && echo "M"; \
(echo "C" && echo "D"); \
It prints:
A
X
Y
N
M
C
D
Then it prints
1
1b
2
and starts building!
I'm totally puzzled here. Why does the first two parenthesized expressions fail, but not the last one?
In fact even writing (true) || echo "ooops" fails at first, but not when I paste it below the ored X Y parenthesis. Apparently the ored parenthesis "fixes" it, whatever state it got stuck on.
What is going on?
It should be noted I cannot reproduce this at the shell prompt but only the statements inserted into the makefile does this.
EDIT:
By removing the # from the beginning it echoes back the command but nothing else, no errors:
fail=; \
if (target_option=k; case ${target_option-} in ?) ;; *) echo "am__make_running_with_option: internal error: invalid" "target option '${target_option-}' specified" >&2; exit 1;; esac; has_opt=no; sane_makeflags=$MAKEFLAGS; if { if test -z '1'; then false; elif test -n 'arm-unknown-linux-gnueabi'; then true; elif test -n '4.2' && test -n '/tmp/inetutils_build'; then true; else false; fi; }; then sane_makeflags=$MFLAGS; else case $MAKEFLAGS in *\\[\ \ ]*) bs=\\; sane_makeflags=`printf '%s\n' "$MAKEFLAGS" | sed "s/$bs$bs[$bs $bs ]*//g"`;; esac; fi; skip_next=no; strip_trailopt () { flg=`printf '%s\n' "$flg" | sed "s/$1.*$//"`; }; for flg in $sane_makeflags; do test $skip_next = yes && { skip_next=no; continue; }; case $flg in *=*|--*) continue;; -*I) strip_trailopt 'I'; skip_next=yes;; -*I?*) strip_trailopt 'I';; -*O) strip_trailopt 'O'; skip_next=yes;; -*O?*) strip_trailopt 'O';; -*l) strip_trailopt 'l'; skip_next=yes;; -*l?*) strip_trailopt 'l';; -[dEDm]) skip_next=yes;; -[JT]) skip_next=yes;; esac; case $flg in *$target_option*) has_opt=yes; break;; esac; done; test $has_opt = yes); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo all-recursive | sed s/-recursive//`; \
case "all-recursive" in \
distclean-* | maintainer-clean-*) list='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests' ;; \
*) list='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests' ;; \
esac; \
for subdir in $list; do \
echo "Making $target in $subdir"; \
if test "$subdir" = "."; then \
dot_seen=yes; \
local_target="$target-am"; \
else \
local_target="$target"; \
fi; \
(CDPATH="${ZSH_VERSION+.}:" && cd $subdir && make $local_target) \
|| eval $failcom; \
done; \
if test "$dot_seen" = "no"; then \
make "$target-am" || exit 1; \
fi; test -z "$fail"
EDIT 2:
Thanks for the tips, I added set -x to the beginning of the rule. These are the commands:
+ fail=
+ target_option=k
+ case ${target_option-} in
+ has_opt=no
+ sane_makeflags=w
+ test -z 1
+ test -n arm-unknown-linux-gnueabi
+ true
+ sane_makeflags=-w
+ skip_next=no
+ for flg in $sane_makeflags
+ test no = yes
+ case $flg in
+ case $flg in
+ test no = yes
+ failcom='exit 1'
+ dot_seen=no
++ echo all-recursive
++ sed s/-recursive//
+ target=all
+ case "all-recursive" in
+ list='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests'
+ for subdir in $list
+ echo 'Making all in lib'
Making all in lib
+ test lib = .
+ local_target=all
+ CDPATH=:
+ eval exit 1
++ exit 1
Did you put SHELL := /bin/bash at the top of your makefile? Otherwise, make(1) tends to invoke /bin/sh as the shell, which has very different properties.

How to use eval Makefile variable from recipe to conditionally execute some commands in recipe

Goal is to apply patch ONLY if patch is not present. If patch is present don't do anything.
I used below makefile rule.
C_FILE_PATCH_SIG=###MAGIC_CODE;
C_FILE_CODE=~/code/file.c
C_PATCH_FILE=~/test.patch
.tmp/patch_c:
cp ${C_PATCH_FILE} ${SDK}
ifneq ($(PATCH_DONE), 1)
$(MAKE) applypatch || $(MAKE) helppatch
endif
#echo DONE > .tmp/patch_c
applypatch:
#echo "Patching ${C_FILE_CODE}"
if grep -Fq '${C_FILE_PATCH_SIG}' ${C_FILE_CODE} ; \
then \
echo 1 > .tmp/PATCH_PRESENT_file; \
else \
echo 0 > .tmp/PATCH_PRESENT_file;\
fi
cat .tmp/PATCH_PRESENT_file
# $(eval PATCH_PRESENT := `cat .tmp/PATCH_PRESENT_file`)
$(eval PATCH_PRESENT := $(shell cat .tmp/PATCH_PRESENT_file))
#echo "WWWWWW PATCH_PRESENT=[$(PATCH_PRESENT)] WWWWWWW"
ifeq ($(PATCH_PRESENT), 0)
#echo "Applying the patch $(PATCH_PRESENT)"
cd ~/code && git apply -v ${C_PATCH_FILE}
else
#echo "NOT Applying the patch $(PATCH_PRESENT)"
endif
helppatch:
#echo -e "\n\n\n"
#echo -e "++++++++++ Apply below patch manually then run 'make build PATCH_DONE=1' ++++++++++\n\n"
#echo -e "+++++++++++++++++++++++++++++++++++++"
#cat ${C_PATCH_FILE}
#echo -e "+++++++++++++++++++++++++++++++++++++"
#echo -e "\n\n\n"
false
But it always evaluates to the else part of ifeq.
Where am I doing wrong?
If I use the patch command of git withing the shell multiline I loose the error code returned by the git patch.
Thanks in advance...
Your ifeq will be evaluated when the makefile is first read (as opposed to when the recipe is run). The eval, on the other hand, will not be executed until the recipe is run (afterwards). Thus, PATCH_PRESENT is not equal to 0 at parse time, and make will expand the else portion of the clause. By the time the eval is run, the if statement is already evaluated and gone from memory.
BTW, a cleaner way to do this is to do everything in bash:
applypatch:
#echo "Patching ${C_FILE_CODE}"
#if grep -Fq '${C_FILE_PATCH_SIG}' ${C_FILE_CODE}; then \
echo "NOT Applying the patch"; \
else \
echo "Applying the patch"; \
cd ~/code && git apply -v ${C_PATCH_FILE}; \
fi

Use help2man in parallel automake

I'm working on a project built using GNU autotools (autoconf, automake). It does work well, but I've a problem with help2man: When building parallel (MAKEFLAGS=-j3), the project is built twice - once using "normal" target, once using the foo.1 make call.
The following is the relevant part from Makefile.am:
foo.1 : $(top_srcdir)/man/foo.x $(top_srcdir)/src/main.c $(top_srcdir)/configure.ac
$(MAKE) $(AM_MAKEFLAGS) foo$(EXEEXT)
-$(HELP2MAN) -o $# --include $< $(top_builddir)/foo
So, my question is how to write Makefile.am to support the following:
Distribute foo.1 to support systems without help2man
Do not throw errors
Rebuild manpage if necessary
I'm looking forward to your answer
foo.1 needs correct prerequisites. AIUI, help2man just needs the executable binary to be built:
foo.1 : $(top_srcdir)/man/foo.x $(top_srcdir)/configure.ac $(top_builddir)/foo
-$(HELP2MAN) -o $# --include $< $(top_builddir)/foo
so that's 3)
don't understand what you want out of 2), which is not possible in general.
dist_man_MANS = foo.1
which is 1)
There seems to be no easy solution to this question; the following works for me.
In configure.ac, you have to check for help2man. If cross-compiling, you must not run help2man, as the executable will be run. The following snippet is therefore contained:
# Man pages
AS_IF([test "$cross_compiling" = "no"], [
AM_MISSING_PROG([HELP2MAN], [help2man])
], [
HELP2MAN=:
])
For building, there is a two-level concept. First, you check if the manpage is newer than the executable; if so, to prohibit unnecessary manpage rebuilds, you check against the source using a temporary file being last altered when the manpage itself was. So, Makefile.am contains:
dist_man_MANS = foo.1
EXTRA_DIST += $(dist_man_MANS:.1=.x) common.x
MOSTLYCLEANFILES += $(dist_man_MANS:=-t)
MAINTAINERCLEANFILES += $(dist_man_MANS)
common_dep = $(top_srcdir)/common.x $(top_srcdir)/configure.ac $(top_srcdir)/.version
common_indirect_dep = $(top_srcdir)/common.x $(top_srcdir)/configure $(top_srcdir)/.version
foo.1 : $(common_indirect_dep) $(top_builddir)/foo$(EXEEXT)
foo.1-t : $(common_dep) $(top_srcdir)/main-helpversion.c
SUFFIXES += .x .1 .1-t
.x.1:
test -f $# || if test -f $(top_srcdir)/`echo $# | $(SED) -e 's,.*/,,'`; then \
touch -r $(top_srcdir)/`echo $# | $(SED) -e 's,.*/,,'` $#; \
else \
touch -d #0 $#; \
fi
touch -r $# $#-t
$(MAKE) $(AM_MAKEFLAGS) $#-t
if test -s $#-t; then \
mv -f $#-t $#; \
else \
rm -f $#-t; \
if test -s $#; then touch $#; else rm -f $#; fi; \
fi
.x.1-t:
$(HELP2MAN) -o $# -I $< -I $(top_srcdir)/common.x -s 1 foo$(EXEEXT)

How can I propagate exit status through a shell 'if' command in a Makefile?

%/all:
if [ -f $(#D)/src/Makefile ]; then \
$(MAKE) -C $(#D); \
fi
If the inner make fails, the outer make continues, presumably because the implicit exit status of the 'if' command is 0. Is there a way around this?
This cannot be a real example. The shell will exit with the result of the last command executed, which if the if-statement succeeds will be the exit code of make, which is what you want. So obviously in your real code, you must be doing some other command between the make and the end. You can keep a copy of the result in a variable and use that as the exit:
if [ -f $(#D)/src/Makefile ]; then \
$(MAKE) -C $(#D); \
r=$$?; \
...do other stuff...; \
exit $$r; \
fi
Somehow I couldn't reproduce your problem but I suppose the following should work for you :
%/all:
if [ -f $(#D)/src/Makefile ]; then \
$(MAKE) -C $(#D) || (echo "make failure: $$?"; exit 1) \
fi

How To test the exit status, and do something in Makefile

I'm trying to do this ..... and this is how my Makefile look like
.PHONY: run
SHELL := /bin/tcsh
run:
md5sum -c md; \
if ($$?==0) then \
echo "PASS" \
else \
echo "FAIL" \
endif
But i got this error.
if: Badly formed number.
make: *** [run] Error 1
Is what I'm doing correct? Or is there a better way of doing that in a Makefile?
Basically, you should simply not, ever, use csh (or tcsh) for writing makefile rules. Write the rule using POSIX shell:
.PHONY: run
run:
md5sum -c md; \
if [ $$? -eq 0 ]; then \
echo "PASS"; \
else \
echo "FAIL"; \
fi

Resources