How to switch behaviour according to glibc version?

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

How to switch behaviour according to glibc version?

David Aldrich-4
Hi

I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application that requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19 so my makefile checks the host o/s and, if it's Ubuntu, it links to my private copy of glibc 2.22:

GLIBC_FLAGS=
ifeq ($(DISTRO),debian)
    echo "Warning: detected Ubuntu o/s so using different glibc to that installed on this system"
    GLIBC=$(MY_OPEN_SOURCE_LIBS)/glibc/v2_22/
    GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/nptl\
    -Wl,--dynamic-linker=${GLIBC}/elf/ld.so
endif

Now, Ubuntu 16.04 has glibc 2.23, so there I can use the standard glibc packaged for the o/s.  So I want to change the makefile code to only use my private copy of glibc if glibc is <2.22.

I'm not sure whether it's best to detect the o/s version or the glibc version.  I can do the latter with:

~$ ldd --version
ldd (Ubuntu GLIBC 2.23-0ubuntu2) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

My question is, how can I extract the glibc version number from that ldd response and use it in my makefile to only set GLIBC and GLIBC_FLAGS if the glibc version is <2.22?

Best regards

David

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

David Boyce
This is primarily a shell coding question, not a make question. Once you've
worked out how to do it at the shell level you can wrap the result in the
$(shell ...) make function and, assuming proper escaping, it will work the
same. It looks to me like the version is the last word of the first line,
thus

% ldd --version | head -1 | awk '{print $NF}'
2.12

Though you could probably avoid the head -1 with smarter use of awk, perl,
etc. I have a make function for comparing dotted version numbers:

