명령 줄에서 추가 변수를 전달하여 작성


614

명령 줄 인수로 변수를 GNU Makefile에 전달할 수 있습니까? 다시 말해, 나는 Makefile에서 변수가 될 인수를 전달하고 싶다.

답변:


753

makefile 외부에서 변수를 설정하는 몇 가지 옵션이 있습니다.

  • 환경에서 -각 환경 변수는 동일한 이름과 값을 가진 makefile 변수로 변환됩니다.

    -e옵션 (aka --environments-override) 을 설정하고 싶을 수도 있으며 환경 변수는 makefile에 지정된 할당을 무시합니다 (이러한 할당 자체가 override지시문을 사용 하지 않는 한 권장되지는 않지만 할당을 사용하는 것이 훨씬 좋고 유연 ?=합니다 (조건부 변수) 대입 연산자의 경우 변수가 아직 정의되지 않은 경우에만 효과가 있습니다.)

    FOO?=default_value_if_not_set_in_environment
    

    특정 변수는 환경에서 상속되지 않습니다.

    • MAKE 스크립트의 이름에서 얻습니다
    • SHELL은 makefile 내에 설정되거나 기본값으로 설정됩니다 /bin/sh(이론 : makefile 내에 명령이 지정되며 쉘에 따라 다릅니다).
  • 명령 행에서 - make대상과 혼합 된 명령 행의 일부로 변수 지정을 수행 할 수 있습니다.

    make target FOO=bar
    

    그러나 지정지시문 을 사용하지 않으면 makefile 내의 변수에 대한 모든 지정 FOO이 무시 됩니다. (효과는 환경 변수 옵션 과 동일 합니다).override-e

  • 상위 Make에서 내보내기-Makefile에서 Make 를 호출하면 일반적으로 다음과 같은 변수 할당을 명시 적으로 작성해서는 안됩니다.

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

    대신 이러한 변수를 내보내는 것이 더 나은 해결책 일 수 있습니다. 변수를 내 보내면 모든 셸 호출 환경으로 변수가 만들어지고 이러한 명령을 호출하면 위에서 지정한 환경 변수가 선택됩니다.

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    인수없이 사용하여 모든 변수를 내보낼 수도 있습니다 export.


10
공백이있는 명령 행에서 make A='"as df"'
벗어나기

4
환경 변수에 관심이 있다면 문제를 묻는 것처럼 보입니다. 우선, 환경이 다르기 때문에 장소 B가 아닌 장소 A에서 작동하면 디버깅 악몽입니다.
James Moore

12
경험을 바탕으로 CFLAGS와 같은 물건을 내보내는 것은 대규모 프로젝트의 악몽을위한 레시피입니다. 대규모 프로젝트에는 종종 특정 플래그 세트로만 컴파일되는 타사 라이브러리가 있습니다 (고정하는 사람은 없습니다). CFLAGS를 내 보내면 프로젝트의 CFLAGS가 타사 라이브러리보다 우선하고 컴파일 오류가 발생합니다. 다른 방법은로 정의 export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)하고 전달하는 것 make -C folder $(PROJECT_MAKE_FLAGS)입니다. 환경을 무시하도록 라이브러리의 makefile에 지시하는 방법이 있다면 이상적입니다 (-e와 반대).
RD

24
경고 : 위의 "부모 제조업체에서 내보내기"섹션에서 "이 작업을 수행하지 마십시오!" 이다 비판적으로 오해의 소지가 . 명령 행에서 변수를 전달하면 서브 메이크 파일의 지정이 대체 되지만 내 보낸 변수는 서브 메이크 파일의 지정이 대체 되지 않습니다 . 서브 메이크 변수를 전달하는이 두 가지 방법은 없다 당량과 혼동해서는 안된다.
조나단 벤-아브라함

4
어떤 차이가 있습니까? make target FOO=bar make FOO=bar target?
gfan

213

가장 간단한 방법은 다음과 같습니다.

