一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3492|回复: 0

Makefile VPATH和vpath的使用

[复制链接]
发表于 2017-1-13 18:02 | 显示全部楼层 |阅读模式
开始接触Makefile已经有好几个月了,最近想好好学习学习
! g( R% f9 Y# ^" S4 L0 d但是一个简单的问题就卡壳了很简单的一个问题
8 D& m' x) }% x|-- Makefile+ s# n) z' @6 s" z) Q! l  y
|-- include* Y1 S# _# T0 u, g+ z, x9 T  f- Y
|   `-- hello.h
) Y: x5 D* P9 J/ }6 w+ T, u`-- src
1 C! A! u# q$ B, F) p    |-- hello.cpp
0 T) C* u# l8 X& |$ v    `-- main.cp
2 V. q* l/ T) W" W首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下
, g4 a- ]- r5 T# ?% w8 N. n7 Z头文件hello.h在include目录下2 |; K& Y4 F" ]
源文件main.cpp和hello.cpp在src目录下9 N! b( M5 h0 q+ @, h+ f
////////////////////////////////, B8 d. T4 [2 D2 |, O1 C; [# Y
hello.h:
) y1 A! \! u/ h( ~#ifndef _HELLO_H__
$ r' Q8 y1 S. `. d#define _HELLO_H__
+ G1 E7 B* l$ g( n5 X* G. ~void hello();
3 v5 D2 h2 G- @9 [#endif$ U% d7 I! e' Q; g7 v, w) m
///////////////////////////8 m- o! a6 ]* [0 [% H. ?+ x9 S
hello.cpp:; ]& B0 d- I4 R) q4 c
#include<iostream>5 m1 C1 z. l5 @/ B
#include"hello.h", p  H) r7 R/ H$ Q: @
using namespace std;
" S3 a2 @! A1 P1 N; M4 y& Qvoid hello()4 r( o7 ~. q7 C1 J* W/ _5 w1 s
{& ~) b+ u' _4 x) y0 y0 ?# T, B
        cout<<"Hello world"<<endl;
8 e$ U; y+ w: K: u% d- m$ \! |}
. w3 Y' T% w: C0 T2 S9 [/////////////////////////////
( b2 p' ?, d4 A( Dmain.cpp:# a3 g$ `' Z* _3 I, q0 G% O
#include<iostream>0 Y* c5 ?( o7 }  D$ }# I. l
#include"hello.h"
; e! [9 b# w4 M" F) zusing namespace std;1 S9 w' n1 O( e) Y  h
int main()
- Z4 V- a- L% m5 s% T6 p{
3 x) k* m$ ^4 F! ?- G          hello();
$ t: |0 |4 T! ?9 o. [          return 0;
. D  u  i0 Q4 x: [5 W: t}; y1 M. u3 N8 N5 u' v5 \3 S2 n
/////////////////////////////////5 }  i2 o3 X; F( ?! W& }9 }8 _
Makfile:7 f- S% \9 o6 I- V4 P) c# t0 V2 l! d
#VPATH=include:src
0 R) v7 l+ s  _5 E9 p+ D/ k, Qvpath %.cpp src- F, |, @  m# [& u- ]- b
vpath %.h include! S' Y, U6 `2 N1 H9 n6 O( T. f8 b
test:main.o hello.o2 P8 L0 Y/ b9 r3 X8 d/ y2 v
g++ -o $@ main.o hello.o* a4 Q  m! L5 p) k9 n, x" }
main.o:main.cpp hello.h' ?/ V: j- A. F! b4 q( k
g++ -c $< -Iinclude) O: e+ ]. C2 q: j3 l0 _
hello.o:hello.cpp hello.h
+ _$ B" k( g3 E; B" B0 f g++ -c $< -Iinclude
/ e* a$ I* `4 S* x$ P6 ]& b- R( n.PHONY:clean
$ T3 R% D2 i4 v5 s  a0 kclean:
; l9 z; t. R  W$ b6 H- b- @ -rm test hello.o. R8 N) E" d' U4 s! ?
//////////////////////////////////
1 d7 F; ]& N" x% x1 y' r. R因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题
& j; u7 b0 C8 x同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径) c, }  h5 J$ ^/ T* K3 T3 K
另一个就是源文件所要包含的头文件等相关文件的路径。
, {* C# }. _! f' Y; z) g& H9 Z对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,  P; ~0 g# j" o8 j
在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。" L+ J' E. q7 S
一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是
( V6 X0 M+ [0 R; J" x首先说明一下makefile的执行步骤:
4 x- L) j- O! M1、读入所有的Makefile。3 E: N) {6 F. R
2、读入被include的其它Makefile。
- R9 K8 N  k, y3、初始化文件中的变量。+ I) V" [, J# u0 P' O; Q# a
4、推导隐晦规则,并分析所有规则。
: b# H7 l& q9 R5、为所有的目标文件创建依赖关系链。; t# c( N, z* K" W% [
6、根据依赖关系,决定哪些目标要重新生成。
' Z* j6 i, S: Z- K9 a) r* ~, r% b7、执行生成命令
4 G$ h  k; @9 ^8 H8 c7 k) mMakefile中所有文件的搜索路径,包括依赖文件和目标文件。
' Y9 S4 F) Q: D4 _  A: q8 W% n- n变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序
0 }* F( n7 B1 {+ f0 X按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
% z( {( M' {6 U3 {# Q9 E例如:# ?2 I0 ^/ U7 y
VPATH = src:../headers
# X0 e3 j# j4 C6 f7 i# |它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”5 K5 ?% s! N# ]; r0 V" v* f
目录下,此时此规则等价于“foo:src:/foo.c”
3 {# T" Z, _$ n& ^: F8 A对于第二种来说:当需要为不类型的文件指定8 |) y3 I% K9 F: |  O9 T; [/ ?( k
不同的搜索目录时需要这种方式+ H/ [$ L* S& ~' E8 U7 ~
vpath:关键字
* j+ [0 [* x& P! L8 b/ i6 @它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
, d, ~, j# l  j& W, n- i它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三  l- `& @! p# U( h* p$ t$ c0 J+ }

  f$ }, B' Y& l1、vpath PATTERN DIRECTORIES 7 E, Q  H8 C1 v- s  B; d. L