# Compares two dotted numeric strings (e.g 2.3.16.1) for $1 >= $2
define version_ge
$(findstring TRUE,$(shell bash -c 'sort -cu -t. -k1,1nr -k2,2nr -k3,3nr
-k4,4nr <(echo -e "$2\n$1") 2>&1 || echo TRUE'))
endef

Sample usage:

verstr := $(shell <command line such as above>)
ifeq ($(call version_ge,$(verstr),2.22),TRUE)
   # the version is sufficient
endif

FWIW glibc has a trick such that you can also execute it directly to get
the version number:

% /lib/libc.so.6 | head -1
GNU C Library stable release version 2.12, by Roland McGrath et al.

But ldd --version will almost certainly always agree with that and may be
easier to use.

> I'm not sure whether it's best to detect the o/s version or the glibc
version

If it's the glibc version that matters, it's almost always better to check
the glibc version. If you ever need to port to another glibc platform the
difference will matter.

-David B

On Tue, Apr 5, 2016 at 1:54 AM, David Aldrich <[hidden email]>
wrote:

> Hi
>
> I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application that
> requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19 so my
> makefile checks the host o/s and, if it's Ubuntu, it links to my private
> copy of glibc 2.22:
>
> GLIBC_FLAGS=
> ifeq ($(DISTRO),debian)
>     echo "Warning: detected Ubuntu o/s so using different glibc to that
> installed on this system"
>     GLIBC=$(MY_OPEN_SOURCE_LIBS)/glibc/v2_22/
>     GLIBC_FLAGS=
> -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/nptl\
>     -Wl,--dynamic-linker=${GLIBC}/elf/ld.so
> endif
>
> Now, Ubuntu 16.04 has glibc 2.23, so there I can use the standard glibc
> packaged for the o/s.  So I want to change the makefile code to only use my
> private copy of glibc if glibc is <2.22.
>
> I'm not sure whether it's best to detect the o/s version or the glibc
> version.  I can do the latter with:
>
> ~$ ldd --version
> ldd (Ubuntu GLIBC 2.23-0ubuntu2) 2.23
> Copyright (C) 2016 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> Written by Roland McGrath and Ulrich Drepper.
>
> My question is, how can I extract the glibc version number from that ldd
> response and use it in my makefile to only set GLIBC and GLIBC_FLAGS if the
> glibc version is <2.22?
>
> Best regards
>
> David
>
> _______________________________________________
> Help-make mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-make
>
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

David Aldrich-4
Hi David

Thanks for your answer to my question. I have one outstanding problem. Part of the makefile is now:

ifeq ($(DISTRO),debian)
  verstr := $(ldd --version | head -1 | awk '{print $NF}')
  @echo glibc $(verstr) detected
  ifneq ($(call version_ge,$(verstr),2.22),TRUE)
    @echo "Warning: system glibc is incompatible with Zodiac so using glibc from OPEN_SOURCE_LIBS"
    GLIBC=$(OPEN_SOURCE_LIBS)/glibc/v2_22/
    GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/n$
  endif
endif

For the first echo statement I get:

Makefile:236: *** missing separator. Stop.

Please can you suggest how I should correct that line?

Best regards

David
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

David Boyce
Makefiles are divided between make syntax and shell (recipe) syntax. Here
you're trying to use a shell command (echo) in a place that's not a recipe.
Replace it with $(warning ...) which is the make-syntax equivalent.

On Tue, Apr 5, 2016 at 9:24 AM, David Aldrich <[hidden email]>
wrote:

> Hi David
>
> Thanks for your answer to my question. I have one outstanding problem.
> Part of the makefile is now:
>
> ifeq ($(DISTRO),debian)
>   verstr := $(ldd --version | head -1 | awk '{print $NF}')
>   @echo glibc $(verstr) detected
>   ifneq ($(call version_ge,$(verstr),2.22),TRUE)
>     @echo "Warning: system glibc is incompatible with Zodiac so using
> glibc from OPEN_SOURCE_LIBS"
>     GLIBC=$(OPEN_SOURCE_LIBS)/glibc/v2_22/
>     GLIBC_FLAGS=
> -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/n$
>   endif
> endif
>
> For the first echo statement I get:
>
> Makefile:236: *** missing separator. Stop.
>
> Please can you suggest how I should correct that line?
>
> Best regards
>
> David
>
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

David Aldrich-4
Hi David

Thanks again for your help. However, I’m not quite there yet.

If I do:

verstr := $(shell ldd --version | head -1)
$(info glibc $(verstr) detected)

I see:

glibc ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19 detected

But if I do:

verstr := $(shell ldd --version | head -1 | awk '{print $NF}')
$(info glibc $(verstr) detected)

I see:

glibc  detected

So there is something wrong with the awk command. It works ok from the command line but not in the makefile.  Might the apostrophes be the problem?

Best regards

David


From: [hidden email] [mailto:[hidden email]] On Behalf Of David Boyce
Sent: 05 April 2016 18:36
To: David Aldrich <[hidden email]>
Cc: [hidden email]
Subject: Re: How to switch behaviour according to glibc version?

Makefiles are divided between make syntax and shell (recipe) syntax. Here you're trying to use a shell command (echo) in a place that's not a recipe. Replace it with $(warning ...) which is the make-syntax equivalent.

On Tue, Apr 5, 2016 at 9:24 AM, David Aldrich <[hidden email]<mailto:[hidden email]>> wrote:
Hi David

Thanks for your answer to my question. I have one outstanding problem. Part of the makefile is now:

ifeq ($(DISTRO),debian)
  verstr := $(ldd --version | head -1 | awk '{print $NF}')
  @echo glibc $(verstr) detected
  ifneq ($(call version_ge,$(verstr),2.22),TRUE)
    @echo "Warning: system glibc is incompatible with Zodiac so using glibc from OPEN_SOURCE_LIBS"
    GLIBC=$(OPEN_SOURCE_LIBS)/glibc/v2_22/
    GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/n$
  endif
endif

For the first echo statement I get:

Makefile:236: *** missing separator. Stop.

Please can you suggest how I should correct that line?

Best regards

David



Click here<https://www.mailcontrol.com/sr/djoNe5tCM8vGX2PQPOmvUnFKm77zQC2t99wVyMYG!KKWuh2fJJLnxEddCKX4K9u8Yv98euDengeTKOxjbsImtQ==> to report this email as spam.
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

Paul Smith-20
On Wed, 2016-04-06 at 09:46 +0000, David Aldrich wrote:

> But if I do:
>
> verstr := $(shell ldd --version | head -1 | awk '{print $NF}')
> $(info glibc $(verstr) detected)
>
> I see:
>
> glibc  detected
>
> So there is something wrong with the awk command. It works ok from the
> command line but not in the makefile.  Might the apostrophes be the
> problem?

You have to always escape all "$" you want to pass through to a shell,
either in a recipe or a variable or a $(shell ...) function call.  All
instances of single "$" are expanded by make as variables or functions,
before it invokes the shell.

So, write:

  verstr := $(shell ldd --version | head -1 | awk '{print $$NF}')
                                                          ^^

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

David Aldrich-4
> So, write:
>
>   verstr := $(shell ldd --version | head -1 | awk '{print $$NF}')

Thanks Paul, that worked fine.

David
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

Yann Droneaud
In reply to this post by David Aldrich-4
Le mardi 05 avril 2016 à 08:54 +0000, David Aldrich a écrit :
> Hi
>
> I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application
> that requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19
> so my makefile checks the host o/s and, if it's Ubuntu, it links to
> my private copy of glibc 2.22:
>

How can "make" could build a C++ application that depends on glibc 2.22
when your system only have glibc 2.19 ?

It feels like you're doing something complicated which could be
avoided.

Regards.

-- 
Yann Droneaud
OPTEYA


_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

David Aldrich-4
> How can "make" could build a C++ application that depends on glibc 2.22 when
> your system only have glibc 2.19 ?

glibc 2.19 has a bug that is critical for us. I don't want to upgrade the version of the system's glibc because that could break other applications. I have a copy of glibc 2.22 that we use just for linking our application.

David
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

Bob Proulx
David Aldrich wrote:
> glibc 2.19 has a bug that is critical for us. I don't want to
> upgrade the version of the system's glibc because that could break
> other applications. I have a copy of glibc 2.22 that we use just for
> linking our application.

Instead of doing either the usual thing in these cases is to create a
replacement function with the correct behavior.  Then test if the
system library has the problem and use the included code if it does.
If not then use the system library.  That would be much better.

Since you say the bug (which you haven't described) is already
corrected in a later glibc version then you can simply use the code
from the later version verbatim.  No need to write any actual code for
this yourself since it already exists.

Bob

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

rakesh sharma
In reply to this post by David Aldrich-4
With GNU Make, we can implement a fairly effective version check mechanism.

# *-*-* vim settings *-*-*# :set list ts=3# inspired from:#     a) J. Cumming make book#    b ) O'Reilly Mecklenburg make book.#    c ) Paul Smith GNU Make author.

SHELL := /bin/sh
NULL := ONE := 1
SPC := $(NULL) $(NULL)TAB := $(NULL)   $(NULL)DOT := .
 TRUE := $(ONE)FALSE := $(NULL)
VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0
[0-9] := 0 1 2 3 4 5 6 7 8 9
X16 := X X X XX16 += $(X16)X16 += $(X16)
define MAX_INT$(strip \ $(foreach i,$(X16),              \ $(foreach j,$(X16),           \ $(foreach k,$(X16),$(X16)))))endef
# $(call encode,$1) converts a number to that many number of Xsencode = $(wordlist 1,$1,$(MAX_INT))
# $(call boolify,$1) converts string to booleandefine boolify$(strip \ $(if $1,                                   \ $(if $(filter $1,$(VALID_FALSE_VALUES)),\ $(FALSE),                            \ $(TRUE)),                            \ $(FALSE)))endef
# $(call not,$1) invert the sense of a booleandefine not$(strip \ $(if $(call boolify,$1),\ $(FALSE),            \ $(TRUE)))endef
# $(call bool2num,$1) converts boolean to numberbool2num = $(words $(call boolify,$1))
# $(call streq,$1,$2) string comparestreq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))
# $(call max,$1,$2) maximum of two numbersdefine max$(strip \ $(words                    \ $(subst XX,X,           \ $(join               \ $(call encode,$1),\ $(call encode,$2)))))endef
# $(call gt,$1,$2) greater of two numbersgt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))
define strip_leading_0s$(strip \ $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \ $(if $(patsubst 0%,%,$1),                     \ $(patsubst 0%,%,$1),                       \ 0),                                        \ $(call strip_leading_0s,$(patsubst 00%,0%,$1))))endef
# $(call eq,$1,$2) compares equality of two numbersdefine eq$(strip \ $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\ $(TRUE),\ $(FALSE)))endef
# $(call cmp,$1,$2) compare two numbersdefine cmp$(strip \ $(if $(call eq,$1,$2),   \ 0,                    \ $(if $(call gt,$1,$2),\ 1,                 \ -1)))endef
# $(call v2w,$1) splits version string into its componentsv2w = $(subst $(DOT),$(SPC),$1)
# $(call msd_ver,version_string)msd_ver = $(word 1,$(call v2w,$1))
# $(call remd_ver,version_string)remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))
pack = $(subst $(SPC),$(NULL),$1)
# $(call _unpack,$1,$2)define _unpack$(strip \ $(if $(word 2,$1),                                 \ $(call _unpack,                                 \ $(wordlist 2,$(words $1),$1),                \ $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\ $(subst $1,$1 ,$2)))endef
# $(call unpack,$1)unpack = $(call _unpack,$([0-9]),$1)
strlen = $(words $(call unpack,$1))
msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))
rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))
define _norm_minor$(strip \ $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\ $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\ $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\ $(call strip_leading_0s,$1)))))endef
# $(call norm_minor,$1) normalize the minor version number incase of major.minor onlydefine norm_minor$(strip \ $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\ $(call _norm_minor,$1),                                       \ $(call _norm_minor,$1).0))endef
define _normalize_ver$(strip \$(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\ $(call strip_leading_0s,$1)))endef
define normalize_ver$(strip \$(if $(word 3,$(call v2w,$1)),\ $(call _normalize_ver,$1),\ $(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\ $(call strip_leading_0s,$1).0.0)))endef
# $(call _cmpver,verstringA,verstringB)define _cmpver$(strip \ $(if $(call msd_ver,$1),                                            \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \ $(if $(call remd_ver,$1)$(call remd_ver,$2),               \ $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\ 0),                                                     \ $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \ $(if $(call eq,$(call msd_ver,$1),0),                         \ $(if $(call remd_ver,$1),                                  \ $(call _cmpver,$(call remd_ver,$1),),                   \ 0),                                                     \ 1)),                                                       \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$2),0),                         \ $(if $(call remd_ver,$2),                                  \ $(call _cmpver,,$(call remd_ver,$2)),                   \ 0),                                                     \ -1))))endef
# $(call cmpver,verstringA,verstringB)cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))
# $(call version_ge,verstringA,verstringB)version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))


