Makefile'da çocuk süreç ortam değişkeni nasıl ayarlanır


135

Bu Makefile'ı değiştirmek istiyorum:

SHELL := /bin/bash
PATH  := node_modules/.bin:$(PATH)

boot:
    @supervisor         \
      --harmony         \
      --watch etc,lib       \
      --extensions js,json      \
      --no-restart-on error     \
        lib

test:
    NODE_ENV=test mocha         \
      --harmony             \
      --reporter spec       \
        test

clean:
    @rm -rf node_modules

.PHONY: test clean

için:

SHELL := /bin/bash
PATH  := node_modules/.bin:$(PATH)

boot:
    @supervisor         \
      --harmony         \
      --watch etc,lib       \
      --extensions js,json      \
      --no-restart-on error     \
        lib

test: NODE_ENV=test
test:
    mocha                   \
      --harmony             \
      --reporter spec       \
        test

clean:
    @rm -rf node_modules

.PHONY: test clean

Maalesef ikincisi çalışmıyor (düğüm süreci hala varsayılan olarak çalışıyor NODE_ENV.

Ne kaçırdım?


Sizin Unfortunatelycomment karşı bir ortam değişkeni arasındaki anlaşmazlıktan kaynaklandığını Makefiledeğişken. Bir ortam değişkeninin ayarlandığını kanıtlamanın en iyi yolu, bu ortam değişkenini makearayacak başka bir program içinde sorgulamaktır . Sadece yapıyor echo $(BLAH)sadece Makefile içine Makefile anahtar / değer mekanizmasını değerlendirmektir. Python'da, print(os.getenv("MURDOC")) ortam değişkenini gerçekten sorgulayabilirsiniz.
truthadjustr

Yanıtlar:


154

Make değişkenleri, varsayılan olarak make invoke işlemlerinin ortamına aktarılmaz. Ancak make'leri bunu yapmaya exportzorlamak için kullanabilirsiniz. Değişiklik:

test: NODE_ENV = test

buna:

test: export NODE_ENV = test

(yeterince modern bir GNU make> = 3.77 sürümüne sahip olduğunuzu varsayarak).


3
GNU'nun 3.81 yapmasına sahibim all: <\n\t>export PROJ_ROOT=$(CURDIR)<\n\t>echo $(PROJ_ROOT)<\n>ve ilk satır için doğru genişletmeyi çıktı, ancak yalnızca echoikinci satır için. PROJ_ROOTmake çalıştırıldıktan sonra ayarlanmadı. Etrafındaki boşluklar =dışa aktarım için "bozuk değişken adı" verir. Örneğinizdeki gibi ön koşul olarak ilk satıra sahip olmak "komutlar ilk hedeften önce başlar" verir
Gauthier

8
@Gauthier evet elbette. Yazdığım bu değil. Benim örneğimde olmayan <\ n \ t> 'den sonra eklediniz all:. Örneğim yazıldığı gibi kullanılmak üzere tasarlandı: hedefe özgü bir değişkeni tanımlamak , tarife bir komut eklemek DEĞİL . Ayrıca bir hedef üzerinde aynı anda hem reçete hem de hedefe özgü değişken kullanamazsınız: hedefi iki kez yazmanız gerekir. Sorudaki ikinci örneğe bakın ve bunu açıklamaya yardımcı olmazsa yeni bir soru sorun: yorumlarda yeterli alan veya biçimlendirme yok.
MadScientist

1
Peki ya birden çok değişken?
holms

1
Sorun değil ama hedefin başına ekledin. Bunları sadece hedef bağlamında listelemek işe yaramaz mı? Çünkü benim için çalışmıyor
Holms

2
Hedefe özgü değişkenler GNU make 3.77'de eklendi. GNU 3.81 markasından itibaren ihraç edilebilirler. Bkz. Git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

80

MadScientist'in belirttiği gibi , tek tek değişkenleri şu şekilde dışa aktarabilirsiniz:

export MY_VAR = foo  # Available for all targets

Veya belirli bir hedef için değişkenleri dışa aktarın ( hedefe özgü değişkenler ):

my-target: export MY_VAR_1 = foo
my-target: export MY_VAR_2 = bar
my-target: export MY_VAR_3 = baz

my-target: dependency_1 dependency_2
  echo do something

Ayrıca .EXPORT_ALL_VARIABLEShedefi de belirtebilirsiniz - tahmin ettiniz! - TÜM ŞEYLERİ İHRACAT !!!:

.EXPORT_ALL_VARIABLES:

MY_VAR_1 = foo
MY_VAR_2 = bar
MY_VAR_3 = baz

test:
  @echo $$MY_VAR_1 $$MY_VAR_2 $$MY_VAR_3

bkz. EXPORT_ALL_VARIABLES


2
İşin garibi, daha önce test ettim, işe yaradığını gösterdi .. (neden şimdi emin değilim ..) Sanırım geri dönüp yorumu silebilirim ..
AnthonyC

3
İki olduğundan @AnthonyC Çalışıyor MY_VARler: Bir makefile değişken olarak erişilir ${MY_VAR}ve başka bir şekilde erişilen bash ihraç değişken olduğu$$MY_VAR
Sergei

Kullanışlı. Ancak yalnızca bir dizi değişkeni dışa aktarmanın bir yolunu bulamaz.
Eric Chen

14

Test komutumu çağırmak için yalnızca yerel olarak ortam değişkenlerine ihtiyacım vardı, işte bir bash kabuğunda birden çok ortam değişkenini ayarlayan ve dolar işaretinden kaçan bir örnek make.

SHELL := /bin/bash

.PHONY: test tests
test tests:
    PATH=./node_modules/.bin/:$$PATH \
    JSCOVERAGE=1 \
    nodeunit tests/

6
Lütfen yanıtınızı bazı açıklamalar içerecek şekilde düzenleyin. Yalnızca kod yanıtları gelecekteki SO okuyucularını eğitmek için çok az şey yapar. Cevabınız düşük kaliteli olduğu için denetim kuyruğunda.
mickmackusa

ThorSummoner, bu çözüm yukarıdaki yaklaşım kadar esnek değil. Örneğin, bir komut çağırmak için tek bir kural ve daha sonra ortam değişkenlerini ayarlayarak bu davranışı değiştiren birkaç başka kurala sahip olmak isteyebilirsiniz. Şunu düşünün: test: cmd perf: export PERF = "yes" perf: test Eğer 'cmd' karmaşıksa (ve genellikle öyledir), bu yaklaşımın sürdürülmesi çok daha kolaydır. Cmd kuralında ortam değişkenini ayarlama yaklaşımınız bunu daha da zorlaştırır.
Keith Hanlan

1

Orijinal hedef testini yeniden yazardım, gerekli değişkenin başlatılacak uygulama olarak AYNI ALT SÜREÇTE tanımlandığına dikkat ederek:

test:
    ( NODE_ENV=test mocha --harmony --reporter spec test )
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.