版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
开始接触Makefile已经有好几个月了,最近想好好学习学习
# \5 m1 @3 Y6 |2 M; O0 O但是一个简单的问题就卡壳了很简单的一个问题
5 e- h6 z+ T) }+ I|-- Makefile
" i3 s% @: C: s$ Q2 N- q, b|-- include
+ N. m8 @9 s3 s| `-- hello.h
- l1 @+ T3 ?4 ]. L' G0 j`-- src
( i: \; Z, _6 e7 L2 D; J5 U |-- hello.cpp' Y. e& [% }8 K4 T) {9 }) x3 \
`-- main.cp
- E( I, v: Y+ b. O" C首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下
3 s( p0 ]; t6 W. w# w. Z) ~$ t4 g头文件hello.h在include目录下& o/ J& s, Y, M9 ~/ H
源文件main.cpp和hello.cpp在src目录下1 C ?" b) Y4 U( X8 ~
////////////////////////////////! a3 E0 X8 s, F
hello.h:$ h# Q8 Z: I- G+ d& G3 [
#ifndef _HELLO_H__
+ f- R! C }' u; Y6 R& K% S( x! G4 ?#define _HELLO_H__% k7 r- T& E2 j! v2 f" e
void hello();
+ J6 Q" X& p/ p) \2 E) R#endif* ^1 |1 e5 b8 e
///////////////////////////4 j1 N' N2 L! m
hello.cpp:3 a5 G! Q V. i+ k# y
#include<iostream>
5 J1 N( h6 M" G) T# V: ^& ^3 L( U#include"hello.h"
+ w' S. R# x$ a5 F5 w1 B0 Nusing namespace std;
" ~" R( m6 Y5 L" V2 e, g) zvoid hello()
3 H, r: Z w8 T% y" [{
+ r! ~0 t5 a* m2 e0 R cout<<"Hello world"<<endl; }! H1 N% T7 c
}0 w. y5 l9 D5 s! W) C
/////////////////////////////, D4 L3 I* B% [8 o* F
main.cpp:
( t4 m1 S& W; }4 ]8 H) f! v#include<iostream>
) e5 ^5 D8 _& T# C( _#include"hello.h"5 ~# q% `5 J9 D
using namespace std;
0 {/ ]) B3 V0 @! n+ wint main()
' C; L- g- M% m* ]. j{) r4 d8 a T9 T% J' n" b, F1 V
hello();+ u# d: e4 I" v6 R
return 0;
+ ^- g% j: C% p6 k: r. l2 Y6 S" }# f8 r}! A9 p# i, Y9 i- A7 R* b1 Z( k1 T. R0 O
/////////////////////////////////
3 p; Z$ {6 g% e1 z8 ]& ^Makfile:
' ~4 G j( w8 V" I1 m! a' N$ \9 ~ K#VPATH=include:src
) l& q. {6 `3 D! R' {vpath %.cpp src
2 b% g1 e X* rvpath %.h include0 b: Q7 z7 G: v, j" G
test:main.o hello.o8 g5 c3 `; v& j4 M& `
g++ -o $@ main.o hello.o$ r* ~+ Y7 Y n; o! l, o
main.o:main.cpp hello.h
4 p ~; @6 a, t( B g++ -c $< -Iinclude
) ^& }5 P/ s; dhello.o:hello.cpp hello.h/ ~8 i! F" e3 I
g++ -c $< -Iinclude' o( v# W5 G ~& s# g8 ^- ?
.PHONY:clean
* _- L4 D; R1 g0 O$ m8 Lclean:
+ J3 r! \3 D2 r) x% z) a9 e. f' o -rm test hello.o: A' w7 ?; O9 `3 B& Q
//////////////////////////////////: ^' L" j( }7 W- p0 e- s. W! y
因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题
8 x4 P* s! m. F1 P$ X5 P0 M同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径
; `! g# L9 t3 v# Y另一个就是源文件所要包含的头文件等相关文件的路径。0 ]4 g+ X& @2 Y7 Q$ p5 [$ k- g
对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,; R' R4 b9 V: x) h$ c* j- k
在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。$ n! H4 n4 O, ^. f9 |- A& g
一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是6 w* d3 o" R# m: Y1 @
首先说明一下makefile的执行步骤:# w6 v3 `+ q8 o$ K% l6 f( X
1、读入所有的Makefile。
0 ^ f! N" P& H, {2、读入被include的其它Makefile。
9 d5 S& a5 o* g4 b! U! H3、初始化文件中的变量。' n2 }) H. Y0 o
4、推导隐晦规则,并分析所有规则。
; N6 p6 n/ |- p: i: w5、为所有的目标文件创建依赖关系链。/ K, x( P8 p: l) |1 I5 U- S
6、根据依赖关系,决定哪些目标要重新生成。
7 _$ P- \+ M3 l$ ^# X' L7、执行生成命令
% w5 @! N" o& ~Makefile中所有文件的搜索路径,包括依赖文件和目标文件。 9 l. A" V% @( l& W( k1 F* p
变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序
7 [+ L4 z% D- W+ Z( O- R; A按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
& v2 R5 [7 t* D% _0 H& z, H! N例如:
8 P5 f" \' l/ X. e3 LVPATH = src:../headers
( _; N. x2 n. Q! X它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”
6 k$ B& L& q: X目录下,此时此规则等价于“foo:src:/foo.c”
$ M& ?4 b. S3 J0 J对于第二种来说:当需要为不类型的文件指定% W2 K2 I( ~# L( N0 N1 j1 G
不同的搜索目录时需要这种方式# u" P" f1 e% O
vpath:关键字
( |( Z. J: m( r4 u9 K t& b它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
2 g$ O8 @9 z1 B/ b它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三# W, K* H* u- M/ a
种) ~6 X F$ h$ {5 ~
1、vpath PATTERN DIRECTORIES
3 F. k* V9 P& Y# I) Z3 J; k3 _为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者
2 n6 `, o* x! x冒号(:)分开。类似上一小节的“VPATH”
" u6 Z% M* Z. D7 _3 B) a2 s- Q2、vpath PATTERN 6 }/ _+ v7 h a! L' t+ g" J
清除之前为符合模式“PATTERN”的文件设置的搜索路径( m0 T% _2 p$ O$ Y- U1 U: U
3、vpath; m Y6 ~6 o( ~ {+ w- L' ]
清除所有已被设置的文件搜索路径。) N4 }* {. b/ ?/ _+ \3 @. K' F
对于vpath的详细说明待续。5 H z2 B6 p# b& R! _) W
在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么* i7 r s# v/ @( D4 ~
VPATH = include:src //指定了makefile的搜索路径
! R6 {0 c% p) q" ^9 i, g5 ~或者
! u8 `9 r8 j4 [/ Q; {2 K8 kvpath %.h include //指定.h类型文件的搜索路径是include& c* ^' e5 ]0 H' L
vpath %.cpp src //指定.cpp类型文件的搜索路径是src
+ {! h ]8 d0 J这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说
' B. o g" \$ l/ O) O3 Q. l0 V在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件
- c* C4 Q+ L# |; b此时要用到了 -I 或者--incude +路径
" H# o& x- @; |/ Z2 b例如依赖是:
) H1 [, e' r+ \: a" ]% xmain.o:main.cpp hello.h
6 @; B4 I D/ d0 U& `3 K即g++ -c $< -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件, Q" }( z" a+ \7 y3 c6 I
% Q6 f; I) T$ N! c, b# r. ]
+ D1 F* O5 L# Y2 T9 D4 X: a4 k* a' l) u
8 y+ f1 P: Z2 { |
|