#i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300#i := 5.2.3000123#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002#i := 0.0002.1.002423.42343242.0000000#i := 2.3#i := 43#i := 2 02 002 20 200 0 00 000 0000 000000000000#########################

> From: [hidden email]
> To: [hidden email]
> Subject: How to switch behaviour according to glibc version?
> Date: Tue, 5 Apr 2016 08:54:01 +0000
>
> Hi
>
> I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application that requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19 so my makefile checks the host o/s and, if it's Ubuntu, it links to my private copy of glibc 2.22:
>
> GLIBC_FLAGS=
> ifeq ($(DISTRO),debian)
>     echo "Warning: detected Ubuntu o/s so using different glibc to that installed on this system"
>     GLIBC=$(MY_OPEN_SOURCE_LIBS)/glibc/v2_22/
>     GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/nptl\
>     -Wl,--dynamic-linker=${GLIBC}/elf/ld.so
> endif
>
> Now, Ubuntu 16.04 has glibc 2.23, so there I can use the standard glibc packaged for the o/s.  So I want to change the makefile code to only use my private copy of glibc if glibc is <2.22.
>
> I'm not sure whether it's best to detect the o/s version or the glibc version.  I can do the latter with:
>
> ~$ ldd --version
> ldd (Ubuntu GLIBC 2.23-0ubuntu2) 2.23
> Copyright (C) 2016 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> Written by Roland McGrath and Ulrich Drepper.
>
> My question is, how can I extract the glibc version number from that ldd response and use it in my makefile to only set GLIBC and GLIBC_FLAGS if the glibc version is <2.22?
>
> Best regards
>
> David
>
> _______________________________________________
> Help-make mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-make
     
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

rakesh sharma
I am re-posting since the newlines are not working properly in the site:

# *-*-* vim settings *-*-*# :set list ts=3
SHELL := /bin/sh
NULL := ONE := 1
SPC := $(NULL) $(NULL)TAB := $(NULL)   $(NULL)DOT := .
 TRUE := $(ONE)FALSE := $(NULL)
VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0
[0-9] := 0 1 2 3 4 5 6 7 8 9
X16 := X X X XX16 += $(X16)X16 += $(X16)
define MAX_INT$(strip \ $(foreach i,$(X16),              \ $(foreach j,$(X16),           \ $(foreach k,$(X16),$(X16)))))endef
# $(call encode,$1) converts a number to that many number of Xsencode = $(wordlist 1,$1,$(MAX_INT))
# $(call boolify,$1) converts string to booleandefine boolify$(strip \ $(if $1,                                   \ $(if $(filter $1,$(VALID_FALSE_VALUES)),\ $(FALSE),                            \ $(TRUE)),                            \ $(FALSE)))endef
# $(call not,$1) invert the sense of a booleandefine not$(strip \ $(if $(call boolify,$1),\ $(FALSE),            \ $(TRUE)))endef
# $(call bool2num,$1) converts boolean to numberbool2num = $(words $(call boolify,$1))
# $(call streq,$1,$2) string comparestreq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))
# $(call max,$1,$2) maximum of two numbersdefine max$(strip \ $(words                    \ $(subst XX,X,           \ $(join               \ $(call encode,$1),\ $(call encode,$2)))))endef
# $(call gt,$1,$2) greater of two numbersgt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))
define strip_leading_0s$(strip \ $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \ $(if $(patsubst 0%,%,$1),                     \ $(patsubst 0%,%,$1),                       \ 0),                                        \ $(call strip_leading_0s,$(patsubst 00%,0%,$1))))endef
# $(call eq,$1,$2) compares equality of two numbersdefine eq$(strip \ $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\ $(TRUE),\ $(FALSE)))endef
# $(call cmp,$1,$2) compare two numbersdefine cmp$(strip \ $(if $(call eq,$1,$2),   \ 0,                    \ $(if $(call gt,$1,$2),\ 1,                 \ -1)))endef
# $(call v2w,$1) splits version string into its componentsv2w = $(subst $(DOT),$(SPC),$1)
# $(call msd_ver,version_string)msd_ver = $(word 1,$(call v2w,$1))
# $(call remd_ver,version_string)remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))
pack = $(subst $(SPC),$(NULL),$1)
# $(call _unpack,$1,$2)define _unpack$(strip \ $(if $(word 2,$1),                                 \ $(call _unpack,                                 \ $(wordlist 2,$(words $1),$1),                \ $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\ $(subst $1,$1 ,$2)))endef
# $(call unpack,$1)unpack = $(call _unpack,$([0-9]),$1)
strlen = $(words $(call unpack,$1))
msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))
rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))
define _norm_minor$(strip \ $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\ $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\ $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\ $(call strip_leading_0s,$1)))))endef
# $(call norm_minor,$1) normalize the minor version number incase of major.minor onlydefine norm_minor$(strip \ $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\ $(call _norm_minor,$1),                                       \ $(call _norm_minor,$1).0))endef
define _normalize_ver$(strip \$(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\ $(call strip_leading_0s,$1)))endef
define normalize_ver$(strip \$(if $(word 3,$(call v2w,$1)),\ $(call _normalize_ver,$1),\ $(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\ $(call strip_leading_0s,$1).0.0)))endef
# $(call _cmpver,verstringA,verstringB)define _cmpver$(strip \ $(if $(call msd_ver,$1),                                            \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \ $(if $(call remd_ver,$1)$(call remd_ver,$2),               \ $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\ 0),                                                     \ $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \ $(if $(call eq,$(call msd_ver,$1),0),                         \ $(if $(call remd_ver,$1),                                  \ $(call _cmpver,$(call remd_ver,$1),),                   \ 0),                                                     \ 1)),                                                       \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$2),0),                         \ $(if $(call remd_ver,$2),                                  \ $(call _cmpver,,$(call remd_ver,$2)),                   \ 0),                                                     \ -1))))endef
# $(call cmpver,verstringA,verstringB)cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))
# $(call version_ge,verstringA,verstringB)version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))
BASELINE_GLIBC_VER := 2.22
#i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300#i := 5.2.3000123#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002#i := 0.0002.1.002423.42343242.0000000#i := 2.3#i := 43#i := 2 02 002 20 200 0 00 000 0000 000000000000##########################


> From: [hidden email]
> To: [hidden email]
> Subject: RE: How to switch behaviour according to glibc version?
> Date: Thu, 14 Apr 2016 11:10:22 +0000
>
> With GNU Make, we can implement a fairly effective version check mechanism.
>
> # *-*-* vim settings *-*-*# :set list ts=3# inspired from:#     a) J. Cumming make book#    b ) O'Reilly Mecklenburg make book.#    c ) Paul Smith GNU Make author.
>
> SHELL := /bin/sh
> NULL := ONE := 1
> SPC := $(NULL) $(NULL)TAB := $(NULL)   $(NULL)DOT := .
>  TRUE := $(ONE)FALSE := $(NULL)
> VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0
> [0-9] := 0 1 2 3 4 5 6 7 8 9
> X16 := X X X XX16 += $(X16)X16 += $(X16)
> define MAX_INT$(strip \ $(foreach i,$(X16),              \ $(foreach j,$(X16),           \ $(foreach k,$(X16),$(X16)))))endef
> # $(call encode,$1) converts a number to that many number of Xsencode = $(wordlist 1,$1,$(MAX_INT))
> # $(call boolify,$1) converts string to booleandefine boolify$(strip \ $(if $1,                                   \ $(if $(filter $1,$(VALID_FALSE_VALUES)),\ $(FALSE),                            \ $(TRUE)),                            \ $(FALSE)))endef
> # $(call not,$1) invert the sense of a booleandefine not$(strip \ $(if $(call boolify,$1),\ $(FALSE),            \ $(TRUE)))endef
> # $(call bool2num,$1) converts boolean to numberbool2num = $(words $(call boolify,$1))
> # $(call streq,$1,$2) string comparestreq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))
> # $(call max,$1,$2) maximum of two numbersdefine max$(strip \ $(words                    \ $(subst XX,X,           \ $(join               \ $(call encode,$1),\ $(call encode,$2)))))endef
> # $(call gt,$1,$2) greater of two numbersgt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))
> define strip_leading_0s$(strip \ $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \ $(if $(patsubst 0%,%,$1),                     \ $(patsubst 0%,%,$1),                       \ 0),                                        \ $(call strip_leading_0s,$(patsubst 00%,0%,$1))))endef
> # $(call eq,$1,$2) compares equality of two numbersdefine eq$(strip \ $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\ $(TRUE),\ $(FALSE)))endef
> # $(call cmp,$1,$2) compare two numbersdefine cmp$(strip \ $(if $(call eq,$1,$2),   \ 0,                    \ $(if $(call gt,$1,$2),\ 1,                 \ -1)))endef
> # $(call v2w,$1) splits version string into its componentsv2w = $(subst $(DOT),$(SPC),$1)
> # $(call msd_ver,version_string)msd_ver = $(word 1,$(call v2w,$1))
> # $(call remd_ver,version_string)remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))
> pack = $(subst $(SPC),$(NULL),$1)
> # $(call _unpack,$1,$2)define _unpack$(strip \ $(if $(word 2,$1),                                 \ $(call _unpack,                                 \ $(wordlist 2,$(words $1),$1),                \ $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\ $(subst $1,$1 ,$2)))endef
> # $(call unpack,$1)unpack = $(call _unpack,$([0-9]),$1)
> strlen = $(words $(call unpack,$1))
> msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))
> rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))
> define _norm_minor$(strip \ $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\ $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\ $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\ $(call strip_leading_0s,$1)))))endef
> # $(call norm_minor,$1) normalize the minor version number incase of major.minor onlydefine norm_minor$(strip \ $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\ $(call _norm_minor,$1),                                       \ $(call _norm_minor,$1).0))endef
> define _normalize_ver$(strip \$(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\ $(call strip_leading_0s,$1)))endef
> define normalize_ver$(strip \$(if $(word 3,$(call v2w,$1)),\ $(call _normalize_ver,$1),\ $(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\ $(call strip_leading_0s,$1).0.0)))endef
> # $(call _cmpver,verstringA,verstringB)define _cmpver$(strip \ $(if $(call msd_ver,$1),                                            \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \ $(if $(call remd_ver,$1)$(call remd_ver,$2),               \ $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\ 0),                                                     \ $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \ $(if $(call eq,$(call msd_ver,$1),0),                         \ $(if $(call remd_ver,$1),                                  \ $(call _cmpver,$(call remd_ver,$1),),                   \ 0),                                                     \ 1)),                                                       \ $(if $(call msd_ver,$2),                                         \ $(if $(call eq,$(call msd_ver,$2),0),                         \ $(if $(call remd_ver,$2),                                  \ $(call _cmpver,,$(call remd_ver,$2)),                   \ 0),                                                     \ -1))))endef
> # $(call cmpver,verstringA,verstringB)cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))
> # $(call version_ge,verstringA,verstringB)version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))
>
>
> #i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300#i := 5.2.3000123#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002#i := 0.0002.1.002423.42343242.0000000#i := 2.3#i := 43#i := 2 02 002 20 200 0 00 000 0000 000000000000#########################
>
> > From: [hidden email]
> > To: [hidden email]
> > Subject: How to switch behaviour according to glibc version?
> > Date: Tue, 5 Apr 2016 08:54:01 +0000
> >
> > Hi
> >
> > I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application that requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19 so my makefile checks the host o/s and, if it's Ubuntu, it links to my private copy of glibc 2.22:
> >
> > GLIBC_FLAGS=
> > ifeq ($(DISTRO),debian)
> >     echo "Warning: detected Ubuntu o/s so using different glibc to that installed on this system"
> >     GLIBC=$(MY_OPEN_SOURCE_LIBS)/glibc/v2_22/
> >     GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/nptl\
> >     -Wl,--dynamic-linker=${GLIBC}/elf/ld.so
> > endif
> >
> > Now, Ubuntu 16.04 has glibc 2.23, so there I can use the standard glibc packaged for the o/s.  So I want to change the makefile code to only use my private copy of glibc if glibc is <2.22.
> >
> > I'm not sure whether it's best to detect the o/s version or the glibc version.  I can do the latter with:
> >
> > ~$ ldd --version
> > ldd (Ubuntu GLIBC 2.23-0ubuntu2) 2.23
> > Copyright (C) 2016 Free Software Foundation, Inc.
> > This is free software; see the source for copying conditions.  There is NO
> > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> > Written by Roland McGrath and Ulrich Drepper.
> >
> > My question is, how can I extract the glibc version number from that ldd response and use it in my makefile to only set GLIBC and GLIBC_FLAGS if the glibc version is <2.22?
> >
> > Best regards
> >
> > David
> >
> > _______________________________________________
> > Help-make mailing list
> > [hidden email]
> > https://lists.gnu.org/mailman/listinfo/help-make
>      
> _______________________________________________
> Help-make mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-make
     
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

