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: david.aldr...@emea.nec.com > To: help-make@gnu.org > 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 > Help-make@gnu.org > https://lists.gnu.org/mailman/listinfo/help-make _______________________________________________ Help-make mailing list Help-make@gnu.org https://lists.gnu.org/mailman/listinfo/help-make