GNU binutils, get version - Page 1
Forum section: electronics / general

author: DiTBho
author_rank: Super Contributor
timestamp: February 16, 2023, 10:47:20 am
content: So, I need to run old toolchains, and and found old binutils respond differently when queried about the versionCode:bu_v="`$ld --version 2> /dev/null | head -n1 | cut -d" " -f4`"(new)Code:bu_v="`$ld --version 2> /dev/null | head -n1 | cut -d" " -f5`"(old)is there a way to always get the same answer?(is there a better way to do it?)this stuff has to be used from a bash scriptCode:# mytc_version_get tc mipsel-unknown-linux-gnu2.21.1/4.5.3(binutils/gcc (crosscompiler))Code:# mytc_version_get bu mipsel-unknown-linux-gnu2.21.1(binutils (crosscompiler))Code:# mytc_version_get cc mipsel-unknown-linux-gnu4.5.3(gcc (crosscompiler))Code:# mytc_version_get tc2.33.1/9.3.0(binutils/gcc (host))

author: DC1MC
author_rank: Super Contributor
timestamp: February 16, 2023, 11:02:30 am
content: Post as many as possible xxxx-ld --version of your toolchains, so we can determine a logic to extract the version. I expect that in the true and tested tradition of "real-programmers" the host OS packaging system is totally ignored and these are installed from archives in different places as it seems fit and eventually added to the path.On my development machines I always pack these myself if not provided, so I can always query dpkg, but out of curiosity I've run the command on few of the toolchains installed:Code:ld --versionGNU ld (GNU Binutils for Ubuntu) 2.30arm-v5te-linux-gnueabi-ld --versionGNU ld (GNU Binutils) 2.31.1arm-ppc-linux-uclibcgnueabi-ld --versionGNU ld (crosstool-NG crosstool-ng-1.23.0) 2.28aarch64-v8a-linux-gnu-ld --versionGNU ld (GNU Binutils) 2.35So here the parsing is elementary, but I'm curious to see the variations for your toolchains. Myreally oldtoolchains are installed on a virtual Ubuntu 16.04 that is not started now.Cheers,DC1MC

author: Kalvin
author_rank: Super Contributor
timestamp: February 16, 2023, 11:03:47 am
content: Quote from: DiTBho on February 16, 2023, 10:47:20 amIf you can't force the same version output format string from different tools versions, then you could try to first parse/match some known version format. If that fails, then try to parse/match some other format etc. until the parser is able to return a valid version string.

author: DiTBho
author_rank: Super Contributor
timestamp: February 16, 2023, 11:20:56 am
content: Code:mipsel-unknown-linux-gnu-ld --versionCode:GNU ld (GNU Binutils 2.35.1 p2) 2.35.1Copyright (C) 2020 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or (at your option) a later version.This program has absolutely no warranty.Code:GNU ld (GNU Binutils) 2.21.1Copyright 2011 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or (at your option) a later version.This program has absolutely no warranty.

author: DC1MC
author_rank: Super Contributor
timestamp: February 16, 2023, 11:27:51 am
content: OK, then pipe your --version results like this, to see if we have some outliers:Code:<your toolchain component> --version | head -n 1 | tr -d ' '| cut -f 2 -d\)

author: Kalvin
author_rank: Super Contributor
timestamp: February 16, 2023, 11:36:16 am
content: The version is the last number at the end of the first line? That is pretty simple to parse with grep.For example in my system:Code:$ ld --versionGNU ld (GNU Binutils for Ubuntu) 2.38Copyright (C) 2022 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or (at your option) a later version.This program has absolutely no warranty.This oneliner will produce version number2.38:Code:$ ld --version | head -n 1 | grep -o "[^[:blank:]]*$"2.38

author: DC1MC
author_rank: Super Contributor
timestamp: February 16, 2023, 12:13:15 pm
content: Quote from: Kalvin on February 16, 2023, 11:36:16 amthis as well, now we need to see if we have some strange versions like 4.22.3/20060821 or, worse 3.35.2 20110222

