簡體   English   中英

源shell腳本進入makefile

[英]Source shell script into makefile

我有一個bash shell腳本,我通常將其源碼發送到我的shell中,定義了許多環境變量,這些變量不會被導出。 我不想:

  1. 導出變量,因為這會使可導出的環境變得太大,並最終使整個系統變慢(必須在從shell運行每個命令時導出)
  2. 在makefile(DRY)中重新定義這些變量

我想將相同的shell腳本源到makefile的環境中,以便我可以訪問這些變量。 這可能嗎? 我怎樣才能做到這一點? 理想情況下我會在makefile中執行:

source setup-env.sh

makefile沒有source命令,但也許等同於什么? 我可以使用任何特殊的黑客來模擬相同的效果嗎?

根據評論中其他問題 ,這里有一種方法可以有效地將整個環境標記為已導出:

for var in $(compgen -v); do export $var; done

compgen -v根據bash手冊,第8.7節“可編程完成內置” ,輸出所有變量名稱。 然后我們簡單地遍歷此列表並export每個列表。

compgen https://stackoverflow.com/a/16337687/2113226 - compgen對我來說是新的。


我可以通過兩種方式將其集成到您的make工作流程中:

- Shell腳本包裝器

只需編寫一個shell腳本來源setup-env.sh,導出所有變量,然后調用make本身。 就像是:

#!/bin/bash

./source setup-env.sh
for var in $(compgen -v); do export $var; done
make $@

- 遞歸制作

可能是您不想要shell腳本包裝器,並且想要出於任何原因直接調用make。 您可以在一個Makefile中執行此操作,該文件以遞歸方式調用自身:

$(info MAKELEVEL=$(MAKELEVEL) myvar=$(myvar))
ifeq ($(MAKELEVEL), 0)
all:
    bash -c "source ./setup-env.sh; \
    for var in \$$(compgen -v); do export \$$var; done; \
    $(MAKE) $@"
else
all: myprog

myprog:
    echo "Recipe for myprog.  myvar=$(myvar)"
endif

此Makefile的輸出是:

$ make
MAKELEVEL=0 myvar=
bash -c "source ./setup-env.sh; \
    for var in \$(compgen -v); do export \$var; done; \
    make all"
MAKELEVEL=1 myvar=Hello World
make[1]: Entering directory `/home/ubuntu/makesource'
echo "Recipe for myprog.  myvar=Hello World"
Recipe for myprog.  myvar=Hello World
make[1]: Leaving directory `/home/ubuntu/makesource'
$ 

我們檢查GNU Make內置變量MAKELEVEL以查看我們所處的遞歸級別。 如果級別為0,那么我們遞歸調用所有目標的make,但首先源./setup-env.sh並導出所有變量。 如果遞歸級別是其他任何東西,我們只是做普通的makefile,但是你看到你需要的變量現在可用了。 這由Makefile頂部的$(info )行突出顯示,該行顯示了遞歸級別以及myvar的值(或不是)。

筆記:

  • 我們必須使用bash -c因為compgen嚴格來說是內置的bash,並且在Posix模式下不可用 - 例如,當make默認調用shell作為sh -c

  • 第一個all:配方中的$需要非常仔細地轉義。 $$$擴展了$ ,並且\\$$從隱式sh擴展了$

  • 有很多文獻認為“遞歸制作被認為是有害的”。 例如http://aegis.sourceforge.net/auug97.pdf

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM