On Wed, Jan 19, 2022 at 2:56 AM Paul Smith <psm...@gnu.org> wrote: > > On Tue, 2022-01-18 at 10:14 +0800, Hongyi Zhao wrote: > > But it seems that the `$?' used above can't obtain the exit status of > > the code block in @(...) when used from outside the @() structure > > [2]. So, I want to know if I can reliably obtain the exit status of > > the code block in @(...) from outside the @() structure. Any hints > > will be greatly appreciated. > > First, of course you must use $$? not $?, because $? is a shell > variable not a make variable so you must escape it from make. > > Second, there's nothing magical about (). > > All versions of make, including GNU make, invoke each logical line of > the recipe in a separate shell. There is no interaction between two > different shells: the exit code of one shell cannot be accessed by a > sibling shell. > > A rule like this: > > foo: > (exit 1) > echo $$? > > causes make to invoke two different shells: > > /bin/sh -c '(exit 1)' > /bin/sh -c 'echo $?' > > The exit code of the first shell is not put into the $? variable of the > second shell. > > If you want to access the exit code of a previous command you must put > them both into the same shell, which means they both need to be in the > same logical line of the recipe. So, this rule: > > foo: > (exit 1) ; \ > echo $$? > > invokes a single shell command: > > /bin/sh -c '(exit 1) ; echo $?' > > now it will work as you expect. > > So, in your makefile rule, you just need to make sure that you add > semicolons and backslashes to ensure that the recipe is treated as one > logical line; change: > > echo "*** located here $(2)" ; \ > exit 1 ; fi ; fi ; fi) > if test $? -eq 0 -a ! -e ../$(3); then \ > > to add the semicolon / backslash: > > echo "*** located here $(2)" ; \ > exit 1 ; fi ; fi ; fi) ; \ > if test $$? -eq 0 -a ! -e ../$(3); then \ >
Based on your comments above, I've now rewritten the original script into the following: ``` # Copyright (C) 2001-2016 Quantum ESPRESSO group # # This program 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 2 # of the License. See the file `License' in the root directory # of the present distribution. # # Utilities ########################################################### # Template function # $(1) = package name # $(2) = package URL # $(3) = directory name # $(4) = plugin/code name ########################################################### define download_and_unpack @package = $(1) @package_URL = $(2) @package_directory = $(3) @package_code = $(4) @package_archive = ../archive/`echo "$(package)" | sed 's/.*\///;s/.*=//'` @( if ! gzip -t $(package_archive) > /dev/null 2>&1 ; then \ rm -fr $(package_archive); \ rm -fr ../$(package_directory); \ wget -O $(package_archive) $(package_URL) > /dev/null 2>&1; \ if [ $$? -ne 0 ]; then \ curl -o $(package_archive) $(package_URL) > /dev/null 2>&1; \ if [ $$? -ne 0 ]; then \ echo "*** Unable to download $(package_code). Test whether curl or wget is installed and working," ; \ echo "*** if you have direct access to internet. If not, copy into archive/ the file" ; \ echo "*** located here $(package_URL)" ; \ exit 1 ; \ fi ; \ fi ; \ fi ) ; \ if [ $$? -eq 0 -a ! -e ../$(package_directory) ]; then \ (gzip -dc $(package_archive) | \ (cd ../ ; tar -xvf - )) ; \ if [ $$? -ne 0 ]; then \ echo "*** Unable to download $(package_URL)." ; \ echo "*** Verify that the url is correct." ; \ exit 1 ; \ else \ (cd ../ ; ln -s $(package) $(package_directory)) ; \ fi ; \ fi endef `` However, the following error will be triggered when compiling one of the targets: ``` $ git log -1 commit ee54a437ab630be869cd12aa767418303f530e8d (HEAD -> develop, origin/develop, origin/HEAD, hongyi-zhao/develop) Merge: 98866d877 f35839efb Author: giannozz <paolo.gianno...@uniud.it> Date: Thu Jan 20 13:25:47 2022 +0000 Merge branch 'develop' into 'develop' Enhance the robustness of `install/install_utils` script. See merge request QEF/q-e!1722 $ module load mkl mpi compiler $ ./configure --with-scalapack=intel MPIF90=mpiifort $ make -j44 all $ make -j44 w90 test -d bin || mkdir bin cd install ; make -f extlibs_makefile liblapack make[1]: Entering directory '/home/werner/q-e/install' make[1]: Nothing to be done for 'liblapack'. make[1]: Leaving directory '/home/werner/q-e/install' ( cd install ; make -f plugins_makefile w90 || exit 1 ) make[1]: Entering directory '/home/werner/q-e/install' make[1]: package: Command not found make[1]: *** [plugins_makefile:94: uncompress-w90] Error 127 make[1]: Leaving directory '/home/werner/q-e/install' make: *** [Makefile:239: w90] Error 1 ``` What is going on here, and where is my mistake? See here [1] for some relevant discussion. [1] https://gitlab.com/QEF/q-e/-/issues/454 Regards, HZ