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


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.