RE: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-21 Thread David Laight
From: Masahiro Yamada
> Sent: 21 December 2020 14:29
> 
> On Sun, Dec 13, 2020 at 6:47 AM David Laight  wrote:
> >
> > From: Masahiro Yamada
> > > Sent: 12 December 2020 16:55
> > >
> > > This script was written in awk in spite of the file extension '.sh'.
> > > Rewrite it as a shell script.
> > ...
> > > +#
> > > +# Usage: $ ./scripts/ld-version.sh ld
> > > +#
> > > +# Print the linker version of `ld' in a 5 or 6-digit form
> > > +# such as `23501' for GNU ld 2.35.1 etc.
> > > +
> > > +first_line="$($* --version | head -n 1)"
> > > +
> > > +if ! ( echo $first_line | grep -q "GNU ld"); then
> > > + echo 0
> > > + exit 1
> > > +fi
> > > +
> > > +# Distributions may append an extra string like 2.35-15.fc33
> > > +# Take the part that consists of numbers and dots.
> > > +VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> > > 's/^\(^[0-9.]*\).*/\1/')
> > > +MAJOR=$(echo $VERSION | cut -d . -f 1)
> > > +MINOR=$(echo $VERSION | cut -d . -f 2)
> > > +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
> > > +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
> >
> >
> > H.
> > You've managed to convert an awk script into something that requires
> > sh, head, grep, sed (twice), and cut (thrice).
> > Plus (probably) a few sub-shells.
> >
> > It is quite ease to do it all in all in the shell.
> >
> > David
> >
> 
> OK, please rewrite the code.

I've posted a couple of versions before, how about this one.
I've added a few comments - which don't need to be in the final version.

# Get the first line of the 'ld --version' output
if input_from_from_stdin; then
read line
else
IFS='
'
set -- $("$@")
line="$1"
fi

