亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于make命令與makefile文件詳解

 更新時間:2018年01月09日 10:57:02   作者:haozlee  
下面小編就為大家分享一篇基于make命令與makefile文件詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

一、多個源文件帶來的問題

在編寫c/c++測試程序時,我們習慣每次修改一處代碼,然后就馬上編譯運行來查看運行的結果。這種編譯方式對于小程序來說是沒有多大問題的,可對于大型程序來說,由于包含了大量的源文件,如果每次改動一個地方都需要編譯所有的源文件,這個簡單的直接編譯所有源文件方式對程序員來說簡直是噩耗。

我們看一個例子:

// main.c
#include "a.h"
// 2.c
#include "a.h"
#include "b.h"
// 3.c
#include "b.h"
#include "c.h"

如果程序員只修改了頭文件c.h,則源文件main.c和2.c都無需編譯,因為它們不依賴這個頭文件。而對3.c來說,由于它包含了c.h,所以在頭文件c.h改動后,就必須得新編譯。

而如果改動了b.h可是忘記編譯了2.c,那么最終的程序就可能無法正常工作。

make 工具就是為了解決上述問題而出現(xiàn)的,它會在必要時重新編譯所有受改動影響的源文件。

二、make 命令

make命令本身支持許多選項,最常用的是-f選項。如果我們直接運行

make

那么make命令會首先在當前目錄查找名為makefile的文件,如果找不到,就會查找名為Makefile的文件。

為了指示make命令將哪個文件作為makefile文件,可以使用 -f 選項:

make -f Makefile1

三、makefile 文件

上面提到makefile文件,那么什么是makefile文件呢?

make命令功能雖然十分強大,但是光憑其自身無法了解如何構建應用程序的。這時,makefile就出來了,它告訴make應用程序如何構建的。make命令和makefile文件的結合提供了一個在管理項目的十分強大的工具,它們不僅用于控制源文件的編譯,而且還提供了將應用程序安裝到目標目錄等其他功能。

3.1 依賴關系

依賴關系定義了應用程序里面每個文件與其他源文件之間的關系。例如在上面的例子中,我們可以定義最終應用程序依賴于目標文件main.o,2.o和3.o。同樣,main.o依賴于main.c和a.h,2.o依賴于2.c,a.h和b.h,3.o依賴于3.c,b.h和c.h。

在makefile文件中,依賴關系的寫法是:先寫目標的名稱,然后緊跟一個冒號,接著是空格或者制表符tab,最后是用空格或者制表符tab隔開的文件列表。上面的例子的依賴關系如下:

myapp: main.o 2.o 3.o
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h

這組依賴關系形成一個層次結構,展示了源文件之間的關系。例如,如果源文件b.h發(fā)生改變,就需要重新編譯2.o和3.o,接下來還需要重新編譯myapp。

3.2 規(guī)則

makefiel文件中的規(guī)則定義了目標的創(chuàng)建方式。在上面的例子中,我們使用gcc -c 2.c創(chuàng)建2.o。這個gcc命令即是目標2.o的創(chuàng)建方式,也即是規(guī)則。

在makefile文件中,規(guī)則都必須以tab開頭。

在源文件所在的目錄下創(chuàng)建Makefile1文件,其內(nèi)容如下。

myapp: main.o 2.o 3.o
 gcc -o myapp main.o 2.o 3.o
main.o: main.c a.h
 gcc -c main.c
2.o: 2.c a.h b.h
 gcc -c 2.c
3.o: 3.c b.h c.h
 gcc -c 3.c

三個頭文件a.h,b.h,c.h內(nèi)容都為空,源文件的內(nèi)容如下:

/* main.c */
#include <stdlib.h>
#include "a.h"
extern void function_two();
extern void function_three();
int main()
{
 function_two();
 function_three();
 exit(EXIT_SUCCESS);
}
/* 2.c */
#include <stdio.h>
#include "a.h"
#include "b.h"
void function_two() {
 printf("function two\n");
}
/* 3.c */
#include <stdio.h>
#include "b.h"
#include "c.h"
void function_three() {
 printf("function three\n");
}

執(zhí)行make命令,:

$ make -f Makefile1 
gcc -c main.c 
gcc -c 2.c 
gcc -c 3.c 
gcc -o myapp main.o 2.o 3.o

運行應用程序:

$ ./myapp 
function two 
function three

從輸出可以說明應用程序已被正確構建。

如果改變b.h頭文件,makefile能夠正確處理這一變化,只有2.c和3.c發(fā)生重新編譯:

$ touch b.h
$ make -f Makefile1 
gcc -c 2.c 
gcc -c 3.c 
gcc -o myapp main.o 2.o 3.o

3.3 注釋

makefile文件使用#來表示注釋,一直延續(xù)到這一行的結束。

3.4 宏

不同的平臺下可能使用不同的編譯器,不同的環(huán)境(例如開發(fā)與線上環(huán)境)也可能使用不同的編譯器選項,為了便于修改makefile這些可變的參數(shù),我們可以使用宏來實現(xiàn)makefile。

makefile引用宏定義的方法為$(MACRONAME)。我們來看如何使用宏來改寫上面的makefile文件。