RE: How to switch behaviour according to glibc version?

Cook, Malcolm-2
In reply to this post by David Aldrich-4
Then compare it to your desired version using sort -V

But only if you have a more recent version of gnu sort

Heh,

Malcolm

-----Original Message-----
From: help-make-bounces+mec=[hidden email] [mailto:help-make-bounces+mec=[hidden email]] On Behalf Of David Aldrich
Sent: Wednesday, April 06, 2016 7:01 AM
To: [hidden email]
Cc: [hidden email]
Subject: RE: How to switch behaviour according to glibc version?

> So, write:
>
>   verstr := $(shell ldd --version | head -1 | awk '{print $$NF}')

Thanks Paul, that worked fine.

David
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: How to switch behaviour according to glibc version?

Rakesh Sharma-6
In reply to this post by rakesh sharma


# *-*-* vim settings *-*-*

# :set list ts=3



SHELL := /bin/sh



NULL :=

 ONE := 1



SPC := $(NULL) $(NULL)

TAB := $(NULL)   $(NULL)

DOT := .



 TRUE := $(ONE)

FALSE := $(NULL)



VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0



[0-9] := 0 1 2 3 4 5 6 7 8 9



X16 := X X X X

X16 += $(X16)

X16 += $(X16)



define MAX_INT

$(strip \

        $(foreach i,$(X16),              \

                $(foreach j,$(X16),           \

                        $(foreach k,$(X16),$(X16)))))

endef


# $(call encode,$1) converts a number to that many number of Xs

encode = $(wordlist 1,$1,$(MAX_INT))



# $(call boolify,$1) converts string to boolean

define boolify

$(strip \

        $(if $1,                                   \

                $(if $(filter $1,$(VALID_FALSE_VALUES)),\

                        $(FALSE),                            \

                        $(TRUE)),                            \

                $(FALSE)))

endef



# $(call not,$1) invert the sense of a boolean

define not

$(strip \

        $(if $(call boolify,$1),\

                $(FALSE),            \

                $(TRUE)))

endef



# $(call bool2num,$1) converts boolean to number

bool2num = $(words $(call boolify,$1))



# $(call streq,$1,$2) string compare

streq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))



# $(call max,$1,$2) maximum of two numbers

define max

$(strip \

        $(words                    \

                $(subst XX,X,           \

                        $(join               \

                                $(call encode,$1),\

                                $(call encode,$2)))))

endef



# $(call gt,$1,$2) greater of two numbers

gt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))



define strip_leading_0s

$(strip \

        $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \

                $(if $(patsubst 0%,%,$1),                     \

                        $(patsubst 0%,%,$1),                       \

                        0),                                        \

                $(call strip_leading_0s,$(patsubst 00%,0%,$1))))

endef



# $(call eq,$1,$2) compares equality of two numbers

define eq

