日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通用makefile

發布時間:2025/4/5 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通用makefile 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 最基本的makefile
      • 1.1 簡單粗暴的makefile
      • 1.2 稍微提高效率的makefile
      • 1.3 更加精煉的makefile
      • 1.4 需要手工添加頭文件規則的makefile
      • 1.5 支持自動檢測頭文件的makefile
      • 1.6 支持自動獲取目標文件的makefile
    • 2 通用makefile
      • 2.1 makefile
      • 2.2 通用makefile的使用說明
      • 2.3 通用makefile的設計思想
      • 2.4 通用makefile原理分析

1 最基本的makefile

有main.c、sub.c、sub.h三個文件,文件內容如下:
main.c:

#include <stdio.h>extern void sub_fun(void);int main(int argc, char* argv[]) {printf("Main fun!\n");sub_fun();return 0; }

sub.c:

#include <stdio.h> #include "sub.h"void sub_fun(void) {printf("Sub fun, A= %d!\n", A); }

sub.h:

#define A 1 void sub_fun(void);

1.1 簡單粗暴的makefile

test : main.c sub.c sub.hgcc -o test main.c sub.c

簡單粗暴,效率低。

1.2 稍微提高效率的makefile

test : main.o sub.ogcc -o test main.o sub.omain.o : main.cgcc -c -o main.o main.csub.o : sub.cgcc -c -o sub.o sub.c clean:rm *.o test -f

效率高,相似規則太多太啰嗦,不支持檢測頭文件。

1.3 更加精煉的makefile

test : main.o sub.ogcc -o test main.o sub.o%.o : %.cgcc -c -o $@ $<clean:rm *.o test -f

效率高,精煉,不支持檢測頭文件。

1.4 需要手工添加頭文件規則的makefile

est : main.o sub.ogcc -o test main.o sub.o%.o : %.cgcc -c -o $@ $<sub.o : sub.hclean:rm *.o test -f

效率高,精煉,支持檢測頭文件(但是需要手工添加頭文件規則)。

注意: 對于只有目標和依賴而沒有命令的規則會將其依賴和有命令的規則進行合并。

1.5 支持自動檢測頭文件的makefile

objs := main.o sub.otest : $(objs)gcc -o test $^# 需要判斷是否存在依賴文件 # .main.o.d .sub.o.d dep_files := $(foreach f, $(objs), .$(f).d) dep_files := $(wildcard $(dep_files))# 把依賴文件包含進來 ifneq ($(dep_files),)include $(dep_files) endif%.o : %.cgcc -Wp,-MD,.$@.d -c -o $@ $<clean:rm *.o test -fdistclean:rm $(dep_files) *.o test -f

效率高,精煉,支持自動檢測頭文件,但是目標文件需要手動指定。

1.6 支持自動獲取目標文件的makefile

src := $(wildcard *.c) objs := $(patsubst %.c, %.o, $(src))test : $(objs)gcc -o test $^# 需要判斷是否存在依賴文件 # .main.o.d .sub.o.d dep_files := $(foreach f, $(objs), .$(f).d) dep_files := $(wildcard $(dep_files))# 把依賴文件包含進來 ifneq ($(dep_files),)include $(dep_files) endif%.o : %.cgcc -Wp,-MD,.$@.d -c -o $@ $<clean:rm *.o test -fdistclean:rm $(dep_files) *.o test -f

2 通用makefile

此處只關注文件目錄,不關注文件的具體內容,測試使用的文件目錄如下:

2.1 makefile

頂層目錄的makefile:

CROSS_COMPILE = AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nmSTRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdumpexport AS LD CC CPP AR NM export STRIP OBJCOPY OBJDUMPCFLAGS := -Wall -O2 -g CFLAGS += -I $(shell pwd)/includeLDFLAGS := export CFLAGS LDFLAGSTOPDIR := $(shell pwd) export TOPDIRTARGET := mainobj-y += main.o obj-y += sub.o obj-y += a/all : start_recursive_build $(TARGET)@echo $(TARGET) has been built!start_recursive_build:make -C ./ -f $(TOPDIR)/Makefile.build$(TARGET) : built-in.o$(CC) $(LDFLAGS) -o $(TARGET) built-in.oclean:rm -f $(shell find -name "*.o")rm -f $(TARGET)distclean:rm -f $(shell find -name "*.o")rm -f $(shell find -name "*.d")rm -f $(TARGET)

頂層目錄的makefile.build:

PHONY := __build __build:obj-y := subdir-y := EXTRA_CFLAGS :=include Makefile# obj-y := a.o b.o c/ d/ # $(filter %/, $(obj-y)) : c/ d/ # __subdir-y : c d # subdir-y : c d __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) subdir-y += $(__subdir-y)# c/built-in.o d/built-in.o subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)# a.o b.o cur_objs := $(filter-out %/, $(obj-y)) dep_files := $(foreach f,$(cur_objs),.$(f).d) dep_files := $(wildcard $(dep_files))ifneq ($(dep_files),)include $(dep_files) endifPHONY += $(subdir-y)__build : $(subdir-y) built-in.o$(subdir-y):make -C $@ -f $(TOPDIR)/Makefile.buildbuilt-in.o : $(cur_objs) $(subdir_objs)$(LD) -r -o $@ $^dep_file = .$@.d%.o : %.c$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<.PHONY : $(PHONY)

