一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

一些通用的Makefile文件模板

 520jefferson 2024-01-11 發(fā)布于中國(guó)香港

作者:Acuity.

原文:

https://blog.csdn.net/qq_20553613/article/details/90649734

圖片

寫(xiě)在前面

對(duì)于Windows下開(kāi)發(fā),很多IDE都集成了編譯器,如Visual Studio,提供了“一鍵編譯”,編碼完成后只需一個(gè)操作即可完成編譯、鏈接、生成目標(biāo)文件。

Linux開(kāi)發(fā)與Windows不同,Linux下一般用的的gcc/g++編譯器,如果是開(kāi)發(fā)ARM下的Linux程序,還需用到arm-linux-gcc/arm-linux-g++交叉編譯器。

Linux下也可以實(shí)現(xiàn)“一鍵編譯”功能,此時(shí)需要一個(gè)編譯腳本“Makefile”,Makefile可以手動(dòng)編寫(xiě),也可以借助自動(dòng)化構(gòu)建工具(如scons、CMake)生成。手動(dòng)編寫(xiě)Makefile是Linux和Windows程序員的區(qū)別之一,一般地一個(gè)通用的Makefile能夠適合大部分Linux項(xiàng)目程序。

3個(gè)Makefile模板

2.1 編譯可執(zhí)行文件Makefile

