一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

搜索
查看: 2955|回复: 0

Makefile VPATH和vpath的使用

[复制链接]
发表于 2017-1-13 18:02 | 显示全部楼层 |阅读模式
开始接触Makefile已经有好几个月了,最近想好好学习学习4 ~/ r; ^) {" w7 ~3 Y0 ]- f+ b/ q
但是一个简单的问题就卡壳了很简单的一个问题5 ]1 \/ E6 N! ^( H; W* d4 t
|-- Makefile
( ?+ C8 Y; V! g. N|-- include: M  \6 E# ^/ j9 \
|   `-- hello.h
6 x5 \; H3 B& h% \/ f`-- src5 D6 ]& {0 B1 H
    |-- hello.cpp. N* L4 c1 C* C5 X$ G" P
    `-- main.cp/ B6 Z$ y; \7 n2 B
首先是Makefile 文件和include文件夹还有src文件夹在同一个目录下) }1 c. D( n# _9 z" Q
头文件hello.h在include目录下
* A  Z+ X# ^& B9 y" L' r源文件main.cpp和hello.cpp在src目录下
1 E" k+ d4 N7 X3 @////////////////////////////////$ C! a* J+ F% ]
hello.h:
. M/ K' Q8 N. R2 @* x1 j#ifndef _HELLO_H__
$ ~7 r) X9 n6 D: R5 ]#define _HELLO_H__2 q* l: M* Y/ V" V
void hello();6 l; X" Q1 v$ ]3 a1 h
#endif
+ }! P: \4 W+ o- w. z! F2 s///////////////////////////
9 }3 X5 v! [6 M' g/ D9 D3 n8 b- dhello.cpp:9 d0 x3 K9 O8 @
#include<iostream>- U6 K7 s& m' ^" [
#include"hello.h"! [, Y. }0 g+ @3 i- B
using namespace std;" |# O# Q3 }- \1 U' }
void hello()  W; J4 Q0 S4 \/ w
{: G1 B! y; Q+ w" D& B2 a+ @! H
        cout<<"Hello world"<<endl;% r+ K! n8 J1 t8 [
}8 u3 l8 {# {( l) c5 x7 }
/////////////////////////////6 F4 Z8 d8 R+ b, u& f
main.cpp:
4 O" c) Z5 o# O5 M1 a#include<iostream>
: W. p7 Z  @  ]! Q, n# L+ z' Q, j1 i#include"hello.h"8 M" [1 Z. C& L/ m1 q
using namespace std;3 N& F1 q$ q% ~5 K
int main()
; l) o; q* L. E! y1 j+ ]{
+ W& M$ \* _1 {( u  G& H          hello();
  X# b; X8 ]4 G+ ^8 `$ ^4 J2 o          return 0;1 Z3 _- M) y$ |! t' e: O# l1 G
}" i" a4 o; o. a  V- S* m/ k. X
/////////////////////////////////
9 i0 e9 _$ T& T% JMakfile:4 ?3 S1 b( L( F, }& Y
#VPATH=include:src
" T( M8 ?- m- tvpath %.cpp src) [: y$ o) O3 t; o9 h& ~
vpath %.h include& |+ }, T- f% o4 e* [
test:main.o hello.o- Q7 X- a6 `1 s, W8 T% m
g++ -o $@ main.o hello.o
- @; l& c: k" q; emain.o:main.cpp hello.h
3 b9 v7 ^  [5 Z. ?0 x+ e' T2 k g++ -c $< -Iinclude
# M  p( B. ]3 |hello.o:hello.cpp hello.h
; O) b  j: |/ @3 T( U g++ -c $< -Iinclude
9 {- w+ X& s- e.PHONY:clean
- }, C9 `+ Z5 q( j0 ]6 L8 Q' ^clean:
  ?1 ?% G7 Y2 v" _ -rm test hello.o
( ]* L. ~7 B7 y2 C) e//////////////////////////////////
* k) M; [: U$ G; @因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题7 e% E6 G# }$ n" m  h. X
同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径
) V7 p6 Y& T) q1 {5 X' b/ N另一个就是源文件所要包含的头文件等相关文件的路径。
) K6 Z2 W! E  @7 t. u0 e8 @( \; U9 t对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,
4 w0 _5 y, e8 I3 w! t6 K在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。
4 S* o0 D" H6 n$ U: W& q8 M一般我们都是用此变量来说明规则中的依赖文件的搜索路径。其实“VPATH”变量所指定的是% t! C, s: h: [: m* r' t
首先说明一下makefile的执行步骤:
7 P- j2 B! c; v4 ]1、读入所有的Makefile。
3 k8 ?* f4 U! h/ b% V/ v- e  _7 z4 W2、读入被include的其它Makefile。
3 [" P4 k  X7 H. S8 v, T3、初始化文件中的变量。
/ c" k' K! h, x3 `6 s3 |4、推导隐晦规则,并分析所有规则。
; V, L" |) R+ K' l5 o  [; [' _- W5、为所有的目标文件创建依赖关系链。/ F4 [* F! E1 D, _5 n3 u1 z9 ?$ P
6、根据依赖关系,决定哪些目标要重新生成。
) ^( K- J8 C. R8 z4 c1 D7、执行生成命令- V- `! d9 d( z: L5 f& i/ x" z: j
Makefile中所有文件的搜索路径,包括依赖文件和目标文件。
: f: x; n5 w6 I' _7 j* _变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序
. I6 M- {& ~, j4 k& J  K- t; [按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。
& t8 {- d1 q# v; }$ e例如:
# T8 L; |- z- \6 s  ~" ~VPATH = src:../headers
$ }+ H3 R7 q) D/ t- e它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”
" ?! i4 E" J, L. W# Y2 X( @目录下,此时此规则等价于“foo:src:/foo.c”/ \! h1 r2 h0 r/ `8 u
对于第二种来说:当需要为不类型的文件指定* o' u; r( G& }& S/ i2 g
不同的搜索目录时需要这种方式
( o  V" {3 b* [2 u9 F4 uvpath:关键字5 r- _7 m( r: `. m- A5 W
它所实现的功能和上一小节提到的“VPATH”变量很类似,但是
; w, ~' Z( d( q$ f9 l, c/ G它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三6 h; ^" H* e* _
, R2 D; ^, j" R2 d5 C* P
1、vpath PATTERN DIRECTORIES . B8 z. T  r; r; C. j* f
为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者4 r; p" w" k% D% C5 j) u
冒号(:)分开。类似上一小节的“VPATH”
, |. s% s$ R8 T, ~4 N2、vpath PATTERN / [& R7 W) i7 f2 ]
清除之前为符合模式“PATTERN”的文件设置的搜索路径
5 B" A# \6 Z% v+ a8 U9 a9 s3、vpath5 v/ B! z  t# ^! a
清除所有已被设置的文件搜索路径。$ L# H7 E. l2 g, N
对于vpath的详细说明待续。& H3 n7 n* @0 i5 \4 T' `9 b
在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么
3 N% h# K2 E' c1 W8 Y0 rVPATH = include:src       //指定了makefile的搜索路径
! ?; S( c( P$ V- I4 b. W或者
% r  X( ~5 k% U9 ^7 A% L; Y( \; _vpath %.h include    //指定.h类型文件的搜索路径是include
, J+ {2 _- P5 z3 C1 e2 A6 ~vpath %.cpp src      //指定.cpp类型文件的搜索路径是src
% R4 {& S) h& h( H这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说
# f" D8 a; W3 q+ m& k: z$ s在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件
% s* o# a- |# n3 j9 r  P* {' a6 ?此时要用到了 -I 或者--incude +路径; r5 L% }5 Y( @. g5 ]2 l& ^6 D
例如依赖是:
. C. d2 d4 _/ Y* ?- y/ J( Lmain.o:main.cpp hello.h
2 H, l  p, t1 `. Y$ o即g++  -c  $<  -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件
8 ?( ~8 @5 s; e( `7 J" m8 Z2 m+ U1 Y
6 a+ F7 s; \  S- \1 |3 E9 m

7 h7 f- N, C( h7 [3 G+ g. Z
+ _3 @% L8 A. x/ l  t
3 E' k! n- ]6 M( y7 L* \/ x( c

本版积分规则

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

GMT+8, 2025-8-20 09:04 , Processed in 0.029847 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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