2007年8月13日 星期一

[程式設計] gnu make makefile 最簡單說明

MinGW - Minimalist GNU for Windows


操作:
Copy: Ctrl + C
Paste: Shift + 滑鼠左鍵


--- Make file 解說  ---
# 定義變數
CLASSPATH = .:/h/Program\ Files/Java/jdk1.6.0/jre/lib/javaws.jar
JFLAGS = -classpath $(CLASSPATH)
JCFLAGS =
JRFLAGS =
JAVAC = javac $(JFLAGS) $(JCFLAGS)
JAVA = java $(JFLAGS) $(JRFLAGS)

# 列出所有要編譯的 java 檔, 全部放到一個變數代替
JAVASRC = $(shell ls *.java ./Manager/*.java)

# 替換規則: 把 JAVASRC 列出結果的所有 .java 換成 .class
CLASSES = $(JAVASRC:.java=.class)
JDK = /h/Program\ Files/Java/jdk1.6.0/

# 通用規則: java -> class 表示 .class 永遠 depend on .java 的意思
# 在後面的 target 中, 若有 class 變動, 就會預設的執行 下面得 javac 命令
# 例如:
# compile : $(CLASSES)
# see example: http://myweb.stedwards.edu/laurab/help/javamakefile.html
#
#也可以寫成 $* 為所有 depend 的檔名 (不含副檔名)
#.java.class:
#[tab鍵]$(JAVAC) $(JFLAGS) $*.java
.SUFFIXES : .java .class
.java.class :
[tab鍵]$(JAVAC) $< # 目標文件 加上 所有比目標文件新的 depend 檔 (ex: javac -o test.class test.java)

all : TargetA TargetB TargetC

# TargetA depend on $(CLASSES) 所有檔案
# 只要
$(CLASSES) 有檔案變化, 則會自動執行 .java.class 的預設命令
TargetA: $(CLASSES)

TargetB:
[tab鍵] javac 其他的編譯命令
[tab鍵] cp *.class /c/test

TargetC:
[tab鍵]javac 其他的編譯命令
[tab鍵]@echo "Application Installed "

# 清除命令
clean:
[tab鍵] rm -f $(CLASSES:.class='



可用在命令的常用變數:

1. $<: 列出目標檔 加上 列表中比[目標檔]新的檔案. 
        常用在編譯指令上, 懶得重寫所有的 depend file 編譯指令 

例如: 目前列表中比 all 新的檔案全部都要編譯
all:a.o b.o c.o

[tab] gcc $< #相當於 gcc -o all a.o b.o c.o

    2. $*: 列出所有的目標檔(不含附檔名)

例如: 編譯所有的 .java 檔案

.java.class:

[tab] java $*.java # 其中 $* 為所有的 class 檔名稱


如果想在 depend 欄位中使用這些常用變數:
  • 在常用變數前面加一個 $. ex: $$*.java
* 如何寫條件式編譯 [GNU make]

  • DEBUG= This is a debug target
  • # make install 安裝目錄設定
    A_DIR=/c/
    B_DIR=/F/
    ifdef DEBUG
    WEBROOT=$(DEBUGROOT)
    else
    WEBROOT=$(EBELLROOT)
    endif

* 如何像串肉粽般地, 進入其他目錄執行另一個 makefile

    DemoTarget:
        cd 目錄; $(MAKE)

    如果是要執行另一個 make 的其他 target, 則範例如下:
    clean:
    [tab] cd 目錄; $(MAKE) clean

     

* 如何用 include, 把一堆公用變數集中處理 ?

   最簡單範例:

-- Var.mk --

# 所有的 make 變數放在 Var.mk 集中管理

CLASSPATH=.:$(JDKROOT)jre/lib/javaws.jar:$(JDKROOT)sample/jnlp/servlet/jnlp.jar
JFLAGS = -classpath $(CLASSPATH)
JCFLAGS = -source 1.5 -target 1.5
JRFLAGS =
JAVAC = javac $(JFLAGS) $(JCFLAGS)
JAVA = java $(JFLAGS) $(JRFLAGS)

--  mymake.mk--

# mymake 放在專案的子目錄中

# 先到上層目錄中, 取得共同定義的變數

include ../Var.mk

SRC=$(shell ls *.java)
CLASSES=$(SRC:.java=.class)

.java.class :
    $(JAVAC) $<
all: ${SRC}
    ${JAVAC} ${SRC}
clean:
    rm -fr *.class


參考資料:

[1] [GNU make 英文說明書]http://theory.uwinnipeg.ca/gnu/make/make_toc.html
[2] http://myweb.stedwards.edu/laurab/help/javamakefile.html
[3][非常詳細的中文解說]
http://www.infosecurity.org.cn/article/hacker/program/7914.html

沒有留言:

張貼留言