VERSION  =1.00
CC   =gcc
DEBUG   =-DUSE_DEBUG
CFLAGS  =-Wall
SOURCES   =$(wildcard ./source/*.c)
INCLUDES   =-I./include
LIB_NAMES  =-lfun_a -lfun_so
LIB_PATH  =-L./lib
OBJ   =$(patsubst %.c, %.o, $(SOURCES))
TARGET  =app

#links
$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)
 @rm -rf $(OBJ)
 
#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要點(diǎn)說(shuō)明】

【1】程序版本

開(kāi)發(fā)調(diào)試過(guò)程可能產(chǎn)生多個(gè)程序版本,可以在目標(biāo)文件后(前)增加版本號(hào)標(biāo)識(shí)。

VERSION = 1.00
$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)

【2】編譯器選擇

Linux下為gcc/g++;arm下為arm-linux-gcc;不同CPU廠商提供的定制交叉編譯器名稱(chēng)可能不同,如Hisilicon“arm-hisiv300-linux-gcc”。

CC = gcc

【3】宏定義

開(kāi)發(fā)過(guò)程,特殊代碼一般增加宏條件來(lái)選擇是否編譯,如調(diào)試打印輸出代碼。-D是標(biāo)識(shí),后面接著的是“宏”。

DEBUG =-DUSE_DEBUG

【4】編譯選項(xiàng)

可以指定編譯條件,如顯示警告(-Wall),優(yōu)化等級(jí)(-O)。

CFLAGS =-Wall -O

【5】源文件

指定源文件目的路徑,利用“wildcard”獲取路徑下所有依賴(lài)源文件。

SOURCES =$(wildcard ./source/*.c)

【6】頭文件

包含依賴(lài)的頭文件,包括源碼文件和庫(kù)文件的頭文件。

INCLUDES =-I./include

【7】庫(kù)文件名稱(chēng)

指定庫(kù)文件名稱(chēng),庫(kù)文件有固定格式,靜態(tài)庫(kù)為libxxx.a;動(dòng)態(tài)庫(kù)為libxxx.so,指定庫(kù)文件名稱(chēng)只需寫(xiě)“xxx”部分,

LIB_NAMES =-lfun_a -lfun_so

【8】庫(kù)文件路徑

指定依賴(lài)庫(kù)文件的存放路徑。注意如果引用的是動(dòng)態(tài)庫(kù),動(dòng)態(tài)庫(kù)也許拷貝到“/lib”或者“/usr/lib”目錄下,執(zhí)行應(yīng)用程序時(shí),系統(tǒng)默認(rèn)在該文件下索引動(dòng)態(tài)庫(kù)。

LIB_PATH =-L./lib

【9】目標(biāo)文件

調(diào)用“patsubst”將源文件(.c)編譯為目標(biāo)文件(.o)。

OBJ =$(patsubst %.c, %.o, $(SOURCES))

【10】執(zhí)行文件

執(zhí)行文件名稱(chēng)

TARGET =app

【11】編譯

%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@

【12】鏈接

可創(chuàng)建一個(gè)“output”文件夾存放目標(biāo)執(zhí)行文件。鏈接完輸出目標(biāo)執(zhí)行文件,可以刪除編譯產(chǎn)生的臨時(shí)文件(.o)。

$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET).$(VERSION)
 @rm -rf $(OBJ)

【13】清除編譯信息

執(zhí)行“make clean”清除編譯產(chǎn)生的臨時(shí)文件。

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

2.2 編譯靜態(tài)庫(kù)Makefile

VERSION     =
CC          =gcc
DEBUG   =
CFLAGS  =-Wall
AR   =ar
ARFLAGS     =rv
SOURCES   =$(wildcard *.c)
INCLUDES    =-I.
LIB_NAMES   =
LIB_PATH  =
OBJ         =$(patsubst %.c, %.o, $(SOURCES))
TARGET      =libfun_a

#link
$(TARGET):$(OBJ)
 @mkdir -p output
 $(AR) $(ARFLAGS) output/$(TARGET)$(VERSION).a $(OBJ)
 @rm -rf $(OBJ)

#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@
  
.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要點(diǎn)說(shuō)明】

基本格式與“編譯可執(zhí)行Makefile”一致,不同點(diǎn)包括以下。

【1】使用到“ar”命令將目標(biāo)文件(.o)鏈接成靜態(tài)庫(kù)文件(.a)。靜態(tài)庫(kù)文件固定命名格式為:libxxx.a。

2.3 編譯動(dòng)態(tài)庫(kù)Makefile

VERSION   =
CC        =gcc
DEBUG     =
CFLAGS    =-fPIC -shared 
LFLAGS   =-fPIC -shared 
SOURCES   =$(wildcard *.c)
INCLUDES  =-I.
LIB_NAMES =
LIB_PATH  =
OBJ       =$(patsubst %.c, %.o, $(SOURCES))
TARGET    =libfun_so

#link
$(TARGET):$(OBJ)
 @mkdir -p output
 $(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) $(LFLAGS) -o output/$(TARGET)$(VERSION).so
 @rm -rf $(OBJ)
 
#compile
%.o: %.c
 $(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $< -o $@

.PHONY:clean
clean:
 @echo "Remove linked and compiled files......"
 rm -rf $(OBJ) $(TARGET) output 

【要點(diǎn)說(shuō)明】

基本格式與“編譯可執(zhí)行Makefile”一致,不同點(diǎn)包括以下。

【1】編譯選項(xiàng)和鏈接選項(xiàng)增加“-fPIC -shared ”選項(xiàng)。動(dòng)態(tài)庫(kù)文件固定命名格式為libxxx.so。

Demo

3.1 編譯應(yīng)用程序

編寫(xiě)測(cè)試?yán)?,文件存放目錄結(jié)構(gòu)如下,頭文件存放在“include”目錄,庫(kù)文件存放在“l(fā)ib”目錄,源文件存放在“source”目錄,Makefile在當(dāng)前目錄下。

圖片

源碼1:

/*頭文件*/
#ifndef _FUN0_H_
#define _FUN0_H_
#endif

extern void fun0_printf(void);
extern void fun1_printf(void);

/*源文件*/
#include <stdio.h>
#include "fun0.h"

void fun0_printf(void)
{
    printf("Call \'fun0\'. \r\n");
}

源碼2:

/*頭文件*/
#ifndef _FUN1_H_
#define _FUN1_H_
#endif

extern void fun1_printf(void);

/*源文件*/
#include <stdio.h>
#include "fun1.h"

void fun1_printf(void)
{
    printf("Call \'fun1\'.\r\n");
}

主函數(shù)源碼:

/*源文件*/
#include <stdio.h>
#include "fun0.h"
#include "fun1.h"
#include "fun_lib_a.h"
#include "fun_lib_so.h"

int main(void)
{
    #ifdef USE_DEBUG
        printf("Debug Application startup.\r\n");
    #endif
    
        fun0_printf();
        fun1_printf();
        fun_lib_a_printf();
        fun_lib_so_printf();
        return 0;
}

庫(kù)文件,“./lib”目錄下存放兩個(gè)庫(kù)文件,一個(gè)靜態(tài)庫(kù)libfun_a.a,一個(gè)動(dòng)態(tài)庫(kù)libfun_so.so。

Makefile文件即為“2.1節(jié)”的Makefile模板。

測(cè)試運(yùn)行:

圖片

【如果執(zhí)行文件提示無(wú)“l(fā)ibfun_so.so”,則需拷貝“l(fā)ibfun_so.so”到根目錄下的“/lib”或者“/usr/lib”目錄下,因?yàn)橄到y(tǒng)執(zhí)行程序,默認(rèn)從該路徑引腳動(dòng)態(tài)庫(kù)】

