青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

C/C++ 通用 Makefile(轉)

Posted on 2009-06-01 14:30 Prayer 閱讀(675) 評論(0)  編輯 收藏 引用 所屬分類: C/C++LINUX/UNIX/AIX


C/C++ 通用 Makefile
Generic Makefile for C/C++ Program

==================================================
Keywords: Makefile, make, Generic, C/C++
Author:   whyglinux (whyglinux AT hotmail DOT com)
Date:     2006-03-04
==================================================

本文提供了一個用于對 C/C++ 程序進行編譯和連接以產生可執行程序的通用 Makefile。

在使用 Makefile 之前,只需對它進行一些簡單的設置即可;而且一經設置,即使以后對源程序文件有所增減一般也不再需要改動 Makefile。因此,即便是一個沒有學習過 Makefile 書寫規則的人,也可以為自己的 C/C++ 程序快速建立一個可工作的 Makefile。

這個 Makefile 可以在 GNU Make 和 GCC 編譯器下正常工作。但是不能保證對于其它版本的 Make 和編譯器也能正常工作。

如果你發現了本文中的錯誤,或者對本文有什么感想或建議,可通過 whyglinux AT hotmail DOT com 郵箱和作者聯系。
此 Makefile 的使用方法如下:

 * 程序目錄的組織
 盡量將自己的源程序集中在一個目錄中,并且把 Makefile 和源程序放在一起,這樣用起來比較方便。當然,也可以將源程序分類存放在不同的目錄中。

 在程序目錄中創建一個名為 Makefile 的文本文件,將后面列出的 Makefile 的內容復制到這個文件中。(注意:在復制的過程中,Makfile 中各命令前面的 Tab 字符有可能被轉換成若干個空格。這種情況下需要把 Makefile 命令前面的這些空格替換為一個 Tab。)

 將當前工作目錄切換到 Makefile 所在的目錄。目前,這個 Makefile 只支持在當前目錄中的調用,不支持當前目錄和 Makefile 所在的路徑不是同一目錄的情況。

 * 指定可執行文件
 程序編譯和連接成功后產生的可執行文件在 Makefile 中的 PROGRAM 變量中設定。這一項不能為空。為自己程序的可執行文件起一個有意義的名子吧。

 * 指定源程序
 要編譯的源程序由其所在的路徑和文件的擴展名兩項來確定。由于頭文件是通過包含來使用的,所以在這里說的源程序不應包含頭文件。

 程序所在的路徑在 SRCDIRS 中設定。如果源程序分布在不同的目錄中,那么需要在 SRCDIRS 中一一指定,并且路徑名之間用空格分隔。

 在 SRCEXTS 中指定程序中使用的文件類型。C/C++ 程序的擴展名一般有比較固定的幾種形式:.c、.C、.cc、.cpp、.CPP、.c++、.cp、或者.cxx(參見 man gcc)。擴展名決定了程序是 C 還是 C++ 程序:.c 是 C 程序,其它擴展名表示 C++ 程序。一般固定使用其中的一種擴展名即可。但是也有可能需要使用多種擴展名,這可以在 SOURCE_EXT 中一一指定,各個擴展名之間用空格分隔。

 雖然并不常用,但是 C 程序也可以被作為 C++ 程序編譯。這可以通過在 Makefile 中設置 CC = $(CXX) 和 CFLAGS = $(CXXFLAGS) 兩項即可實現。

 這個 Makefile 支持 C、C++ 以及 C/C++ 混合三種編譯方式:
 o 如果只指定 .c 擴展名,那么這是一個 C 程序,用 $(CC) 表示的編譯命令進行編譯和連接。
 o 如果指定的是除 .c 之外的其它擴展名(如 .cc、.cpp、.cxx 等),那么這是一個 C++ 程序,用 $(CXX) 進行編譯和連接。
 o 如果既指定了 .c,又指定了其它 C++ 擴展名,那么這是 C/C++ 混合程序,將用 $(CC) 編譯其中的 C 程序,用 $(CXX) 編譯其中的 C++ 程序,最后再用 $(CXX) 連接程序。

 這些工作都是 make 根據在 Makefile 中提供的程序文件類型(擴展名)自動判斷進行的,不需要用戶干預。

