В make файле я хотел бы определить переменную, определяющую, превышает ли текущий redhat-release более 5,3. (Эта переменная будет передана gcc как #define)
Ответ 3
Я понимаю, что это старый вопрос, но все же. На самом деле вы можете прибегнуть к lsb_release
, который, как мне показалось, установлен в каждой недавней системе RedHat.
Чтобы быть точным, вы использовали
lsb_release -sr
внутри $(shell ...)
, а затем разделите на .
следующим образом:
RH_VER:=$(shell lsb_release -sr)
RH_MAJVER:=$(word 1, $(subst ., ,$(RH_VER)))
RH_MINVER:=$(word 2, $(subst ., ,$(RH_VER)))
теперь у вас есть основные/второстепенные части версии выпуска, и вы можете проверить это против того, что вам нравится.
Классическим случаем будет $(filter ...)
, а другая текстовые функции, которые GNU make предоставляет.
Тем не менее я согласен с тем, что какой-то a config.h
будет иметь больше смысла, хотя Autotools ни в коем случае не идеален для всех сценариев (есть другие инструменты сборки, которые пытаются одинаково, хотя).
Ответ 4
Немного короче решение:
RH_GT_5_3 := $(shell echo -e "5.4\n$(RH_VER_NUM)"|sort -ct. -k1,1n -k2,2n && echo YES)
Это установит RH_GT_5_3 в "YES", если RH_VER_NUM больше или равно 5.4 (так больше 5.3). В противном случае RH_GT_5_3 будет пустым.
Если необходимо проверить несколько номеров версий, мы можем определить функцию:
IF_VER_GE = $(shell echo -e "$2\n$1"|sort -ct. -k1,1n -k2,2n && echo YES)
GLIBC := $(word 2,$(shell getconf GNU_LIBC_VERSION))
...
all:
ifeq "$(call IF_VER_GE, $(GLIBC), 2.5)" "YES"
echo "GE"
else
echo "LT"
endif
Я использовал "$ (слово 2,..." вместо "$ (lastword,...", потому что позже не работает в make 3.8. И короче...
... некоторые эоны позже
Я попытался решить сравнение версий с внутренними функциями makefile. Я нашел проект (GNU Make Standard Library (GMSL)), который добавляет include в make файл, который реализует целочисленную арифметику. К сожалению, общая система унарная численная система. Но сравнение номеров версий сложнее. Когда я работал с версиями с номерами больше 100_000, я решил реализовать более общее решение. Он работает с произвольным количеством номеров подрывных операций с произвольными цифрами. Некоторые идеи были заимствованы из проекта GMSL
Он реализует функцию ver.lt. Он возвращает "T", если номер первой версии меньше второй. Он возвращает пустую строку в противном случае. Конечно, числа подрывной деятельности сравниваются численно не лексикографически. Таким образом, 1.20 больше 1,3. Есть некоторые проблемы. 1,2 < 1.2.0, 1.0.1 < 1,00,1, 1,9,1 1.01.1 (так как ожидается, что число начинается с ненулевой цифры, кроме самого 0). Я не хочу сейчас их решать.
Решение
Это testAed под gnu make 3.82.90. Есть несколько очень длинных строк, поскольку makefile добавляет пробелы, если используется '\'. Я оставил некоторые реализованные, но не используемые функции в коде. Возможно, я бы использовал лучшие временные имена переменных (например, GMSL использует _gmsl). Иногда временные переменные могут быть остановлены, но код будет более загадочным.
.SILENT:
S :=
SP := $S $S
# For non empty strings
#not = $(if $1,$S,T)
#str.ne = $(if $(subst $1,,$2),T,$S)
str.eq = $(if $(subst $1,,$2),$S,T)
str.le = $(call str.eq,$(word 1,$(sort $1 $2)),$1)
#str.ge = $(call str.eq,$(word 1,$(sort $1 $2)),$2)
# Creates a list of digits from a number
mklist = $(eval __tmp := $1)$(foreach i,0 1 2 3 4 5 6 7 8 9,$(eval __tmp := $$(subst $$i,$$i ,$(__tmp))))$(__tmp)
# reverse: $(subst $(SP),,$(list))
#pop = $(wordlist 2, $(words $1), x $1)
#push = $1 $2
shift = $(wordlist 2, $(words $1), $1)
#unshift = $2 $1
num.le = $(eval __tmp1 := $(call mklist,$1))$(eval __tmp2 := $(call mklist,$2))$(if $(call str.eq,$(words $(__tmp1)),$(words $(__tmp2))),$(call str.le,$1,$2),$(call str.le,$(words $(__tmp1)),$(words $(__tmp2))))
#num.ge = $(eval __tmp1 := $(call mklist,$1))$(eval __tmp2 := $(call mklist,$2))$(if $(call str.eq,$(words $(__tmp1)),$(words $(__tmp2))),$(call str.ge,$1,$2),$(call str.ge,$(words $(__tmp1)),$(words $(__tmp2))))
#Strip zeroes from the beginning of a list
list.strip = $(eval __flag := 1)$(foreach d,$1,$(if $(__flag),$(if $(subst 0,,$d),$(eval __flag :=)$d,$S),$d))
#Strip zeroes from the beginning of a number
#num.strip = $(subst $(SP),,$(call list.strip,$(call mklist,$1)))
# temp string: 0 - two number equals, L first LT, G first GT or second is short,
gen.cmpstr = $(eval __Tmp1 := $(subst ., ,$1))$(eval __Tmp2 := $(subst ., ,$2))$(foreach i,$(__Tmp1),$(eval j := $(word 1,$(__Tmp2)))$(if $j,$(if $(call str.eq,$i,$j),0,$(if $(call num.le,$i,$j),L,G)),G)$(eval __Tmp2 := $$(call shift,$(__Tmp2))))$(if $(__Tmp2), L)
ver.lt = $(call str.eq,$(word 1,$(call list.strip,$(call gen.cmpstr,$1,$2))),L)
all:
echo ver.lt,1.20,1.3:$(call ver.lt,1.20,1.3)%
echo ver.lt,1.5.9,1.5:$(call ver.lt,1.5.9,1.5)%
echo ver.lt,1.4.9,1.5:$(call ver.lt,1.4.9,1.5)%
echo ver.lt,1.2,1.2.0:$(call ver.lt,1.2,1.2.0)%
echo ver.lt,1.20.3.4.5,1.10.5:$(call ver.lt,1.20.3.4.5,1.10.5)%
echo ver.lt,1.20.3.4.5,1.0.5:$(call ver.lt,1.20.3.4.5,1.0.5)%
echo ver.lt,1.0,1.0.5:$(call ver.lt,1.0,1.0.5)%
echo ver.lt,1.20,1.10.3:$(call ver.lt,1.20,1.10.3)%
echo ver.lt,1.20,1.30.3::$(call ver.lt,1.20,1.30.3)%
echo ver.lt,1.10.3,1.10.3:$(call ver.lt,1.10.3,1.10.3)%
И вывод
ver.lt,1.20,1.3:%
ver.lt,1.5.9,1.5:%
ver.lt,1.4.9,1.5:T%
ver.lt,1.2,1.2.0:T%
ver.lt,1.20.3.4.5,1.10.5:%
ver.lt,1.20.3.4.5,1.0.5:%
ver.lt,1.0,1.0.5:T%
ver.lt,1.20,1.10.3:%
ver.lt,1.20,1.30.3::T%
ver.lt,1.10.3,1.10.3:%
Больше музыки
Я нашел еще один интересный проект под названием makepp (makepp.sourceforge.net). Он позволяет реализовать новые функции в perl внутри make файла.