私たちもAndroidについて話します.mk(4)-依存:ターゲットプログラミングのモード

5902 ワード

私たちもAndroidについて話します.mk(4)-依存:ターゲットプログラミングのモード
別のパターン
私はずっと感じて、Makefileは确かにC/C++プログラマーの良配で、Makefileが使う2つのパターンはすべてC/C++プログラマーが熟知していないので、1つは関数式の思想で、1つは構成の目標チェーンに依存するモードです.
Makefileは最も基本的には、以下のように抽象化することができます.
    target ... : prerequisites ...
            command
            ...
            ...

よく知られているように、prerequisitesが更新されたときにcommandコマンドを実行するという意味です.targetが真のターゲット、すなわち真のファイルに対応する場合、このファイルが生成されます.擬似ターゲットであれば、cleanのような入口として使用してもよいし、実際のターゲットへの依存として使用してもよい.明らかに2つの部分に分けることができる:1つはtarget依存チェーンのパターンであり、これはプロセス言語のC言語とは非常に異なる.蒋軍の言葉で言えば、Prologに少し似ています.独自の論理システムを持っています後ろのcommand、私たちは前にたくさん話しましたが、個人的には関数式の思想で書いてほしいです.
実際の例では
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
    $(call build-systemimage-target,$@)

この$(BUILT_SYSTEMIMAGE)は、生成するファイルsystemに対応するリアルなターゲットです.imgは、以下の通りです.
BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img

次に見てみましょうimgが依存する目標は、まず最初のものを見てみると、実際には2つあります.
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)

そして、この依存性が拡張していることを発見しました.
INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
    $(ALL_PREBUILT) \
    $(ALL_COPIED_HEADERS) \
    $(ALL_GENERATED_SOURCES) \
    $(ALL_DEFAULT_INSTALLED_MODULES) \
    $(PDK_FUSION_SYSIMG_FILES) \
    $(RECOVERY_RESOURCE_ZIP))

拡張はまだ続いています例えばALL_PREBUILTは、各モジュールが自分のものをどんどん増やしています.
ALL_PREBUILT += $(TARGET_OUT)/bin/monkey

