2011年9月18日 星期日

在Makefile裡面的command line設定變數值

在Makefile裡面的格式如下所示

target : prerequisites
command


請參考nmake 簡單教學

一般來說,要設定變數,只能在Makefile的最上面的部分
在上面那一個文章的Makefile的範例裡面,就是在everything之上設定變數

但是,我現在想做的是,依不同的target設定不同的數值~也就是想把設定數值的部分擺在command裡面。但是,在nmake的環境下,我在設定完後,直接印出來,似乎沒有達到效果。

target : prerequisites
SET TEST_VALUE=YES
ECHO $(TEST_VALUE)


最後,在多方嘗試之後,發現是可以達到我的需求的,但是,有以下幾點限制
1. 在目前的Makefile的command line設定的變數,必需觸發的下一個Makefile內才能使用
2. 變數必需不能有小寫

直接看例子吧~

Hello.c
#include <stdio.h>

int
main (
)
{
printf ("Good Morning!\n");
return 0;
}


例子一:
First.makefile
all:
[tab] SET TEST_VALUE=YES
[tab] nmake /f Second.makefile all

Second.makefile
# Program, flags, etc.
ASM = cl
OBJ = Hello.obj
TARGET = Hello.exe

all: clean everything
!IFDEF TEST_VALUE
[tab]ECHO $(TEST_VALUE)
!ENDIF

everything: $(TARGET)

clean:
[tab]- del $(OBJ) $(TARGET)

.c.obj:
[tab]$(ASM) $< /Fo$@

$(TARGET): $(OBJ)
[tab]$(ASM) $(OBJ) /Fe$@


執行指令
%> nmake /f First.makefile

如此一來,就可以在command line設定變數了,並且可以使用了。

但是,這樣的程式碼實在很難看~
那就用遞迴的方式,自己的Makefile呼叫自己的Makefile
Makefile
# Program, flags, etc.
ASM = cl
OBJ = Hello.obj
TARGET = Hello.exe

!IFDEF TEST_VALUE
all: clean everything
[tab]ECHO $(TEST_VALUE)
!ELSE
all:
[tab]SET TEST_VALUE=YES
[tab]$(MAKE) $@
!ENDIF

everything: $(TARGET)

clean:
[tab]- del $(OBJ) $(TARGET)

.c.obj:
[tab]$(ASM) $< /Fo$@

$(TARGET): $(OBJ)
[tab]$(ASM) $(OBJ) /Fe$@


執行指令
%> nmake

這一個Makefile會被執行兩次,在第一次的時候,TEST_VALUE變數並沒有被定義,
而第二次的時候,TEST_VALUE有被定義,如此一來,只需要一個Makefile就可以了

[2011.11.02 補充]
在make裡面,可以在target裡另外指定變數的值
foo = abc

all: foo = xyz
all:
[tab]echo $(foo)

這個時候的foo的值為xyz
以下的語法也提供相同的功能
all: override foo = xyz
all: export foo =xyz

但是,這個方法,似乎只能在linux下,正統的make下使用~
nmake並不支援這個語法~

參考資料:
Makefile 語法簡介

沒有留言: