makefile文件编写 文件在C#中有用么?

向大家推荐一个C/C++通用Makefile
本文推荐了一个用于对 C/C++ 程序进行编译和连接以产生可执行程序的通用 Makefile。
3 U& N* l3 Z) O( h) |' l$ q& @3 j&&F. W) z! C 在使用 Makefile 之前,只需对它进行一些简单的设置即可;而且一经设置,即使以后对源程序有所增减一般也不再需要改动 Makefile。因此,即便是一个没有学习过 Makefile 书写规则的人,也可以为自己的 C/C++ 程序快速建立一个可工作的 Makefile。
9 d# Y6 S: O8 d2 ~8 }& p7 }. k+ t& _* ] * I( k5 V6 C* U0 o这个 Makefile 可以在 GNU Make 和 GCC 编译器下正常工作。但是不能保证对于其它版本的 Make 和编译器也能正常工作。 * }% y8 b+ z& Z$ r1 Y, K- I9 Z; Q6 ?- D6 d 此 Makefile 的使用方法如下: 6 M% ], D/ ]) x* n) `9 X: A& B& k7 _&&_ 程序目录的组织 8 M9 F& d+ s8 I, r' L5 ^ 尽量将自己的源程序集中在一个目录中,并且把 Makefile 和源程序放在一起,这样用起来比较方便。当然,也可以将源程序分类存放在不同的目录中。 0 Q+ y, T' L& N; y 在程序目录中创建一个名为 Makefile 的文本文件,将后面列出的 Makefile 的内容复制到这个文件中。(注意:在复制的过程中,Makfile 中各命令前面的 Tab 字符有可能被转换成若干个空格。这种情况下需要把 Makefile 命令前面的这些空格替换为一个 Tab。)
8 x9 M- g8 N& m 将当前工作目录切换到 Makefile 所在的目录。目前,这个 Makefile 只支持在当前目录中的调用,不支持当前目录和 Makefile 所在的路径不是同一目录的情况。6 L. J8 u& B0 z% [* ~& N
9 E' ]' w# R. T: G% h指定可执行文件 &&^. A&&d8 z7 K. t, F* | 程序编译和连接成功后产生的可执行文件在 Makefile 中的 PROGRAM 变量中设定。这一项不能为空。为自己程序的可执行文件起一个有意义的名子吧。 * [1 H7 |- t* O& y1 Y' R5 Q2 W& n/ L1 a/ ?' A3 o 指定源程序 ! F) |- [, C; A) o& f) e2 I; G 要编译的源程序由其所在的路径和文件的扩展名两项来确定。由于头文件是通过包含来使用的,所以在这里说的源程序不应包含头文件。
&&A1 z( S7 T/ B6 V 程序所在的路径在 SRCDIRS 中设定。如果源程序分布在不同的目录中,那么需要在 SRCDIRS 中一一指定,并且路径名之间用空格分隔。 4 t. y# m1 X& q+ x1 {8 X0 O0 L 在 SRCEXTS 中指定程序中使用的文件类型。C/C++ 程序的扩展名一般有比较固定的几种形式:.c、.C、.cc、.cpp、.CPP、.c++、.cp、或者.cxx(参见 man gcc)。扩展名决定了程序是 C 还是 C++ 程序:.c 是 C 程序,其它扩展名表示 C++ 程序。一般固定使用其中的一种扩展名即可。但是也有可能需要使用多种扩展名,这可以在 SOURCE_EXT 中一一指定,各个扩展名之间用空格分隔。 3 ^9 R3 ?0 |& i# P8 J9 @3 s7 k7 m 虽然并不常用,但是 C 程序也可以被作为 C++ 程序编译。这可以通过在 Makefile 中设置 CC = $(CXX) 和 CFLAGS = $(CXXFLAGS) 两项即可实现。 - u7 `0 [, A+ g& r2 |. } 这个 Makefile 支持 C、C++ 以及 C/C++ 混合三种编译方式: ! \&&o9 b8 s7 z* r1 l8 Q& ?; q) E: y3 X/ P2 o) }+ S 如果只指定 .c 扩展名,那么这是一个 C 程序,用 $(CC) 表示的编译命令进行编译和连接。 $ {: [6 k: P9 E% d! P) Z, o. \' e7 [2 i3 W* ~3 X 如果指定的是除 .c 之外的其它扩展名(如 .cc、.cpp、.cxx 等),那么这是一个 C++ 程序,用 $(CXX) 进行编译和连接。 - m( r/ f) E/ a, _; F, p: z 如果既指定了 .c,又指定了其它 C++ 扩展名,那么这是 C/C++ 混合程序,将用 $(CC) 编译其中的 C 程序,用 $(CXX) 编译其中的 C++ 程序,最后再用 $(CXX) 连接程序。 - d% ^7 p- p! S, S1 y& F 这些工作都是 make 根据在 Makefile 中提供的程序文件类型(扩展名)自动判断进行的,不需要用户干预。 9 n8 M( N- P, a/ Y( F4 S3 w. Q( S1 I& E. R( e3 ` 指定编译选项 . y&&|1 t& n/ t 编译选项由三部分组成:预处理选项、编译选项以及连接选项,分别由 CPPFLAGS、CFLAGS与CXXFLAGS、LDFLAGS 指定。 , S: {- O* J5 B4 |# d! B, P CPPFLAGS 选项可参考 C 预处理命令 cpp 的说明,但是注意不能包含 -M 以及和 -M 有关的选项。如果是 C/C++ 混合编程,也可以在这里设置 C/C++ 的一些共同的编译选项。
8 ?) t& Y2 `$ I8 O) Z CFLAGS 和 CXXFLAGS 两个变量通常用来指定编译选项。前者仅仅用于指定 C 程序的编译选项,后者仅仅用于指定 C++ 程序的编译选项。其实也可以在两个变量中指定一些预处理选项(即一些本来应该放在 CPPFLAGS 中的选项),和 CPPFLAGS 并没有明确的界限。 : y: s/ ~3 {2 r! \/ V& v8 Y 连接选项在 LDFLAGS 中指定。如果只使用 C/C++ 标准库,一般没有必要设置。如果使用了非标准库,应该在这里指定连接需要的选项,如库所在的路径、库名以及其它联接选项。 ' N&&P+ U2 i8 X6 q& S/ e% T 现在的库一般都提供了一个相应的 .pc 文件来记录使用库所需要的预编译选项、编译选项和连接选项等信息,通过 pkg-config 可以动态提取这些选项。与由用户显式指定各个选项相比,使用 pkg-config 来访问库提供的选项更方便、更具通用性。在后面可以看到一个 GTK+ 程序的例子,其编译和连接选项的指定就是用 pkg-config 实现的。 1 e8 ~/ V&&`& J/ ~: H & H: d/ [) s& {- B编译和连接* g$ \0 M# M$ k: J; U 5 g' E( ]2 [' F$ |&&J! w& @- N! w 上面的各项设置好之后保存 Makefile 文件。执行 make 命令,程序就开始编译了。
9 _# I' f3 s5 k1 d5 {% J0 G( G- I 命令 make 会根据 Makefile 中设置好的路径和文件类型搜索源程序文件,然后根据文件的类型调用相应的编译命令、使用相应的编译选项对程序进行编译。 & m1 t& F& h$ x' {! d' Y$ O8 Q 编译成功之后程序的连接会自动进行。如果没有错误的话最终会产生程序的可执行文件。
9 P; I6 f. v- X# W7 c 注意:在对程序编译之后,会产生和源程序文件一一对应的 .d 文件。这是表示依赖关系的文件,通过它们 make 决定在源程序文件变动之后要进行哪些更新。为每一个源程序文件建立相应的 .d 文件这也是 GNU Make 推荐的方式。&&_&&J& F3 l! `+ H/ r. t' x% y% I* k / ?$ \, X7 ~; b2 z3 y& { Makefile 目标(Targets) . I! L& @0 S. U9 O4 V. y / ]; n% g/ \& R# r& y0 n下面是关于这个 Makefile 提供的目标以及它所完成的功能: & G# O3 j) L: u% ?+ P! [: J 5 e. L2 @. l' W& Emake
& v0 u& u' e6 M&&_( s编译和连接程序。相当于 make all。 0 w5 @) }4 Q; \& I6 c( l6 p) ^&&E , B0 ?2 S' N* ]&&k; ^3 {make objs 8 S' s5 j&&f8 T$ X) R% j& x 仅仅编译程序产生 .o 目标文件,不进行连接(一般很少单独使用)。 4 G* I$ }4 ^& ]2 l2 K. [ / `1 `, n9 z# \/ A8 {5 l* cmake clean &&d$ n# f, `8 W( ^% O 删除编译产生的目标文件和依赖文件。 7 m6 n, B2 E6 d. Z6 Q&&O 6 `) Z2 V+ c. f# d4 Xmake cleanall 4 n+ V' ^, @0 j' _- d 删除目标文件、依赖文件以及可执行文件。 & e& \/ D- S8 S # j, C6 b& U* \& U! p! X& O( M. `make rebuild
) e9 D& q% a1 I; ^5 V3 K4 S! d* T# Y7 l重新编译和连接程序。相当于 make clean && make all。 ! }/ Z# U( P0 L! l& L2 v& X3 n! ]8 ~, g/ F 关于这个 Makefile 的实现原理不准备详细解释了。如果有兴趣的话,可参考文末列出的“参考资料”。 4 I; s1 h7 [' G! J7 T! E5 R4 x8 i* T2 b7 z2 B, ?
$ W' f+ j3 H&&r4 X# E5 L8 t( ]) ]7 L! E$ E' N! p Makefile 的内容如下:
6 y5 ?8 X; j% Y# R / D: T. y5 T5 `& g& UC代码
: X: S1 n8 E% @, p8 M& Q. q$ c2 w1.#############################################################& & & J* y( ~! f&&f&&p( w2.# Generic Makefile for C/C++ Program& &9 E1 G- z9 Y/ M 3.#& &&&u5 O, b& t5 x2 v* k( P 4.# License: GPL (General Public License)& & 1 }. E: R5 c9 u& R0 n+ n' B5.# Author:&&whyglinux &whyglinux AT gmail DOT com&& & * z* G8 T; A5 q5 P6.# Date:& &
(version 0.1)& &* [# K+ R. Z3 Z0 P8 I' i 7.#& && && &
(version 0.2)& & : p2 E% C; k* r& `6 u& E& [8.#& && && &
(version 0.3)& & , h- A# H3 p0 c. h5 I9.#& && && &
(version 0.4)& & 5 I; h& ]% D5 L10.#& && && &
(version 0.5)& & . }/ H& L( F4 i11.#& & $ p8 J/ R: A' I) [12.# Description:& &5 J6 w) m8 A+ @, O! J2 o 13.# ------------& & 2 l# D9 _* I3 o* H/ c&&{9 R14.# This is an easily customizable makefile template. The purpose is to& &/ }, ?9 `0 t1 C4 N8 z 15.# provide an instant building environment for C/C++ programs.& & * D7 X: Y4 `/ J4 s3 W- h' O4 C. g16.#& &% B- H5 T: {+ _2 E 17.# It searches all the C/C++ source files in the specified directories,& & ! ^( U* N8 A: a) F9 L1 E7 x18.# makes dependencies, compiles and links to form an executable.& &$ o% j+ D4 ~$ C 19.#& & ' m- D1 T0 p0 x&&B! \* u' H+ `20.# Besides its default ability to build C/C++ programs which use only& &* |- D9 d4 I6 ^( |& ?* G 21.# standard C/C++ libraries, you can customize the Makefile to build& &* Y* J+ u* N1 u/ x 22.# those using other libraries. Once done, without any changes you can& &) F. G* N, n& z: |8 S 23.# then build programs using the same or less libraries, even if source& &) A5 H; w! p1 e& u 24.# files are renamed, added or removed. Therefore, it is particularly& & & d& k6 _4 C/ T+ B6 D; @# b/ Z25.# convenient to use it to build codes for experimental or study use.& & 0 a. W/ B6 J# P, M- N26.#& &# _; E+ F! j4 _& F; G' q 27.# GNU make is expected to use the Makefile. Other versions of makes& & % J$ [7 \4 g7 |- t& I( v4 X28.# may or may not work.& & 3 M* k- F) k& k$ f29.#& & + Z% a. j' H3 D8 h7 q30.# Usage:& & 1 t, J0 g& W+ `5 M31.# ------& &( q0 b1 l6 m' Q5 ~% }/ m 32.# 1. Copy the Makefile to your program directory.& &2 d& s& g* e& u4 b) r& r 33.# 2. Customize in the &Customizable Section& only if necessary:& &1 p& p& _&&U, k7 N$ \3 c( {- Z 34.#& & * to use non-standard C/C++ libraries, set pre-processor or compiler& & 0 d. b2 |, I+ I35.#& && &options to &MY_CFLAGS& and linker ones to &MY_LIBS&& & / N&&^8 C0 H0 G6 u6 l36.#& && &(See Makefile.gtk+-2.0 for an example)& &7 J7 a. G# |* j 37.#& & * to search sources in more directories, set to &SRCDIRS&& & ) J2 G) b. w& r2 _& ?) Z38.#& & * to specify your favorite program name, set to &PROGRAM&& & 9 W8 v& u, Y6 ^- ?: H3 v39.# 3. Type make to start building your program.& &/ ]2 O1 J6 v. N& m7 m 40.#& &% e8 D+ e$ B9 Y' O- P 41.# Make Target:& & 4 W2 A% Q2 z. l&&M! k8 G* L42.# ------------& & 0 |6 z. h& A4 S, D0 H! D% {43.# The Makefile provides the following targets to make:& &! e) o+ P4 v2 q' I4 } 44.#& &$ make& && && &&&compile and link& & 9 |+ ?/ y/ g% ~/ A& S45.#& &$ make NODEP=yes compile and link without generating dependencies& & ! |3 Q( E# @, k* K% u46.#& &$ make objs& && &compile only (no linking)& &. c) H) L- C- A 47.#& &$ make tags& && &create tags for Emacs editor& &; S, f/ y8 D- \&&J, Q0 T 48.#& &$ make ctags& &&&create ctags for VI editor& &# Y) {% |* R- q( X/ V6 @( b 49.#& &$ make clean& &&&clean objects and the executable file& & 8 ]&&b- Z) p% M% I. n+ C. i50.#& &$ make distclean clean objects, the executable and dependencies& & & ^5 S/ ~! y&&d3 J4 a. S7 V51.#& &$ make help& && &get the usage of the makefile& & - X( Z% a$ e+ Z5 T* g52.#& &$ s% A/ [3 a3 j, m+ M 53.#===========================================================================& &% {# _, x& d( J( \8 } 54.&&: k9 u% m2 ^( G% j$ t8 ]: P9 L# o8 Y 55.## Customizable Section: adapt those variables to suit your program.& & & G5 E3 c6 d1 a56.##==========================================================================& &7 j- j0 h/ E3 ~1 D: q 57.&&3 A, C2 T! _: M( ` 58.# The pre-processor and compiler options.& & 0 P, i! Q7 ?& W' o) A* W0 V* ?59.MY_CFLAGS =& & . o& c. m2 |/ ^* E7 Z&&h! b&&C7 t60.&& : a2 C. A- W; T( _, F61.# The linker options.& & $ O6 p$ }9 r% P! f62.MY_LIBS& &=& &4 L# A! }2 `: T/ b6 t 63.&&8 b! d1 f( D% ~9 i7 j+ ^ 64.# The pre-processor options used by the cpp (man cpp for more).& &# e$ ?0 a* y, V( e 65.CPPFLAGS&&= -Wall& & ! ^' E& ^# }: A* J66.&&# d$ I( q' n7 F2 ~+ c&&]4 N 67.# The options used in linking as well as in any direct use of ld.& && e: J7 O3 W+ m$ c 68.LDFLAGS& &=& &7 |4 ^/ p' w' q+ z1 {$ m. k/ F 69.&&/ |: x&&\* v9 H) s* ~# i0 Z( b& B8 H 70.# The directories in which source files reside.& & 0 V* P& y+ ~- r71.# If not specified, only the current directory will be serached.& & + `, x' X# B5 T72.SRCDIRS& &=& & * C) q1 c1 G! T5 l1 U! U/ y73.&& + D3 E7 B' L2 ^. Y( w( N74.# The executable file name.& &1 m9 Z1 M/ G8 G5 `& v+ M/ D 75.# If not specified, current directory name or `a.out' will be used.& &- v( l7 c! F3 _0 C# x+ _% {' c 76.PROGRAM& &=& & 6 l2 c, t5 X; Q& X; w77.&& 7 r&&?. B$ \+ [& u! ]* X78.## Implicit Section: change the following only when necessary.& &+ h, x&&A* z: I4 B2 y) w# @ 79.##==========================================================================& &8 c2 E$ r, t' T, ?1 ]- `7 [ 80.&&. V' u5 r, s& h& @0 Z: q% b8 j 81.# The source file types (headers excluded).& &) w) @6 U7 d3 X: n& R) { 82.# .c indicates C source files, and others C++ ones.& &* U* ^1 i3 u( I8 V2 u/ V: i 83.SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp& & : ?4 K2 N. ~8 `. }84.&& & \5 L1 u5 o* I: r8 B; f85.# The header file types.& & & e% V/ R& h5 O86.HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp& && d& s9 |/ t6 M 87.&& , i3 u# B0 l% |* ~% K2 y88.# The pre-processor and compiler options.& &# ?( G! D* t) U. M- N&&V 89.# Users can override those variables from the command line.& &$ n) W8 C. u6 L& v1 N 90.CFLAGS&&= -g -O2& &7 c- v' _' u* {; k! G7 h8 [&&R 91.CXXFLAGS= -g -O2& && k. o3 P, ?8 e0 c# S9 A( ]& o 92.&& 5 b' l9 ?* D9 G$ K, c3 [) e93.# The C program compiler.& & & j* e8 V6 L1 r- Z94.#CC& &&&= gcc& & 0 g. M! O4 L/ v) {1 N95.&&& N2 I1 C2 k7 N' Y/ N) H 96.# The C++ program compiler.& & 1 q&&i& k* h. a3 Q; ]: p97.#CXX& & = g++& &# Z' A+ k! k8 \- t& y7 P&&B 98.&& ) m: E$ B$ ~& R99.# Un-comment the following line to compile C programs as C++ ones.& & - p3 Y8 p$ N; a3 y2 N100.#CC& &&&= $(CXX)& & 6 b5 F7 [6 F7 B, h! U& H& P5 R/ ]101.&& 8 C5 P) Z7 d& \& [- g102.# The command used to delete file.& & & u: Q9 u2 P) g4 Q2 H3 u103.#RM& &&&= rm -f& &- ?+ G. r9 G4 e7 s&&b 104.&&9 \8 g5 E% Z5 t: c 105.ETAGS = etags& & / \9 \( F4 N# j* J2 a+ z# S; f3 j106.ETAGSFLAGS =& & 1 U9 N& R) D8 _) U2 |107.&& &&K0 r$ X0 |; B& O& y$ Z108.CTAGS = ctags& &+ B: w& W3 g( T; x 109.CTAGSFLAGS =& &- [6 u4 M3 ]9 h! d&&v& Q1 r6 m9 x% D0 @ 110.&&; H0 k. ^) j) d, {&&w 111.## Stable Section: usually no need to be changed. But you can add more.& && }- o- b, o! X 112.##==========================================================================& & 0 s- [7 J& _8 ]113.SHELL& &= /bin/sh& & 0 S- @0 S* b( f/ d114.EMPTY& &=& & 9 A& g' E! b$ p2 _6 n. S! J6 s0 C115.SPACE& &= $(EMPTY) $(EMPTY)& & ; _&&l&&w! ~# q% Q& U116.ifeq ($(PROGRAM),)& &) y5 J$ U8 R4 O 117.&&CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))& & 1 ~! k3 D+ ^/ N4 A118.&&PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES))& &2 L3 w3 ~- N! p9 Z* m 119.&&ifeq ($(PROGRAM),)& & 5 n+ a& J7 X+ B& t4 J120.& & PROGRAM = a.out& &2 y0 E9 _: z, E8 d 121.&&endif& &! m4 r2 V* r4 |, N- l5 _&&W 122.endif& & , _$ p3 c, c: t& S9 r) z&&d123.ifeq ($(SRCDIRS),)& &) T( y3 A2 @6 v! C& v5 K+ n 124.&&SRCDIRS = .& &+ A$ x- _! ?5 G/ P 125.endif& &' }& q/ O. W+ r3 {7 g 126.SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))& &$ G4 h+ `&&A* G8 F 127.HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS))))& & $ [! L&&o8 r( a# `$ Q2 Z0 r128.SRC_CXX = $(filter-out %.c,$(SOURCES))& & & m! S* v5 b3 s8 {6 q&&x129.OBJS& & = $(addsuffix .o, $(basename $(SOURCES)))& &9 A4 ^) G% Z2 K! j 130.DEPS& & = $(OBJS:.o=.d)& & 9 `& c) @$ {( b& G0 t4 ~: [131.&&: o' o&&?' M* O) f 132.## Define some useful variables.& &/ J# o. C* X/ \0 |& A 133.DEP_OPT = $(shell if `$(CC) --version | grep &GCC& &/dev/null`; then \& & 5 O! g& @4 x4 Y4 U( E! e8 L134.& && && && && && &echo &-MM -MP&; else echo &-M&; fi )& &9 p- x9 P! a& O1 D 135.DEPEND& && &= $(CC)&&$(DEP_OPT)&&$(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS)& &. _2 I! f( I. H1 f5 w0 {0 x( W: A 136.DEPEND.d& & = $(subst -g ,,$(DEPEND))& & 4 _& Y! z4 j, v% _! G3 V, U9 P</PILE.c& &= $(CC)&&$(MY_CFLAGS) $(CFLAGS)& &$(CPPFLAGS) -c& & 9 v! v( I/ ~* ?7 I; K. [</PILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c& & ( m. D3 V' Y, Q9 @8 D6 C9 \% A139.LINK.c& && &= $(CC)&&$(MY_CFLAGS) $(CFLAGS)& &$(CPPFLAGS) $(LDFLAGS)& &% M$ ~* m& O# `& e6 c( R' u: ]! \6 ` 140.LINK.cxx& & = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)& & 1 Q7 U/ Q# \: W( h1 E&&c7 k141.&& ' }, W, X; v/ |$ {6 \1 [142..PHONY: all objs tags ctags clean distclean help show& & ; Z&&`( D4 a, @% K7 K143.&& * z3 [( @, L# y# |2 {5 q5 O) z144.# Delete the default suffixes& & ; |0 H' J% d) n0 R% h, Z145..SUFFIXES:& & 8 u&&Q) L: S- [146.&& 1 c6 H5 w- O- {0 i! ?2 b* N: ~- Z147.all: $(PROGRAM)& & & }4 C+ q) N4 O8 s. E. l148.&& 3 ~. C& {8 z: }149.# Rules for creating dependency files (.d).& &+ C) L3 U& |8 w# }$ l 150.#------------------------------------------& & # S& i! }, d: N% z9 ^151.&& $ _# ]8 N0 y8 }; n152.%.d:%.c& & 8 M7 G8 q1 ^& t) f153.& & @echo -n $(dir $&) & $@& &9 e8 F* T8 S2 L0 N# X 154.& & @$(DEPEND.d) $& && $@& & 0 ~% t& X6 v# U6 `( A0 ^% w& w155.&& ! |* q+ I&&I4 u6 m& `: |156.%.d:%.C& & * |( X6 F9 A# t4 L157.& & @echo -n $(dir $&) & $@& & 4 F8 S! P/ ^* G! X% y9 N158.& & @$(DEPEND.d) $& && $@& &4 E* q& r1 h% m& @ 159.&&0 |, I4 Y, P1 r 160.%.d:%.cc& &# a/ p6 R3 t$ e: A: t6 v 161.& & @echo -n $(dir $&) & $@& & 4 q3 T. ^. U# h162.& & @$(DEPEND.d) $& && $@& &3 b' E$ x9 h3 ^. m 163.&&&&i( s$ l. i( |8 Z 164.%.d:%.cpp& &&&g, |0 t. M: t$ g( ?( c( Y 165.& & @echo -n $(dir $&) & $@& &: o1 ]0 D. P9 G 166.& & @$(DEPEND.d) $& && $@& &&&u1 d3 x( S; ^ 167.&&$ a, ~* m* Y+ X* K6 T3 g 168.%.d:%.CPP& &3 e1 \+ G& I0 v3 ^$ x 169.& & @echo -n $(dir $&) & $@& &5 r0 x0 x2 f% D/ [' V8 m, D 170.& & @$(DEPEND.d) $& && $@& & , {- j2 J$ j& Z3 d171.&& ( f$ [1 d# i: R6 i172.%.d:%.c++& & 0 ?, {/ h& @' f6 p( d6 `2 h173.& & @echo -n $(dir $&) & $@& && f! N. M& N$ g 174.& & @$(DEPEND.d) $& && $@& & & |* u& z8 Y3 l+ e+ F% O&&z175.&& 9 D: H/ A&&|% d6 m# I176.%.d:%.cp& &; W) a& L/ A; m 177.& & @echo -n $(dir $&) & $@& & ; ?2 {$ q2 ~, x# w% J1 j3 H1 w178.& & @$(DEPEND.d) $& && $@& & - c- x, C. R) P8 `( B7 T179.&& ( S) ]0 k8 c9 @: o/ f/ w! {0 b2 M180.%.d:%.cxx& &7 F* V1 O2 h3 g1 V) q6 ]: C 181.& & @echo -n $(dir $&) & $@& &0 H2 X+ R, R# Z: c2 L# h2 ~0 v* p4 S 182.& & @$(DEPEND.d) $& && $@& &5 [+ S8 P' v' [ 183.&&$ D6 m5 a! T$ O$ O: s( i&&@ 184.# Rules for generating object files (.o).& & ; i1 ]$ `6 A4 l9 G0 b185.#----------------------------------------& & / p' c1 ]1 u9 H186.objs:$(OBJS)& &4 j! |, f8 s2 A 187.&& & V. x6 v1 y: V* Y) H- @1 N188.%.o:%.c& & 7 k4 ?. a- y' j3 A5 @/ l: m189.& & $(COMPILE.c) $& -o $@& &/ n4 m* H) Q8 `% L0 Z' {* K 190.&& 6 ?) ]6 \&&r. b+ n' M3 W191.%.o:%.C& &# L; _& D7 o, e1 U 192.& & $(COMPILE.cxx) $& -o $@& & . A2 h8 [& d&&F2 G, \9 k2 N193.&& ' a, y! g8 F7 k& i194.%.o:%.cc& &2 ^7 T( Z% ?: t! j, ] 195.& & $(COMPILE.cxx) $& -o $@& & & A$ {. n' D: Z( \&&t196.&& ' E6 k$ e) o% N5 y/ {1 B6 u197.%.o:%.cpp& &9 A- q- P$ }, b/ ]9 |9 t# I# V 198.& & $(COMPILE.cxx) $& -o $@& & # X) }9 Q6 s8 \* g- J) o2 a199.&& ) S. R( {3 m( C2 V0 P% p) p: b200.%.o:%.CPP& & % s7 w) f8 c3 C* F6 V8 ^9 b0 [201.& & $(COMPILE.cxx) $& -o $@& &9 `! S/ r' S$ i/ L% f8 r 202.&&: S; X) t3 i& F) b 203.%.o:%.c++& & - c- q1 H4 j+ \0 r* X204.& & $(COMPILE.cxx) $& -o $@& &2 n3 Q& i&&y$ m+ n7 c& Y/ | 205.&& 6 o! y& n& c0 A! o- j206.%.o:%.cp& & & _&&N8 J5 @) V* j0 c# M# X! R& c207.& & $(COMPILE.cxx) $& -o $@& && @) Q3 n7 R& {3 D9 H, g! y7 T2 }3 n 208.&&4 ^* ?2 S! `9 X! e1 U5 a! r- j4 X# u 209.%.o:%.cxx& & ( I7 j5 K: F& C1 _1 L( e5 m7 Q& m210.& & $(COMPILE.cxx) $& -o $@& && u: c&&n3 Y$ d' o&&^: A; x 211.&&6 ~- a* ]( `& m+ K&&z 212.# Rules for generating the tags.& &$ Q5 b: ?6 J# o&&c 213.#-------------------------------------& &. ]& }&&I3 m) c2 ~. o7 P6 X9 S 214.tags: $(HEADERS) $(SOURCES)& &1 E, v# g! T* R0 m# ~ 215.& & $(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES)& &6 `5 C) i/ D- f 216.&& &&k, F2 X$ y3 ~217.ctags: $(HEADERS) $(SOURCES)& &) J( G8 g! n5 Y8 J 218.& & $(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES)& & 3 |+ u! D4 \& B1 q219.&& / Q1 q+ m/ g3 y% ~9 L0 {220.# Rules for generating the executable.& & ' C' Q- i- O2 n) w9 v: t221.#-------------------------------------& && h' B# L& J&&j* y 222.$(PROGRAM):$(OBJS)& & ' y6 z9 C4 ^7 }6 A8 s9 D223.ifeq ($(SRC_CXX),)& && && && &&&# C program& & % }5 S! F&&O0 O& ?6 i/ d+ a224.& & $(LINK.c)& &$(OBJS) $(MY_LIBS) -o $@& & # s&&}5 f&&^. d# g) X( F0 v225.& & @echo Type ./$@ to execute the program.& & 8 ?, s3 L; M, y4 G& t* n9 x226.else& && && && && && && && && & # C++ program& & 9 K7 G. l- o' E2 f7 F227.& & $(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@& &&&a- g- B! D5 \ 228.& & @echo Type ./$@ to execute the program.& &/ e, U5 T7 u# T+ h* ~0 p2 t 229.endif& & $ \' N) J. Z0 e- D0 h230.&& 8 `7 Z2 z2 m4 H* G231.ifndef NODEP& & 4 T, ^' R4 c9 n232.ifneq ($(DEPS),)& &6 Z' P) ?$ z$ J: v/ y 233.&&sinclude $(DEPS)& & 4 C3 G5 \: _7 `- M6 z- D& T) ~234.endif& & ; T) |: s7 o7 s$ ~6 Q& w! d. ^8 R235.endif& &8 @& N3 W2 {, u) ~, y 236.&&; B4 X! C& M9 u6 [2 [6 g$ J 237.clean:& & ' @9 e1 W% \4 g. B, ~238.& & $(RM) $(OBJS) $(PROGRAM) $(PROGRAM).exe& & + |& e: F& k4 ]2 ]1 [239.&& # \: Q' N+ _) _240.distclean: clean& &9 P' z5 [' k2 V3 I 241.& & $(RM) $(DEPS) TAGS& &- C. {+ a6 h6 w6 h. q&&i 242.&&0 D+ ?7 A; v) B( C/ T8 n9 m 243.# Show help.& & ! K* P& h: b6 P' q! v244.help:& &$ J& \4 c7 W* _0 t3 S0 d7 o 245.& & @echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5'&& / m3 Z* D&&e& A, p% l246.& & @echo 'Copyright (C)
whyglinux &&'&&&&{; [&&x' p* w0 z 247.& & @echo& &3 g3 a7 u6 m% {8 z&&D1 F8 c 248.& & @echo 'Usage: make [TARGET]'&& 5 `0 E& X( |0 f7 g9 Q249.& & @echo 'TARGETS:'&&$ X9 a0 I* i# ?8 z9 Q( ]5 D7 Y3 B 250.& & @echo '&&all& && & (=make) compile and link.'&& 2 N, B9 }& x* H) o&&U251.& & @echo '&&NODEP=yes make without generating dependencies.'&& 1 Q/ B/ P& c& b% L2 i& s252.& & @echo '&&objs& && &compile only (no linking).'&& 5 y7 s5 N, I: i% ]# t9 b253.& & @echo '&&tags& && &create tags for Emacs editor.'&&; j) G&&i& |* H) D 254.& & @echo '&&ctags& &&&create ctags for VI editor.'&& 8 I% Y% T9 l7 ?2 e5 l# o255.& & @echo '&&clean& &&&clean objects and the executable file.'&& , D' F7 c9 e6 X5 X) S256.& & @echo '&&distclean clean objects, the executable and dependencies.'&& $ a) Z4 |& U1 v2 V& d* I257.& & @echo '&&show& && &show variables (for debug use only).'&& 7 @4 g6 k( I# U& K- U% \7 T, [258.& & @echo '&&help& && &print this message.'&& 0 @5 v8 O. i) e$ c$ x259.& & @echo& & 2 t$ _1 @1 ^0 W& }# }& |260.& & @echo 'Report bugs to &whyglinux AT gmail DOT com&.'&&) G9 Y0 v1 G# I8 ] 261.&& & r0 i: e. ^* O8 M3 f$ `262.# Show variables (for debug use only.)& &# c0 G1 Y2 G& c8 B# p( Q# B 263.show:& & 8 i8 q: I& v$ y/ _264.& & @echo 'PROGRAM& &&&:' $(PROGRAM)& &+ M9 y9 [; L! ] 265.& & @echo 'SRCDIRS& &&&:' $(SRCDIRS)& &7 D% \2 j6 j( y% K! \% t 266.& & @echo 'HEADERS& &&&:' $(HEADERS)& & 7 Y& X0 r# d&&^2 d& m&&v267.& & @echo 'SOURCES& &&&:' $(SOURCES)& &9 S# H% K+ j! T1 V. V 268.& & @echo 'SRC_CXX& &&&:' $(SRC_CXX)& &$ [5 T/ n9 L; C 269.& & @echo 'OBJS& && &&&:' $(OBJS)& && w9 D4 Y' t&&M$ `, A5 t0 \ 270.& & @echo 'DEPS& && &&&:' $(DEPS)& &1 p& z1 s: \% Z; E/ J$ V 271.& & @echo 'DEPEND& && &:' $(DEPEND)& & . Z+ v1 C) L, v272.& & @echo 'COMPILE.c& &:' $(COMPILE.c)& & * Z&&u& b+ m5 @2 o273.& & @echo 'COMPILE.cxx :' $(COMPILE.cxx)& & , V& r2 e& J9 s+ q7 [+ k. g274.& & @echo 'link.c& && &:' $(LINK.c)& & ( u, ~0 T/ N0 d. \! y275.& & @echo 'link.cxx& & :' $(LINK.cxx)& & ' }6 V6 D( S9 e2 m( X276.&& # K1 C% D4 N% W% x277.## End of the Makefile ##&&Suggestions are welcome&&## All rights reserved ##& &8 G5 ~8 L3 k9 A, [+ P 278.##############################################################&& 3 b( k+ L# }7 P8 O1 v* ?############################################################# / k5 O4 j0 ?3 e* ]# Generic Makefile for C/C++ Program/ o% }' h* U1 }; Y. b% a* c* Q* z # & P! A( m/ B) }- y( @&&]$ B) e* r# License: GPL (General Public License) ( \! I& e3 ?: v# Author:&&whyglinux &whyglinux AT gmail DOT com& 4 o9 O, Y&&Z2 }: y7 @&&D# Date:& &
(version 0.1) , n7 l0 H% |& F6 J5 p8 a#& && && &
(version 0.2); `* w( K& ?$ }4 W& n' K4 C1 B #& && && &
(version 0.3) # z+ w3 J/ ^#& && && &
(version 0.4) 8 P* g& I! q( f. G$ R* {4 Q#& && && &
(version 0.5)2 O1 s- ]- B* w) M # 3 x9 k# d& x5 ?&&J) t. z& F# v4 E0 G. V# Description: ) S7 S1 d) M4 H& I, R6 W# ------------! K# H& |& j, H5 e # This is an easily customizable makefile template. The purpose is to+ \& W2 U&&C; L # provide an instant building environment for C/C++ programs. - {' e: ~, f' t9 u/ b3 w* Y& M6 C# ( o6 s&&u, Y) ?# L1 a6 v8 D# It searches all the C/C++ source files in the specified directories,+ c+ J' c+ ^# Z # makes dependencies, compiles and links to form an executable.7 j# Y) _, P4 f' Y1 {0 W #&&z$ j$ |% ?&&{$ n2 M2 E # Besides its default ability to build C/C++ programs which use only 0 i* P! C) ~8 T# standard C/C++ libraries, you can customize the Makefile to build 9 ^: m9 _) n&&g; V& Q& T5 d5 a# those using other libraries. Once done, without any changes you can# \6 v&&[& k8 {' e # then build programs using the same or less libraries, even if source- q$ E6 c) E: I # files are renamed, added or removed. Therefore, it is particularly& s' w' p) c/ q' l # convenient to use it to build codes for experimental or study use.: ]&&y0 O5 P: U5 G) A1 W7 p #( h. T8 ~. i+ G8 Q$ O* o # GNU make is expected to use the Makefile. Other versions of makes2 l6 h&&G& ^- x+ C( ? # may or may not work. 8 e5 ~5 W* l4 J9 t# 5 E&&P& V$ m& c/ ~( I- V& k. C# Usage: &&A. d# K! [6 ^& t&&F* e& N# ------( B0 B% @9 ~/ z8 V7 \ # 1. Copy the Makefile to your program directory. 5 K* W. t9 m& L) N, s0 Q# 2. Customize in the &Customizable Section& only if necessary:4 c6 U# K% F& n6 G# f( d. w: k( o+ I #& & * to use non-standard C/C++ libraries, set pre-processor or compiler 1 ~& [2 a$ x( x/ H#& && &options to &MY_CFLAGS& and linker ones to &MY_LIBS& , {$ ]6 N9 O/ [' V+ G6 X3 O2 x#& && &(See Makefile.gtk+-2.0 for an example)6 z' k, `! ?0 p* ^1 V #& & * to search sources in more directories, set to &SRCDIRS& 7 r3 K4 g' G8 s& f) Z4 C/ q7 y) }7 l0 P#& & * to specify your favorite program name, set to &PROGRAM& % S' _1 [/ n& X, Z, v/ X# 3. Type make to start building your program.; z8 w4 m6 Q+ c% l2 U- s) X% [. e #- c. |# b& C. H3 {& h3 R9 k8 K # Make Target: ; A0 s5 W; L/ a3 L8 p&&\# ------------% P# ~, T5 h* [9 |5 F # The Makefile provides the following targets to make:- ]( K% R( u4 K7 x/ S& r8 H #& &$ make& && && &&&compile and link7 d, p, i$ b+ [( ^ #& &$ make NODEP=yes compile and link without generating dependencies ; f&&^# W. |! \2 z+ X! I#& &$ make objs& && &compile only (no linking)4 ^& A7 T, c& Z/ l- Y #& &$ make tags& && &create tags for Emacs editor8 w8 c& F; i( N- q% W2 R #& &$ make ctags& &&&create ctags for VI editor# h4 v1 Z- V/ |5 A0 N. T #& &$ make clean& &&&clean objects and the executable file5 u. F: ^7 e3 B, E0 C! g0 H. ? #& &$ make distclean clean objects, the executable and dependencies 2 {* T0 r( s# V! P& T#& &$ make help& && &get the usage of the makefile) K% }&&q* j9 p0 c6 U, p # / x, l9 ?; E4 b$ T1 a& X#===========================================================================& e( A9 c2 S9 r& U 5 ]4 }0 H1 }+ P1 K7 l2 Y9 B ## Customizable Section: adapt those variables to suit your program.: {& ]; c/ U1 N4 z, C8 ^; ^6 C ##========================================================================== 6 L3 Q& N&&S2 G, ^8 C/ z. t7 r , W# e3 _& \* ?) Y# D* S# The pre-processor and compiler options. 2 W&&\+ u* k7 C# f. F: y&&?MY_CFLAGS =( n6 d: C& R. [5 p- n9 \( T
$ p& E/ E, Z/ h# The linker options. 8 {8 w0 U4 V7 x1 tMY_LIBS& &= 6 h$ `% ]0 y, X; B9 G& j2 P0 e! [1 M # The pre-processor options used by the cpp (man cpp for more). # A4 S( T2 C8 c0 K' k' Q2 [CPPFLAGS&&= -Wall ! O&&w. {&&n- I2 E9 ~$ I- }6 f5 G! c # The options used in linking as well as in any direct use of ld.- b) J. |1 ?& @$ \3 B- r8 N: p LDFLAGS& &= # ?! g6 x# M, l/ x2 {* t7 y9 j! r8 m # The directories in which source files reside./ d3 z& h: p( S9 v* r* {3 P # If not specified, only the current directory will be serached.3 x( g) y+ l&&x4 |+ `3 W2 X& z&&s SRCDIRS& &=* _0 Y* K! p2 i) b2 I% x
: F% L, |* Y) J4 K! \; C+ X- s# The executable file name.+ a. p3 Z3 @% a # If not specified, current directory name or `a.out' will be used. 2 O5 G: {+ }! e& d* yPROGRAM& &= 5 E9 H4 ~2 R% F: e( y&&j/ Q+ M- s* E# s3 C/ Y; S ## Implicit Section: change the following only when necessary.- a7 T0 O2 [& E% T3 L! z ##==========================================================================- D/ y' [: H- G1 K, c7 g8 A7 B
: A, B( ^9 c&&i& c! P# The source file types (headers excluded). ( z4 J6 k' p5 g) k2 Q) {# .c indicates C source files, and others C++ ones. / `! g! \! o! xSRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp# u4 t4 d7 D4 D; s1 q9 g) O ( Q# D4 Q) k5 ]% L # The header file types.8 V: [& k3 }/ ? HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp 4 R' j5 d# D&&c9 u, ]0 s) b & |# L8 o7 M- v. [# The pre-processor and compiler options.& ?$ W&&R) p% H3 E: C0 y # Users can override those variables from the command line. , F0 y( \& i: J& Q( W' TCFLAGS&&= -g -O2 & d3 c: f( l+ }: WCXXFLAGS= -g -O2& ~( @1 [/ x/ i% Y8 t
8 m: n* d/ O4 [& ~# U# The C program compiler.4 f: t+ ]&&~* o4 L- G #CC& &&&= gcc ; c, V$ }& Y3 d 8 ?) T4 \7 U# _, ~- x3 ^9 q# The C++ program compiler. ! R- y9 U&&v9 f% Z0 k#CXX& & = g++ ( N# b2 t3 {% ] 6 M/ g# `/ `4 X5 \' n& I4 ?# Un-comment the following line to compile C programs as C++ ones. 3 Z, _' Q+ P# |/ q2 J#CC& &&&= $(CXX) ! Y0 x# }, L$ W! Q&&n8 [3 i& a! F. h! Q# X( d( i$ v. o. \ # The command used to delete file.4 s' K( z1 p6 }9 h #RM& &&&= rm -f4 z) B3 b9 r2 Y1 F5 K2 B# D4 X7 r
* }0 ~( P5 }0 w! S&&c- W&&C6 qETAGS = etags , ^3 ^; O; T% g& v) I% g! @& sETAGSFLAGS = 9 Z0 H. x# Y! A+ l- {, E- O5 D+ B- B* z&&a7 s& P% [ CTAGS = ctags( ]# {6 x+ ]5 R+ s' G' a5 o CTAGSFLAGS =4 f' L4 d& n' `&&t7 V ; r/ J& k( X7 z+ r5 U' ~: X ## Stable Section: usually no need to be changed. But you can add more. ! V3 Y/ X$ h4 w0 N( X7 l! w&&W##========================================================================== ' ^/ v% ~6 _' S2 DSHELL& &= /bin/sh 8 Q' f) u( H& D/ \EMPTY& &=. v/ ]* K8 N) {% v* T SPACE& &= $(EMPTY) $(EMPTY)# r! t&&v: Q0 b8 n( m$ N ifeq ($(PROGRAM),) % [2 C& k0 ]# w1 Y&&|&&CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))# M5 z9 I4 P&&H4 a# W &&PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES)) ) I, W# x& F: ~9 d&&m&&ifeq ($(PROGRAM),)4 H5 h3 o/ l# {8 V& @0 G* p* y, Y & & PROGRAM = a.out8 n7 Q! Y- w/ G) @$ l( ` &&endif / `2 o5 w$ o& O! Q' k$ }endif/ |& t+ o2 s. F/ N7 H) C1 F4 D9 _ ifeq ($(SRCDIRS),) 0 Q, x6 N# R& M&&z&&SRCDIRS = .; }/ S/ T6 H4 G endif ' N&&@/ |7 W& |5 Z# {5 p/ H/ oSOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))+ S& _4 R1 ~&&p' E$ p' t5 }0 N HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS)))) . B: N, r% o. RSRC_CXX = $(filter-out %.c,$(SOURCES)) & q2 ^' U2 o, }& nOBJS& & = $(addsuffix .o, $(basename $(SOURCES)))( }% c2 f4 r7 J DEPS& & = $(OBJS:.o=.d)! f1 m6 t& f' v2 K& n3 h0 _
# S) s) K&&}* d( j! g## Define some useful variables.4 y9 ^- R6 v: x# W& s DEP_OPT = $(shell if `$(CC) --version | grep &GCC& &/dev/null`; then \ : g4 L$ S9 n% ?$ N4 a) Q: e' k& && && && && && &echo &-MM -MP&; else echo &-M&; fi ) * T4 a5 |: O4 M. t0 \DEPEND& && &= $(CC)&&$(DEP_OPT)&&$(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) , g. O9 y&&q) _6 Y% A9 _: zDEPEND.d& & = $(subst -g ,,$(DEPEND))! a1 f7 F0 E. B' x) d COMPILE.c& &= $(CC)&&$(MY_CFLAGS) $(CFLAGS)& &$(CPPFLAGS) -c8 o8 E5 U; Q& O7 ]) S# Z% \ COMPILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c 4 `! U& B/ n! S0 Z1 VLINK.c& && &= $(CC)&&$(MY_CFLAGS) $(CFLAGS)& &$(CPPFLAGS) $(LDFLAGS)& Z. c, V# [0 H) k$ Q8 R LINK.cxx& & = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)$ P* i, O$ ~1 } % S, t7 B6 F7 k$ f& S2 {0 k- x .PHONY: all objs tags ctags clean distclean help show ! a4 z& V& D- U# V; X# [ ! c4 }3 Y( e, G4 s- d&&a& ?( D# Delete the default suffixes7 S* B* A, w8 N& y/ j .SUFFIXES: ( {& c/ H' W. W. u &&q; L) z7 J3 wall: $(PROGRAM) 5 a' e7 z& p $ O: [; ~7 X# d9 E6 O. V# Rules for creating dependency files (.d). * I+ Z0 q3 i, g& C#------------------------------------------$ ]7 U% n1 d& l# x! u&&~% M& C&&q
6 @6 A/ j8 G# {0 [: h, ?%.d:%.c + p+ b9 X7 d. E* B& & & & @echo -n $(dir $&) & $@( K4 P- [$ ?0 R: T! X: b- X & & & & @$(DEPEND.d) $& && $@6 W/ w# ?! n+ \$ z/ b - P, R5 W&&~6 a' C %.d:%.C $ h: B2 q+ p4 W& & & & @echo -n $(dir $&) & $@( S9 z7 X) j9 L! a & & & & @$(DEPEND.d) $& && $@! f5 V8 F$ w0 a( X, ?* f6 C3 G. R ! t$ B: o0 {/ {. A& P! X %.d:%.cc 8 |) I& i. h) B) A1 S$ l6 g0 W& c& & & & @echo -n $(dir $&) & $@ # i. Z( |) v% A) u& R3 D# ~; z& & & & @$(DEPEND.d) $& && $@6 k9 s* \1 y2 f& d0 U& q2 o
0 G6 Z( C&&F% L& W; ~2 k%.d:%.cpp: B&&b8 L4 U; X+ w & & & & @echo -n $(dir $&) & $@# F+ h, I, T( Z# T, E( p & & & & @$(DEPEND.d) $& && $@ # K7 O% t5 g/ s. @4 W) c9 `0 Z9 @8 Q' T9 h7 X; F, k* [# l %.d:%.CPP 3 R7 Y; S* ^* j& & & & @echo -n $(dir $&) & $@3 E0 S6 {0 d, ~) b+ I, B & & & & @$(DEPEND.d) $& && $@, Y! h9 Q& |' b3 U7 K&&N. j
8 |7 E& M2 `0 W+ {3 S%.d:%.c++ * G; J; ?# J' `& E$ _5 ?! L& & & & @echo -n $(dir $&) & $@' W* Y. H3 C( W+ J4 m0 |1 g6 m & & & & @$(DEPEND.d) $& && $@2 _# m0 J- M9 P+ d& m9 o
: O; A- Q. M: R3 u# P% Q%.d:%.cp1 Z+ U&&g9 |1 R. H+ L. i & & & & @echo -n $(dir $&) & $@ $ F/ E. X3 X3 |8 z) s& & & & @$(DEPEND.d) $& && $@ : h: m3 \' l$ x1 E + p: _* C+ H- V4 Y2 i%.d:%.cxx 0 ^& z8 V&&t) ~) j& & & & @echo -n $(dir $&) & $@ ' _; x. C, X& & & & @$(DEPEND.d) $& && $@&&J$ B& H' p! D% f# {3 c . E& t% E( w1 m8 H # Rules for generating object files (.o).8 e+ E- b) P5 x1 D- j #----------------------------------------- P# X8 \# U; j7 M% [) D objs:$(OBJS)5 d2 C5 ]1 |7 L6 L&&g7 j: j&&i& P5 R 8 D5 S$ D) x' m0 f %.o:%.c 9 z$ B8 ~: @' F) Z& u$ \& & & & $(COMPILE.c) $& -o $@ + ]&&|& }- h+ k3 H$ T&&^- T' h2 |- `8 i! G1 u9 w %.o:%.C , J& b8 q6 [5 ]8 ^; v, I& }&&x3 n. d1 A& & & & $(COMPILE.cxx) $& -o $@ 1 \&&E, M. O# Y/ Q% M 9 d# o/ s' M) G- {6 e7 ~/ R3 R%.o:%.cc0 S&&~, j% Q5 C. }' P- f & & & & $(COMPILE.cxx) $& -o $@ : Q' L5 W: P+ ^9 {: H7 h) }1 ~1 g/ ], I) Z) Y5 ? %.o:%.cpp # L# Y. M- |# y- B/ ~, I) V& \* p5 q& & & & $(COMPILE.cxx) $& -o $@ # D: W# F: y) c4 ^, {% z 0 \7 f, ]' Z+ P5 f3 W5 l%.o:%.CPP2 o4 `; f. B7 N8 r&&l & & & & $(COMPILE.cxx) $& -o $@ / t&&x5 Q2 i&&O* P & `: x8 Z3 n6 t4 }%.o:%.c++& Q& x/ F: M7 I! p$ k2 f & & & & $(COMPILE.cxx) $& -o $@ 4 M) z! F$ b# h' }9 w2 [0 G - p3 j2 g3 l2 i/ K& d%.o:%.cp : ]) G! H& k&&l# F. h9 [& & & & $(COMPILE.cxx) $& -o $@ 3 [1 S3 r+ o6 C, c# Y' }) j! t6 A* [( V+ \9 R&&M %.o:%.cxx 1 [# H9 t/ a/ Z0 A&&P9 r& & & & $(COMPILE.cxx) $& -o $@5 ?& k. i8 B) R1 X# K
1 b9 H9 L& X6 \' x# Rules for generating the tags.: n: o, l- i' ^( J, a( I% o #-------------------------------------5 G2 N4 R; p. K4 q% N tags: $(HEADERS) $(SOURCES) &&M9 C: Y/ m, @) A, P- K( A3 z& & & & $(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES)7 h$ h1 N: ~' h2 |&&l & D0 l! v1 {9 Y! j' k+ \/ b ctags: $(HEADERS) $(SOURCES)6 V% r, H; x& p! j( ^! K3 n9 j & & & & $(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES)2 K% y& T% B' q' N& K; M2 \ 3 X: N4 B2 V1 @- X+ q # Rules for generating the executable. $ y+ H+ V, C7 H, H. ?#------------------------------------- , C1 z1 S9 ]; d* T7 {0 j0 ]. j4 K$(PROGRAM):$(OBJS)- }* `& i6 D9 }& J7 O9 _8 ? ifeq ($(SRC_CXX),)& && && && &&&# C program &&n, c: v1 `- J9 N; ^& & & & $(LINK.c)& &$(OBJS) $(MY_LIBS) -o $@ ) z+ t9 e- i* c& H; `% Q1 Z& & & & @echo Type ./$@ to execute the program. & V4 e( M9 F+ _6 z2 melse& && && && && && && && && & # C++ program& ^9 J& Q! T% G# R & & & & $(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@7 F- I( S% W/ D& B% s & & & & @echo Type ./$@ to execute the program.: c+ s, S4 h2 R$ `8 _8 z& g endif $ m- ~* `: n7 Z2 \1 @9 K; V. e8 j+ y9 t! f6 |% E ifndef NODEP 8 l&&{! H; M% g4 E3 k5 P. u$ Pifneq ($(DEPS),)- |! m/ q0 a, z6 q( r2 A &&sinclude $(DEPS)7 r+ c. R&&f1 h7 i8 U+ p! A endif : ~% X9 C. l1 {endif& E; v( q7 ^- M8 _7 ]
: q& A+ \( Q, t2 Z, C4 X&&~clean: 4 Z1 x1 h3 E7 H$ [: A& & & & $(RM) $(OBJS) $(PROGRAM) $(PROGRAM).exe 4 g1 @* z. P. w& b, N1 \: Z( H' ]+ `' s0 H) \3 H! o) z distclean: clean5 V1 a! q7 }1 B$ V & & & & $(RM) $(DEPS) TAGS 5 e( ?* f+ [&&?8 { 9 G4 |9 A& t! ]&&I8 Q6 j# ]# Show help.3 L/ D( ^8 F0 N4 ^9 I- \) w: g: q help: ) c&&K- N) }; ]' }&&o( s2 L8 E' N, }& & & & @echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5' $ Z' t$ b7 F2 f5 ^&&\$ S: n/ k& i& ?& & & & @echo 'Copyright (C)
whyglinux &&' + Z3 g7 w& X' Q9 |9 ^$ j& & & & @echo! }! `* q( f6 ^: A7 |* O & & & & @echo 'Usage: make [TARGET]'+ H5 }4 s. R2 C8 m/ K8 h& J* c & & & & @echo 'TARGETS:' 5 t& D# ]3 K& j& K& P6 n/ }- V& & & & @echo '&&all& && & (=make) compile and link.'; Y3 Y% c' ^, E9 Q, E, C, j( D & & & & @echo '&&NODEP=yes make without generating dependencies.'; E2 i9 F2 D( d$ U3 z3 o! L8 P & & & & @echo '&&objs& && &compile only (no linking).' ; |& b&&`0 A3 `3 y. S0 ?2 r. i0 X& & & & @echo '&&tags& && &create tags for Emacs editor.' & y: C& J& y/ f& ]! r( I8 j! J% |& & & & @echo '&&ctags& &&&create ctags for VI editor.'- A* c. a( @) R, N7 f& y & & & & @echo '&&clean& &&&clean objects and the executable file.' ( u&&?( r% }* R; x& & & & @echo '&&distclean clean objects, the executable and dependencies.'; }; {$ Y/ }+ @&&s&&A0 r & & & & @echo '&&show& && &show variables (for debug use only).' + F1 j2 l9 E&&w7 ~4 @& & & & @echo '&&help& && &print this message.' & t% _& r5 L$ d& Q3 r5 @& & & & @echo&&?# M9 P* s+ l& d & & & & @echo 'Report bugs to &whyglinux AT gmail DOT com&.'& C1 q# h7 c$ K+ }
) c3 X+ G4 I( h* G5 A# Show variables (for debug use only.) , l# c# x7 d6 \6 c5 ~$ {show: , H/ \2 e) h. Z- U9 g' z& & & & @echo 'PROGRAM& &&&:' $(PROGRAM)4 j0 h% G: V% y% ?' ?- ^( o & & & & @echo 'SRCDIRS& &&&:' $(SRCDIRS)+ D. M: d9 V2 L& l9 z& j, X & & & & @echo 'HEADERS& &&&:' $(HEADERS)7 R( e5 U* l+ A. ^ & & & & @echo 'SOURCES& &&&:' $(SOURCES) : A- i: a6 V# o) P+ K+ p. B& & & & @echo 'SRC_CXX& &&&:' $(SRC_CXX)7 J2 k# I% m7 C4 o: I% p&&i. } & & & & @echo 'OBJS& && &&&:' $(OBJS)5 Q& ^4 @& P0 H. b1 ^' [# _ & & & & @echo 'DEPS& && &&&:' $(DEPS). u7 n3 w. L% N. u1 e4 l&&l & & & & @echo 'DEPEND& && &:' $(DEPEND) ! v3 q&&^&&g/ K% Y&&?4 s2 |& & & & @echo 'COMPILE.c& &:' $(COMPILE.c). Y. b/ F&&U6 t: r & & & & @echo 'COMPILE.cxx :' $(COMPILE.cxx)&&E6 X0 _: o&&b$ ?: P& g & & & & @echo 'link.c& && &:' $(LINK.c). }/ v7 P( @0 \! w' d) m& L. N&&D & & & & @echo 'link.cxx& & :' $(LINK.cxx) 9 K6 P' L/ P) u7 V3 g7 t3 x$ p: @9 {% u% f5 s+ A5 P ## End of the Makefile ##&&Suggestions are welcome&&## All rights reserved ## . [; S5 k% z: ?! ~* D4 E############################################################## , ~4 \: s) Y) P% b5 c- X, Q&&0 u$ L8 E$ Q+ g( S8 W &&`* R% [+ h( L5 j: J
: b0 W# N+ J&&b' x. e2 O5 m/ P$ ` & Y: c: f1 u) F& ~7 |* v2 F1 O
8 }% P) A, |6 @# B下面提供两个例子来具体说明上面 Makefile 的用法。 ! c5 s1 |; c, a' m7 H 7 ?% i/ }, c8 [6 k5 N&&m 例一 Hello World 程序 7 _) o. G; D6 V0 z1 k, i$ }! V1 ~5 o& [ 这个程序的功能是输出 Hello, world! 这样一行文字。由 hello.h、hello.c、main.cxx 三个文件组成。前两个文件是 C 程序,后一个是 C++ 程序,因此这是一个 C 和 C++ 混编程序。- ~9 O; g&&Z+ }# ?. t
% O& b&&G) u6 s+ {C代码
4 U& ?% O; t* _6 F, H1./* File name: hello.h&&% k0 y5 ?3 _9 [ 2. * C header file&&, ]% ?: @& Z* Z5 ?) ~ 3. */&&) k& J5 z, H- Y& O; ?4 v 4.&&) w9 N& ?! {: }* w# w 5.#ifndef HELLO_H& &8 X- F% c9 w' @; E, g6 ~, y9 x 6.#define HELLO_H& & 2 d( f& o. |7 z. b$ J' M5 X7.&& ! I4 S, I&&y7 v$ i: D* B; |8.#ifdef __cplusplus& & ( j4 i&&?&&m, f$ H2 f: ~0 ~9.extern &C& {& & # S& A7 N' `3 ^' n10.#endif& & 7 l5 Q&&K4 Z- s4 S, N; J&&c11.&& 7 F2 u% t, T+ ~/ k12.&&void print_hello();& &1 S3 a3 B6 @6 \6 a 13.#ifdef __cplusplus& & 4 i7 U0 f& X% W* E5 z) Z14.}& &) g: P0 P- E; o- i 15.&& ( o* H% t0 x$ t) y8 y! N$ I4 m0 M16.#endif& & , n* J. c) F5 G# c# w( `17.#endif& &5 W3 u& i9 R, v$ a8 b, i. b$ \ 18.&&( r8 a0 i4 l, X9 R$ H5 V- G 19.&& ! j4 |! t% o6 {2 Q' Q20./* File name: hello.c&& - M+ K. T. g+ b% p6 e- P21. * C source file.&& 2 c. x1 W5 N& S22. */&&; O% o* e&&@5 m& O& ^# w 23.&& . l% b9 Y7 D, Y* _% g# s$ Z5 D&&[24.#include &hello.h&& & / Y3 T& _2 j# r6 `25.#include &stdio.h&& & ' p/ T/ @, _/ U# t26.&& ; j9 t, k, m2 O( `&&u27.void print_hello()& &5 E$ |4 Y&&i* M5 e, R3 Y7 }* z# @8 u 28.{& &, B&&z9 w&&q* O3 R! Z( ]! A 29.&&puts( &Hello, world!& );& &/ y6 ~+ V4 r& V; g& p% } 30.}& &( O/ q& _6 `, O6 o) G' W' ?3 R: P 31.&& * d&&a0 P3 l9 ]& a, j/ K32.&& + ?. P1 g5 B) X9 N& M1 ?33./* File name: main.cxx&&6 \0 a2 `- h$ l: H6 ^ 34. * C++ source file.&& $ _* n- _2 J' T9 p5 E35. */&& & v( S$ v7 v- y/ Y& l& T36.&& , C$ |$ ?- H* i1 d' B9 ~0 d37.#include &hello.h&& &8 j% M* K4 I. a7 P3 }9 {$ q 38.&& ; t8 k4 X& j&&K0 d! ?39.int main()& &+ R0 ~( `( K; I% ]/ h% Z 40.{& &: G/ a. `. _! \&&b0 E 41.&&print_hello();& & . B9 x6 n+ O! u- ^- s& }4 f( X6 O& x42.&&return 0;& & 2 ?6 _8 I- i. Y! f' A; ?& w43.}&& . V+ j. p6 q4 x' A/* File name: hello.h3 h, P+ m& a9 P8 q) N * C header file # p' C8 C+ P6 y0 w */' |2 m2 h& I( G1 N) c & z: [. H, E6 r) T! v0 y2 g #ifndef HELLO_H 5 @6 _6 T0 K4 i( Z# J#define HELLO_H ) P5 j6 y! [/ `& ~; K% n! j&&l 0 J8 I2 L9 n# F; P% J+ \#ifdef __cplusplus7 @0 v& _& L% y: b# z9 T extern &C& { , o/ h- a- u9 c7 R& ?#endif 4 z4 A* d* [+ d8 N3 ^: E1 u: Z: ]2 _5 A &&void print_hello(); 5 g% z8 M% S) r#ifdef __cplusplus# E# S& x8 `& m7 r }0 H+ j& B; p# |, Q4 r( y&&F; x ' |2 B# K! e8 U6 V #endif+ a% q' E5 J( H& t0 Z) S, {3 l7 Z #endif5 x3 R6 ], l: i7 g0 t) @
6 E) y8 n2 j6 h&&@ % \+ E4 b* O& I( V6 o& s: {/* File name: hello.c8 F+ w) o9 W1 L# Z! M7 f- ?7 ? * C source file.&&L) m1 a' `$ y */& B7 c( T, y7 K: ]
, O) k2 N9 A& T/ g$ P#include &hello.h&8 K& _1 A( f3 _ #include &stdio.h& 6 g) ?/ J. F1 p/ h4 Z- [* N! f& m0 S/ g0 v+ F& ` void print_hello() ) b4 M* W' i5 i+ n{$ _6 @! [, J) o8 T&&d &&puts( &Hello, world!& ); , P4 O& `' r+ H$ K} : E: f0 i) ~: E% s 7 a3 T* x& T2 s+ [* A; I4 M0 p ! Q: o- ^3 J2 [+ p$ w6 }/* File name: main.cxx 0 }9 E6 O, f( x: k * C++ source file.& i, c9 S& T) X */ ! i& C' x. D# D4 e7 [- \1 C7 ^ & b, z3 u& i, y8 a#include &hello.h& / H4 i$ G&&Q, t / z& N$ c1 U5 ]6 f% Wint main()! A; ]6 M7 i4 X$ S1 T { 3 B$ [: I/ b+ @/ F7 u&&print_hello(); % o1 o& O3 u. o&&return 0; ( L. S7 h( }/ A$ z1 x}&& % a6 u6 P2 _+ E& m- ^
5 u+ Z7 Z* h/ b: ~4 h4 |8 C( y! x6 f&&A/ ? 建立一个新的目录,然后把这三个文件拷贝到目录中,也把 Makefile 文件拷贝到目录中。之后,对 Makefile 的相关项目进行如下设置: # O9 ]0 [: N8 U. X; J8 t7 e) _
2 {&&`$ v* M% R&&F% K/ U&&b% JPROGRAM& &:= hello& && &# 设置运行程序名! p! \1 s1 B* r7 E&&K/ P6 m8 L6 H 3 ]- \4 q' ~0 j0 h+ w SRCDIRS& &:= .& && && & # 源程序位于当前目录下' N7 P& p1 N% a. J! L6 u : W. W; ?: m6 H( O. z! { 4 C' L0 g0 b6 @' q SRCEXTS& &:= .c .cxx& & # 源程序文件有 .c 和 .cxx 两种类型 / T; M6 h6 Y( |8 K- o6 G5 F: E. z4 b, m5 ^3 _ CFLAGS& & := -g& && && &# 为 C 目标程序包含 GDB 可用的调试信息) n* [# H! N+ I&&~&&v
' i&&b- t6 z% K( ~/ gCXXFLAGS&&:= -g& && && &# 为 C++ 目标程序包含 GDB 可用的调试信息 : y7 t$ r& I1 h0 m6 B9 e7 I&&l
2 n* p4 U, ^6 V. B7 W+ K&&x 由于这个简单的程序只使用了 C 标准库的函数(puts),所以对于 CFLAGS 和 CXXFLAGS 没有过多的要求,LDFLAGS 和 CPPFLAGS 选项也无需设置。
3 ]6 x% {. }( T1 ?& g7 q* I- }7 t4 r# \& e% W5 K6 N 经过上面的设置之后,执行 make 命令就可以编译程序了。如果没有错误出现的话,./hello&&就可以运行程序了。3 S% \* @5 C8 H+ L4 h 1 S) C: `* X1 y4 M4 T9 b1 k 如果修改了源程序的话,可以看到只有和修改有关的源文件被编译。也可以再为程序添加新的源文件,只要它们的扩展名是已经在 Makefile 中设置过的,那么就没有必要修改 Makefile。 : N* c% a0 b1 \* L& L - @! o1 ^3 [, K/ `/ [
( w# {9 C3 Z1 Q% O, R5 M( ^9 w' N 例二 GTK+ 版 Hello World 程序 : n- V4 N* y6 o. ^; `8 ?6 d# d& S$ S: q1 v1 j( u 这个 GTK+ 2.0 版的 Hello World 程序可以从下面的网址上得到:。当然,要编译 GTK+ 程序,还需要你的上已经安装好了 GTK+。 % J1 ^. Q' `( ], v5 v 跟第一个例子一样,单独创建一个新的目录,把上面网页中提供的程序保存为 main.c 文件。对 Makefile 做如下设置:
( K4 e) v0 x. w# z: C* lPROGRAM& &:= hello& && &# 设置运行程序名# `4 p6 P. K9 } SRCDIRS& &:= .& && && & # 源程序位于当前目录下&&x4 O1 X3 F3 h+ ~! E SRCEXTS& &:= .c& && && &# 源程序文件只有 .c 一种类 $ l' w0 ?& p3 E0 f, _# ` ( A2 g& L8 T( x- yCFLAGS& & := `pkg-config --cflags gtk+-2.0`&&# CFLAGS , o- z% S- u&&w! }/ D& pLDFLAGS& &:= `pkg-config --libs gtk+-2.0`& & # LDFLAGS! f# y4 p$ J7 ~+ c7 s2 W& j
& K+ F5 d0 `5 m9 g$ ?% q) }) F这是一个 C 程序,所以 CXXFLAGS 没有必要设置——即使被设置了也不会被使用。
1 U% p5 @8 G, _8 ^3 Y: @, m编译和连接 GTK+ 库所需要的 CFLAGS 和 LDFLAGS 由 pkg-config 程序自动产生。
&&W, I. W1 ^0 U现在就可以运行 make 命令编译、./hello 执行这个 GTK+ 程序了。
手写makefile太累了吧? 这种方式应该早早淘汰掉.
太复杂啦。看的头疼
没有MSVC系列的通用makefile吗
正打算学习下;makefile到底是怎么回事
红薯云云:给我弄到代码区!!!!!
cmake or scons
谁能出个bakefile教程吗?
悲剧呀,不知道bakefile怎么编写,简单的例子是会了,bakefile也有不少例子我都看了。到最后因为写不出makefile.bkl,还是只有改wxsqlite3的makefile.gcc,花了好几天的时间才搞定一个小程序的编译。但是用wxsqlite3居然用result取不出中文字段,头痛中。。。
wxSQLite3ResultSet set = db-&ExecuteQuery(wxT(&SELECT * FROM test&)); & &int count = 0; &while (set.NextRow()) &{ &&wxString s = set.GetAsString(1);
/*假定第二个字段含中文
那么这个里面的s居然是空的。。。不知道啥情况。。。
*/ &&count++; &}

我要回帖

更多关于 makefile文件编写 的文章

 

随机推荐