author: Kalvin
author_rank: Super Contributor
timestamp: February 16, 2023, 12:18:16 pm
content: Quote from: DC1MC on February 16, 2023, 12:13:15 pmGrep is able to perform alternative matching using | operator, so it may be still possible to parse different version string formats with a single oneliner.

author: DiTBho
author_rank: Super Contributor
timestamp: February 16, 2023, 12:27:01 pm
content: @DC1MCit works!!!perfect job

author: DC1MC
author_rank: Super Contributor
timestamp: February 16, 2023, 12:37:12 pm
content: Quote from: DiTBho on February 16, 2023, 12:27:01 pmMost welcome

author: DiTBho
author_rank: Super Contributor
timestamp: February 16, 2023, 12:41:21 pm
content: Code:# ./mybuild-2023kernel-2.6.37.1(mips.32/le)tc) show toolchain versionup) script_update0) clean1) configure2) compile app3) app module4) tftp kernel@192.168.1.21:5) toolsapp_name = kernel-2.6.37.1-32bitmachine_note = revBqualified_host = { macmini-intel } ... acceptedtoolchain = mipsel-unknown-linux-gnu:2.21.1/4.5.3checking toolchain ... failed[!] panicmodule=profile/do/utils_verreason=found gcc-v4.5.3, needed gcc-v{ 4.6.0 .. 4.7.0 }This is a practical application when you want to share a kernel/firmware repo among different machines with different ecosystems, or among different ecosystems on the same machine.That check remembers me I have to select the proper toolchain version.Code: aarch64-unknown-linux-gnu-6.5.0 aarch64-unknown-linux-gnu-9.3.0 * armv5tel-softfloat-linux-gnueabi-6.5.0 * armv5tel-softfloat-linux-gnueabi-9.3.0 armv7a-unknown-linux-gnueabihf-6.5.0 armv7a-unknown-linux-gnueabihf-8.4.0 armv7a-unknown-linux-gnueabihf-9.3.0 * hppa-unknown-linux-gnu-6.5.0 hppa-unknown-linux-gnu-9.3.0 * hppa64-unknown-linux-gnu-6.5.0 hppa64-unknown-linux-gnu-9.3.0 * i686-pc-linux-gnu-4.9.4-gnat2016 i686-pc-linux-gnu-6.5.0 i686-pc-linux-gnu-7.3.1-gnat2018 i686-pc-linux-gnu-7.5.0 i686-pc-linux-gnu-8.3.1-gnat2019 i686-pc-linux-gnu-8.4.0 i686-pc-linux-gnu-9.3.0 * i686-pc-linux-gnu-10.2.0 mips-unknown-linux-gnu-4.1.2-legacy mips-unknown-linux-gnu-4.5.3-legacy mips-unknown-linux-gnu-6.5.0 mips-unknown-linux-gnu-9.3.0 * mips64-unknown-linux-gnu-6.5.0 * mips64-unknown-linux-gnu-9.3.0 mipsel-unknown-linux-gnu-4.5.3-legacy * mipsel-unknown-linux-gnu-6.5.0 mipsel-unknown-linux-gnu-9.3.0 powerpc-unknown-linux-gnu-6.5.0 powerpc-unknown-linux-gnu-9.3.0 * powerpc64-unknown-linux-gnu-9.3.0 * sparc64-unknown-linux-gnu-6.5.0 * sparc64-unknown-linux-gnu-9.3.0 x86_64-pc-linux-gnu-10.2.0 *Or ... that I have to compile the correct version of the cross-compiler

