On Fri, Jan 21, 2022 at 9:24 AM Hongyi Zhao <hongyi.z...@gmail.com> wrote: > > 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)
I wonder if the followin formats shoud be used here? @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