$(strip \

        $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\

                $(TRUE),\

                $(FALSE)))

endef



# $(call cmp,$1,$2) compare two numbers

define cmp

$(strip \

        $(if $(call eq,$1,$2),   \

                0,                    \

                $(if $(call gt,$1,$2),\

                        1,                 \

                        -1)))

endef



.PHONY: all

all:; @:



# $(call concat,:,a b c d e)

define concat

$(if $(word 2,$2),                                                 \

        $(firstword $2)$1$(call concat,$1,$(wordlist 2,$(words $2),$2)),\

        $2)

endef



# $(call v2w,$1) splits version string into its components

v2w = $(subst $(DOT),$(SPC),$1)



# $(call msd_ver,version_string)

msd_ver = $(word 1,$(call v2w,$1))



# $(call remd_ver,version_string)

remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))



pack = $(subst $(SPC),$(NULL),$1)



# $(call _unpack,$1,$2)

define _unpack

$(strip \

        $(if $(word 2,$1),                                 \

                $(call _unpack,                                 \

                        $(wordlist 2,$(words $1),$1),                \

                        $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\

                $(subst $1,$1 ,$2)))

endef



# $(call unpack,$1)

unpack = $(call _unpack,$([0-9]),$1)



strlen = $(words $(call unpack,$1))



msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))



rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))



define _norm_minor

$(strip \

        $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\

                $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\

                        $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\

                                $(call strip_leading_0s,$1)))))

endef



# $(call norm_minor,$1) normalize the minor version number incase of major.minor only

define norm_minor

$(strip \

        $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\

        $(call _norm_minor,$1),                                       \

        $(call _norm_minor,$1).0))

endef



define _normalize_ver

$(strip \

$(if $(word 2,$(call v2w,$1)),\

        $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\

        $(call strip_leading_0s,$1)))

endef



define normalize_ver

$(strip \

$(if $(word 3,$(call v2w,$1)),\

        $(call _normalize_ver,$1),\

        $(if $(word 2,$(call v2w,$1)),\

                $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\

                $(call strip_leading_0s,$1).0.0)))

endef



# $(call _cmpver,verstringA,verstringB)

define _cmpver

$(strip \

        $(if $(call msd_ver,$1),                                            \

                $(if $(call msd_ver,$2),                                         \

                        $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \

                                $(if $(call remd_ver,$1)$(call remd_ver,$2),               \

                                        $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\

                                        0),                                                     \

                                $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \

                        $(if $(call eq,$(call msd_ver,$1),0),                         \

                                $(if $(call remd_ver,$1),                                  \

                                        $(call _cmpver,$(call remd_ver,$1),),                   \

                                        0),                                                     \

                                1)),                                                       \

                $(if $(call msd_ver,$2),                                         \

                        $(if $(call eq,$(call msd_ver,$2),0),                         \

                                $(if $(call remd_ver,$2),                                  \

                                        $(call _cmpver,,$(call remd_ver,$2)),                   \

                                        0),                                                     \

                                -1))))

endef



# $(call cmpver,verstringA,verstringB)

cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))



# $(call ver_ge,verstringA,verstringB)

version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))



BASELINE_GLIBC_VER := 2.22



verstr := $(word 3,$(shell ldd --version))

$(info glibc $(verstr) detected)

ifeq ("$(call version_ge,$(verstr),$(BASELINE_GLIBC_VER))","$(TRUE)")

$(info "Warning: system glibc is incompatible with Zodiac so using glibc from OPEN_SOURCE_LIBS")

endif



#i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300

#i := 5.2.3000123

#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002

#i := 0.0002.1.002423.42343242.0000000

#i := 2.3

#i := 43

#i := 2 02 002 20 200 0 00 000 0000 000000000000



________________________________________
From: Help-make <help-make-bounces+sharma__r=[hidden email]> on behalf of rakesh sharma <[hidden email]>
Sent: Thursday, April 14, 2016 7:11 AM
To: [hidden email]
Subject: RE: How to switch behaviour according to glibc version?

I am re-posting since the newlines are not working properly in the site:

# *-*-* vim settings *-*-*# :set list ts=3
SHELL := /bin/sh
NULL := ONE := 1
SPC := $(NULL) $(NULL)TAB := $(NULL)   $(NULL)DOT := .
 TRUE := $(ONE)FALSE := $(NULL)
VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0
[0-9] := 0 1 2 3 4 5 6 7 8 9
X16 := X X X XX16 += $(X16)X16 += $(X16)
define MAX_INT$(strip \ $(foreach i,$(X16),              \              $(foreach j,$(X16),           \                 $(foreach k,$(X16),$(X16)))))endef
# $(call encode,$1) converts a number to that many number of Xsencode = $(wordlist 1,$1,$(MAX_INT))
# $(call boolify,$1) converts string to booleandefine boolify$(strip \  $(if $1,                                   \            $(if $(filter $1,$(VALID_FALSE_VALUES)),\                       $(FALSE),                            \                  $(TRUE)),                            \          $(FALSE)))endef
# $(call not,$1) invert the sense of a booleandefine not$(strip \       $(if $(call boolify,$1),\               $(FALSE),            \          $(TRUE)))endef
# $(call bool2num,$1) converts boolean to numberbool2num = $(words $(call boolify,$1))
# $(call streq,$1,$2) string comparestreq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))
# $(call max,$1,$2) maximum of two numbersdefine max$(strip \   $(words                    \            $(subst XX,X,           \                       $(join               \                          $(call encode,$1),\                             $(call encode,$2)))))endef
# $(call gt,$1,$2) greater of two numbersgt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))
define strip_leading_0s$(strip \        $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \              $(if $(patsubst 0%,%,$1),                     \                 $(patsubst 0%,%,$1),                       \                    0),                                        \            $(call strip_leading_0s,$(patsubst 00%,0%,$1))))endef
# $(call eq,$1,$2) compares equality of two numbersdefine eq$(strip \   $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\                $(TRUE),\               $(FALSE)))endef
# $(call cmp,$1,$2) compare two numbersdefine cmp$(strip \      $(if $(call eq,$1,$2),   \              0,                    \         $(if $(call gt,$1,$2),\                 1,                 \                    -1)))endef
# $(call v2w,$1) splits version string into its componentsv2w = $(subst $(DOT),$(SPC),$1)
# $(call msd_ver,version_string)msd_ver = $(word 1,$(call v2w,$1))
# $(call remd_ver,version_string)remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))
pack = $(subst $(SPC),$(NULL),$1)
# $(call _unpack,$1,$2)define _unpack$(strip \  $(if $(word 2,$1),                                 \            $(call _unpack,                                 \                       $(wordlist 2,$(words $1),$1),                \                  $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\          $(subst $1,$1 ,$2)))endef
# $(call unpack,$1)unpack = $(call _unpack,$([0-9]),$1)
strlen = $(words $(call unpack,$1))
msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))
rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))
define _norm_minor$(strip \     $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\         $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\                   $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\                            $(call strip_leading_0s,$1)))))endef
# $(call norm_minor,$1) normalize the minor version number incase of major.minor onlydefine norm_minor$(strip \ $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\ $(call _norm_minor,$1),                                       \ $(call _norm_minor,$1).0))endef
define _normalize_ver$(strip \$(if $(word 2,$(call v2w,$1)),\   $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\   $(call strip_leading_0s,$1)))endef
define normalize_ver$(strip \$(if $(word 3,$(call v2w,$1)),\    $(call _normalize_ver,$1),\     $(if $(word 2,$(call v2w,$1)),\         $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\         $(call strip_leading_0s,$1).0.0)))endef
# $(call _cmpver,verstringA,verstringB)define _cmpver$(strip \  $(if $(call msd_ver,$1),                                            \           $(if $(call msd_ver,$2),                                         \                      $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \                         $(if $(call remd_ver,$1)$(call remd_ver,$2),               \                                    $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\                                       0),                                                     \                               $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \                    $(if $(call eq,$(call msd_ver,$1),0),                         \                         $(if $(call remd_ver,$1),                                  \                                    $(call _cmpver,$(call remd_ver,$1),),                   \                                       0),                                                     \                               1)),                                                       \            $(if $(call msd_ver,$2),                                         \                      $(if $(call eq,$(call msd_ver,$2),0),                         \                         $(if $(call remd_ver,$2),                                  \                                    $(call _cmpver,,$(call remd_ver,$2)),                   \                                       0),                                                     \                               -1))))endef
# $(call cmpver,verstringA,verstringB)cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))
# $(call version_ge,verstringA,verstringB)version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))
BASELINE_GLIBC_VER := 2.22
#i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300#i := 5.2.3000123#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002#i := 0.0002.1.002423.42343242.0000000#i := 2.3#i := 43#i := 2 02 002 20 200 0 00 000 0000 000000000000##########################


