一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3244|回复: 0

Makefile VPATH和vpath的使用

[复制链接]
发表于 2017-1-13 18:02 | 显示全部楼层 |阅读模式
开始接触Makefile已经有好几个月了,最近想好好学习学习
: d/ {; [* L& n9 {: ~1 e9 S( @0 h但是一个简单的问题就卡壳了很简单的一个问题; |, A* a5 _% _
|-- Makefile& E1 u0 ]3 ?2 h$ c6 T. B
|-- include( f* a* V( f1 w& m
|   `-- hello.h
' P  P# K0 D# x% J2 V" e/ S3 v`-- src
$ F3 ~% u: I8 M5 O    |-- hello.cpp8 s. |) ^5 |4 K  m% v+ U0 R+ P
    `-- main.cp
8 Q2 [. Y; P. \/ [& V! Z$ f! U4 m首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下8 D$ K3 e$ b2 H, o) q* ^8 ]
头文件hello.h在include目录下
$ I% A$ X2 D) W- t源文件main.cpp和hello.cpp在src目录下6 J; M; F* h$ n/ V1 v+ R
////////////////////////////////. g4 w! f: W/ Y- C" d
hello.h:# w& d+ ]% d3 Y3 f) }
#ifndef _HELLO_H__
. M& j+ S! I' j#define _HELLO_H__+ r: Z& G, B7 Y) f* ]) }
void hello();$ J$ e+ W2 j8 s* F0 s& V
#endif
$ V  M" U1 j; \3 C! E2 E! e///////////////////////////) i! i# S8 `0 e: R9 b9 K  N
hello.cpp:' c/ S6 U: |* @/ i$ @
#include<iostream>
1 ^8 f- m; g2 Z9 }- b& P#include"hello.h": V" q/ j4 z; W) a- k" G9 k
using namespace std;' i- |( ~  P) I( v- x) n0 [% U* J
void hello()
! I9 D7 H) l: |2 X  M' J% m6 D9 a{# q+ _  ^' B2 H" u8 e' O# j
        cout<<"Hello world"<<endl;
* h2 ^- D9 z) q+ E}* n* M% t' f+ R4 P1 m% C& S: Z
/////////////////////////////
3 Q0 f- p4 G+ `: E8 R7 r1 xmain.cpp:" U4 Z# @! ]2 E/ u
#include<iostream>
0 S4 M' ?1 Y% L$ Y9 \  g2 Q#include"hello.h"+ f# B0 ?1 ^+ N  r/ c! S' W
using namespace std;* i) J6 n& h2 e" u  s+ r
int main()
( w# I# r, N+ e/ e1 m" A{: I0 G* n. x6 y1 q9 p- N0 k
          hello();' {; ~) j9 M/ n
          return 0;( S" i7 d" l" ~2 m' o; v
}! U3 o/ _" [' g# v; n
/////////////////////////////////
2 ]6 t& h$ K2 N! |! t. nMakfile:
+ f( U! j) R1 `  V$ H# U) W#VPATH=include:src& F$ C" C/ U* k2 H1 n
vpath %.cpp src
* G2 p; X8 G3 g% a  t! e- Svpath %.h include
' g* N7 t; e0 D% k5 p# ~& X, ]test:main.o hello.o( n, h; ^. j% y! G, z8 @/ [, q
g++ -o $@ main.o hello.o
# m% h4 N( ~/ a) ]main.o:main.cpp hello.h
" j3 k- }& b( C% b! J g++ -c $< -Iinclude  F7 p0 d* D. W; h  c+ S/ u
hello.o:hello.cpp hello.h
( f8 }; s) Y: S+ x( H# c; ^ g++ -c $< -Iinclude2 a# P( j0 R$ t) Z% o8 J& e
.PHONY:clean- Q2 b  a, t( [$ Q4 M+ y4 I  ?8 P7 s
clean:
  ~6 U: Q! s  Q1 S( u5 M5 X8 j# S -rm test hello.o
% r8 C1 O+ p( w! o# A" U//////////////////////////////////0 C8 E. K* z0 V1 Y8 z
因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题
7 W4 i/ u! o+ Y0 R同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径1 d$ q( X/ `8 {& O& x2 ^5 w7 I
另一个就是源文件所要包含的头文件等相关文件的路径。
1 [! a- w  k6 [4 _$ B对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,9 V% ]& P- X) _& n8 T* }
在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。
9 K3 U5 c8 w+ [9 N$ W3 C一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是
+ z! `2 A) q# _' Q首先说明一下makefile的执行步骤:
8 b9 l0 ^. ?7 s/ B7 V- e$ r1、读入所有的Makefile。( B* R' p' Z/ L* E) t
2、读入被include的其它Makefile。  _  L& P7 H# S" [, @
3、初始化文件中的变量。& f7 H$ I8 h# x7 R) x
4、推导隐晦规则,并分析所有规则。
$ h4 e* n9 x( A1 @5 z5、为所有的目标文件创建依赖关系链。
' x( {) L/ m4 c, x9 K6、根据依赖关系,决定哪些目标要重新生成。
  }+ x/ ^) |7 N- q" g: J7、执行生成命令
7 B& }: e+ L8 t% c. {% dMakefile中所有文件的搜索路径,包括依赖文件和目标文件。 - @' K. L6 A. Q1 F1 P. M
变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序& H  Z( P( d: S; I  }/ V# D
按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。. x4 U( C$ K3 D0 A7 W
例如:
  x* R( c/ J4 h! MVPATH = src:../headers
( M! g% N' P  _) f% [' Q" @. o它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”+ _) V, ~, B# t+ X
目录下,此时此规则等价于“foo:src:/foo.c”; ?6 L2 ^' s, F1 U9 Q- s. D
对于第二种来说:当需要为不类型的文件指定% C' B! e' L" Z( l
不同的搜索目录时需要这种方式+ w9 v, q: _5 o" |+ J5 z
vpath:关键字' @; ?1 z; v0 b( B, P
它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
5 A' v! B7 i; M; C它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三
3 o- u% ^3 E; x7 v, t2 Z9 {* o, B, v& N9 T. R7 p
1、vpath PATTERN DIRECTORIES
& V- L( `1 J# y$ F5 `+ M为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者0 H  S" |" \/ r# T, Y) M% C8 L& }/ D
冒号(:)分开。类似上一小节的“VPATH” $ ]& _8 q0 \1 l% Q0 U  h7 S
2、vpath PATTERN ' C+ B  ?3 \* S. V, D4 u6 q
清除之前为符合模式“PATTERN”的文件设置的搜索路径; x0 J6 q0 I) |
3、vpath
1 p: p0 i$ b) Q$ O: A6 A清除所有已被设置的文件搜索路径。6 K( G% m& Y5 G  q
对于vpath的详细说明待续。3 D" v4 e5 G, L, f& s
在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
; ?9 }* C3 z- {: e" BVPATH = include:src       //指定了makefile的搜索路径
- C, j% S, w8 `: n, Y或者+ {6 W6 \1 H5 c. F
vpath %.h include    //指定.h类型文件的搜索路径是include
* }4 [, ^; f( F2 j7 \$ \) n0 avpath %.cpp src      //指定.cpp类型文件的搜索路径是src
5 ^7 K- J; _1 q6 o1 w这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说) Y( n& q' {8 b6 u0 P
在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件
5 i' M5 g& V2 w5 L! d此时要用到了 -I 或者--incude +路径4 Y8 r/ Q5 W7 ^, r/ W1 ^" O2 m
例如依赖是:7 p7 a% n' U8 S! p# q
main.o:main.cpp hello.h' |/ X$ W( r6 t0 Z, w
即g++  -c  $<  -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件8 B- j; R& t9 V( O  w% x
4 a3 @3 A; y2 v, p0 I: k
* }' S% @8 O/ q, R0 G6 ?

. B$ P, C$ x: `1 l/ Y3 E- x7 k$ f/ m

本版积分规则

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

GMT+8, 2025-12-13 20:50 , Processed in 0.029797 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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