一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3113|回复: 0

Makefile VPATH和vpath的使用

[复制链接]
发表于 2017-1-13 18:02 | 显示全部楼层 |阅读模式
开始接触Makefile已经有好几个月了,最近想好好学习学习
6 |) X0 ~7 R$ |/ }3 e但是一个简单的问题就卡壳了很简单的一个问题, e3 G. M( L1 L' D  K! Z- O
|-- Makefile
$ @# h* b; k4 M: O+ u, _|-- include- z" T. P. p$ Q
|   `-- hello.h
3 h" G- F/ [6 M7 A6 ]8 ~; ?`-- src
! o4 K$ J& k3 B& h- m9 q& \    |-- hello.cpp
& I9 ?- w' ^3 y, g& W) _    `-- main.cp2 Y! Q2 q5 D3 ?& l$ Z1 v
首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下9 m, a9 M# A1 `/ r) ~* v
头文件hello.h在include目录下- F2 U/ b. A# |: S4 q
源文件main.cpp和hello.cpp在src目录下1 J3 Y1 j" `  U1 h1 }4 R
////////////////////////////////
, s( l; Y2 T5 o3 G& B7 i: v2 _# B7 T& shello.h:$ o& I' X5 O) C: W: r
#ifndef _HELLO_H__
1 y$ F. Z5 d4 B+ R#define _HELLO_H__
- [# f. {1 ]* J" x9 c( p" J: j5 nvoid hello();
: P- W8 `2 |7 f( P  g#endif/ E& G  O9 R* j  Y! }/ P3 c
///////////////////////////, K3 z2 r% F7 u$ U
hello.cpp:
* W# {& {6 H7 M" f8 G$ I" P#include<iostream>
$ m! G9 v( i8 ?( M* L! H5 i; S#include"hello.h"& p7 `# x+ E) e; [; c0 b( s
using namespace std;3 e. O- V( ?  @; G  S) e
void hello()
& L! S2 R% R6 {+ [3 g# _$ G- B1 u$ p{1 \/ X7 @0 y# V0 z1 b+ k
        cout<<"Hello world"<<endl;! K: L$ F8 W) C; [
}6 m; x* F- U5 U
/////////////////////////////0 t; ?/ B3 x9 j: b
main.cpp:5 f# U- x2 y# Q
#include<iostream>
  O$ |& d6 D7 `2 f# D/ |#include"hello.h". _8 K, U: o" |; t1 L1 ~% J& L
using namespace std;7 C8 r4 f7 ?. \
int main()9 s  b/ p  X! u! D5 _( j
{
. D4 q3 c3 y8 O6 W( k- X          hello();8 }5 v$ Z/ T% m, h  R
          return 0;
, a. E, k! J4 n% `}
3 t6 \: ], y6 p8 f% r7 u# L5 m/////////////////////////////////
  m+ @4 n# P: q0 cMakfile:
. C, ^, z" ^) V8 T' @: e#VPATH=include:src8 Y% |- c! v3 H: ?* n# Z; G/ i9 \
vpath %.cpp src; V, O% l$ M4 H, h
vpath %.h include+ h4 A" Z0 B8 O) A, {
test:main.o hello.o3 J  q7 Z+ z4 k: y
g++ -o $@ main.o hello.o
+ ^* A5 }/ v- T6 H! \. {0 Pmain.o:main.cpp hello.h
2 u, @7 O: w  p" r! l  j( ~; M- r* _ g++ -c $< -Iinclude8 K, @# R* u* \) @' [8 S
hello.o:hello.cpp hello.h4 C/ G; E# {/ g( T
g++ -c $< -Iinclude8 S3 E) W. T; ?
.PHONY:clean
; P$ v: R& I$ |& g# mclean:5 y  _9 b- ]+ p' m
-rm test hello.o
) F' {* k2 s5 a//////////////////////////////////
% D; J" ~+ K, Y因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题
7 |! e( n0 i% A) `% x/ i同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径- D$ @& R+ I! n6 ?/ G9 S" W
另一个就是源文件所要包含的头文件等相关文件的路径。+ C6 m# _) P4 P4 G+ j
对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,
! u7 w% J* p7 t, @" S在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。. U8 U% i8 t4 X" d. [
一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是8 h! a9 Q$ r) ^
首先说明一下makefile的执行步骤:# P# b- k/ I: m* |+ C. M
1、读入所有的Makefile。3 ^/ x7 U# a, Z$ A; F$ Q1 ?
2、读入被include的其它Makefile。2 {, I9 H& p5 |0 {0 N& F- P
3、初始化文件中的变量。' c$ _% e# h, d& m
4、推导隐晦规则,并分析所有规则。3 K* I' h0 n" D
5、为所有的目标文件创建依赖关系链。
( Q5 a: k5 |; f9 d( w! T6、根据依赖关系,决定哪些目标要重新生成。
1 D4 x5 u4 K% h7、执行生成命令
  X7 w1 x: Q# D% x( OMakefile中所有文件的搜索路径,包括依赖文件和目标文件。 " _) b. d4 A" H4 A" y7 J
变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序4 k1 N' A* c; G5 {- A
按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
8 G/ ~! n  e$ q- m例如:
$ O' Z# P8 F  S4 h1 ZVPATH = src:../headers
* N# t- ?. h0 ]! u! q! }' f" r: L5 j它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”
( u. r' _# ]4 u; ]' k0 s目录下,此时此规则等价于“foo:src:/foo.c”9 t! U6 j3 W# t4 g& `/ g0 B, m/ y
对于第二种来说:当需要为不类型的文件指定+ Z. u/ U' H7 Y0 K
不同的搜索目录时需要这种方式
% P7 s, X  G* A6 |- ?7 R( kvpath:关键字
8 c# }2 I1 n  R: K- I0 n它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
% V2 P: y  n  p- q! q% C: o7 a它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三3 ^7 |) A- v* ]5 k' t
" T* @3 s/ E, N2 w# Q
1、vpath PATTERN DIRECTORIES
  c9 ^# `; a1 Z" L+ J为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者2 X8 s* B: e2 x& w
