iceboy 的 makefile 學習筆記

來源:互聯網
上載者:User
今天晚上學習了一下 makefile 的使用, 使用的工具是微軟的 nmake.

以下內容全部是摸索出來的, 官方文檔還沒來得及看.

1. 注釋

#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# You may only use this code if you agree to the terms of the Windows Research Kernel Source Code License agreement (see License.txt).
# If you do not agree to the terms, do not use the code.
#

2. 定義、使用變數

格式如下:
變數名=內容
$(變數名)

變數內容可以為多行, 在每一行後加上反斜線 '\' 即可.
變數也可以在 nmake 的參數裡定義, 格式為 'nmake 變數名=內容'.
同時還可以使用環境變數, 如 $(SYSTEMROOT)、$(LIB)、$(PATH) 等
還可以使用部分內建的變數, 如 $(CC)、$(AS)、$(MAKE)、$(MAKEDIR)
有趣的是, cc、as、make 均為 GNU 的名稱.
另外, 變數名區分大小寫, 環境變數名被全部變成了大寫.

舉例:
subargs=/$(MAKEFLAGS) ntos=$(MAKEDIR) pub=$(MAKEDIR)\..\..\public

3. 預先處理指令
格式:
!if 運算式
...
!else if defined(變數名)
...
!else
...
!endif

!ERROR 錯誤資訊

!include 另一個 makefile 檔案

注意運算式裡可以使用 &&、||、! 等邏輯運算子.

defined 運算子表示判斷某變數是否定義

舉例:
!if defined(x86) && !defined(amd64)
subargs  = $(subargs) targ=i386   topobj=$(MAKEDIR)\BUILD\obji386
targ     = i386
lmachine = x86

!else if !defined(x86) &&  defined(amd64)
subargs  = $(subargs) targ=amd64  topobj=$(MAKEDIR)\BUILD\objamd64
targ     = amd64
lmachine = amd64

!else
!ERROR Usage:  nmake (x86=|amd64=)  [clean]
!endif

4. 定義任務
一個 makefile 裡可以定義多個任務, 格式如下:
default:
____# commands here
task_a:
____# commands here
task_b:
____# commands here

default 表示預設任務.

通過 nmake [任務名], nmake 會執行不同的命令序列. 比如輸入命令 nmake task_b, 就會執行 task_b 下面的命令序列. 如果不指定任務名, 那麼會執行 default 任務.

注意任務名似乎不能為一個字元長, 我也不知道為什麼.

另外, 每個任務後面可以有多行命令, 但是每行前必須至少有一個空格或者一個 Tab, 否則會出錯. 由於百度會吃空格, 我在這裡用底線代替.

還可以定義任務之間的依賴關係, 格式如下:
task_c: task_a task_b
____# private commands here

nmake 會在 task_a、task_b 執行完畢後再執行 task_c.
注意依賴項必須和任務名寫在同一行, 中間用空格分隔.

只要可能, nmake 會自動根據任務的依賴關係找出一個合適的執行順序.
如果出現循環相依性, nmake 會報錯:

aa: bb
bb: aa

NMAKE : fatal error U1071: cycle in dependency tree for target 'aa'
Stop.

還可以一次定義多個任務:
task_d task_e task_f:
____@echo $(@R)

上面兩行定義了 task_d、task_e、task_f 三個任務, 均使用 echo 列印任務名.
echo 前面的 @ 是批處理命令列首碼, 這種用法從 DOS 開始就有了, 表示不輸出本命令列.
@R 參數表示任務名首碼, 在這裡就等於任務名
任務名首碼是指, 比如有一個任務叫做 'abcd.efgh', 那麼它的首碼是 'abcd'.

5. 變數內容替換
For example, 我們有下面兩條語句.
var_a = aa_bb_cc_dd_ee
var_b = head_$(var_a:_=_split_)_tail

大家猜猜 var_b 是什麼?

有了前面的知識, 大家不妨自己寫個 makefile 試一試:

var_a = aa_bb_cc_dd_ee
var_b = head_$(var_a:_=_split_)_tail

default:
____@echo $(var_b)

6. 一個常用的技巧

OBJ = obj$(targ)

modules = rtl config ex ob se mm ke ps io\iomgr io cache lpc dbgk raw fstub fsrtl wmi perf init
buildtargets = $(modules: =.build ).build
cleantargets = $(modules: =.clean ).clean

default: checktoolpath $(buildtargets) kernel

checktoolpath:
____checktoolarch $(lmachine)

kernel:
____cd $(MAKEDIR)\BUILD
________@$(MAKE) $(subargs) module=BUILD
____@cd $(MAKEDIR)

$(buildtargets):
____cd $(MAKEDIR)\$(@R)\BUILD
________@$(MAKE) $(subargs) module=$(@R)
____@cd $(MAKEDIR)

clean: $(cleantargets) clean0

clean0:
____-del $(MAKEDIR)\BUILD\$(OBJ)\** $(MAKEDIR)\BUILD\EXE\** /Q

$(cleantargets):
____cd $(MAKEDIR)\$(@R)\BUILD
________@$(MAKE) $(subargs) module=$(@R) clean
____@cd $(MAKEDIR)

簡單解釋一下.

modules = rtl config ex ob se mm ke ps io\iomgr io cache lpc dbgk raw fstub fsrtl wmi perf init
buildtargets = $(modules: =.build ).build
這兩行, 表示把 modules 裡面所有空格替換成 '.build ', 並在後面加上了 '.build'.
於是 buildtargets = rtl.build config.build (...省略...) init.build

$(buildtargets):
____cd $(MAKEDIR)\$(@R)\BUILD
________@$(MAKE) $(subargs) module=$(@R)
____@cd $(MAKEDIR)

這就定義了 rtl.build、config.build 等等任務, 我們把 rtl.build 展開看看:
rtl.build:
____cd $(MAKEDIR)\rtl\BUILD
________@$(MAKE) $(subargs) module=rtl
____@cd $(MAKEDIR)

default: checktoolpath $(buildtargets) kernel
這樣, nmake 會先 checktoolpath, 再依次 build 各個模組, 最後執行 kernel 任務.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.