一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3383|回复: 0

Makefile VPATH和vpath的使用

[复制链接]
发表于 2017-1-13 18:02 | 显示全部楼层 |阅读模式
开始接触Makefile已经有好几个月了,最近想好好学习学习
  c$ O& g2 N- N, Z6 o3 H5 f& V但是一个简单的问题就卡壳了很简单的一个问题
1 G$ y. \7 L% ^- X8 T  @/ x|-- Makefile3 u3 e8 I) K" i
|-- include
' ?9 K. W0 F! ^8 x|   `-- hello.h
- K7 e. T" j  q0 L4 T5 Y1 c+ W1 f2 ``-- src4 \" c( i0 s: F, c1 w4 b
    |-- hello.cpp3 E4 y4 q6 ]. Q3 T3 S. ?5 R- O
    `-- main.cp' H9 d4 U# \* {* O% q: _
首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下( g! X4 r- h3 X: ]
头文件hello.h在include目录下+ t$ i' q  ^0 s3 |# N1 J
源文件main.cpp和hello.cpp在src目录下; t+ @$ `" ~: Y
////////////////////////////////
0 P5 u( d; Q, a) ehello.h:
7 u, u3 a! H- w9 u#ifndef _HELLO_H__
! D& B  i: l, R  E9 c. ^#define _HELLO_H__1 ^/ e) m6 E1 f& s
void hello();
/ G7 z6 J) n. Q#endif
8 W) m% `: g+ f; W* y; a, D///////////////////////////" Y4 r) m- l( t  h& U  i
hello.cpp:
1 w) P" E6 T* t1 c7 S#include<iostream>
4 L, Y+ }( h8 O- N7 c9 H#include"hello.h": p3 M1 w* ?" V9 O
using namespace std;
6 s3 [( {3 R* V; V. G* |void hello()
5 m' q8 P2 j2 h- @% N+ |{  e! B& T* p5 Q; v1 t7 f
        cout<<"Hello world"<<endl;
1 a: e. R7 I: x% W  J$ @}9 g  V9 [  Q2 u1 l9 U
/////////////////////////////
, h+ e( i3 t% T0 e" F( fmain.cpp:
  [! O8 [" v' i7 E/ ^9 e# W+ H1 F#include<iostream>
- }( V. |8 P' S#include"hello.h"
+ W7 ~+ T% M- t9 ^0 O- yusing namespace std;8 Y) P- m7 X- b. k& t
int main()# m1 G& x" _# w1 n2 x* W5 z0 e5 ]
{
4 E5 Q$ \: o5 i7 D- B6 d) l. x          hello();& _& Y' Z9 K: }' A% `6 u
          return 0;
3 o, D: i9 L( M/ g6 E5 x' n' \$ F}; t- s) Y$ ^4 }, B% Z# E8 P
/////////////////////////////////9 @1 d0 ]& t) _  G/ x! i7 A8 N
Makfile:
  K7 l: d" |$ v- ?% f#VPATH=include:src/ E7 h, j7 p+ R8 g& X6 Q