all: myapp
# 編譯器
CC = gcc
# include的搜索路徑
INCLUDE = .
# 編譯器參數(shù)
CFLAGS = -g -Wall -ansi
myapp: main.o 2.o 3.o
 $(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c

我們習慣在makefile文件中將第一個目標定義為all,然后再列出其他從屬的目標,上面的makefile也遵循這個約定。

運行make命令:

$ make -f Makefile2 
gcc -I. -g -Wall -ansi -c main.c 
gcc -I. -g -Wall -ansi -c 2.c 
gcc -I. -g -Wall -ansi -c 3.c 
gcc -o myapp main.o 2.o 3.o

同樣也正確構建了應用程序myapp。

3.5 多個目標

makefile文件除了定義編譯的目標外,還可以定義其他的目標。例如,增加一個clean選項來刪除不需要的目標文件,增加一個install選項來將編譯成功的應用程序安裝到另一個目錄下,等等。

all: myapp
CC = gcc
INSTDIR = /usr/local/bin
INCLUDE = .
CFLAGS = -g -Wall -ansi
myapp: main.o 2.o 3.o
 $(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
 -rm main.o 2.o 3.o
install: myapp
 @if [ -d $(INSTDIR) ]; \
  then \
  cp myapp $(INSTDIR);\
  chmod a+x $(INSTDIR)/myapp;\
  chmod og-w $(INSTDIR)/myapp;\
  echo "Install in $(INSTDIR)";\
 else \
  echo "sorry, $(INSTDIR) does not exist";\
 fi

上面的makefile文件有幾點需要注意的。

(1)特殊目標all只指定了myapp這個目標,因此,在執(zhí)行make命令時未指定目標,它的默認行為就是創(chuàng)建目標myapp。

(2)目標clean用來測試編譯過程中產(chǎn)生的中間文件。

(3)目標install用于將應用程序安裝到指定目錄,它依賴于myapp,即執(zhí)行install前須先創(chuàng)建myapp。install目標由shell腳本組成,由于make命令在執(zhí)行規(guī)則時會調(diào)用一個shell,并且會針對每個規(guī)則使用一個新的shell,所以必須在上面每行代碼的結尾加上一個\,讓所有的shell腳本都處于同一行。

腳本以@開頭,說明make在執(zhí)行這些規(guī)則之前不會在標準輸出顯示命令本身。

創(chuàng)建myapp:

$ make -f Makefile3 
gcc -I. -g -Wall -ansi -c main.c 
gcc -I. -g -Wall -ansi -c 2.c 
gcc -I. -g -Wall -ansi -c 3.c 
gcc -o myapp main.o 2.o 3.o

將myapp安裝到指到目錄:

$ make -f Makefile3 install 
Install in /usr/local/bin

然后可以直接執(zhí)行myapp:

$ myapp 
function two 
function three

刪除中間文件:

$ make -f Makefile3 clean 
rm main.o 2.o 3.o

以上這篇基于make命令與makefile文件詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • C語言+EasyX實現(xiàn)數(shù)字雨效果

    C語言+EasyX實現(xiàn)數(shù)字雨效果

    這篇文章主要為大家詳細介紹了C語言+EasyX實現(xiàn)數(shù)字雨效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • C語言利用EasyX實現(xiàn)繪制足球圖案

    C語言利用EasyX實現(xiàn)繪制足球圖案

    這篇文章主要為大家詳細介紹了C語言如何利用EasyX繪圖庫實現(xiàn)繪制一個簡單的足球圖案,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-11-11
  • C語言中const,volatile,restrict的用法總結

    C語言中const,volatile,restrict的用法總結

    以下是對C語言中const,volatile,restrict的用法進行了詳細的總結介紹,需要的朋友可以過來參考下
    2013-10-10
  • C++實現(xiàn)查詢本機信息的示例代碼

    C++實現(xiàn)查詢本機信息的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C++實現(xiàn)查詢本機信息,并且進行上報,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的可以了解一下
    2023-05-05
  • C++深入淺出講解內(nèi)存四區(qū)與new關鍵字的使用

    C++深入淺出講解內(nèi)存四區(qū)與new關鍵字的使用

    內(nèi)存四區(qū),一個非常重要的知識點,搞懂了內(nèi)存四區(qū),才能更快的去搞懂指針。我們寫的C語言代碼,不夸張的說,都是直接或者間接的在操作內(nèi)存。C語言之所以能夠開發(fā)操作系統(tǒng),就是指針的存在,而指針說白了就是地址,內(nèi)存地址,指針變量說白了就是存儲地址的變量
    2022-05-05
  • VC++實現(xiàn)添加文件關聯(lián)的方法示例

    VC++實現(xiàn)添加文件關聯(lián)的方法示例

    這篇文章主要介紹了VC++實現(xiàn)添加文件關聯(lián)的方法,涉及VC++針對注冊表的寫入與VC事件響應相關操作技巧,需要的朋友可以參考下
    2017-08-08
  • 基于Qt播放器的實現(xiàn)詳解(支持Rgb,YUV格式)

    基于Qt播放器的實現(xiàn)詳解(支持Rgb,YUV格式)

    這篇文章主要為大家詳細介紹了如何利用Qt實現(xiàn)簡易的播放器,可以支持支持Rgb,YUV格式。文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下
    2022-12-12
  • C/C++中字符串流詳解及其作用介紹

    C/C++中字符串流詳解及其作用介紹

    這篇文章主要介紹了C/C++中字符串流詳解及其作用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • C++中priority_queue模擬實現(xiàn)的代碼示例

    C++中priority_queue模擬實現(xiàn)的代碼示例

    在c++語言中數(shù)據(jù)結構中的堆結構可以通過STL庫中的priority_queue 優(yōu)先隊列來實現(xiàn),這樣做極大地簡化了我們的工作量,這篇文章主要給大家介紹了關于C++中priority_queue模擬實現(xiàn)的相關資料,需要的朋友可以參考下
    2021-08-08
  • linux c模擬ls命令詳解

    linux c模擬ls命令詳解

    本篇文章是對linux中基于c模擬ls命令的實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06

最新評論