找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2178|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

makefile相關(guān)的知識(shí)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:108615 發(fā)表于 2016-3-13 17:22 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
makefile的功能太過(guò)強(qiáng)大,完全個(gè)人總結(jié),知 識(shí)有限,歡迎糾正錯(cuò)誤!


main.c

#include "main.h"
int main()
{
        printf_hello();
        printf_ok();
        return ;
}

main.h

#ifndef _MAIN_H
#define _MAIN_H
#include "hello.h"
#include "ok.h"
#endif


printf_hello.c

#include "hello.h"
void printf_hello(void)
{
        printf("hello!\n");
        printf_thanks();
}
void printf_thanks(void)
{
        printf("thanks!!!\n");
}

hello.h

#ifndef _HELLO_H
#define _HELLO_H
#include <stdio.h>
void printf_thanks(void);
void printf_hello(void);
#endif

printf_ok.c

#include "ok.h"
void printf_ok(void)
{
        printf("ok!!!\n");
        printf_thanks();
}

ok.h

#ifndef _OK_H_
#define _OK_H_
#include <stdio.h>
void printf_ok(void);
extern void printf_thanks(void);
#endif

在編譯六個(gè)文件組成的項(xiàng)目時(shí),可以不用寫(xiě)makefile文件因?yàn)槲募臄?shù)量比較的少所以
可以直接在linux系統(tǒng)下直接使用  gcc  main.c  printf_hello.c  printf_ok.c  -o  main
編譯成執(zhí)行文件  main  ,可以直接./main執(zhí)行此文件即可。(上面的所有的文件必須
在一個(gè)文件夾中,才可以編譯,否則 將會(huì)報(bào)錯(cuò)說(shuō)找不到目標(biāo)文件)。

當(dāng)項(xiàng)目比較大的時(shí)候,文件可能幾千甚至更多的時(shí)候,我們可以先創(chuàng)建一個(gè)工程文件名
為project的文件夾,之后在其中在創(chuàng)建兩個(gè)文件夾,一個(gè)取名為inc   ,另一個(gè)取名為
src 。在inc中我們通常是放.h文件,而在src中我們通常放的是.c文件和makefile文件。

一般的makefile文件如下:

main:main.o printf_hello.o printf_ok.o
        gcc main.o printf_hello.o printf_ok.o -o main
main.o:main.c
        gcc -c -I ../inc/ main.c -o main.o
printf_hello.o:printf_hello.c
        gcc -c -I ../inc/ printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
        gcc -c -I ../inc/ printf_ok.c -o  printf_ok.o
clean:
        -rm -f *.o main    //移除后綴為.o和目標(biāo)文件

每一個(gè)gcc命令的最后加上  -g   就可以使用   gdb  編譯。!

makefile 通常有三種寫(xiě)法  Makefile ,   makefile   ,   GNU makefile
第一種使用較多,因?yàn)榇髮?xiě)的M的 ASCII 較小系統(tǒng)擺放文件時(shí)將其放在了前面。

調(diào)用make命令可輸入
target是Makefile文件中定義的目標(biāo)之一,如果省略target,make就將生成
Makefile文件中定義的第一個(gè)目標(biāo)。
例如:在上面的例子中我們可以輸入   make  main.o   或  make  printf_hello.o
等等  ,但是如果你輸入的是make  main.o 那么他只會(huì)執(zhí)行g(shù)cc -c -I ../inc/ main.c
-o main.o   這一個(gè)命令!而單獨(dú)的一個(gè)“make”命令等價(jià)于make  main命令,
由于依賴的關(guān)系所以下面的命令都執(zhí)行除了clean命令外(clean命令和他們沒(méi)有
依賴的關(guān)系)。

因?yàn)閙ain是Makefile文件中定義的第一個(gè)目標(biāo),make首先將其讀入,然后從第一行
開(kāi)始執(zhí)行,把第一個(gè)目標(biāo)main作為它的最終目標(biāo),所有后面的目標(biāo)的更新都會(huì)影響到
main的更新。

如果直接在linux系統(tǒng)下敲擊make命令,則系統(tǒng)執(zhí)行的命令是makefile,而
不是執(zhí)行的是Makefile文件的命令。如果文件夾中既有makefile 也有Makefile文
件,我們需要使用make的命令,make  -f    Makefile  就可以執(zhí)行Makefile的文
件的命令。而以上的makefile文件可以通過(guò)更改頭文件的路徑而更改,.h文件不必
改變。

