chapter 1 introduction. – software is categorized archiver 除了 filename 及其 file content...
TRANSCRIPT
Chapter 1 Introduction
• www.freshmeat.net– Software is categorized
• Archiver 除了 filename 及其 file content 以外,還必須要保留 meta-data. 如 file owner, execution permission, etc.– 目的在於當 file 被 archived 後,即可從 filesystem 把原檔
刪除,日後若有需要,由 archive 回復即可。 ( 可是我打 sudo tar cvf tt.tar /tmp 後cwhuang$ tar xvf tt.tar 看檔案的權限與 ls –al /tmp 不同 !!
– 所以,不只是 concatenate multiple files one by one 而已。
Archive Tools
file shell command can query the meta-data of any file.
Watch for Possible Clobber!!
• 當解開 archive file 時,小心注意他要被解到哪裡 !!– cpio 允許解到絕對路徑,如此就可能覆蓋了重
要檔案。如 /etc/hosts 底下的東西。建議使用cpio 時,打上 GNU –no-absolute-filenames option ,如此,就會被解到 ./etc/hosts 下。
– GNU tar 預設上會幫我們把 leading ‘/’ 拿掉。
Authenticate
• Download from unsafe location (say a mirror site), 記得 acquire checksum from trusted site.
Digital Signature• You trust people to check before they sign.• You trust people to keep their private key and passphrase secret.• You trust the public key is authenticated. (otherwise you may reject something that is original)• You trust the people who issue the key pair. (they are who they claim to be)• No need to obtain data-dependent string. Only a single public key is needed.
How to Inspect a Package
• The package name is encoded inside the package file and should be visible with a basic package file query.– After the package is installed, it can be referred to only by
the name specified inside the package file, so querying a package file for its official name is a good first query.
– 例 : 有一個 foo.rpm 裡面裝的 package 叫作 gcc.安裝前使用 rpm –qip foo.rpm安裝後使用 rpm –qi gcc
• The rpm command normally queries the RPM database, but the -p option specifies that a package file is the target of the query.
Query on Package Files
Advanced Package Tool, APTA set of commands• apt-cache
– query the list of available packages downloaded to the local cache, which is faster than repeatedly querying repositories on the Internet.
– This list includes all available packages, including those you have not installed as well as updates to what you have installed.
• apt-key – add public signatures from a trusted source to your database, – inspect the ones you already have.
• apt-setup– specify the preferred repositories that Apt should search when looking for
packages.– edit the /etc/apt/sources.list file by hand to include more agnostic repositories.
• apt-get
– The workhorse
setuid, setgid, sticky bit
setgid bit
setuid, setgid 範例
sticky bit• 設在 directory 上。– 當該 directory file 賦予了 group 或 other write and execute
權限時,表示有多人可以在此目錄下新增及刪除檔案。– 如果你希望能夠避免刪除別人的檔案,則可以對此目錄
設定 sticky bit ,以侷限使用者的”影響範圍”。– 例如 /tmp 目錄,即設有此 bit
• A directory with the sticky bit set is indicated with a t or a T in the execute permission for others.
Chapter 2 Building from Source
Make utility
• To automate and track the build process.• During the build, shell does the work while
make supervises.• Lacking the scripting capability, several variant
of make built on top of the original make. (GNU make is one of them)– Drawback: make scripts are not guaranteed to
interwork.
Makefile basics
• Collections of (implicit and explicit) rulestarget: prerequisite1 prerequisite2 … prerequisteN
commands• Unlike traditional sequentially-executed script. You name
a starting rule when executing the make with input Makefile. (default rule is the 1st rule.)– make will try to satisfy (stop when satisfied) the time-
dependency of the prerequisites in the current rule by • commanding the shell to execute the command portion of the rule. • If the modify time of one of the prerequisite is undetermined (needs
to be confirmed),– make will execute the associated rule recursively.
Makefile
Simplest rule:• target consists of a single filename, and • prerequisite contains one or more filenames. • If the target is older than any of its prerequisites, the commands
associated with the rule are executed. • Typically, the commands contain instructions to build the target.例 :
foo: foo.cgcc -o foo foo.c
• Here, foo is the target, and foo.c is the prerequisite. • If foo doesn’t exist or If foo.c is newer than foo, make executes
the command gcc -o foo foo.c.
• In a more complicated example, the prerequisite of one rule can be the target in another rule.– In that case, those other dependencies must be
evaluated before the current dependency is evaluated.$@ 為 targetCommand 中把 prerequisite 明白寫出是因為不見得每條 command 都會用到所有的 prerequisites.Rule 2 does not have prerequisite, recall there are two conditions that execute the command1. Traget does not exist2. Prerequisite(s) is newer than target.Now prerequisite is empty, so the only condition for
this rule is when target (source.c) does not exist.
Pseudo target
• Targets that are not file names.• E.g. conventionally, use all as the first (default) rule.– We can write the first rule as
all: job1 job2 … jobn
With empty command.When make evaluate 1st rule, it will evaluate each job recursively.
– GNU make tells explicitly that all is a pseudo-target by.PHONY: all
So make will not search for file named ‘all’ mistakenly.
Defining Variables• VAR = value • VAR := value
– allows variables to reference themselves without recursion.– VAR = $(VAR) more // wrong!! Infinite recursion.– VAR := $(VAR) more // when you want to concatenate more terms.
GNU extension makes intention clearer– VAR += more
• Variable value is store literally and has no meaning until it is used in context. ( 沒有人用他,就只是呆呆存在著,不起作用 )– 常見一種使用 shell command output 來取代變數值,以達到動態改變變數內容的作用– VAR = `shell command` (backtick `` enclosing the shell command)例
LOG = `date +%02d%02m%02y`.logall:
@echo $(LOG) ( 加上 @ 目的在把執行 shell 的 command hide 起來,只顯示 command output. “Silent” mode)$make ( 在執行時,會將變數的內容以 command output 取代 )050909.log
– 在這裏強調 context ,因為 shell 看得懂 backtick 的 intention ,所以會進行內容替代。若妳把 LOG 當作target 或是 prerequisite ,make 不會去解讀 backtick 為特殊意義,而是如往常般,直接 literally 解讀,也就是當作一般的 ASCII 自元看待。all: $(LOG)command // 會把 $(LOG) 直接展開為兩個 ugly prerequisites // `date 及 // +%02d%02m%02y`.dat
Whitespaces and Newlines in Variable Definitions
• make automatically removes leading and trailing white space from your variable values when you use the traditional syntax. Specifically, any spaces following the = do not appear in the variable contents, and any spaces before the newline are removed as well.
• By contrast, when you use the define syntax, leading and trailing spaces are preserved.例• TRAD = Hello World (removed)• define DEFD (preserved)
Hello Worldendef
所以,取決於你的意圖,選擇適當的表示法 !!• TRAD = $() Hello World $() (preserved)$() is the empty variable in traditional way. 相當於加上兩個 "sentinels" ,標示起頭與結尾。 make allows you to break long lines using the backslash character (\) as the last
character on a line.
Referencing and Modifying Variables
• Enclose the name in parentheses or brackets.$(MACRO) # this is most common${MACRO} # less common but still okay
• Unlike variables in a script, which change value during the course of execution, – Makefile variables are assigned once and never change value during
the course of the build. ( 好處是一致性 )• The definition of variable (say FLAGS) is fixed before any rules are
evaluated. (make 的作法是 : 先確定下變數的值,才進行 rule的 evaluation)– When FLAGS is defined, make will discard old definitions as new ones are
encountered so that the last definition in the file is the only one that matters. (make 以最後一個定義為準 )
Minimal Makefiles Using Implicit Rules
• 許多 rules 的長相很類似,有規則可循時,可以用一個‘ pattern’ 來代表所有滿足的 rules. 減少copy&paste 。
• make comes with numerous predefined implicit rules (make –p 查詢 )that cover many patterns commonly found in Makefiles.– Use make without a Makefile
$ make foocc –o foo foo.c // 這是一條 implicit rule
Implicit Rules and Variables• suffix rules
.c.o: $(COMPILE.c) $(OUTPUT_OPTION) $<
“If you see a target with an .o extension, and there is no explicit rule for it, look for a file with the same base and the .c extension. If you find it, run these commands.”
所以,當打 make foo.o 即便沒寫 Makefile ,照樣會作出 foo.o• By typing make -p. ( 列出所有 built-in variables and implicit rules)
會發現COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -cCC = gcc
• Interestingly, only one of these additional variables (CC) is actually defined; the others are quietly replaced with empty strings. – 妳可以自行定義這些變數的值。– 不定義也可以,就當作 empty. – 也可在 command line 時, override 原本的定義。
• $< 這個 automatic variable 代表 1st prerequisite ( 此例為找到的 .c file)• Given the flexibility of implicit rules for object code, you may never need to write explicit
rules for generating object files, for example.
Common Implicit Variables and Rules(can be overrided)
Define Your Custom Implicit Rules
• 假設你想新增一個 implicit suffix rule for files with .cyy extension..SUFFIXES: .cyy # let make know .cyy is a new extension.
.cyy.o:$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
• GNU make 提供的 pattern rule 表達上更為清楚。%.o : %.cyy
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<– 不需要寫 .SUFFIXES pseudo-target. 把意圖寫在一行內– uses a % character to match filenames or targets, like a wildcard
character.
Search Order for Explicit and Implicit Rules
• Each time make searches for a specific target, it searches the explicit rules first. Only if it cannot find a match does it attempt to apply the implicit rules.
Automatic Variables• 在 implicit rule 或是 pattern rule 中,當我們要指涉 (refer)
make 自動幫我們找到的那些 files 時,必須使用 make 所提供的 automatic variables.
• Unlike other make variables, automatic variables have unique values for every rule.
program1: $(PROG1_OBJS)$(CC) –o $@ $^
Program2: $(PROG2_OBJS)$(CC) –o $@ $^
build_c_program = $(CC) –o $@ $^program1: $(PROG1_OBJS)
$(build_c_program )Program2: $(PROG2_OBJS)
$(build_c_program )
Easier to read
substitution reference
SRCS = foo.c bar.c apple.cOBJS = $(SRCS: .c=.o) # 取 SRCS 中的值,但將 .c 換成 .o
# 有擴充取值動作的味道# 想成 $(SRCS: .c=>.o) 更明顯
• we take the value of the SRCS variable, substitute .o for all the .c extensions, and store the result in the OBJS variable.
避免重複輸入的麻煩與更新時的困難。C_SRCS = foo.c bar.cCXX_SRCS = orange.cppOBJS = $(C_SRCS: .c=.o) $(CXX_SRCS: .cpp=.o)
Manipulating Variables with Functions
• GNU make’s function extensions are versatile tools for manipulating variable contents.
下列兩式是等價的• OBJS=$(SRCS:.c=.o)• OBJS:=$(patsubst %.c, %.o, $(SRCS))若要做到多重取代,則要使用 nested functionSRCS = foo.c bar.cpp good.c bad.c soso.cppOBJS:=$(patsubst %.cpp, %.o, $(SRCS))
先做$(patsubst %.c, %.o, $(SRCS))
OBJS:=$(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS)))
更簡潔的 Substitution 作法OBJS:=$(addsuffix .o, $(basename $(SRCS)))• The basename function takes a list of filenames (in
this case, the contents of SRCS) and strips the extension from each of them. It doesn’t matter what the extension is; – basename just strips off all the characters following the last
period in the text. (視作 extension)– We take the output and glue .o to the end of each
basename, using the addsuffix function. This gives us the list of objects we want.
– 進行切換”尾巴”的動作
在 Prerequisite and Target 也適用的取代函數 --shell
NAME = $(shell date +%02d%02m%02y).dat• 如此,使用在 prerequisite or target 時,就
不會被 make單純以 whitespace 作為 token delimiter.
• 注意,使用變數定義的方式,由於 make 會在 evaluate rules之前,先確定下變數值,之後即不會改變。也就是無法做到每條 rule的個別需要。所以,若妳要的是 global scope 則可使用此方式。
Value to change over timeCURRENT_TIME=$(shell date +%T)something:
@echo started $(CURRENT_TIME)sleep 5@echo finished $(CURRENT_TIME)
• 執行結果$ makestarted 9:49:45sleep 5finished 9:49:45-----------------------------------------------------------------------------------------------------------------------------------• If you want the value to change over time, you will have to call the shell each time, which is
what the backticks do. For example:CURRENT_TIME=`date +%T`$ makestarted 9:49:45sleep 5finished 9:49:50
Commonly Used Functions
Commonly used Functions (cont)
Defining your own function• 透過GNU make 內建的 call function ,來呼叫自行定義的 function as call’s 1st
argument.$(call myfunction, arg1, arg2,…,argn)
– 而 myfunction 的 argument 則依序以‘ ,’隔開,緊隨列在後面。例 :myfunction = @echo $(1) $(2) all:
$(call myfunction, Hello, wolrd)$ makeHello world– The definition of myfunction looks just like a variable except that it now has access to
positional arguments.– Because a function definition looks no different from a variable definition, for example,
you can still use a function as a variable. (精確的說, make並不是一種程式語言,而function 這個詞有點misleading.)
$(myfunction)– the positional arguments—$(1), $(2), and so on—are replaced with empty strings.
Conditional Construct
• GNU make extension.• 4 conditionals:
例 1: ( 內包 Variable)ifeq ($(shell uname -o),GNU/Linux)
CPPFLAGS += -DLINUX // any valid make linesendif
例 2: ( 內包 rule)ifeq ($(shell uname -o),GNU/Linux)
all: linux_programselse
all: bsd_programsendif
例 3: ( 內含 command)ifeq ($(A),0) # A isn't defined yet
all: @echo $(A) == 0
elseall: @echo $(A) != 0
endif
Conditional Construct
• The ifdef clause tests for variable definitions, which can be useful for using variables as command-line options.
ifdef (debug)CFLAGS += -g
elseCFLAGS += -O2
endif$ make debug=1 (If you want to compile for debugging)
• ifndef cluaseifndef (A_VITAL_VARIABLE)
$(error A_VITAL_VARIABLE is not set)endif
Pulling Source from Various Places
• 若想把 source directory 與 build directory分開• 可使用 make 的 VPATH variable 來設定 source
directory, 例 ./src放 source, ./bin放 object files. Makefile 由於是 directing build process產生出 object files 的,所以放在 bin 目錄下。
VPATH=../srcfoo: foo.c
$(CC) $(CPPFLAGS) $(CFLAGS) $^ –o $@
• VPATH indicates that make should search for targets and prerequisites – 1st in the current directory then the ../src directory.
GNU make extention—vpath directive
• Specify filename patterns so that make will search only for – particular type of files in particular directories.
• Example: – you could put C++ source in a directory named
/cxxsrc and C source in a directory named /csrc.vpath %.cpp ../cxxsrcvpath %.c ../csrc
2.2.3 How Programs are Linked