# Split the line on 'space' and get the last word
IFS=' '
set -- $line
shift $(($# - 1))
version="$1"

# Split on '.' and '-'
IFS='.-'
set -- $version

# The three version components are now $1 $2 and $3
# so you can do either
printf "%d%02d%02d\\n" $1 $2 $3
# or
echo $(($1 * 1 + $2 * 100 + $3))
# both are builtins on recent shells (printf is most likely not to be).

So this should be the same as the script above:

#! /bin/sh
IFS='
'
set -- $("$@")
# The last word contains the version
IFS=' '
set -- $1
shift $(($# - 1))
# Get the first 3 parts of the version
IFS='.-'
set -- $1
printf "%d%02d%02d\\n" $1 $2 $3

Seems to work for me.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)


Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-21 Thread Masahiro Yamada
On Sun, Dec 13, 2020 at 6:47 AM David Laight  wrote:
>
> From: Masahiro Yamada
> > Sent: 12 December 2020 16:55
> >
> > This script was written in awk in spite of the file extension '.sh'.
> > Rewrite it as a shell script.
> ...
> > +#
> > +# Usage: $ ./scripts/ld-version.sh ld
> > +#
> > +# Print the linker version of `ld' in a 5 or 6-digit form
> > +# such as `23501' for GNU ld 2.35.1 etc.
> > +
> > +first_line="$($* --version | head -n 1)"
> > +
> > +if ! ( echo $first_line | grep -q "GNU ld"); then
> > + echo 0
> > + exit 1
> > +fi
> > +
> > +# Distributions may append an extra string like 2.35-15.fc33
> > +# Take the part that consists of numbers and dots.
> > +VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> > 's/^\(^[0-9.]*\).*/\1/')
> > +MAJOR=$(echo $VERSION | cut -d . -f 1)
> > +MINOR=$(echo $VERSION | cut -d . -f 2)
> > +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
> > +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
>
>
> H.
> You've managed to convert an awk script into something that requires
> sh, head, grep, sed (twice), and cut (thrice).
> Plus (probably) a few sub-shells.
>
> It is quite ease to do it all in all in the shell.
>
> David
>

OK, please rewrite the code.



-- 
Best Regards
Masahiro Yamada


Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-21 Thread Masahiro Yamada
On Sun, Dec 13, 2020 at 2:48 AM Dominique Martinet
 wrote:
>
> Masahiro Yamada wrote on Sun, Dec 13, 2020:
> > This script was written in awk in spite of the file extension '.sh'.
> > Rewrite it as a shell script.
>
> Wow! I wasn't expecting so much, would have sent some rework after the
> upcoming merge window.
> Thank you.
>
> Some comments below that you can probably ignore, this works for me.
>
>
> > diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh
> > index 0f8a2c0f9502..c214aeb3200d 100755
> > --- a/scripts/ld-version.sh
> > +++ b/scripts/ld-version.sh
> > @@ -1,11 +1,22 @@
> > -#!/usr/bin/awk -f
> > +#!/bin/sh
> >  # SPDX-License-Identifier: GPL-2.0
> > -# extract linker version number from stdin and turn into single number
> > - {
> > - gsub(".*\\)", "");
> > - gsub(".*version ", "");
> > - gsub("-.*", "");
> > - split($1,a, ".");
> > - print a[1]*1 + a[2]*100 + a[3];
> > - exit
> > - }
> > +#
> > +# Usage: $ ./scripts/ld-version.sh ld
> > +#
> > +# Print the linker version of `ld' in a 5 or 6-digit form
> > +# such as `23501' for GNU ld 2.35.1 etc.
> > +
> > +first_line="$($* --version | head -n 1)"
>
> Just nitpicking: this ($*) would fail if the argument contains spaces,
> it's generally better to use "$@" or "$1" (with quotes)

This is just a copy-paste work based on scripts/lld-version.sh.

"$@" is better, I agree.




> Probably doesn't matter here as gcc/clang-version scripts have the same
> problem, so if someone had a problem with that they probably would have
> reported it there.

Talking about gcc/clang-version, "$1" is not acceptable because the first
word of the arguments may not be the compiler.

For example, when CC="ccache gcc" is passed in,
scripts/gcc-version.sh  ccache  gcc
must return the gcc version.




Difference between "$@" and "$*" matters only
when it is directly passed to some command.


masahiro@grover:~$ set  "a   b"  c  d
masahiro@grover:~$ ls  "$*"
ls: cannot access 'a   b c d': No such file or directory
masahiro@grover:~$ ls  "$@"
ls: cannot access 'a   b': No such file or directory
ls: cannot access 'c': No such file or directory
ls: cannot access 'd': No such file or directory


"$*" was expanded into a single string, 'a   b c d'.
It forgot which spaces were the part of the argument,
and which spaces were argument delimiters.

In contrast, "$@" was expanded into three arguments,
'a   b', 'c', and 'd'.
It correctly preserved the original arguments.



Let me continue some more experiments...


masahiro@grover:~$ set  "a   b"  c  d
masahiro@grover:~$ compiler="$*"
masahiro@grover:~$ ls "$compiler"
ls: cannot access 'a   b c d': No such file or directory
masahiro@grover:~$ ls $compiler
ls: cannot access 'a': No such file or directory
ls: cannot access 'b': No such file or directory
ls: cannot access 'c': No such file or directory
ls: cannot access 'd': No such file or directory



masahiro@grover:~$ set  "a   b"  c  d
masahiro@grover:~$ compiler="$@"
masahiro@grover:~$ ls "$compiler"
ls: cannot access 'a   b c d': No such file or directory
masahiro@grover:~$ ls $compiler
ls: cannot access 'a': No such file or directory
ls: cannot access 'b': No such file or directory
ls: cannot access 'c': No such file or directory
ls: cannot access 'd': No such file or directory


The result is the same.
So, whichever we use, after it is assigned to the variable "compiler",
it forgets the origin of the spaces.


If we really want to preserve the passed arguments,
we need to use "$@" directly in scripts/gcc-version.sh
like this:

MAJOR=$(echo __GNUC__ | "$@" -E -x c - | tail -n 1)

If we do this,

  scripts/gcc-version.sh  ccache gcc

will succeed, and

  scripts/gcc-version.sh  "ccache gcc"

will fail.




> > +
> > +if ! ( echo $first_line | grep -q "GNU ld"); then
> > + echo 0
> > + exit 1
> > +fi
> > +
> > +# Distributions may append an extra string like 2.35-15.fc33
> > +# Take the part that consists of numbers and dots.
> > +VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> > 's/^\(^[0-9.]*\).*/\1/')
> > +MAJOR=$(echo $VERSION | cut -d . -f 1)
> > +MINOR=$(echo $VERSION | cut -d . -f 2)
> > +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
> > +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
>
> There is a bug if there is no dot at all (e.g. if binutils ever releases
> a version 3 and call it version 3 and not 3.0, the script would print
> 30303 because cut when no delimiter is found always returns the whole
> string)
> This can be fixed by artificially appending a dot to VERSION:
> VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> 's/^\(^[0-9.]*\).*/\1./')
>
> I'm not sure it's worth worrying about either.

Ah, good catch.



--
Best Regards
Masahiro Yamada


RE: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-12 Thread David Laight
From: Masahiro Yamada
> Sent: 12 December 2020 16:55
> 
> This script was written in awk in spite of the file extension '.sh'.
> Rewrite it as a shell script.
...
> +#
> +# Usage: $ ./scripts/ld-version.sh ld
> +#
> +# Print the linker version of `ld' in a 5 or 6-digit form
> +# such as `23501' for GNU ld 2.35.1 etc.
> +
> +first_line="$($* --version | head -n 1)"
> +
> +if ! ( echo $first_line | grep -q "GNU ld"); then
> + echo 0
> + exit 1
> +fi
> +
> +# Distributions may append an extra string like 2.35-15.fc33
> +# Take the part that consists of numbers and dots.
> +VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> 's/^\(^[0-9.]*\).*/\1/')
> +MAJOR=$(echo $VERSION | cut -d . -f 1)
> +MINOR=$(echo $VERSION | cut -d . -f 2)
> +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
> +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL


H.
You've managed to convert an awk script into something that requires
sh, head, grep, sed (twice), and cut (thrice).
Plus (probably) a few sub-shells.

It is quite ease to do it all in all in the shell.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-12 Thread kernel test robot
Hi Masahiro,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on kbuild/for-next arm64/for-next/core linus/master 
v5.10-rc7 next-20201211]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-amigaone_defconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/0eab60f5e1f804528a4d0dd9566cb30f62242d22
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
git checkout 0eab60f5e1f804528a4d0dd9566cb30f62242d22
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   /bin/sh: 1: [: -ge: unexpected operator
>> /bin/sh: 1: [: -lt: unexpected operator

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-12 Thread kernel test robot
Hi Masahiro,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on kbuild/for-next arm64/for-next/core linus/master 
v5.10-rc7 next-20201211]
[cannot apply to mmarek/misc]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc64-randconfig-r014-20201213 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 
84c09ab44599ece409e4e19761288ddf796fceec)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc64 cross compiling tool for clang build
# apt-get install binutils-powerpc64-linux-gnu
# 
https://github.com/0day-ci/linux/commit/0eab60f5e1f804528a4d0dd9566cb30f62242d22
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
git checkout 0eab60f5e1f804528a4d0dd9566cb30f62242d22
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross 
ARCH=powerpc64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> /bin/sh: 1: [: -ge: unexpected operator
   /bin/sh: 1: [: -lt: unexpected operator
--
>> /bin/sh: 1: [: -ge: unexpected operator
--
>> /bin/sh: 1: [: -ge: unexpected operator

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-12 Thread kernel test robot
Hi Masahiro,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on kbuild/for-next arm64/for-next/core linus/master 
v5.10-rc7 next-20201211]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-tqm8xx_defconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/0eab60f5e1f804528a4d0dd9566cb30f62242d22
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Masahiro-Yamada/kbuild-do-not-use-scripts-ld-version-sh-for-checking-spatch-version/20201213-010621
git checkout 0eab60f5e1f804528a4d0dd9566cb30f62242d22
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> /bin/sh: 1: [: -ge: unexpected operator
   /bin/sh: 1: [: -lt: unexpected operator
--
>> /bin/sh: 1: [: -ge: unexpected operator
--
>> /bin/sh: 1: [: -ge: unexpected operator

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH 3/3] kbuild: rewrite ld-version.sh in shell script

2020-12-12 Thread Dominique Martinet
Masahiro Yamada wrote on Sun, Dec 13, 2020:
> This script was written in awk in spite of the file extension '.sh'.
> Rewrite it as a shell script.

Wow! I wasn't expecting so much, would have sent some rework after the
upcoming merge window.
Thank you.

Some comments below that you can probably ignore, this works for me.


> diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh
> index 0f8a2c0f9502..c214aeb3200d 100755
> --- a/scripts/ld-version.sh
> +++ b/scripts/ld-version.sh
> @@ -1,11 +1,22 @@
> -#!/usr/bin/awk -f
> +#!/bin/sh
>  # SPDX-License-Identifier: GPL-2.0
> -# extract linker version number from stdin and turn into single number
> - {
> - gsub(".*\\)", "");
> - gsub(".*version ", "");
> - gsub("-.*", "");
> - split($1,a, ".");
> - print a[1]*1 + a[2]*100 + a[3];
> - exit
> - }
> +#
> +# Usage: $ ./scripts/ld-version.sh ld
> +#
> +# Print the linker version of `ld' in a 5 or 6-digit form
> +# such as `23501' for GNU ld 2.35.1 etc.
> +
> +first_line="$($* --version | head -n 1)"

Just nitpicking: this ($*) would fail if the argument contains spaces,
it's generally better to use "$@" or "$1" (with quotes)

Probably doesn't matter here as gcc/clang-version scripts have the same
problem, so if someone had a problem with that they probably would have
reported it there.

> +
> +if ! ( echo $first_line | grep -q "GNU ld"); then
> + echo 0
> + exit 1
> +fi
> +
> +# Distributions may append an extra string like 2.35-15.fc33
> +# Take the part that consists of numbers and dots.
> +VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
> 's/^\(^[0-9.]*\).*/\1/')
> +MAJOR=$(echo $VERSION | cut -d . -f 1)
> +MINOR=$(echo $VERSION | cut -d . -f 2)
> +PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
> +printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL

There is a bug if there is no dot at all (e.g. if binutils ever releases
a version 3 and call it version 3 and not 3.0, the script would print
30303 because cut when no delimiter is found always returns the whole
string)
This can be fixed by artificially appending a dot to VERSION:
VERSION=$(echo $first_line | sed 's/.* \([^ ]*\)$/\1/' | sed 
's/^\(^[0-9.]*\).*/\1./')

I'm not sure it's worth worrying about either.


Thanks again,
-- 
Dominique