> From: [hidden email]
> To: [hidden email]
> Subject: RE: How to switch behaviour according to glibc version?
> Date: Thu, 14 Apr 2016 11:10:22 +0000
>
> With GNU Make, we can implement a fairly effective version check mechanism.
>
> # *-*-* vim settings *-*-*# :set list ts=3# inspired from:#     a) J. Cumming make book#    b ) O'Reilly Mecklenburg make book.#    c ) Paul Smith GNU Make author.
>
> SHELL := /bin/sh
> NULL := ONE := 1
> SPC := $(NULL) $(NULL)TAB := $(NULL)   $(NULL)DOT := .
>  TRUE := $(ONE)FALSE := $(NULL)
> VALID_FALSE_VALUES := 0 -0 0. $(NULL) 0.0
> [0-9] := 0 1 2 3 4 5 6 7 8 9
> X16 := X X X XX16 += $(X16)X16 += $(X16)
> define MAX_INT$(strip \       $(foreach i,$(X16),              \              $(foreach j,$(X16),           \                 $(foreach k,$(X16),$(X16)))))endef
> # $(call encode,$1) converts a number to that many number of Xsencode = $(wordlist 1,$1,$(MAX_INT))
> # $(call boolify,$1) converts string to booleandefine boolify$(strip \        $(if $1,                                   \            $(if $(filter $1,$(VALID_FALSE_VALUES)),\                       $(FALSE),                            \                  $(TRUE)),                            \          $(FALSE)))endef
> # $(call not,$1) invert the sense of a booleandefine not$(strip \     $(if $(call boolify,$1),\               $(FALSE),            \          $(TRUE)))endef
> # $(call bool2num,$1) converts boolean to numberbool2num = $(words $(call boolify,$1))
> # $(call streq,$1,$2) string comparestreq = $(call not,$(subst x$1,$(NULL),x$2)$(subst x$2,$(NULL),x$1))
> # $(call max,$1,$2) maximum of two numbersdefine max$(strip \ $(words                    \            $(subst XX,X,           \                       $(join               \                          $(call encode,$1),\                             $(call encode,$2)))))endef
> # $(call gt,$1,$2) greater of two numbersgt = $(call boolify,$(filter-out $2,$(call max,$1,$2)))
> define strip_leading_0s$(strip \      $(if $(call streq,$(patsubst 00%,0%,$1),$1),     \              $(if $(patsubst 0%,%,$1),                     \                 $(patsubst 0%,%,$1),                       \                    0),                                        \            $(call strip_leading_0s,$(patsubst 00%,0%,$1))))endef
> # $(call eq,$1,$2) compares equality of two numbersdefine eq$(strip \ $(if $(filter $(call strip_leading_0s,$1),$(call strip_leading_0s,$2)),\                $(TRUE),\               $(FALSE)))endef
> # $(call cmp,$1,$2) compare two numbersdefine cmp$(strip \    $(if $(call eq,$1,$2),   \              0,                    \         $(if $(call gt,$1,$2),\                 1,                 \                    -1)))endef
> # $(call v2w,$1) splits version string into its componentsv2w = $(subst $(DOT),$(SPC),$1)
> # $(call msd_ver,version_string)msd_ver = $(word 1,$(call v2w,$1))
> # $(call remd_ver,version_string)remd_ver = $(wordlist 2,$(words $(call v2w,$1)),$(call v2w,$1))
> pack = $(subst $(SPC),$(NULL),$1)
> # $(call _unpack,$1,$2)define _unpack$(strip \        $(if $(word 2,$1),                                 \            $(call _unpack,                                 \                       $(wordlist 2,$(words $1),$1),                \                  $(subst $(word 1,$1),$(word 1,$1)$(SPC),$2)),\          $(subst $1,$1 ,$2)))endef
> # $(call unpack,$1)unpack = $(call _unpack,$([0-9]),$1)
> strlen = $(words $(call unpack,$1))
> msd3 = $(call pack,$(wordlist 1,3,$(call unpack,$1)))
> rest = $(call pack,$(wordlist 4,$(words $(call unpack,$1)),$(call unpack,$1)))
> define _norm_minor$(strip \   $(if $(call gt,$(call strlen,$1),3),$(call strip_leading_0s,$(call msd3,$1))$(DOT)$(call _norm_minor,$(call rest,$1)),\         $(if $(call eq,$(call strlen,$1),1),$(call strip_leading_0s,$(1)00),\                   $(if $(call eq,$(call strlen,$1),2),$(call strip_leading_0s,$(1)0),\                            $(call strip_leading_0s,$1)))))endef
> # $(call norm_minor,$1) normalize the minor version number incase of major.minor onlydefine norm_minor$(strip \       $(if $(call gt,$(words $(call v2w,$(call _norm_minor,$1))),1),\ $(call _norm_minor,$1),                                       \ $(call _norm_minor,$1).0))endef
> define _normalize_ver$(strip \$(if $(word 2,$(call v2w,$1)),\ $(call strip_leading_0s,$(call msd_ver,$1))$(DOT)$(call _normalize_ver,$(call remd_ver,$1)),\   $(call strip_leading_0s,$1)))endef
> define normalize_ver$(strip \$(if $(word 3,$(call v2w,$1)),\  $(call _normalize_ver,$1),\     $(if $(word 2,$(call v2w,$1)),\         $(call strip_leading_0s,$(word 1,$(call v2w,$1))).$(call norm_minor,$(word 2,$(call v2w,$1))),\         $(call strip_leading_0s,$1).0.0)))endef
> # $(call _cmpver,verstringA,verstringB)define _cmpver$(strip \        $(if $(call msd_ver,$1),                                            \           $(if $(call msd_ver,$2),                                         \                      $(if $(call eq,$(call msd_ver,$1),$(call msd_ver,$2)),        \                         $(if $(call remd_ver,$1)$(call remd_ver,$2),               \                                    $(call _cmpver,$(call remd_ver,$1),$(call remd_ver,$2)),\                                       0),                                                     \                               $(call cmp,$(call msd_ver,$1),$(call msd_ver,$2))),        \                    $(if $(call eq,$(call msd_ver,$1),0),                         \                         $(if $(call remd_ver,$1),                                  \                                    $(call _cmpver,$(call remd_ver,$1),),                   \                                       0),                                                     \                               1)),                                                       \            $(if $(call msd_ver,$2),                                         \                      $(if $(call eq,$(call msd_ver,$2),0),                         \                         $(if $(call remd_ver,$2),                                  \                                    $(call _cmpver,,$(call remd_ver,$2)),                   \                                       0),                                                     \                               -1))))endef
> # $(call cmpver,verstringA,verstringB)cmpver = $(call _cmpver,$(call normalize_ver,$1),$(call normalize_ver,$2))
> # $(call version_ge,verstringA,verstringB)version_ge = $(if $(call eq,$(call cmpver,$2,$1),1),$(FALSE),$(TRUE))
>
>
> #i := 002 2 2.3 2.3.0 2.03 2.03.2 2.03.0 04.3 004.03 04.3.2 04.3.0 5.2.300#i := 5.2.3000123#i := 0.2 0.02 0.00002 0.00002.1 0.00002.0 0.00002#i := 0.0002.1.002423.42343242.0000000#i := 2.3#i := 43#i := 2 02 002 20 200 0 00 000 0000 000000000000#########################
>
> > From: [hidden email]
> > To: [hidden email]
> > Subject: How to switch behaviour according to glibc version?
> > Date: Tue, 5 Apr 2016 08:54:01 +0000
> >
> > Hi
> >
> > I am running gnu make 4.1 on Ubuntu.  Make builds my C++ application that requires glibc 2.22 or higher.  Ubuntu 14.04 has only glibc 2.19 so my makefile checks the host o/s and, if it's Ubuntu, it links to my private copy of glibc 2.22:
> >
> > GLIBC_FLAGS=
> > ifeq ($(DISTRO),debian)
> >     echo "Warning: detected Ubuntu o/s so using different glibc to that installed on this system"
> >     GLIBC=$(MY_OPEN_SOURCE_LIBS)/glibc/v2_22/
> >     GLIBC_FLAGS= -Wl,-rpath=${GLIBC}:${GLIBC}/math:${GLIBC}/elf:${GLIBC}/dlfcn:${GLIBC}/nss:${GLIBC}/nis:${GLIBC}/rt:${GLIBC}/resolv:${GLIBC}/crypt:${GLIBC}/nptl\
> >     -Wl,--dynamic-linker=${GLIBC}/elf/ld.so
> > endif
> >
> > Now, Ubuntu 16.04 has glibc 2.23, so there I can use the standard glibc packaged for the o/s.  So I want to change the makefile code to only use my private copy of glibc if glibc is <2.22.
> >
> > I'm not sure whether it's best to detect the o/s version or the glibc version.  I can do the latter with:
> >
> > ~$ ldd --version
> > ldd (Ubuntu GLIBC 2.23-0ubuntu2) 2.23
> > Copyright (C) 2016 Free Software Foundation, Inc.
> > This is free software; see the source for copying conditions.  There is NO
> > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> > Written by Roland McGrath and Ulrich Drepper.
> >
> > My question is, how can I extract the glibc version number from that ldd response and use it in my makefile to only set GLIBC and GLIBC_FLAGS if the glibc version is <2.22?
> >
> > Best regards
> >
> > David
> >
> > _______________________________________________
> > Help-make mailing list
> > [hidden email]
> > https://lists.gnu.org/mailman/listinfo/help-make
>
> _______________________________________________
> Help-make mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-make

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make