3. 2 生成靜態(tài)庫(kù)

編寫(xiě)測(cè)試?yán)?,生產(chǎn)的庫(kù)文件即為“3.1節(jié)”調(diào)用的庫(kù)文件(libfun_a.a)。文件存放目錄結(jié)構(gòu)如下:

圖片

源文件:

/*頭文件*/
#ifndef _FUN_LIB_A_H_
#define _FUN_LIB_A_H_
#endif

extern void fun_lib_a_printf(void);

/*源文件*/
#include <stdio.h>
#include "fun_lib_a.h"

void fun_lib_a_printf(void)
{
    printf("Call \'fun_lib_a\'.\r\n");
}

Makefile文件即為“2.2節(jié)”的Makefile模板。

編譯生成靜態(tài)庫(kù):

圖片

3. 3 生成動(dòng)態(tài)庫(kù)

編寫(xiě)測(cè)試?yán)?,生產(chǎn)的庫(kù)文件即為“3.1節(jié)”調(diào)用的庫(kù)文件(libfun_so.so)。文件存放目錄結(jié)構(gòu)如下:

圖片

源文件:

/*頭文件*/
#ifndef _FUN_LIB_SO_H_
#define _FUN_LIB_SO_H_
#endif

extern void fun_lib_so_printf(void);

/*頭文件*/

#include <stdio.h>
#include "fun_lib_so.h"

void fun_lib_so_printf(void)
{
    printf("Call \'fun_lib_so\'.\r\n");
}

編譯生成動(dòng)態(tài)庫(kù):

圖片

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    这里只有九九热精品视频| 亚洲中文字幕视频一区二区| 麻豆精品在线一区二区三区| 日韩性生活片免费观看| 激情五月天免费在线观看| 99久久免费中文字幕| 99久久国产综合精品二区| 国产视频一区二区三区四区| 自拍偷拍一区二区三区| 亚洲日本加勒比在线播放| av在线免费播放一区二区| 欧美成人免费视频午夜色| 中文文精品字幕一区二区| 在线日本不卡一区二区| 国产精品欧美日韩中文字幕| 国产午夜精品久久福利| 午夜午夜精品一区二区| 亚洲熟女国产熟女二区三区| 亚洲综合精品天堂夜夜| 欧美黑人在线一区二区| 亚洲最新中文字幕一区| 儿媳妇的诱惑中文字幕| 国产日韩精品激情在线观看| 国产精品免费福利在线| 国产传媒欧美日韩成人精品| 国产二级一级内射视频播放| 久久精品亚洲欧美日韩| 日本一区二区三区久久娇喘| 91欧美一区二区三区成人| 国产精品国产亚洲区久久| 国产精品免费自拍视频| 国内女人精品一区二区三区| 中文字幕五月婷婷免费| 亚洲精品国产福利在线| 中文字幕日韩欧美亚洲午夜| 国产一级片内射视频免费播放| 成人精品一级特黄大片| 好吊日在线视频免费观看| 精品少妇人妻av一区二区蜜桃 | 五月婷婷综合缴情六月| 精品国产一区二区欧美|