make的執(zhí)行過(guò)程:
1.如果目標(biāo)文件的時(shí)問(wèn)戳比依賴文件還早,就按規(guī)則中定義的命令更新目標(biāo)文件。
2.如果該規(guī)則中的依賴文件又是其他規(guī)則中的目標(biāo)文件,那么依照規(guī)則鏈不斷執(zhí)行這
個(gè)過(guò)程,直到Makefile文件的結(jié)束,至少可以找到一個(gè)不是規(guī)則生成的最終依賴文
件,獲得此文件的時(shí)間戳
3.然后從下到上依照規(guī)則鏈執(zhí)行目標(biāo)文件的時(shí)間戳比此文件時(shí)間戳舊的規(guī)則,直到最
頂層的規(guī)則

#include "../inc/ok.h"    //將相對(duì)路徑添加到頭文件中
void printf_ok(void)
{
        printf("ok!!!\n");
        printf_thanks();
}

#include "../inc/hello.h"    //將相對(duì)路徑添加到頭文件中
void printf_hello(void)
{
        printf("hello!\n");
        printf_thanks();
}
void printf_thanks(void)
{
        printf("thanks!!!\n");
}

#include "../inc/main.h"   //將相對(duì)路徑添加到頭文件中
int main()
{
        printf_hello();
        printf_ok();
        return ;
}

修改后的makefile文件:
main:main.o printf_hello.o printf_ok.o
        gcc main.o printf_hello.o printf_ok.o -o main
main.o:main.c
        gcc -c  main.c -o main.o
printf_hello.o:printf_hello.c
        gcc -c printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
        gcc -c printf_ok.c -o  printf_ok.o
clean:
        -rm -f *.o main

Makefile的變量
(1)變量名不包括: “   :”  、“   #   ”  、“  =  ”
(2)變量名是大小寫(xiě)敏感的,“  foo ”與“ Foo ”代表不同的變量
(3)預(yù)留大寫(xiě)字母作為作為控制隱含規(guī)則參數(shù)或者用戶重載命令選項(xiàng)

Makefile中的變量分為:
            用戶自定義變量
            預(yù)定義變量、
            自動(dòng)變量

1.用戶自定義的變量
例如將上面的makefile改變:
A=main.o printf_hello.o printf_ok.o
B=gcc

main:$(A)
        $(B)  $(A) -o main
main.o:main.c
        $(B)  -c  main.c -o main.o
printf_hello.o:printf_hello.c
        $(B)  -c printf_hello.c -o printf_hello.o
printf_ok.o:printf_ok.c
        $(B)  -c printf_ok.c -o  printf_ok.o
clean:
        -rm -f *.o main

2.預(yù)定義變量
A=main.o printf_hello.o printf_ok.o
B=gcc
$@     目標(biāo)文件的完整名稱
$<      第一個(gè)依賴的文件名稱

main:$(A)
        $(B)  $(A) -o $@
main.o:main.c
        $(B)  -c   $<  -o  $@
printf_hello.o:printf_hello.c
        $(B)  -c  $<  -o  $@
printf_ok.o:printf_ok.c
        $(B)  -c  $<  -o   $@
clean:
        -rm -f *.o main

也可以寫(xiě)成:
main:$(A)
        $(B)  -o $@   $(A)
main.o:main.c
        $(B)  -c    -o   $@      $<
printf_hello.o:printf_hello.c
        $(B)  -c    -o   $@      $<
printf_ok.o:printf_ok.c
        $(B)  -c    -o   $@      $<
clean:
        -rm -f *.o main

3. 自動(dòng)變量
實(shí)際上,make可以使工作更加自動(dòng)化,也就是說(shuō),make知道一些默認(rèn)
的動(dòng)作,它有一些稱作隱含規(guī)則的內(nèi)置的規(guī)則。
如上例完全可以寫(xiě)成:
A=main.o printf_hello.o printf_ok.o
B=gcc
$@     目標(biāo)文件的完整名稱
$<      第一個(gè)依賴的文件名稱

main:$(A)
        $(B)  $(A) -o $@
clean:
        -rm -f *.o main

可以省略最后兩條,因?yàn)镸akefile的隱式規(guī)則指出都可由“ .c ”文件使用
以下命令生成:
$(B) $(CFLAGS)  $(CPPFLAGS)  -c   –o  file.o file.c

CFLAGS   CPPFLAGS  是系統(tǒng)的默認(rèn)的變量為空  ,我們可以給他賦值,也
可以不理會(huì)。!

makefile還有一種模式規(guī)則可以將makefile變更為:
A=main.o printf_hello.o printf_ok.o
B=gcc

main:$(A)
        $(B)  -o  $@  $(A)
%.o:%.c                                //代表了一系列這樣的文件
        $(B)  -c    -o   $@      $<
clean:
        -rm -f *.o main
1.模式規(guī)則是用來(lái)定義相同處理規(guī)則的多個(gè)文件的,模式規(guī)則可以引入用戶自定義
變量,為多個(gè)文件建立相同的規(guī)則,從而簡(jiǎn)化Makefile的編寫(xiě)。
2.模式規(guī)則中相關(guān)文件前必須用“    %    ”



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表