[shell] 명령 출력을 Makefile 변수에 지정하는 방법

설치된 Python이 특정 버전 (예 : 2.5)보다 큰 경우에만 일부 make 규칙을 조건부로 실행해야합니다.

나는 실행과 같은 것을 할 수 있다고 생각했다.

python -c 'import sys; print int(sys.version_info >= (2,5))'

그런 다음 ifeqmake 문 에서 출력 (확인 인 경우 ‘1’, 그렇지 않으면 ‘0’)을 사용합니다.

간단한 bash 쉘 스크립트에서는 다음과 같습니다.

MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'`

그러나 그것은 Makefile에서 작동하지 않습니다.

어떤 제안? 나는 이것을 달성하기 위해 다른 합리적인 해결책을 사용할 수 있습니다.



답변

다음 shell과 같이 Make 내장 기능을 사용하십시오.MY_VAR=$(shell echo whatever)

me@Zack:~$make
MY_VAR IS whatever

me@Zack:~$ cat Makefile 
MY_VAR := $(shell echo whatever)

all:
    @echo MY_VAR IS $(MY_VAR)


답변

과제를 포장하는 eval것이 나를 위해 일하고 있습니다.

# dependency on .PHONY prevents Make from 
# thinking there's `nothing to be done`
set_opts: .PHONY
  $(eval DOCKER_OPTS = -v $(shell mktemp -d -p /scratch):/output)


답변

다음은 레시피 내부에 배관 및 변수 할당을 사용하는 좀 더 복잡한 예입니다.

getpodname:
    # Getting pod name
    @eval $$(minikube docker-env) ;\
    $(eval PODNAME=$(shell sh -c "kubectl get pods | grep profile-posts-api | grep Running" | awk '{print $$1}'))
    echo $(PODNAME)


답변

문제를 해결하는 실제 구문에 대한 가시성을 높이는 답변을 작성 중입니다. 불행히도, 누군가가 사소한 것으로 볼 수있는 것은 합리적인 질문에 대한 간단한 답변을 찾는 사람에게는 매우 심각한 두통이 될 수 있습니다.

다음을 “Makefile”파일에 넣으십시오.

MY_VAR := $(shell python -c 'import sys; print int(sys.version_info >= (2,5))')

all:
    @echo MY_VAR IS $(MY_VAR)

보고 싶은 동작은 다음과 같습니다 (최근에 파이썬이 설치되어 있다고 가정).

make
MY_VAR IS 1

위의 텍스트를 복사하여 Makefile에 붙여 넣으면 얻을 수 있습니까? 아마 아닙니다. 여기에보고 된 것과 같은 오류가 발생할 수 있습니다.

makefile : 4 : *** 구분 기호가 없습니다. 중지

이유 : 개인적으로 정품 탭을 사용했지만 스택 오버플로 (도움이 되려고 시도 함)는 탭을 여러 공백으로 변환합니다. 좌절 한 인터넷 시민 여러분, 이제 여러분이 제가 사용한 것과 같은 텍스트를 가지고 있다고 생각하면서 이것을 복사하십시오. make 명령은 이제 공백을 읽고 “all”명령의 형식이 잘못되었음을 발견합니다. 따라서 위의 텍스트를 복사하여 붙여 넣은 다음 “@echo”앞의 공백을 탭으로 변환하면이 예제가 도움이 될 것입니다.


답변

이와 같은 요리법을 조심하십시오

target:
    MY_ID=$(GENERATE_ID);
    echo $MY_ID;

두 가지가 잘못되었습니다. 레시피의 첫 번째 라인은 두 번째 라인과 별도의 쉘 인스턴스에서 실행됩니다. 그 동안 변수가 손실됩니다. 두 번째로 잘못된 것은 $이스케이프되지 않는다는 것입니다.

target:
    MY_ID=$(GENERATE_ID); \
    echo $$MY_ID;

두 가지 문제가 해결되었으며 변수를 사용할 수 있습니다. 백 슬래시는 두 줄을 결합하여 하나의 단일 셸에서 실행되므로 변수 설정과 변수 뒷문 읽기가 작동합니다.

원래 게시물이 쉘 명령의 결과를 MAKE 변수로 가져 오는 방법을 말 했으며이 답변은 쉘 변수로 가져 오는 방법을 보여줍니다. 그러나 다른 독자들도 도움이 될 수 있습니다.

소비자가 “환경 변수”가 설정 될 것으로 기대하는 경우 최종 개선 사항 중 하나를 내 보내야합니다.

my_shell_script
    echo $MY_ID

makefile에서 이것을 필요로 할 것입니다

target:
    export MY_ID=$(GENERATE_ID); \
    ./my_shell_script;

누군가에게 도움이되기를 바랍니다. 일반적으로 누군가가 ‘–dry-run’옵션과 함께 makefile을 사용하여 수행 할 작업 만 볼 경우 바람직하지 않은 부작용이 없기 때문에 레시피 이외의 실제 작업은 피해야합니다. 모든 $(shell)호출은 컴파일 타임에 평가되며 실수로 실수가 발생할 수 있습니다. 가능한 경우 ID 생성과 같은 실제 작업을 레시피 내부에 두는 것이 좋습니다.


답변

GNU의 메이크업으로, 당신은 사용할 수 있습니다 shelleval임의의 명령 행 호출에서 저장, 실행 및 할당 출력. 아래 예제와 사용하는 것의 차이점 :=:=할당이 한 번만 발생한다는 것입니다. 로 재귀 적으로 확장 된 변수 =는 조금 더 “게으르다”; 다른 변수에 대한 참조는 변수 자체가 참조 될 때까지 유지되며, 변수가 참조 될 때 마다 후속 재귀 확장이 발생 하며 이는 “일관되고 호출 가능하며 스 니펫”을 만드는 데 바람직합니다. 자세한 정보는 변수 설정에 대한 매뉴얼을 참조하십시오 .

# Generate a random number.
# This is not run initially.
GENERATE_ID = $(shell od -vAn -N2 -tu2 < /dev/urandom)

# Generate a random number, and assign it to MY_ID
# This is not run initially.
SET_ID = $(eval MY_ID=$(GENERATE_ID))

# You can use .PHONY to tell make that we aren't building a target output file
.PHONY: mytarget
mytarget:
# This is empty when we begin
    @echo $(MY_ID)
# This recursively expands SET_ID, which calls the shell command and sets MY_ID
    $(SET_ID)
# This will now be a random number
    @echo $(MY_ID)
# Recursively expand SET_ID again, which calls the shell command (again) and sets MY_ID (again)
    $(SET_ID)
# This will now be a different random number
    @echo $(MY_ID)


답변

아래 예제에서 Makefile 폴더 경로를 저장 LOCAL_PKG_DIR한 다음 LOCAL_PKG_DIR대상에서 변수 를 사용 했습니다.

메이크 파일 :

LOCAL_PKG_DIR := $(shell eval pwd)

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

터미널 출력 :

$ make print
/home/amrit/folder