*



 * 指定編譯選項
 編譯選項由三部分組成:預處理選項、編譯選項以及連接選項,分別由 CPPFLAGS、CFLAGS與CXXFLAGS、LDFLAGS 指定。

 CPPFLAGS 選項可參考 C 預處理命令 cpp 的說明,但是注意不能包含 -M 以及和 -M 有關的選項。如果是 C/C++ 混合編程,也可以在這里設置 C/C++ 的一些共同的編譯選項。

 CFLAGS 和 CXXFLAGS 兩個變量通常用來指定編譯選項。前者僅僅用于指定 C 程序的編譯選項,后者僅僅用于指定 C++ 程序的編譯選項。其實也可以在兩個變量中指定一些預處理選項(即一些本來應該放在 CPPFLAGS 中的選項),和 CPPFLAGS 并沒有明確的界限。

 連接選項在 LDFLAGS 中指定。如果只使用 C/C++ 標準庫,一般沒有必要設置。如果使用了非標準庫,應該在這里指定連接需要的選項,如庫所在的路徑、庫名以及其它聯接選項。

 現在的庫一般都提供了一個相應的 .pc 文件來記錄使用庫所需要的預編譯選項、編譯選項和連接選項等信息,通過 pkg-config 可以動態提取這些選項。與由用戶顯式指定各個選項相比,使用 pkg-config 來訪問庫提供的選項更方便、更具通用性。在后面可以看到一個 GTK+ 程序的例子,其編譯和連接選項的指定就是用 pkg-config 實現的。

 * 編譯和連接
 上面的各項設置好之后保存 Makefile 文件。執行 make 命令,程序就開始編譯了。

 命令 make 會根據 Makefile 中設置好的路徑和文件類型搜索源程序文件,然后根據文件的類型調用相應的編譯命令、使用相應的編譯選項對程序進行編譯。

 編譯成功之后程序的連接會自動進行。如果沒有錯誤的話最終會產生程序的可執行文件。

 注意:在對程序編譯之后,會產生和源程序文件一一對應的 .d 文件。這是表示依賴關系的文件,通過它們 make 決定在源程序文件變動之后要進行哪些更新。為每一個源程序文件建立相應的 .d 文件這也是 GNU Make 推薦的方式。

 * Makefile 目標(Targets)
 下面是關于這個 Makefile 提供的目標以及它所完成的功能:
 o make
 編譯和連接程序。相當于 make all。
 o make objs
 僅僅編譯程序產生 .o 目標文件,不進行連接(一般很少單獨使用)。
 o make clean
 刪除編譯產生的目標文件和依賴文件。
 o make cleanall
 刪除目標文件、依賴文件以及可執行文件。
 o make rebuild
 重新編譯和連接程序。相當于 make clean && make all。


關于這個 Makefile 的實現原理不準備詳細解釋了。如果有興趣的話,可參考文末列出的“參考資料”。

Makefile 的內容如下:

###############################################################################
#
# Generic Makefile for C/C++ Program
#
# Author: whyglinux (whyglinux AT hotmail DOT com)
# Date: 2006/03/04

# Description:
# The makefile searches in <SRCDIRS> directories for the source files
# with extensions specified in <SOURCE_EXT>, then compiles the sources
# and finally produces the <ROGRAM>, the executable file, by linking
# the objectives.

# Usage:
# $ make compile and link the program.
# $ make objs compile only (no linking. Rarely used).
# $ make clean clean the objectives and dependencies.
# $ make cleanall clean the objectives, dependencies and executable.
# $ make rebuild rebuild the program. The same as make clean && make all.
#==============================================================================

## Customizing Section: adjust the following if necessary.
##=============================================================================

# The executable file name.
# It must be specified.
# PROGRAM := a.out # the executable name
PROGRAM :=

# The directories in which source files reside.
# At least one path should be specified.
# SRCDIRS := . # current directory
SRCDIRS :=

# The source file types (headers excluded).
# At least one type should be specified.
# The valid suffixes are among of .c, .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx.
# SRCEXTS := .c # C program
# SRCEXTS := .cpp # C++ program
# SRCEXTS := .c .cpp # C/C++ program
SRCEXTS :=

