版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
开始接触Makefile已经有好几个月了,最近想好好学习学习
" V. g; C$ F2 W+ a7 M1 k3 j/ t0 i但是一个简单的问题就卡壳了很简单的一个问题3 _2 g' I" {, u( X( D" _2 `" I. F
|-- Makefile5 x8 s( y1 M/ @* j
|-- include
1 b; V) P8 a; _* ]" }| `-- hello.h1 K' [* S: q$ g7 R9 Z1 ? m
`-- src
$ r: ?7 J2 Y$ C: ?! Q& P |-- hello.cpp
; n" D; R; _4 ?5 H9 L `-- main.cp
* [9 {- @5 i9 C+ c5 Q& U首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下. n3 }2 G" U, n+ e6 J: r% \. V
头文件hello.h在include目录下
' N! |. s! k4 j# S8 N源文件main.cpp和hello.cpp在src目录下
( u4 c' J( F- h: x////////////////////////////////7 I# c! z$ v: V+ _
hello.h:/ Q% t/ s% G7 U+ i# |0 H
#ifndef _HELLO_H__
& B+ C3 ^; {% U3 {#define _HELLO_H__
% C' }7 f( T0 E( G! a) z$ \void hello();
) t z, S" v6 o) F6 A+ o#endif: b' r/ V& T; T1 k2 J
///////////////////////////% l* Q9 \- W! W4 a; g* P- @
hello.cpp:
. n) w) U" e/ P#include<iostream> `* E# w4 j4 G$ d( W6 G
#include"hello.h"
5 _% z( o4 K: musing namespace std;, G' F8 h1 A8 ` }
void hello()
$ q& b8 A) ~! @3 Q. h/ Q{
5 Q2 W# [2 ^- g cout<<"Hello world"<<endl;
3 ]4 A9 L* t! p}
: y/ d' P# R9 B/////////////////////////////
7 }7 O( ]7 D, V, g5 ~( Z" Imain.cpp:
2 |" U* p' u6 i7 t" x/ E2 d& x#include<iostream>
2 \, p! `& y4 h8 `. z. Z v. B#include"hello.h"& ^' ]; K/ z: Y( A5 Z# {
using namespace std;$ \! o' {( c3 U0 m% A6 M
int main()2 p( o( \* T/ u) y
{" k, E% T; X- w, f8 q% G& |/ H
hello();
4 @4 E" Y# h; d: A4 y4 v, r return 0;
( _6 [" E4 p$ Q/ P6 Z}7 q2 D- g% ^* `( @
/////////////////////////////////2 K7 S" X( L; b4 k7 g
Makfile:
( v Q4 j4 r4 z+ E, U) K9 ?#VPATH=include:src
: C' ^ v2 N: N5 R( o. {/ Tvpath %.cpp src
" F0 S5 s# S4 R2 Z. G% xvpath %.h include
5 B# Z# C4 o, O8 k; b. f0 \' vtest:main.o hello.o
& R0 c% ^; G( m R g++ -o $@ main.o hello.o
$ b8 J5 |9 V0 A7 W6 x5 u. _main.o:main.cpp hello.h" k" K( E+ X' t' E; W+ Y
g++ -c $< -Iinclude
$ }$ R% J P' s ?0 l5 \hello.o:hello.cpp hello.h
9 I) i) S) Z1 g g++ -c $< -Iinclude. A8 ?$ k6 ?" D+ o4 V9 u- g+ M
.PHONY:clean
0 F, p! V% b" U6 L& Cclean:- M- X0 y3 y9 w9 r9 H1 D: g
-rm test hello.o
1 S5 ~6 c3 Y3 X/ u//////////////////////////////////
4 w; S3 a" _# I+ [* `: B因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题
' G9 f: |; L! y g- f4 l& U同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径 u) \9 n6 W! c2 m8 g
另一个就是源文件所要包含的头文件等相关文件的路径。
9 M6 O) s+ Y1 N W! B' f对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,
6 {( b! E1 b5 e在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。, r5 Q+ F. x- C& v. T# }; Y( s
一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是4 e1 P: Y! C* Q( k4 m4 [
首先说明一下makefile的执行步骤:4 h" p" Y$ f9 ^2 Q6 o
1、读入所有的Makefile。8 K$ I& F$ {. E" _2 R0 ?& B4 Z
2、读入被include的其它Makefile。$ c8 r B- [: S% M0 R
3、初始化文件中的变量。8 a2 L+ m" P# W* f( i' n% S
4、推导隐晦规则,并分析所有规则。
7 \" l) R9 Q) B; a8 l0 h" [5、为所有的目标文件创建依赖关系链。
3 L. d& R0 o7 y3 ^2 v6、根据依赖关系,决定哪些目标要重新生成。. V* Y! o0 D/ ~6 E. j% I$ l* D
7、执行生成命令0 M3 F5 E: e% l/ z7 z( A6 ^
Makefile中所有文件的搜索路径,包括依赖文件和目标文件。 ; B F! _" b6 X1 t ~5 w
变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序- n. F; N, C6 L! J. d, {
按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
# L i' s4 M) s" i例如:
' F7 V7 k9 Z! x2 }VPATH = src:../headers: ]! g& q( s( Q
它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”0 @0 D) D8 D: i( S4 v9 s
目录下,此时此规则等价于“foo:src:/foo.c” P8 r1 Z% M P, h# R. J! V
对于第二种来说:当需要为不类型的文件指定
6 P+ G1 ]/ o8 `/ e不同的搜索目录时需要这种方式* u5 M7 T' p" j! u1 f/ s2 `# t
vpath:关键字! F% h1 `3 P. [8 x: \0 z5 ]
它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
3 @( Z: i; H1 _它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三
6 M0 ]: t, p& M) U6 F; ~种. B+ K( I& I! o& n- M. n
1、vpath PATTERN DIRECTORIES
9 z( ^9 j! ? R* P4 n为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者' ? H- p' Y9 H6 s1 U1 d! Q
冒号(:)分开。类似上一小节的“VPATH” * v: X2 ~. g8 s- V- A. L
2、vpath PATTERN , p' s5 o' J# b) D* q4 w4 M* `0 X! _
清除之前为符合模式“PATTERN”的文件设置的搜索路径
, M3 p' B% X) i+ i) a3、vpath
: O& j% ~4 E n7 _清除所有已被设置的文件搜索路径。
+ y3 r t) T9 d! Q7 a+ I对于vpath的详细说明待续。
@# O3 x5 e5 }( y在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
]0 N# r, w9 ~& L' \* _VPATH = include:src //指定了makefile的搜索路径
4 }7 x- t. b+ C或者4 b. b6 g, [& A3 F( S% U2 u
vpath %.h include //指定.h类型文件的搜索路径是include. Y n4 L9 o, t1 B$ B" p* ~
vpath %.cpp src //指定.cpp类型文件的搜索路径是src( G5 t$ K4 t" h4 f; u5 B
这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说) W, m4 u7 z$ }5 C; r
在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件
5 b, @$ Z! g' v8 Z+ X' N5 h5 E" Y此时要用到了 -I 或者--incude +路径
" ^4 G( d) k9 p' W7 u例如依赖是:& y0 S3 P6 ^( [" s$ ]
main.o:main.cpp hello.h
$ p0 |1 P t! t7 c) ]1 C+ f$ p- `即g++ -c $< -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件3 R5 k- Y* B: m; f1 x# W: c( a
0 |- P7 T' G2 I9 U; k6 R1 U; Z7 H, @4 \3 W& m/ }
! j- U1 ]1 C1 \5 E+ o
% n3 t; f8 I" Y+ D |
|