他の目標原理が通じているので、ここでは紙面を無駄にしません.要するに、この大きな目標の中で、いずれかが変化している限り、system.imgは再生成されます.どのように生成しますか?次の行にはbuild-systemimage-targetを呼び出しましょうと書いてあります.
Makefile作成ガイド
目標式と関数式の2つのパターンをマスターしました.次は私たちがどのように材料を組織して私たちの工事を完成する時です.
  • 総目標Makefileの総目的は、1つ以上の結果ファイルを出力することであり、まず総目標を定義することである.次に、サブターゲットが構築されていると仮定し、これらの中間製品を最終ターゲットにするスクリプトを書きます.例えば簡単なCプログラムをコンパイルして、全体の目標は1つの実行可能なファイルで、最終的に加工する時の材料はすでにコンパイルしたのです.oファイルや入力したサードパーティのライブラリファイルなどは、どのようにコンパイルされているかにかかわらず、すでに作成されていると仮定して、リンクのスクリプトを書くだけでいいです.上のシステムのようにimgの例は、どうせ依存が多いから、別の列に分けましょう.最終的にはバッグを打つだけでいいです.
  • 層が分解され、徐々に完成してから探して、この大きな目標を構成する第1層の部材は何なのか、上で見たように、層ごとに拡張されています.Cファイルについては、このときになってからそれぞれを考える.oソースファイルからどのようにコンパイルされたか.
  • モジュール化、関数化の上の2つのステップはすべてターゲットモードで、このステップは関数モードを始めました.各ターゲットで再利用可能な関数を抽象化すると,そのファイルはファイルに分けられ,その整理コードはコードなどを整理する
  • である.
  • テストチューニング1つのプロジェクトがある程度大きくなると、Makefileの読み取り可能性が大幅に低下します.このとき,ターゲット式と関数式の2つの主線によって複雑さを低減した.目標は階層式で、私たちは1層1層デバッグすることができて、例えば先に調整することができます.c到oのコンパイルプロセスを再調整する.oリンクされたアセンブリ部分どのサブモジュールに問題が発生したら、その部分を調整します.機能部分について、私たちはずっと関数式の思想を強調して、ある確実性の入力に対して、確定的な出力があって、副作用がなくて、このようにデバッグの難易度を下げることができて、私たちは1つの関数を1つの関数でデバッグすることができます.Makefileのデバッグはログ作成を主とし、make-pで完全な変数とターゲットリストを出力することもできます.

  • make-p、makeが何をしたか見てみましょう
    次はcygwinでのmake-pの出力結果のセクションです.
    Makeツールの情報
    まず、Makeツールが自分の基礎状況を報告します.
    The files is:main.cpp
    # GNU Make 4.1
    # Built for x86_64-unknown-cygwin
    # Copyright (C) 1988-2014 Free Software Foundation, Inc.
    # License GPLv3+: GNU GPL version 3 or later 
    # This is free software: you are free to change and redistribute it.
    # There is NO WARRANTY, to the extent permitted by law.
    
    # make     ,    Tue May  3 17:54:36 2016
    

    変数#ヘンスウ#
    次は変数のリストです.私たちが定義したものも含まれています.makeが自動的に生成したものも含まれています.
    #   
    
    # 'override' directive
    GNUMAKEFLAGS := 
    #   
    

    ディレクトリ情報
    #   
    
    # SCCS:       stat   。
    # . (   114478965,i-   1688849860268365):10   , 19    .
    # RCS:       stat   。
    
    # 10   , 19      3    。
    

    暗黙のルール情報
    #     。
    
    %.out:
    
    %.a:
    
    %.ln:
    
    %.o:
    
    %: %.o
    #  recipe to execute (  ):
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.c:
    
    %: %.c
    #  recipe to execute (  ):
        $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.ln: %.c
    #  recipe to execute (  ):
        $(LINT.c) -C$* $<
    
    %.o: %.c
    #  recipe to execute (  ):
        $(COMPILE.c) $(OUTPUT_OPTION) $<
    
    %.cc:
    
    %: %.cc
    #  recipe to execute (  ):
        $(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.o: %.cc
    #  recipe to execute (  ):
        $(COMPILE.cc) $(OUTPUT_OPTION) $<
    
    %.C:
    
    %: %.C
    #  recipe to execute (  ):
        $(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.o: %.C
    #  recipe to execute (  ):
        $(COMPILE.C) $(OUTPUT_OPTION) $<
    
    %.cpp:
    
    %: %.cpp
    #  recipe to execute (  ):
        $(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.o: %.cpp
    #  recipe to execute (  ):
        $(COMPILE.cpp) $(OUTPUT_OPTION) $<
    
    %.p:
    
    %: %.p
    #  recipe to execute (  ):
        $(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@
    
    %.o: %.p
    #  recipe to execute (  ):
        $(COMPILE.p) $(OUTPUT_OPTION) $<
    ...
    

    ファイルターゲットとダミーターゲット
    #   
    
    #       :
    .web.p:
    #  Builtin rule
    #              。
    #          。
    #         。
    #  recipe to execute (  ):
        $(TANGLE) $<
    
    #       :
    .l.r:
    #  Builtin rule
    #              。
    #          。
    #         。
    #  recipe to execute (  ):
        $(LEX.l) $< > $@ 
         mv -f lex.yy.r $@
    
    all8:
    #      (.PHONY   )。
    #              。
    #       。
    #         。
    #  recipe to execute (from 'Makefile', line 66):
        @echo $(filter-out default interpreter jit optimizing,xoc)
        @echo $(filter-out default interpreter jit optimizing,default)
    
    all9:
    #      (.PHONY   )。
    #              。
    #       。
    #         。
    #  recipe to execute (from 'Makefile', line 75):
        $(eval ARCH_OF_BOOT_OAT := $(lastword $(subst /, ,$(dir $(BOOT_ART_SRC)))))
        $(eval OAT_TEMP := $(PRODUCT_OUT)/data/dalvik-cache/temp-oat/system/framework/$(ARCH_OF_BOOT_OAT))
        $(eval OAT_SRC := $(patsubst %.art,%.oat,$(BOOT_ART_SRC)))
        $(eval OAT_DIST := $(patsubst %.art,%.oat,$(BOOT_ART_DST)))
        @echo $(ARCH_OF_BOOT_OAT)
        @echo $(OAT_TEMP)
        @echo $(OAT_SRC)
        @echo $(OAT_DIST)
    ...