冒号(:)分开。类似上一小节的“VPATH” 9 f, o9 x# W+ S& @
2、vpath PATTERN
. |7 L+ f# w, M清除之前为符合模式“PATTERN”的文件设置的搜索路径5 j  T  ?, ~. w, R  C
3、vpath* Y0 T. S7 n0 ~
清除所有已被设置的文件搜索路径。. |  u) |& r# i% d8 m) _( L2 F
对于vpath的详细说明待续。
: v* m9 Q, _+ n' Y' Y. g在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
1 Z/ H/ M+ D, hVPATH = include:src       //指定了makefile的搜索路径* i4 f2 ?: l- a2 E8 w5 g# e
或者
7 z1 Z* J  c9 E& Qvpath %.h include    //指定.h类型文件的搜索路径是include
# p8 z7 g8 w3 Zvpath %.cpp src      //指定.cpp类型文件的搜索路径是src0 e4 u1 U; x+ {2 |4 y/ [" y: z
这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说
. C: e$ k' j5 a8 X) t5 d在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件
0 j; N* x' U; ~3 U) F, y" A此时要用到了 -I 或者--incude +路径
7 D" w- P3 \  a+ l3 N" t2 G例如依赖是:) D( m/ i7 d+ [5 j6 h
main.o:main.cpp hello.h" n* ^" A: J0 J: J7 E. b! u* r
即g++  -c  $<  -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件
& n5 v0 m* C. @4 m
3 p' M# h& @& W$ W0 i

' S0 a" S4 N9 u
: Z' X1 l0 g2 t3 {0 z

+ m- L2 W) q. `) H$ p+ A

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-10-27 09:34 , Processed in 0.029840 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表