타겟별 make 변수

타겟별 make 변수

타겟별 변수를 강제로 즉시 설정하는 방법(라인 2)? 내가 원하는 결과는 maketo releasemake debugto be 입니다 debug.

X = release
debug: X = debug
debug: all

# the rest is included from an external file; cannot be changed
Y := $(X)
BUILD := $(Y)

all:
    @echo $(BUILD)

답변1

문제는 GNUMake가 파일을 구문 분석하는 방식으로 인해 발생합니다.

GNU make는 두 가지 별개의 단계로 작동합니다. 첫 번째 단계에서는 모든 메이크파일, 포함된 메이크파일 등을 읽고 모든 변수와 해당 값, 암시적 및 명시적 규칙을 내부화하고 모든 대상과 전제 조건의 종속성 그래프를 작성합니다. 두 번째 단계에서 make는 이러한 내부 구조를 사용하여 재구축해야 할 대상을 결정하고 이를 수행하는 데 필요한 규칙을 호출합니다.

메이크파일 읽기

make debug종속성을 실행하면 all:마치 실행한 것처럼 값이 인쇄되는 것처럼 보입니다 make all. 당신이 해야 할 일은 all둘 다 debug동일한 종속성을 트리거하도록 makefile을 수정하는 것입니다. 일반적으로 다음과 같은 내용이 표시됩니다.

all: $(executable)
debug: $(executable)
$(executable): $(objs)
    <compile objects to executable>

debug절대로 실행되지 않지만 all두 경우 모두 실행 파일을 컴파일합니다.

귀하의 코드는 다음과 같습니다.

X = release

debug: X = debug

Y = $(X)
BUILD = $(Y)

.PHONY: print
print:
        @echo $(BUILD)

all: print
debug: print

생성되는 실제 개체가 아니기 때문에 가짜 종속성을 인쇄해야 했습니다. 그렇지 않으면 이것이 debug둘 다 필요 all하지만 설정한 플래그에 따라 다르게 컴파일되는 종속성이 됩니다 .

답변2

Y그리고 BUILD변수는단순 확장 변수:=( 대신 =)을 사용하여 할당되므로 다음을 참조하세요.수동더 많은 정보를 알고 싶습니다. 기본적으로 변수에는 값이 할당됩니다.변수가 정의되면, 이는 당신이 하고 싶은 일을 하지 못하게 방해합니다.

그러나 대상별 변수는 전역 변수보다 우선해야 하므로 이를 재정의하면 BUILD대상 범위에서 전역 변수가 숨겨지기 때문에 작동합니다.BUILDdebug:all:

X = release
debug: BUILD = debug
debug: all

Y := $(X)
BUILD := $(Y)

all:
    @echo $(BUILD)

converse를 사용하면 그 자체로는 확장 변수일 뿐이므로 debug: Y = debug작동하지 않습니다 .BUILD

왜 이런 것이 debug: X := debug작동하지 않는지 정확히 이해할 수 없습니다. 그런데 대상 특정 변수는 전역 단순 확장 변수 이후에 해결된 것 같습니다. 이는 타겟별 BUILD변수가 내 솔루션에서 전역 변수를 가릴 수 있는 이유이기도 합니다 .


@jecxjo의 답변이 부분적으로 잘못되었습니다. 재정의 Y(또는) 할당을 방지하는 것은 해당 항목이 사용되지만 할당되지 않는다는 BUILD것입니다 . 즉, 초기 코드는 정확히 원하는 것이 아닌 다음 을 사용합니다.:===:=

X = release
debug: X = debug
debug: all

# Note the '=' assignment instead of the ':='
Y = $(X)
BUILD = $(Y)

all:
    @echo $(BUILD)

이것은 실제로 재작성 대상이 아니라 문제를 해결하는 그의 답변 변경입니다. 그러나 이러한 할당이 편집할 수 없는 다른 파일에 포함되어 있다고 언급하셨기 때문에 이는 해결책이 아닙니다.

관련 정보