<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      輕松玩轉Makefile | 企業項目級Makefile實例

      前言

      本文展示了一個比較完整的企業項目級別的Makefile文件,包括了:文件調用,源文件、頭文件、庫文件指定,軟件版本號、宏定義,編譯時間,自動目錄等內容。

      1、目錄架構

      本文中所采用的目錄架構,在企業項目開發中十分常見:源文件都放在src目錄中,頭文件都放在inc目錄中,并且這兩個目錄都可以有對應的子目錄。庫文件放在lib目錄中,makefile相關文件放在build目錄中,編程生成的程序放在自動生成的output目錄中。目錄結構展示如下:

      .
      ├── build
      │   ├── Makefile
      │   └── srcpathconfig.mk
      ├── code
      │   ├── inc
      │   │   ├── com
      │   │   └── func
      │   │       └── fun.h
      │   └── src
      │       ├── com
      │       │   └── main.c
      │       └── func
      │           └── fun.c
      └── lib
          ├── inc
          │   └── mylib.h
          └── libs
              └── libmylib.so
      

      2、源文件及Makefile內容

      本文所用到的所有文件,也可以直接到我的公眾號,后臺回復“ mk ”獲取。

      源文件

      /* fun.h */
      #ifndef __FUN_H__
      #define __FUN_H__
      
      void fun();
      
      #endif
      
      
      /* fun.c */
      #include <stdio.h>
      
      void fun()
      {
      
      #ifdef MACRO_DEF
          printf("macro definition enable!\n");
      #endif
      
      
      #ifdef COMPILER_IS_ARM_LINUX_GCC
          printf("The compilation target is arm!\n");
      #endif
      
      #ifdef COMPILER_IS_LINUX_GCC
          printf("The compilation target is linux!\n");
      #endif
      
      	printf("This is fun()!\n");
      }
      
      /* mylib.h */
      void mylib();
      
      
      /* libmylib.so */
      // mylib()函數,打印This is mylib()!
      
      /* main.c */
      #include "fun.h"
      #include "mylib.h"
      
      int main()
      { 
          fun();
      	mylib();
          return 0; 
      }
      

      srcpathconfig.mk

      這個文件的內容,其實也可以放在Makefile中,本案例單獨用一個文件來配置路徑,是為了后期好管理

      #源文件目錄
      SRCCODEDIRS   :=../code/src/func \
                      ../code/src/com \
      	
      
      #頭文件目錄
      SRCHEADDIRS   :=../code/inc/func \
      				../code/inc/com \
      
      #lib文件目錄
      LIBFILEDIRS := ../lib/libs
      
      #lib頭文件目錄
      LIBHEADDIRS := ../lib/inc/
      
      #lib文件
      LIBFILE := -lmylib
      
      

      Makefile

      #引用其他文件
      include srcpathconfig.mk
      
      #時間信息
      tmpbuildtm := `date |sed 's/ /_/g'`
      TMPBUILDTM = $(tmpbuildtm)
      
      #軟件版本
      APPVERSION = 1.0.0.0
      
      
      #不同的目標采用不同的宏定義
      ifeq ($(MAKECMDGOALS),arm)
      COMPILEMACRO += COMPILER_IS_ARM_LINUX_GCC
      else
      COMPILEMACRO += COMPILER_IS_LINUX_GCC MACRO_DEF
      endif
      
      
      #循環獲取源文件和中間件
      SRCFILE := $(foreach d,$(SRCCODEDIRS),$(wildcard $(addprefix $(d)/*,.c)))
      OBJFILE := $(patsubst %.c,%.o,$(SRCFILE))
      
      #宏定義,源文件路徑,頭文件路徑
      CURCMPLMACRO   := $(addprefix -D ,$(COMPILEMACRO))
      CURSRCHEADDIRS := $(addprefix -I ,$(SRCHEADDIRS))
      CURLIBHEADDIRS := $(addprefix -I ,$(LIBHEADDIRS))
      
      #程序輸出路徑
      OUTPUTDIR := ../output
      
      #編譯器及選項
      CC := gcc
      CFLAGS := -Wall -c
      
      RM := rm
      RMFLAGS := -rf
      
      #目標文件	
      TARGETNAME = app
      
      $(TARGETNAME):$(OBJFILE)
      	@mkdir -p $(OUTPUTDIR)
      	@echo ""
      	@echo "all files have been compiled , now begin to link every obj for excutable file"
      	@echo ""
      	@echo "linking............"
      	@echo $(OBJFILE)
      	@$(CC)  -o $(OUTPUTDIR)/$(TARGETNAME).$(APPVERSION) $(OBJFILE) -L$(LIBFILEDIRS) $(LIBFILE)
      	@echo ""
      	@echo "linked ok," $(TARGETNAME) "has been created"
      	@echo ""
      	@echo $(TMPBUILDTM)
      	
      %.o: %.c
      	@echo ""
      	@echo "start " $< "......compiling"
      	@$(CC) $(CURCMPLMACRO) $(CFLAGS) $(CURSRCHEADDIRS) $(CURLIBHEADDIRS) $< -o $@
      	@echo "created " $@
      	@echo "end   " $< "......compiled ok"
      	@echo ""
      
      .PHONY: arm clean
      
      arm:$(TARGETNAME)
      
      clean:
      	@-$(RM) $(RMFLAGS) $(TARGETNAME) $(OBJFILE) $(OUTPUTDIR)
      

      3、效果演示

      輸入make 或者 make arm ,打印如下

      start  ../code/src/func/fun.c ......compiling
      created  ../code/src/func/fun.o
      end    ../code/src/func/fun.c ......compiled ok
      
      
      start  ../code/src/com/main.c ......compiling
      created  ../code/src/com/main.o
      end    ../code/src/com/main.c ......compiled ok
      
      
      all files have been compiled , now begin to link every obj for excutable file
      
      linking............
      ../code/src/func/fun.o ../code/src/com/main.o
      
      linked ok, app has been created
      
      Fri_Mar__3_22:14:09_PST_2023
      

      生成的文件架構如下

      .
      ├── build
      │   ├── Makefile
      │   └── srcpathconfig.mk
      ├── code
      │   ├── inc
      │   │   ├── com
      │   │   └── func
      │   │       └── fun.h
      │   └── src
      │       ├── com
      │       │   ├── main.c
      │       │   └── main.o
      │       └── func
      │           ├── fun.c
      │           └── fun.o
      ├── lib
      │   ├── inc
      │   │   └── mylib.h
      │   └── libs
      │       └── libmylib.so
      └── output
          └── app.1.0.0.0
      

      運行output中生成的app.1.0.0.0程序

      /* 由make命令編譯生成的app.1.0.0.0 */
      
      macro definition enable!
      The compilation target is linux!
      This is fun()!
      This is mylib()
      
      /* 由make arm命令編譯生成的app.1.0.0.0 */
      
      The compilation target is arm!
      This is fun()!
      This is mylib()
      

      4、Makefile內容解析

      4.1 文件調用

      include srcpathconfig.mk
      

      相當于把srcpathconfig.mk的內容都拿過來,srcpathconfig.mk中的變量,在Makefile文件中都可以直接使用。

      4.2 編譯時間

      tmpbuildtm := `date |sed 's/ /_/g'`
      TMPBUILDTM = $(tmpbuildtm)
      
      @echo $(TMPBUILDTM)
      

      這個是把當前的時間,保存到TMPBUILDTM變量中,可以運用到源碼中,本案例只是打印一下此變量。

      4.3 軟件版本

      APPVERSION = 1.0.0.0
      @$(CC)  -o $(OUTPUTDIR)/$(TARGETNAME).$(APPVERSION) $(OBJFILE) -L$(LIBFILEDIRS) $(LIBFILE)
      

      開發過程中,我們會有多個版本的程序,可以在程序加上版本號作為后綴。

      4.4 宏定義

      ifeq ($(MAKECMDGOALS),arm)
      COMPILEMACRO += COMPILER_IS_ARM_LINUX_GCC
      else
      COMPILEMACRO += COMPILER_IS_LINUX_GCC MACRO_DEF
      endif
      
      CURCMPLMACRO   := $(addprefix -D ,$(COMPILEMACRO))
      
      %.o: %.c
      	@$(CC) $(CURCMPLMACRO) $(CFLAGS) $(CURSRCHEADDIRS) $(CURLIBHEADDIRS) $< -o $@
      

      makefile中也可以使用條件判斷,具體用法這里不多做介紹。

      MAKECMDGOALS,是make命令后面跟的目標,比如make arm,那么MAKECMDGOALS的值就為arm。

      這里利用MAKECMDGOALS的值來選擇使用哪些宏定義,假如make 后面跟的是arm,宏定義則是COMPILER_IS_ARM_LINUX_GCC,假如make后面跟的不是arm,宏定義則是COMPILER_IS_LINUX_GCC和MACRO_DEF。

      這些宏定義在fun.c中有使用,對應的是打印不同的內容。在實際項目中,宏定義的作用很廣,可以用來跨平臺開發,也可以用來調試打印。

      4.5 源文件及中間件

      SRCFILE := $(foreach d,$(SRCCODEDIRS),$(wildcard $(addprefix $(d)/*,.c)))
      OBJFILE := $(patsubst %.c,%.o,$(SRCFILE))
      

      由于我們的源文件是放在src目錄下的不同子目錄中,所以使用了foreach函數來循環獲取。簡單說明一下,foreach后面跟著的d,是中間變量,這一行的作用就是將SRCCODEDIRS的路徑下的.c文件,逐個逐個拿出來,加上對應的路徑前綴。

      關于foreach的函數的具體使用方法,不做過多介紹。

      4.6 頭文件

      SRCHEADDIRS   :=../code/inc/func \
      				../code/inc/com \
      				
      LIBHEADDIRS := ../lib/inc/				
      
      CURSRCHEADDIRS := $(addprefix -I ,$(SRCHEADDIRS))
      CURLIBHEADDIRS := $(addprefix -I ,$(LIBHEADDIRS))
      
      %.o: %.c
      	@$(CC) $(CURCMPLMACRO) $(CFLAGS) $(CURSRCHEADDIRS) $(CURLIBHEADDIRS) $< -o $@
      

      將普通頭文件和庫頭文件的存放路徑單獨用變量表示

      4.7 庫文件

      LIBFILEDIRS := ../lib/libs
      LIBFILE := -lmylib
      
      $(TARGETNAME):$(OBJFILE)
      	@$(CC)  -o $(OUTPUTDIR)/$(TARGETNAME).$(APPVERSION) $(OBJFILE) -L$(LIBFILEDIRS) $(LIBFILE)
      

      將庫文件的名字和存放路徑單獨用變量表示

      4.8 編譯選項

      CC := gcc
      CFLAGS := -Wall -c
      
      RM := rm
      RMFLAGS := -rf
      

      CC := gcc,指定編譯器為gcc;CFLAGS 和RMFLAGS中的內容可以根據需求調整,所以單獨拿出來,-Wall是表示編譯的時候可以產生告警,便于分析。

      4.9 自動目錄

      OUTPUTDIR := ../output
      
      @mkdir -p $(OUTPUTDIR)
      
      @-$(RM) $(RMFLAGS) $(TARGETNAME) $(OBJFILE) $(OUTPUTDIR)
      

      make命令會自動創建output目錄,用來存放生成的目標文件。

      make clean會將此目錄及目錄中的所有內容都刪除

      4.10 打印信息

      TARGETNAME = app
      
      $(TARGETNAME):$(OBJFILE)
      	@mkdir -p $(OUTPUTDIR)
      	@echo ""
      	@echo "all files have been compiled , now begin to link every obj for excutable file"
      	@echo ""
      	@echo "linking............"
      	@echo $(OBJFILE)
      	@$(CC)  -o $(OUTPUTDIR)/$(TARGETNAME).$(APPVERSION) $(OBJFILE) -L$(LIBFILEDIRS) $(LIBFILE)
      	@echo ""
      	@echo "linked ok," $(TARGETNAME) "has been created"
      	@echo ""
      	@echo $(TMPBUILDTM)
      	
      %.o: %.c
      	@echo ""
      	@echo "start " $< "......compiling"
      	@$(CC) $(CURCMPLMACRO) $(CFLAGS) $(CURSRCHEADDIRS) $(CURLIBHEADDIRS) $< -o $@
      	@echo "created " $@
      	@echo "end   " $< "......compiled ok"
      	@echo ""
      
      

      所有@echo的內容,都是為了編譯的時候,打印一些信息,方便查看才加上去的,實際上有真正有用的是下面這些

      TARGETNAME = app
      
      $(TARGETNAME):$(OBJFILE)
      	@mkdir -p $(OUTPUTDIR)
      	@$(CC)  -o $(OUTPUTDIR)/$(TARGETNAME).$(APPVERSION) $(OBJFILE) -L$(LIBFILEDIRS) $(LIBFILE)
      
      %.o: %.c
      	@$(CC) $(CURCMPLMACRO) $(CFLAGS) $(CURSRCHEADDIRS) $(CURLIBHEADDIRS) $< -o $@
      
      
      

      ————————————————————————————————

      碼字不易,點個贊再走吧!

      歡迎關注我的同名公眾號,這里有更多好料等著你哦!

      posted @ 2023-03-04 14:42  知微之見  閱讀(380)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品国产一区二区三| 日韩伦理片| 亚洲va成无码人在线观看天堂| 国产伦精品一区二区三区妓女下载| 亚洲av精选一区二区| 少妇被粗大的猛烈进出69影院一 | 九九热爱视频精品视频| 精品无码一区二区三区电影| 又湿又紧又大又爽A视频男| 国产精品久久久久久久久人妻| 天堂V亚洲国产V第一次| 国产91精品调教在线播放| 国产在线观看免费人成视频| 被c到高潮疯狂喷水国产| 久久精品国产色蜜蜜麻豆| 日韩精品国内国产一区二| AV人摸人人人澡人人超碰| 国产精品免费AⅤ片在线观看| 欧美色丁香| 国产成人无码免费视频麻豆| 国产亚洲精品第一综合麻豆| 成人区人妻精品一区二蜜臀| 亚洲av无码乱码在线观看野外| 国产女人在线视频| 人妻聚色窝窝人体WWW一区| 在线综合亚洲欧洲综合网站| 日韩AV片无码一区二区不卡| 日韩高清国产中文字幕| 国产精品一线天粉嫩av| 亚洲人成网线在线播放VA| 亚洲高清国产拍精品网络战| 久久99日本免费国产精品| 一区二区中文字幕久久| 国产成人免费ā片在线观看| 91色老久久精品偷偷性色| 国产成人一区二区三区免费| 日本免费一区二区三区最新vr| 成人精品自拍视频免费看| 不卡一区二区国产在线| 日本一卡二卡不卡视频查询 | 国产精品视频免费一区二区|