vpath %.cpp src' Q4 M: F$ I% J$ Y' _$ H- B
vpath %.h include
& J# t& V8 R2 P/ o& d. M7 @: s" y0 K& {test:main.o hello.o
$ D. h( R4 K) v1 g% O g++ -o $@ main.o hello.o" w& P( G( ?6 ]! z# {( v4 T
main.o:main.cpp hello.h
5 m" ~. }: b; ]5 Q4 [$ ?+ ]  w- r7 f g++ -c $< -Iinclude, {  }7 S) c; E, D' E* v
hello.o:hello.cpp hello.h1 _9 c, f& I& I9 G1 \- ]
g++ -c $< -Iinclude
1 T+ X: [% @& L9 a/ U: T.PHONY:clean) B: p) A% t. |/ R0 x6 o
clean:; E6 n2 D* x7 }/ T# ~9 t2 c
-rm test hello.o8 N; d0 u# Z$ k) g
//////////////////////////////////  V3 D& [2 p/ B: n$ K
因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题6 r/ s; O" B- D9 E
同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径
: W2 H9 ^6 N" L  K- U. `另一个就是源文件所要包含的头文件等相关文件的路径。
5 y. m, |* `3 _7 g对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,
6 ^( H5 m. c+ l" ?& M在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。
8 H% I* P- N9 p: X1 u. T: h5 G一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是4 |9 I( r" D9 l- V( ^4 D
首先说明一下makefile的执行步骤:
* w: p9 v( z2 q+ e# @1、读入所有的Makefile。5 q" }* G* E. I+ r) y- s" s$ {
2、读入被include的其它Makefile。  H# i8 N# _' L
3、初始化文件中的变量。
, o* ^/ k, l' O% B& \4、推导隐晦规则,并分析所有规则。
+ Y/ e% b* k0 u5、为所有的目标文件创建依赖关系链。% [+ X4 F" F7 t1 _: ?
6、根据依赖关系,决定哪些目标要重新生成。3 E( [6 h+ s$ \8 Q# t  T2 j
7、执行生成命令: P% C- t& D$ F7 I! J
Makefile中所有文件的搜索路径,包括依赖文件和目标文件。 : |$ H" i! E( t# L$ }6 n
变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序* [! \; j, P  s  i. V( U
按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
' C. G) k5 X' J9 }例如:
* B) h# G* e# B; ^( A) WVPATH = src:../headers
  V8 }8 P4 Y1 `$ A8 s9 e% g, b3 k它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”
$ d; B  B/ }7 ?& z$ Y目录下,此时此规则等价于“foo:src:/foo.c”0 [! x. w; z  P9 j% N6 V
对于第二种来说:当需要为不类型的文件指定4 |/ H8 e; ~- ^# j
不同的搜索目录时需要这种方式
) n5 h1 c0 J- G3 S1 I) o" W8 Avpath:关键字
1 A4 `2 ^) B+ L: [* A它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
  \5 p5 f8 \$ p1 a) Q它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三& b/ B' L2 B( ^
1 @, [4 X9 W1 _6 X. d7 d! E
1、vpath PATTERN DIRECTORIES 9 O" O9 p; U1 F9 [" c
为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者
0 p# q2 L% d8 h冒号(:)分开。类似上一小节的“VPATH”
  I1 k2 M* d3 I. N5 U: {2、vpath PATTERN
0 @! i$ O& i/ ]( ?: w7 r清除之前为符合模式“PATTERN”的文件设置的搜索路径* W4 P. y  P% L6 c9 s" K! _8 C0 f
3、vpath
( \# p0 b1 u! E6 ~9 P' i清除所有已被设置的文件搜索路径。
0 {- N9 X' z# }对于vpath的详细说明待续。- [$ F! g! H8 e' Y# Q
在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
) a0 j# P9 r. m6 y8 i( WVPATH = include:src       //指定了makefile的搜索路径
: c5 P& C* Q. X8 C2 B或者4 ~1 F  E. v+ b; n
vpath %.h include    //指定.h类型文件的搜索路径是include* m4 c, d+ D- j% K
vpath %.cpp src      //指定.cpp类型文件的搜索路径是src+ K9 @! Z5 q+ A2 X" A* |8 j6 s
这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说4 ]4 C4 R7 z/ H" b8 o* |1 W7 h
在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件# M6 ]# k0 v( {2 w" Z) `
此时要用到了 -I 或者--incude +路径
) t* [/ C, l3 C; i+ ~( ~例如依赖是:
; T. O4 }5 J$ U, {* [+ U2 |% lmain.o:main.cpp hello.h
# b  W7 d2 u% X. K; b* t1 A6 H即g++  -c  $<  -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件
" O$ k" K" a" v' W

5 v: |) @. ^( {  P/ z+ O0 S- x- I$ @

2 A+ x( g9 A+ K8 @7 |' {" _
! O7 o6 r8 J. C: t# ~

本版积分规则

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

GMT+8, 2026-2-25 13:17 , Processed in 0.029021 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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