久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    一些通用的Makefile文件模板

     520jefferson 2024-01-11 發布于中國香港

    作者:Acuity.

    原文:

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

    圖片

    寫在前面

    對于Windows下開發,很多IDE都集成了編譯器,如Visual Studio,提供了“一鍵編譯”,編碼完成后只需一個操作即可完成編譯、鏈接、生成目標文件。

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

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

    3個Makefile模板

    2.1 編譯可執行文件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 

    【要點說明】

    【1】程序版本

    開發調試過程可能產生多個程序版本,可以在目標文件后(前)增加版本號標識。

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

    【2】編譯器選擇

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

    CC = gcc

    【3】宏定義

    開發過程,特殊代碼一般增加宏條件來選擇是否編譯,如調試打印輸出代碼。-D是標識,后面接著的是“宏”。

    DEBUG =-DUSE_DEBUG

    【4】編譯選項

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

    CFLAGS =-Wall -O

    【5】源文件

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

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

    【6】頭文件

    包含依賴的頭文件,包括源碼文件和庫文件的頭文件。

    INCLUDES =-I./include

    【7】庫文件名稱

    指定庫文件名稱,庫文件有固定格式,靜態庫為libxxx.a;動態庫為libxxx.so,指定庫文件名稱只需寫“xxx”部分,

    LIB_NAMES =-lfun_a -lfun_so

    【8】庫文件路徑

    指定依賴庫文件的存放路徑。注意如果引用的是動態庫,動態庫也許拷貝到“/lib”或者“/usr/lib”目錄下,執行應用程序時,系統默認在該文件下索引動態庫。

    LIB_PATH =-L./lib

    【9】目標文件

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

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

    【10】執行文件

    執行文件名稱

    TARGET =app

    【11】編譯

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

    【12】鏈接

    可創建一個“output”文件夾存放目標執行文件。鏈接完輸出目標執行文件,可以刪除編譯產生的臨時文件(.o)。

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

    【13】清除編譯信息

    執行“make clean”清除編譯產生的臨時文件。

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

    2.2 編譯靜態庫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 

    【要點說明】

    基本格式與“編譯可執行Makefile”一致,不同點包括以下。

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

    2.3 編譯動態庫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 

    【要點說明】

    基本格式與“編譯可執行Makefile”一致,不同點包括以下。

    【1】編譯選項和鏈接選項增加“-fPIC -shared ”選項。動態庫文件固定命名格式為libxxx.so。

    Demo

    3.1 編譯應用程序

    編寫測試例程,文件存放目錄結構如下,頭文件存放在“include”目錄,庫文件存放在“lib”目錄,源文件存放在“source”目錄,Makefile在當前目錄下。

    圖片

    源碼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");
    }

    主函數源碼:

    /*源文件*/
    #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;
    }

    庫文件,“./lib”目錄下存放兩個庫文件,一個靜態庫libfun_a.a,一個動態庫libfun_so.so。

    Makefile文件即為“2.1節”的Makefile模板。

    測試運行:

    圖片

    【如果執行文件提示無“libfun_so.so”,則需拷貝“libfun_so.so”到根目錄下的“/lib”或者“/usr/lib”目錄下,因為系統執行程序,默認從該路徑引腳動態庫】

    3. 2 生成靜態庫

    編寫測試例程,生產的庫文件即為“3.1節”調用的庫文件(libfun_a.a)。文件存放目錄結構如下:

    圖片

    源文件:

    /*頭文件*/
    #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節”的Makefile模板。

    編譯生成靜態庫:

    圖片

    3. 3 生成動態庫

    編寫測試例程,生產的庫文件即為“3.1節”調用的庫文件(libfun_so.so)。文件存放目錄結構如下:

    圖片

    源文件:

    /*頭文件*/
    #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");
    }

    編譯生成動態庫:

    圖片

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 亚洲AV成人噜噜无码网站| H无码动漫在线观看| 正在播放国产剧情亂倫| 亚洲欧美日韩中文在线制服| 亚洲欧美偷国产日韩| 国色天香天天影院综合网| 婷婷四房播播| AV区无码字幕中文色| 欧美人与禽2o2o性论交| 日韩AV无码精品一二三区| 我国产码在线观看av哈哈哈网站| 国产女主播白浆在线看| 亚洲综合色AAA成人无码| 国产亚洲综合欧美视频| 国产一区二区三区在线视頻| 又色又污又爽又黄的网站| 东京热人妻无码一区二区av| 色AV专区无码影音先锋| 亚洲av成人无码精品电影在线| 国产AV无码专区亚洲AV潘金链| 无码囯产精品一区二区免费| 亚洲高清乱码午夜电影网| 亚洲日本欧洲二区精品| 国产精品久久久久久AV| 午夜大片爽爽爽免费影院| 日本道精品一区二区三区| 精品国精品自拍自在线| 久热综合在线亚洲精品| 亚洲国产精品成人网址| 狠狠躁夜夜躁人人爽天天天天| 亚洲二区中文字幕在线| 精品乱人伦一区二区三区| 四虎影视一区二区精品| 中文字幕人妻日韩精品| 97人人超碰国产精品最新O| 欧美国产综合欧美视频| 国产成人精彩在线视频| 少妇熟女久久综合网色欲| 亚洲高清揄拍自拍| 免费A级毛片中文字幕| 日本一区不卡高清更新二区 |