Makefile ifeq 논리적 또는


94

make ifeq연산자를 사용하여 논리 OR을 어떻게 수행 합니까?

예를 들어, (간체) :

ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

그러나 이러한 라인을 통합하고 싶습니다.

(예, 예, autotools, 구성 등; 현재 상황에 비해 너무 무거워서 여기에서 Makefile 내의 모든 것을 유지하고 싶습니다)

[이 질문의 논리적 반대 : 'ifeq'문에서 다중 조건을 사용하는 방법 ]



1
속임수라고 생각하지 마세요. 연결된 질문은 연결 ifdef연산자와 관련이 있습니다.이 질문은 연결 ifeq연산자 와 관련이 있습니다 . 비슷하지만 대답은 확실히 다릅니다.
Pat

답변:


104

메일 링리스트 아카이브에서 볼 수 있듯이

필터 기능을 사용할 수 있습니다 .

예를 들면

 ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))

필터 X, ABX와 동일한 A, B의 항목을 반환합니다.

이것의 변형은

 ifneq (,$(filter $(GCC_MINOR),4 5))

대신 빈 문자열에 대한 음의 비교가 사용됩니다 ( GCC_MINOR이 인수와 일치하지 않으면 필터 는 빈 문자열을 반환합니다).

이러한 메서드의 단점은 인수가 한 단어 여야한다는 것입니다.


7
후기 참고 : 위의 두 가지 변형에서 $ (GCC_MINOR)이 비어 있으면 첫 번째는 참으로 해결되지만 두 번째는 그렇지 않습니다 (일반적으로 두 번째가 더 나은 솔루션입니다).
John

1
실제로는되어야합니다 ifneq (,$(filter 4 5,$(GCC_MINOR))):)
Tuxdude

2
단순성을 위해 그대로 두는 것이 더 낫습니까?
제이슨

또 다른 참고 : 이것은 일반적인 OR 문 으로 작동하지 않습니다 . 우리는 우리가 확인하고 싶은 것이 있습니다 if(flagA == TRUE || flagB == true). 그러나 만약 당신이 $(filter true, $(flagA) $(flagB)그리고 둘 다 사실이라면 당신은 얻을 수 있습니다ifeq(true, true true)
Charlie Su

27

다른 변수를 도입 할 수 있습니다. 두 수표를 모두 통합하지는 않지만 적어도 본문을 두 번 넣을 필요가 없습니다.

do_it = 
ifeq ($(GCC_MINOR), 4)
    do_it = yes
endif
ifeq ($(GCC_MINOR), 5)
    do_it = yes
endif
ifdef do_it
    CFLAGS += -fno-strict-overflow
endif

7
규모에서 이것의 유지 보수성은 나에게별로 좋지 않은 것 같습니다 : / 다시 한번 우리가 규모에 대해 이야기하기 시작하면, 나는 우리가 autotools에 대해 이야기하고있는 것 같아요
Pat

2
@Pat : 저는 Makefile의 한 위치에서 할당을 분리 할 수있는이 방법을 선호합니다. 라인을 읽기 어렵게 만드는 필터 함수를 사용하는 것보다 ifeq / else ifeq / else를 사용하여 더 많은 값과 비교할 수 있습니다. .
jcarballo

15

간결하고 현명한 방법은 없다고 생각하지만 장황하고 현명한 방법 (예 : Foo Bah 's)과 간결하고 병리적인 방법이 있습니다.

ifneq (,$(findstring $(GCC_MINOR),4-5))
    CFLAGS += -fno-strict-overflow
endif

(문자열 $ (GCC_MINOR)이 문자열 4-5 안에 나타나면 명령을 실행합니다).


4
좋든 나쁘 든 (아마 나쁘게) 내가 찾던 더러운 해킹의 종류 일 뿐이다. 감사합니다
Pat

1
Makefile의 모든 것이 병적 이라는 사실 외에는 이것이 전혀 병적이라고 생각하지 않습니다 . 정말 우아합니다. 이를 달성하기 위해 4 ~ 5 개의 다른 방법을 읽었으며 귀하의 방법이 이해하기 가장 쉽습니다.
Michael Geary

8

더 유연한 변형 : 외부 셸을 사용하지만 임의의 조건을 확인할 수 있습니다.

ifeq ($(shell test ".$(GCC_MINOR)" = .4  -o  \
                   ".$(GCC_MINOR)" = .5  -o  \
                   ".$(TODAY)"     = .Friday  &&  printf "true"), true)
    CFLAGS += -fno-strict-overflow
endif

1
ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

이 경우 사용할 수있는 또 다른 방법은 다음과 같습니다.

GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -c "^gcc version (4.[2-9]|[5-9])")

# -Wstrict-overflow: http://www.airs.com/blog/archives/120
ifeq ($(GCC42_OR_LATER),1)
  CFLAGS += -Wstrict-overflow
endif

나는 별도의 config또는 을 유지하고 싶지 않기 때문에 실제로 내 코드에서 동일하게 사용합니다 Configure.

하지만 makeGNU make ( gmake) 와 같은 휴대용 비 빈혈을 사용해야하며 Posix의 make.

그리고 논리적 ANDOR.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.