author: eutectique
author_rank: Frequent Contributor
timestamp: February 16, 2023, 05:03:42 pm
content: In case you are still interested, here are some more strings:Code:GNU ld (2.34-4ubuntu1+13ubuntu1) 2.3GNU ld (GNU Arm Embedded Toolchain 9-2020-q2-update) 2.34.0.20200428GNU ld (GNU Arm Embedded Toolchain 10.3-2021.10) 2.36.1.20210621GNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122GNU ld (Arm GNU Toolchain 12.2.MPACBTI-Bet1 (Build arm-12-mpacbti.16)) 2.39.50.20220821GNU ld (Zephyr SDK 0.15.2) 2.38The pattern seems to be "GNU ld (some text) some.number.and.more"

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 17, 2023, 11:55:16 am
content: I'd use GNU sed andld --version 2>/dev/null | sed -ne 's|^.* \([0-9][^ ]*\) *$|\1|p ; q'to print the final token on the first line that is preceded by a space and starts with a digit, and nothing else. Theqis a GNU extension, so if you use some other sed, check that it supportsqfirst.If you prefer awk,ld --version 2>/dev/null | awk 'NR > 1 { exit } NF > 1 { print $NF }'which does not require GNU awk, and works fine with other awk variants likemawk.

author: DiTBho
author_rank: Super Contributor
timestamp: February 17, 2023, 12:00:43 pm
content: Code:function toolchain_cc_get_ver(){local testlocal cc="$1"test="`$cc 1> /dev/null 2> /dev/null`"test="$?"if [ "$test" == "0" ]then#not installed"ans="?"elseans="`$cc -dumpversion 2> /dev/null`"fi#return ans}function toolchain_bu_get_ver(){local testlocal ld="$1"test="`$ld 1> /dev/null 2> /dev/null`"test="$?"if [ "$test" == "0" ]then#not installed"ans="?"elseans="`$ld --version 2> /dev/null | head -n1 | tr -d ' ' | cut -f 2 -d\)`"fi#return ans}function get_fixed(){local name=$1local value=$3local myarch=$4local content=$2if [ "*$myarch" != "*" ]thenvalue="$myarch-$value"fi# if name is not defined by ENV# then define it#echo "[$1][$2][$3][$4]"if [ "*$content" == "*" ]theneval $name=$valuefi}function get_info(){local myarch="$1"#global cc#global cc_v#global ld#global bu_v#global tc_v# echo "myarch=[$myarch]"get_fixed "cc" "$cc" "gcc" "$myarch"get_fixed "ld" "$ld" "ld" "$myarch"toolchain_cc_get_ver "$cc"cc_v="$ans"toolchain_bu_get_ver "$ld"bu_v="$ans"tc_v="$bu_v/$cc_v"}function app(){local option="$1"local myarch="$2"#global cc#global cc_v#global ld#global bu_v#global tc_vget_info "$myarch"case $option in"cc") echo "$cc_v" ;;"bu") echo "$bu_v" ;;"as") echo "$bu_v" ;;"ld") echo "$bu_v" ;;*) echo "$tc_v" ;;esac}app "$1" "$2"This is the final bash-script.needs to run it on- GNU/Linux- BSD/NetBSDg-sed is supported

author: DiTBho
author_rank: Super Contributor
timestamp: February 17, 2023, 12:32:26 pm
content: Code:function fooo(){local argc="$#" # how many args line ?local args=("$@") # args[]={arg0..argC}i=$(($argc-1))item="${args[$i]}"echo "[$item]"}test="`ld --version | head -n1`"fooo $testtest="`mips-unknown-linux-gnu-ld --version | head -n1`"fooo $testtest="`mipsel-unknown-linux-gnu-ld --version | head -n1`"fooo $testtest="`mipsle-unknown-linux-gnu-ld --version | head -n1`"fooo $testCode:[2.33.1][2.34.0][2.35.1][2.21.1]Maybe too silly (sorry), but this trick seems to work too

author: Kalvin
author_rank: Super Contributor
timestamp: February 17, 2023, 12:49:56 pm
content: Hint: It is also possible to use Bash'shere-document feature to embed a Perl/Python script straight into the Bash command file. This way it is possible to use more suitable tool for a job without external script file dependencies.For example, if parsing the version number information seems to get too complicated using basic grep and cut, it is possible to use Perl or Python do the parsing instead, and use the full potential and expressiveness of those programming languages.

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 17, 2023, 01:00:00 pm
content: Quote from: DiTBho on February 17, 2023, 12:00:43 pmBash?Code:# LastToken VARNAME COMMAND...function LastTokenOf() {declare -n thevar=$1shift 1local tokens=($(LANG=C LC_ALL=C "$@" 2>/dev/null | head -n 1))if [ ${#tokens[@]} -gt 1 ]; thenthevar="${tokens[-1]}"elif [ -z "${tokens[*]}" ]; thenthevar="none"elsethevar="unknown"fi}LastTokenOf LD_VERSION ${LD:-ld} --versionLastTokenOf GCC_VERSION $(CC:-gcc} --versionusing traditional test ([) instead of Bash-specific[[, so that it'll run even on ancient Bashes.The variable will be set to the last token on the first line, to "none" if the command is not found or it produces no output or an empty first line, or to "unknown" if the command prints a single token on its first line.

author: eutectique
author_rank: Frequent Contributor
timestamp: February 18, 2023, 07:26:32 pm
content: Just one small note for the sake of completeness, about-vversus--version. The former produces just one line with the version information, while the latter adds copyright and stuff:Code:> arm-none-eabi-ld -vGNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122> arm-none-eabi-ld --versionGNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122Copyright (C) 2021 Free Software Foundation, Inc.This program is free software; you may redistribute it under the terms ofthe GNU General Public License version 3 or (at your option) a later version.This program has absolutely no warranty.

author: Kalvin
author_rank: Super Contributor
timestamp: February 19, 2023, 01:29:04 pm
content: Here is an example of a Bash-script which is using ahere-document embedding a Python script which will parse a version number.Bash script fileparse_version.sh:Code:#!/bin/bash## parse_version.sh#PYTHON="python3"function parse_version() {local VERSIONSTR="$@"VER=$(${PYTHON} - <<EOFimport res = '$VERSIONSTR'PATTERNS = [r'\s([\d\.]+)\/[\d]+$', # 4.22.3/20060821 => 4.22.3r'\s([\d\.]+)\s[\d\.]+$', # 3.35.2 20110222 => 3.35.2r'\s([\d\.]+)\.\d{8}$', # 2.39.50.20220821 => 2.39.50r'\s([\d\.]+)$' # 2.38 => 2.38]for p in PATTERNS:m = re.search(p, s)if m is not None:# Found valid version stringv = m.group(1)print(v)exit(0)# Did not find valid version stringprint('None')exit(1)EOF)}## Run tests for the given test version strings#VERSIONS=( \"1 GNU ld (GNU Binutils for Ubuntu) 2.38" \"2 GNU ld (GNU Binutils for Ubuntu) 4.22.3/20060821" \"3 GNU ld (GNU Binutils for Ubuntu) 3.35.2 20110222" \"4 GNU ld (2.34-4ubuntu1+13ubuntu1) 2.3" \"5 GNU ld (GNU Arm Embedded Toolchain 9-2020-q2-update) 2.34.0.20200428" \"6 GNU ld (GNU Arm Embedded Toolchain 10.3-2021.10) 2.36.1.20210621" \"7 GNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122" \"8 GNU ld (Arm GNU Toolchain 12.2.MPACBTI-Bet1 (Build arm-12-mpacbti.16)) 2.39.50.20220821" \"9 GNU ld (Zephyr SDK 0.15.2) 2.38" \"10 GNU ld (Zephyr SDK 0.15.2)" \"11 GNU ld (Zephyr SDK 0.15.2) 1.2.H")for v in "${VERSIONS[@]}"; doparse_version $vecho "Exit code=$?, Version='$VER'"doneProduced output:Code:$ ./parse_version.shExit code=0, Version='2.38'Exit code=0, Version='4.22.3'Exit code=0, Version='3.35.2'Exit code=0, Version='2.3'Exit code=0, Version='2.34.0'Exit code=0, Version='2.36.1'Exit code=0, Version='2.37'Exit code=0, Version='2.39.50'Exit code=0, Version='2.38'Exit code=1, Version='None'Exit code=1, Version='None'

author: DiTBho
author_rank: Super Contributor
timestamp: February 19, 2023, 06:53:16 pm
content: WOW, impressed!Thanks you