make foo=bar target

그런 다음 makefile에서을 참조하십시오 $(foo). 이것은 하위 메이크에 자동으로 전파되지 않습니다.

하위 메이크를 사용하는 경우이 기사 : 하위 메이크에 변수 전달


2
하위 make included로 메인 makefile 의 makefile을 의미 합니까?
Pablo

2
@Michael : makefile 내부에서 make를 다시 호출한다는 의미입니다. 이 세부 사항에 관심이있는 것 같아서 답변을 업데이트했습니다.
Mark Byers

2
"이것은 하위 제조업체에 자동으로 전파되지 않습니다." 올바르지 않은! "기본적으로 환경 또는 명령 행에서 온 변수 만 재귀 호출로 전달됩니다. export 지시문을 사용하여 다른 변수를 전달할 수 있습니다." gnu.org/software/make/manual/html_node/…
ThomasMcLeod 1

82

다음과 같은 makefile이 있다고 가정하십시오.

action:
    echo argument is $(argument)

그런 다음 그것을 부를 것입니다 make action argument=something


5
그래서 목표와 인수가 위치 측면에서 교환 될 수 있습니까?
Pablo

4
@Michael : 예 (Mark Byers의 답변 참조)
nc3b

25

로부터 수동 :

make의 변수는 make가 실행되는 환경에서 올 수 있습니다. make 시작시 확인되는 모든 환경 변수는 이름과 값이 같은 make 변수로 변환됩니다. 그러나 makefile 또는 명령 인수를 사용하여 명시 적으로 지정하면 환경이 대체됩니다.

그래서 당신은 (bash에서) 할 수 있습니다 :

FOOBAR=1 make

FOOBARMakefile에 변수 가 생깁니다.


2
다른 방법은 거의 모든 경우에 실제로 더 좋습니다. 완전성을 위해 여기에 남겨 두겠습니다.
토마스

이것은 같은 줄에서 make 명령 전에 변수 할당을 보여주는 유일한 대답입니다 . 구문 오류가 아니라는 것을 아는 것이 좋습니다.
M_M

7

Stallman과 McGrath의 GNU Make 책에는 http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html을 참조 하십시오 . 예를 제공합니다.

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

지정된 매개 변수가에 나타나는지 확인하는 과정이 포함됩니다 MAKEFLAGS. 예를 들어 .. c ++ 11의 스레드에 대해 연구하고 있고 여러 파일 ( class01, ..., classNM)로 연구를 나누었 으며 다음을 수행하려고한다고 가정합니다. 플래그가 지정된 경우 ( -r예 :) 시간을 지정하고 실행하십시오 . 따라서 다음을 수행 할 수 있습니다 Makefile.

CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread

SOURCES = class01 class02 class03

%: %.cxx
    $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

그렇게하면 :

  • 파일을 빌드하고 실행 make -r class02 ;
  • 모든 승 구축 / make또는make all ;
  • 모든 빌드 및 실행 (모두 make -r특정 종류의 어설트가 포함되어 있고 모두 테스트하고 싶다고 가정하십시오)

6

그것은 보인다

명령 인수는 환경 변수를 덮어 씁니다.

메이크 파일

send:
    echo $(MESSAGE1) $(MESSAGE2)

예제 실행

$ MESSAGE1=YES MESSAGE2=NG  make send MESSAGE2=OK
echo YES OK
YES OK

5

Makefile이라는 파일을 만들고 $ (unittest)와 같은 변수를 추가하면 와일드 카드로도 Makefile 내에서이 변수를 사용할 수 있습니다

예 :

make unittest=*

BOOST_TEST를 사용하고 --run_test = $ (unittest) 매개 변수에 와일드 카드를 제공하면 정규식을 사용하여 Makefile을 실행하려는 테스트를 필터링 할 수 있습니다.


4
export ROOT_DIR=<path/value>

그런 다음 $(ROOT_DIR)Makefile에서 변수를 사용하십시오 .

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