目錄a下的makefile:

EXTRA_CFLAGS := -D DEBUG CFLAGS_sub3.o := -D DEBUG_SUB3obj-y += sub2.o obj-y += sub3.o

2.2 通用makefile的使用說明

本程序的Makefile分為3類:

  • 頂層目錄的Makefile
  • 頂層目錄的Makefile.build
  • 各級子目錄的Makefile
  • 一、各級子目錄的Makefile:

    它最簡單,形式如下:

    EXTRA_CFLAGS := CFLAGS_file.o := obj-y += file.o obj-y += subdir/

    其中:

    • “obj-y += file.o” ,表示把當前目錄下的file.c編進程序里。
    • “obj-y += subdir/” ,表示要進入subdir這個子目錄下去尋找文件來編進程序里,是哪些文件由subdir目錄下的Makefile決定。
    • “EXTRA_CFLAGS”, 它給當前目錄下的所有文件(不含其下的子目錄)設置額外的編譯選項, 可以不設置。
    • “CFLAGS_xxx.o”, 它給當前目錄下的xxx.c設置它自己的編譯選項, 可以不設置。

    注意:

  • "subdir/“中的斜杠”/"不可省略。
  • 頂層Makefile中的CFLAGS在編譯任意一個.c文件時都會使用。
  • CFLAGS 、EXTRA_CFLAGS 、 CFLAGS_xxx.o 三者組成xxx.c的編譯選項。
  • 二、頂層目錄的Makefile:

    它除了定義obj-y來指定根目錄下要編進程序去的文件、子目錄外,還定義工具鏈前綴CROSS_COMPILE,定義編譯參數CFLAGS,定義鏈接參數LDFLAGS,這些參數就是文件中用export導出的各變量。

    三、頂層目錄的Makefile.build:
    這是最復雜的部分,它的功能就是把某個目錄及它的所有子目錄中、需要編進程序去的文件都編譯出來,打包為built-in.o。

    四、怎么使用這套Makefile:

  • 把頂層Makefile, Makefile.build放入程序的頂層目錄,在各自子目錄創建一個空白的Makefile。

  • 確定編譯哪些源文件:
    修改頂層目錄和各自子目錄Makefile的obj-y :
    obj-y += xxx.o
    obj-y += yyy/
    這表示要編譯當前目錄下的xxx.c, 要編譯當前目錄下的yyy子目錄

  • 確定編譯選項、鏈接選項:
    修改頂層目錄Makefile的CFLAGS,這是編譯所有.c文件時都要用的編譯選項;
    修改頂層目錄Makefile的LDFLAGS,這是鏈接最后的應用程序時的鏈接選項;

    修改各自子目錄下的Makefile:
    “EXTRA_CFLAGS”, 它給當前目錄下的所有文件(不含其下的子目錄)設置額外的編譯選項, 可以不設置
    “CFLAGS_xxx.o”, 它給當前目錄下的xxx.c設置它自己的編譯選項, 可以不設置

  • 使用哪個編譯器?
    修改頂層目錄Makefile的CROSS_COMPILE, 用來指定工具鏈的前綴(比如arm-linux-)。

  • 確定應用程序的名字:
    修改頂層目錄Makefile的TARGET, 這是用來指定編譯出來的程序的名字。

  • 執行"make"來編譯,執行"make clean"來清除,執行"make distclean"來徹底清除。

  • 2.3 通用makefile的設計思想

    1. 在Makefile文件中確定要編譯的文件、目錄,比如:

    obj-y += main.o obj-y += a/

    “Makefile”文件總是被“Makefile.build”包含的。

    2. 在Makefile.build中設置編譯規則,有3條編譯規則:

    i. 怎么編譯子目錄? 進入子目錄編譯:

    $(subdir-y):make -C $@ -f $(TOPDIR)/Makefile.build

    ii. 怎么編譯當前目錄中的文件?

    %.o : %.c$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<

    iii. 當前目錄下的.o和子目錄下的built-in.o要打包起來:

    built-in.o : $(cur_objs) $(subdir_objs)$(LD) -r -o $@ $^

    3. 頂層Makefile中把頂層目錄的built-in.o鏈接成APP:

    $(TARGET) : built-in.o$(CC) $(LDFLAGS) -o $(TARGET) built-in.o

    2.4 通用makefile原理分析


  • 韋東山全系列視頻第1季快速入門
  • 總結

    以上是生活随笔為你收集整理的通用makefile的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。