# The flags used by the cpp (man cpp for more).
# CPPFLAGS := -Wall -Werror # show all warnings and take them as errors
CPPFLAGS :=

# The compiling flags used only for C.
# If it is a C++ program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C parts.
CFLAGS :=
CFLAGS +=

# The compiling flags used only for C++.
# If it is a C program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C++ parts.
CXXFLAGS :=
CXXFLAGS +=

# The library and the link options ( C and C++ common).
LDFLAGS :=
LDFLAGS +=

## Implict Section: change the following only when necessary.
##=============================================================================
# The C program compiler. Uncomment it to specify yours explicitly.
#CC = gcc

# The C++ program compiler. Uncomment it to specify yours explicitly.
#CXX = g++

# Uncomment the 2 lines to compile C programs as C++ ones.
#CC = $(CXX)
#CFLAGS = $(CXXFLAGS)

# The command used to delete file.
#RM = rm -f

## Stable Section: usually no need to be changed. But you can add more.
##=============================================================================
SHELL = /bin/sh
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
OBJS = $(foreach x,$(SRCEXTS), \
 $(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))
DEPS = $(patsubst %.o,%.d,$(OBJS))

.PHONY : all objs clean cleanall rebuild

all : $(PROGRAM)

# Rules for creating the dependency files (.d).
#---------------------------------------------------
%.d : %.c
 @$(CC) -MM -MD $(CFLAGS) $<

%.d : %.C
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.cc
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.cpp
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.CPP
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.c++
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.cp
 @$(CC) -MM -MD $(CXXFLAGS) $<

%.d : %.cxx
 @$(CC) -MM -MD $(CXXFLAGS) $<

# Rules for producing the objects.
#---------------------------------------------------
objs : $(OBJS)

%.o : %.c
 $(CC) -c $(CPPFLAGS) $(CFLAGS) $<