为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者
. ~8 x; k6 f% A/ T8 U+ L& ]- J冒号(:)分开。类似上一小节的“VPATH”
0 ^0 `" y& P; j# A+ r/ q2、vpath PATTERN 9 c; O/ K& s; _7 M! Z# I
清除之前为符合模式“PATTERN”的文件设置的搜索路径
+ o( N; x/ t# T2 m+ Q3、vpath
7 B4 X) O: v& P5 ]4 _' A0 g8 d清除所有已被设置的文件搜索路径。
& X. A  Y7 R+ W0 V: V1 i对于vpath的详细说明待续。8 c; q: K' ?; Y5 S* _* e4 |
在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
; e& g, s8 Q" G1 \  Y8 _VPATH = include:src       //指定了makefile的搜索路径
+ b: ]/ B! a) Y. [7 J0 b% U或者9 G" z4 o/ |- E6 i' s8 s
vpath %.h include    //指定.h类型文件的搜索路径是include
1 Q0 k7 t+ m/ S! Nvpath %.cpp src      //指定.cpp类型文件的搜索路径是src
! S8 Y0 r! }" t6 ^2 R0 {, C这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说
2 Y, _& R. E0 C. T4 A在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件" y8 K6 t" m8 g! F( y* A9 f
此时要用到了 -I 或者--incude +路径4 n* _1 o3 @" f; E" _+ U3 }
例如依赖是:
  k3 k3 J1 ^* L. I% a- p1 @, ~main.o:main.cpp hello.h9 {! T+ u1 d; ~: D6 B  ?( n
即g++  -c  $<  -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件
; Z$ F3 U1 F: S7 C0 d' ?

( t2 ?# V  Z# q6 Y5 y
% s# w0 i# Z; ?2 j1 |" A

3 S/ V' V% o6 C8 U& z9 S8 ?, S# ~3 x# H) |3 ^2 H

本版积分规则

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

GMT+8, 2026-4-17 16:25 , Processed in 0.028257 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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