%.o : %.C
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.cc
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.cpp
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.CPP
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.c++
 $(CXX -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.cp
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

%.o : %.cxx
 $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<

# Rules for producing the executable.
#----------------------------------------------
$(PROGRAM) : $(OBJS)
ifeq ($(strip $(SRCEXTS)), .c) # C file
 $(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
else # C++ file
 $(CXX) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
endif

-include $(DEPS)

rebuild: clean all

clean :
 @$(RM) *.o *.d

cleanall: clean
 @$(RM) $(PROGRAM) $(PROGRAM).exe

### End of the Makefile ## Suggestions are welcome ## All rights reserved ###
###############################################################################

下面提供兩個例子來具體說明上面 Makefile 的用法。

例一 Hello World 程序

這個程序的功能是輸出 Hello, world! 這樣一行文字。由 hello.h、hello.c、main.cxx 三個文件組成。前兩個文件是 C 程序,后一個是 C++ 程序,因此這是一個 C 和 C++ 混編程序。

/* File name: hello.h
* C header file
*/

#ifndef HELLO_H
#define HELLO_H

#ifdef __cplusplus
extern "C" {
#endif

 void print_hello();

#ifdef __cplusplus
}
#endif

#endif



/* File name: hello.c
* C source file.
*/
#include "hello.h"
#include <stdio.h>

void print_hello()
{
 puts( "Hello, world!" );
}



/* File name: main.cxx
* C++ source file.
*/
#include "hello.h"

int main()
{
 print_hello();

 return 0;
}


建立一個新的目錄,然后把這三個文件拷貝到目錄中,也把 Makefile 文件拷貝到目錄中。之后,對 Makefile 的相關項目進行如下設置:

PROGRAM := hello # 設置運行程序名
SRCDIRS := . # 源程序位于當前目錄下
SRCEXTS := .c .cxx # 源程序文件有 .c 和 .cxx 兩種類型
CFLAGS := -g # 為 C 目標程序包含 GDB 可用的調試信息
CXXFLAGS := -g # 為 C++ 目標程序包含 GDB 可用的調試信息


由于這個簡單的程序只使用了 C 標準庫的函數(puts),所以對于 CFLAGS 和 CXXFLAGS 沒有過多的要求,LDFLAGS 和 CPPFLAGS 選項也無需設置。

經過上面的設置之后,執行 make 命令就可以編譯程序了。如果沒有錯誤出現的話,./hello 就可以運行程序了。

如果修改了源程序的話,可以看到只有和修改有關的源文件被編譯。也可以再為程序添加新的源文件,只要它們的擴展名是已經在 Makefile 中設置過的,那么就沒有必要修改 Makefile。

例二 GTK+ 版 Hello World 程序

這個 GTK+ 2.0 版的 Hello World 程序可以從下面的網址上得到:http://www.gtk.org/tutorial/c58.html#SEC-HELLOWORLD。當然,要編譯 GTK+ 程序,還需要你的系統上已經安裝好了 GTK+。

跟第一個例子一樣,單獨創建一個新的目錄,把上面網頁中提供的程序保存為 main.c 文件。對 Makefile 做如下設置:

PROGRAM := hello # 設置運行程序名
SRCDIRS := . # 源程序位于當前目錄下
SRCEXTS := .c # 源程序文件只有 .c 一種類型
CFLAGS := `pkg-config --cflags gtk+-2.0` # CFLAGS
LDFLAGS := `pkg-config --libs gtk+-2.0` # LDFLAGS


這是一個 C 程序,所以 CXXFLAGS 沒有必要設置——即使被設置了也不會被使用。

編譯和連接 GTK+ 庫所需要的 CFLAGS 和 LDFLAGS 由 pkg-config 程序自動產生。

現在就可以運行 make 命令編譯、./hello 執行這個 GTK+ 程序了。

參考資料:

 * Multi-file projects and the GNU Make utility
 Author: George Foot
 http://www.elitecoders.de/mags/cscene/CS2/CS2-10.html

 * GNU Make Manual
 http://www.gnu.org/software/make/manual/

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久影院午夜论| 免费av成人在线| 欧美精品v国产精品v日韩精品 | 国产精品综合久久久| 欧美美女bb生活片| 欧美精品久久久久久久久久| 欧美va天堂| 一区二区日韩伦理片| 久久精品亚洲一区二区三区浴池| 性欧美xxxx视频在线观看| 欧美在线观看日本一区| 久久久久免费观看| 欧美va日韩va| 蜜桃视频一区| 亚洲国产欧美一区二区三区丁香婷| 久久免费少妇高潮久久精品99| 美女主播一区| 99国产一区| 欧美一区二视频| 免费看亚洲片| 国产精品女主播| 影音先锋久久精品| 99xxxx成人网| 久久国产精品久久精品国产| 欧美成人久久| 一区二区欧美精品| 久久久一二三| 欧美性做爰猛烈叫床潮| 国产综合欧美| 亚洲精品久久嫩草网站秘色| 亚洲欧美美女| 欧美成人黄色小视频| 999在线观看精品免费不卡网站| 亚洲男女毛片无遮挡| 欧美jizzhd精品欧美巨大免费| 欧美日韩中文字幕| 亚洲大片免费看| 亚洲欧美日韩综合| 欧美激情1区2区3区| 一区二区三区色| 久久久久国产一区二区| 欧美日韩国语| 亚洲第一综合天堂另类专| 亚洲女女女同性video| 欧美一区二区三区日韩视频| 亚洲一区亚洲| 亚洲片国产一区一级在线观看| 亚洲一区二区三区免费视频| 鲁鲁狠狠狠7777一区二区| 国产欧美在线观看| 欧美电影电视剧在线观看| 国产精品久久久久一区二区三区共 | 美女啪啪无遮挡免费久久网站| 欧美午夜视频网站| 91久久久在线| 久久亚洲综合色| 午夜精品一区二区三区在线播放| 欧美日韩中字| 一区二区av| 亚洲第一主播视频| 久久久久九九视频| 韩国av一区二区三区在线观看| 亚洲欧美日韩中文视频| 亚洲日产国产精品| 美女网站在线免费欧美精品| 韩国在线一区| 久久婷婷激情| 久久久九九九九| 国产在线乱码一区二区三区| 久久久久国产精品www| 欧美亚洲免费在线| 黄色av日韩| 蜜桃av噜噜一区二区三区| 久久久久久网| 91久久精品国产91久久| 欧美岛国激情| 欧美粗暴jizz性欧美20| 亚洲日本欧美| 亚洲高清色综合| 欧美激情偷拍| 蜜桃久久av一区| 亚洲男女自偷自拍| 亚洲视频视频在线| 国产精品高潮呻吟视频| 亚洲欧美日韩国产成人精品影院| 亚洲图片欧美日产| 国产亚洲福利| 欧美激情一区二区三区四区| 欧美日韩成人一区| 一区二区三区国产在线| 亚洲一区三区视频在线观看| 国产欧美一区二区色老头| 久久午夜视频| 欧美日韩精品久久久| 欧美一区二区精美| 久久精品国产精品亚洲| 亚洲麻豆av| 午夜亚洲福利| 亚洲精品乱码久久久久久蜜桃91 | 伊人蜜桃色噜噜激情综合| 免费日韩一区二区| 女人天堂亚洲aⅴ在线观看| 日韩一级免费观看| 亚洲一区二区三| 亚洲韩国日本中文字幕| 一区二区久久久久| 国模大胆一区二区三区| 葵司免费一区二区三区四区五区| 欧美激情一区在线观看| 久久精品视频播放| 免费欧美在线视频| 一本色道**综合亚洲精品蜜桃冫| 亚洲一区免费在线观看| 亚洲精品网址在线观看| 欧美在线高清| 亚洲欧美电影在线观看| 久久综合伊人77777尤物| 亚洲一区在线免费| 欧美成人综合在线| 欧美wwwwww| 国内精品久久久久久 | 国产一区二区日韩| 亚洲精品国产视频| 国产欧美日韩亚洲一区二区三区 | 亚洲精品日韩欧美| 久久精品国产99国产精品澳门| 一区二区成人精品| 老司机午夜精品视频| 亚洲欧美资源在线| 欧美日韩国产小视频在线观看| 欧美成人精品不卡视频在线观看| 欧美性一区二区| 亚洲毛片在线| 亚洲精品午夜| 久久久国产一区二区| 久久精品国产精品亚洲精品| 国产精品丝袜xxxxxxx| 中文av一区特黄| 亚洲网站啪啪| 欧美激情一区二区三区四区| 欧美大片免费观看在线观看网站推荐| 欧美日韩中文在线| 欧美国产精品| 亚洲第一精品影视| 欧美尤物一区| 久久久久久夜精品精品免费| 国产日韩欧美一区| 久久成人免费网| 狂野欧美激情性xxxx欧美| 有码中文亚洲精品| 久久在线视频| 欧美国产大片| 一区二区三区欧美亚洲| 欧美日韩国产综合网| 99精品99| 亚洲综合成人婷婷小说| 国产精品video| 亚洲视频在线观看视频| 欧美综合国产| 国产一区在线看| 久久国产精品网站| 欧美国产综合| 欧美国产在线视频| 亚洲一区精品在线| 亚洲中无吗在线| 国产精品s色| 久久精品一本| 欧美成人小视频| 99国产麻豆精品| 国产精品福利在线| 亚洲欧美春色| 久久久一区二区三区| 亚洲激情图片小说视频| 欧美手机在线| 久久久国产精品一区二区中文| 亚洲国产精品久久| 亚洲免费在线精品一区| 在线观看日韩精品| 国产精品国产自产拍高清av王其| 亚洲欧美中日韩| 欧美国产在线电影| 亚洲欧美日韩中文视频| 国产一区二区三区四区三区四| 久久亚洲高清| 91久久精品国产91性色tv| 亚洲欧美一区二区三区久久| 亚洲福利视频一区| 欧美日韩综合| 麻豆国产精品777777在线| 99视频国产精品免费观看| 久久青青草原一区二区| 中文精品视频| 亚洲国产成人久久综合| 国产精品久久久久久久第一福利| 久久精品视频导航| 亚洲少妇自拍| 亚洲欧洲精品成人久久奇米网 | 国产在线拍偷自揄拍精品| 欧美黄污视频| 久久综合色综合88|