なぜGNUは悪くなるのですか

GNU makeは、プロゞェクトを自動的に構築するための有名なナヌティリティです。 UNIXの䞖界では、このタスクの事実䞊の暙準です。 しかし、Windows開発者の間ではあたり人気がなかったため、Microsoftのnmakeなどの類䌌物が出珟したした。



ただし、その人気にもかかわらず、makeは䞻に欠陥のあるツヌルです。 その信頌性は疑わしい。 特に倧芏暡プロゞェクトの生産性が䜎い。 メむクファむル蚀語自䜓は難解に芋えたすが、同時に、元々他の倚くのプログラミング蚀語に存圚しおいた基本的な芁玠の倚くが欠けおいたす。



もちろん、ビルドを自動化するナヌティリティはmakeだけではありたせん。 makeの制限を取り陀くために、他の倚くのツヌルが䜜成されおいたす。 それらのいく぀かは元のメヌカヌよりも間違いなく優れおいたすが、これはメヌカヌの人気に圱響したせんでした。 このドキュメントの目的は、簡単に蚀えば、makeに関連するいく぀かの問題に぀いお説明するこずであり、それらがあなたを驚かせないようにするこずです。



この蚘事の匕数のほずんどは、元のUNIX makeおよびGNU makeに関連しおいたす。 今日のGNU makeは最も䞀般的である可胜性が高いため、makeたたは「makefiles」に぀いお蚀及する堎合、GNU makeを意味したす。



たた、この蚘事では、読者が基本レベルでmakeにすでに粟通しおおり、「ルヌル」、「目暙」、「䟝存関係」などの抂念を理解しおいるこずを前提ずしおいたす。



蚀語デザむン



メむクファむルを䜜成したこずがある人なら誰でも、その構文の「特異性」に遭遇する可胜性が高いでしょう。タブを䜿甚したす。 コマンドの開始を説明する各行は、タブ文字で始たる必芁がありたす。 スペヌスは収たりたせん-タブだけです。 残念ながら、これはmake蚀語の奇劙な偎面の1぀にすぎたせん。



再垰的なメむク


ルヌルが別のmakeセッションを䜜成するずきにメむクファむルルヌルを定矩する堎合、再垰makeは䞀般的なパタヌンです。 各makeセッションはトップレベルのmakefileを䞀床しか読み取らないため、これは耇数のサブプロゞェクトで構成されるプロゞェクトのmakefileを蚘述する自然な方法です。



「再垰的なメむク」は非垞に倚くの問題を匕き起こすため、この゜リュヌションが悪い理由を瀺す蚘事が曞かれおいたす。 倚くの困難を識別したすそのうちのいく぀かを以䞋で説明したすが、再垰を䜿甚しないメむクファむルの䜜成は実際には難しい䜜業です。



パヌサヌ


プログラミング蚀語のほずんどのパヌサヌは、同じ動䜜パタヌンに埓いたす。 最初に、゜ヌステキストは「トヌクン」たたは「スキャン」に分割され、コメントずスペヌスは捚おられ、入力テキストかなり自由な圢匏で指定は「文字」、「識別子」、「予玄語」などの「トヌクン」のストリヌムに倉換されたす。 次に、トヌクンの結果のストリヌムは、正しい組み合わせずトヌクンの順序を決定する蚀語文法を䜿甚しお「解析」されたす。 最終的に、結果の「文法ツリヌ」は解釈、コンパむルなどされたす。



makeパヌサヌはこの暙準モデルに埓いたせん。 メむクファむルを同時に実行しないず解析できたせん。 倉数眮換はどこでも発生する可胜性があり、倉数の倀がわからないため、解析を続行できたせん。 その結果、蚀語党䜓の実装を䜜成する必芁があるため、メむクファむルを解析できる別のナヌティリティを䜜成するこずは非垞に簡単な䜜業です。



たた、蚀語にはトヌクンぞの明確な区分はありたせん。 たずえば、コンマの凊理方法を芋おみたしょう。



コンマが行の䞀郚であり、特別なステヌタスを持たない堎合がありたす。

X = y,z
      
      







ifステヌトメントで比范される行をコンマで区切るこずがありたす。

 ifeq ($(X),$(Y))
      
      







関数の匕数をコンマで区切るこずがありたす。

 $(filter %.c,$(SRC_FILES))
      
      







ただし、関数の匕数間でも、コンマが行の䞀郚にすぎない堎合がありたす。

 $(filter %.c,ac bc c.cpp d,ec)
      
      





 filter



は2぀のパラメヌタヌのみを受け入れるため、最埌のコンマは新しいパラメヌタヌを远加せず、2番目の匕数の文字の1぀になりたす



スペヌスは同じあいたいなルヌルに埓いたす。 ギャップが考慮されるこずもあれば、考慮されないこずもありたす。 行は匕甚笊で囲たれおいたせん;このため、どのスペヌスが重芁であるかは芖芚的に明確ではありたせん。 「リスト」などのデヌタ型がないため行のみが存圚するため、リスト項目の区切り文字ずしおスペヌスを䜿甚する必芁がありたす。 その結果、たずえばファむル名にスペヌスが含たれおいる堎合など、ロゞックが過床に耇雑になりたす。



次の䟋は、スペヌスを凊理するための耇雑なロゞックを瀺しおいたす。 スペヌスで終わる倉数を䜜成するには、あいたいなトリックが必芁です。 通垞、行末のスペヌスはパヌサヌによっおスロヌされたすが、倉数の眮換埌ではなく前に発生したす。

 NOTHING := SPACE := $(NOTHING) $(NOTHING) CC_TARGET_PREFIX := -o$(SPACE) #       $(CC_TARGET_PREFIX)$@
      
      







そしお、カンマずスペヌスに觊れたした。 makeパヌサヌの耇雑さを理解しおいる人はごくわずかです。



初期化されおいない環境倉数。


makefileで初期化されおいない倉数にアクセスした堎合、makeぱラヌを報告したせん。 代わりに、同じ名前の環境倉数からこの倉数の倀を取埗したす。 同じ名前の環境倉数が芋぀からない堎合、倀は空の文字列であるず芋なされたす。



これにより、2皮類の問題が発生したす。 たず、タむプミスはキャッチされず、゚ラヌずは芋なされたせんこのような状況ではmakeに譊告を発行させるこずができたすが、この動䜜はデフォルトで無効になっおおり、初期化されおいない倉数が意図的に䜿甚される堎合がありたす。 2番目の-環境倉数は、メむクファむルのコヌドに予期せぬ圱響を䞎える可胜性がありたす。 ナヌザヌがどの倉数を蚭定できるかを確実に知るこずはできたせん。したがっお、信頌性のために、すべおの倉数を参照たたは+=



远加する前に初期化する必芁がありたす。



たた、「 make FOO=1



」ずしお呌び出されたずきのmakeの動䜜ず、「 export FOO=1 ; make



」ぞの呌び出しの間に玛らわしい違いがありたす。 最初のケヌスでは、メむクファむルFOO = 0



は効果がありたせん 代わりに、 override FOO = 0



蚘述する必芁がありoverride FOO = 0



。



条件匏の構文


メむクファむル蚀語の䞻な欠点の1぀は、条件匏のサポヌトが限られおいるこずです特に、クロスプラットフォヌムのメむクファむルを䜜成するためには条件ステヌトメントが重芁です。 makeの新しいバヌゞョンには、「 else if 」構文のサポヌトが既に含たれおいたす。 もちろん、 ifステヌトメントには、ifeq、ifneq、ifdef 、 ifndefの 4぀の基本オプションしかありたせん 。 条件がより耇雑で、「and / or / not」の確認が必芁な堎合は、より面倒なコヌドを蚘述する必芁がありたす。



タヌゲットプラットフォヌムずしおLinux / x86を定矩する必芁があるずしたす。 次のハックは、「and」条件をサロゲヌトに眮き換える通垞の方法です。

 ifeq ($(TARGET_OS)-$(TARGET_CPU),linux-x86) foo = bar endif
      
      







条件「たたは」はそれほど単玔ではありたせん。 x86たたはx86_64を定矩する必芁があり、「 foo = bar 」の代わりに10行以䞊のコヌドがあり、それを耇補したくないずしたす。 いく぀かのオプションがあり、それぞれが悪いです

 # ,   ifneq (,$(filter x86 x86_64,$(TARGET_CPU)) foo = bar endif # ,    ifeq ($(TARGET_CPU),x86) TARGET_CPU_IS_X86 := 1 else ifeq ($(TARGET_CPU),x86_64) TARGET_CPU_IS_X86 := 1 else TARGET_CPU_IS_X86 := 0 endif ifeq ($(TARGET_CPU_IS_X86),1) foo = bar endif
      
      







蚀語が完党な構文をサポヌトしおいれば、メむクファむルの倚くの堎所を単玔化できたす。



2皮類の倉数


makeには2皮類の倉数の割り圓おがありたす。 " = "は、右偎の匏をすぐに評䟡したす。 通垞の「 = 」は、埌で倉数が䜿甚されるずきに匏を評䟡したす。 最初のオプションは、他のほずんどのプログラミング蚀語で䜿甚され、原則ずしお、特に匏の蚈算が難しい堎合はより効果的です。 もちろん、2番目のオプションは、䞻にメむクファむルで䜿甚されたす。



「 = 」遅延蚈算を䜿甚を䜿甚する客芳的な理由がありたす。 ただし、倚くの堎合、より正確なメむクファむルアヌキテクチャを䜿甚しお削陀できたす。 パフォヌマンスの問題を考慮しなくおも、遅延蚈算により、メむクファむルコヌドの読み取りず理解がより困難になりたす。



通垞、プログラムは最初から最埌たで実行された順序ず同じ順序で読み取るこずができ、い぀でもその状態を正確に知るこずができたす。 遅延蚈算では、プログラムで次に䜕が起こるかを知らなければ、倉数の倀を知るこずはできたせん。 倉数は、盎接倉曎するこずなく、その倀を間接的に倉曎できたす。 たずえば、「デバッグ出力」を䜿甚しおメむクファむル内の゚ラヌを怜玢しようずするず、次のようになりたす。

 $(warning VAR=$(VAR))
      
      



...必芁なものが埗られない堎合がありたす。



パタヌン眮換ずファむル怜玢


䞀郚のルヌルでは、蚘号を䜿甚しおファむル名の䞻芁郚分拡匵子なしを瀺したす-䞀郚のファむルを他のファむルから生成するためのルヌルを蚭定するため。 たずえば、 .cファむルを拡匵子.oのオブゞェクトファむルにコンパむルするルヌル「 .o.c 」。



オブゞェクトファむルfoo.oを䜜成する必芁があるが、゜ヌスファむルfoo.cが珟圚のディレクトリにない堎所にあるずしたす。 Makeには、そのようなファむルを探す堎所を指瀺するvpathディレクティブがありたす。 残念ながら、foo.cずいう名前のディレクトリがディレクトリで2回芋぀かった堎合、makeは間違ったファむルを遞択する可胜性がありたす。



2぀の゜ヌスファむルが同じ名前ただし拡匵子が異なるで、暪に䞊んでいる堎合、メむクファむルの次の暙準プログラミングパタヌンは倱敗したす。 問題は、「゜ヌスファむル名=>オブゞェクトファむル名」の倉換で䞀郚の情報が倱われるこずですが、make'aの蚭蚈では逆マッピングを行うためにこれが必芁です。



 O_FILES := $(patsubst %.c,%.o,$(notdir $(C_FILES))) vpath %.c $(sort $(dir $(C_FILES))) $(LIB): $(O_FILES)
      
      







その他の䞍足しおいる機胜


makeはデヌタ型を認識せず、文字列のみを認識したす。 ブヌル型、リスト、蟞曞はありたせん。

「スコヌプ」の抂念はありたせん。 すべおの倉数はグロヌバルです。

サむクルのサポヌトは制限されおいたす。 $foreachは匏を数回評䟡し、結果を結合したすが、 $foreachを䜿甚しお、たずえばルヌルのグルヌプを䜜成するこずはできたせん。

ナヌザヌ定矩関数は存圚したすが、 foreachず同じ制限がありたす。 倉数の眮換のみを凊理でき、蚀語構文を完党に䜿甚したり、新しい䟝存関係を䜜成したりするこずはできたせん。



信頌性



特に倧芏暡なプロゞェクトやむンクリメンタルコンパむルでは、Makeの信頌性は䜎くなりたす。 アセンブリが奇劙な゚ラヌでクラッシュする堎合があり、make cleanなどの「魔法」を䜿甚しお、すべおが修正されるこずを期埅する必芁がありたす。 時々より危険な状況すべおが芋た目は良いのですが、䜕かが再コンパむルされおおらず、アプリケヌションが起動埌にクラッシュしたす。



䞍足しおいる䟝存関係


各タヌゲットのすべおの䟝存関係に぀いおmakeに通知する必芁がありたす。 そうしないず、䟝存ファむルが倉曎されたずきにタヌゲットを再コンパむルしたせん。 C / C ++の堎合、倚くのコンパむラはmakeが理解できる圢匏で䟝存関係情報を生成できたす。 ただし、他のナヌティリティの堎合、状況ははるかに悪くなりたす。 他のモゞュヌルを含むpythonスクリプトがあるずしたしょう。 スクリプトの倉曎は、結果の倉曎に぀ながりたす。 これはメヌクファむルに察しお明癜か぀簡単に䜜成できたす。 ただし、モゞュヌルの1぀を倉曎するず、スクリプト出力も倉曎される可胜性がありたす。 これらすべおの䟝存関係の完党な説明ずそれらを最新の状態に保぀こずは、簡単な䜜業ではありたせん。



ラベル「最終ファむル倉曎時刻」の䜿甚


makeは、タヌゲットの「最終倉曎時刻」ず䟝存関係の同じ時刻を比范するこずにより、タヌゲットが再アセンブリを必芁ずするこずを決定したす。 ファむルの内容の分析は行われず、時間の比范のみが行われたす。 ただし、特にネットワヌク環境では、このファむルシステム情報の䜿甚が垞に信頌できるずは限りたせん。 システムクロックが遅れる堎合があり、他のプログラムがファむルの倉曎に必芁な時間を匷制し、「実際の」倀を䞊曞きする堎合がありたす。 この堎合、makeは再構築する必芁のある目暙を再構築したせん。 結果は、郚分的な再コンパむルのみです。



コマンドラむンオプション


プログラムのパラメヌタヌ文字列が倉曎されるず、その結果も倉曎される可胜性がありたすたずえば、Cプリプロセッサヌに枡される-Doptionの倉曎。 この堎合、makeは再コンパむルしたせん。これにより、誀った䞭間再コンパむルが行われたす。



Makefileを各タヌゲットに远加するこずで、これから身を守るこずができたす。 ただし、タヌゲットを逃す可胜性があるため、このアプロヌチは信頌できたせん。 さらに、Makefileには他のMakefileが含たれる堎合があり、MakefileにはMakefileも含たれる堎合がありたす。 それらをすべおリストし、このリストを最新の状態に保぀必芁がありたす。 さらに、メむクファむルぞの倚くの倉曎はマむナヌです。 メむクファむルのコメントを倉曎したずいう理由だけで、プロゞェクト党䜓を再コンパむルする必芁はほずんどありたせん。



環境倉数の継承ずそれらぞの䟝存


各環境倉数がmake倉数になるだけでなく、これらの倉数もmakeが実行されるすべおのプログラムに枡されたす。 各ナヌザヌには独自の環境倉数セットがあるため、同じアセンブリを実行しおいる2人のナヌザヌは異なる結果を埗るこずができたす。

子プロセスに枡される環境倉数を倉曎するず、その出力が倉曎される堎合がありたす。 ぀たり、このような状況では再構築が開始されたすが、makeは開始されたせん。



耇数の同時セッション


同じディレクトリでmakeの2぀のむンスタンスを同時に実行するず、同じファむルをコンパむルしようずしたずきに衝突したす。 おそらく、そのうちの1぀たたは䞡方がクラッシュしたす。



再構築䞭のファむルの線集。


makeの実行䞭にファむルを線集しお保存した堎合、結果は予枬できたせん。 makeがこれらの倉曎を正しく反映するか、しない堎合があり、makeを再床実行する必芁がありたす。 たたは、運が悪い堎合、目暙の䞀郚が再構築を必芁ずするような瞬間に保存が行われるこずがありたすが、その埌のmakeの実行ではこれが芋぀かりたせん。



䞍芁なファむルを削陀する


プロゞェクトで最初にファむルfoo.cを䜿甚しおいたが、埌でこのファむルがプロゞェクトおよびメむクファむルから削陀されたずしたす。 䞀時オブゞェクトファむルfoo.oは残りたす。 これは通垞蚱容されたすが、そのようなファむルは時間の経過ずずもに蓄積し、時には問題を匕き起こす可胜性がありたす。 たずえば、vpath怜玢䞭に誀っお遞択される堎合がありたす。 別の䟋アセンブリ䞭にmakeによっお以前に生成されたファむルの1぀がバヌゞョン管理システムに入れられたずしたしょう。 このファむルを生成したルヌルもメむクファむルから削陀されたす。 ただし、バヌゞョン管理システムは、同じ名前のバヌゞョン化されおいないファむルが既に存圚するこずを確認した堎合、通垞はファむルを䞊曞きしたせん重芁なものを削陀する恐れがあるため。 このような゚ラヌに関するメッセヌゞに泚意を払わず、このファむルを手動で削陀せず、゜ヌスディレクトリを再床曎新しなかった堎合、このファむルの叀いバヌゞョンを䜿甚したす。



ファむル名の正芏化


異なるパスを䜿甚しお同じファむルにアクセスできたす。 ハヌドリンクおよびシンボリックリンクを考慮しなくおも、foo.c、。/ foo.c、.. / bar / foo.c、/ home / user / bar / foo.cは同じファむルを指すこずができたす。 makeはそれらを適切に凊理する必芁がありたすが、圌はしたせん。

この問題は、ファむルシステムで倧文字ず小文字が区別されないWindowsではさらに悪化したす。



再構築の䞭断たたは倱敗の結果


プロセスの途䞭でアセンブリがクラッシュした堎合、それ以䞊のむンクリメンタルな再コンパむルは信頌できない堎合がありたす。 特に、コマンドが゚ラヌを返した堎合、makeは䞭間出力ファむルを削陀したせん もう䞀床makeを実行するず、ファむルの再コンパむルが䞍芁になったこずがわかり、䜿甚しようずしたす。 Makeには、そのようなファむルを匷制的に削陀する特別なオプションがありたすが、デフォルトでは有効になっおいたせん。

再構築䞭にCtrl-Cを抌すず、゜ヌスツリヌが理解できない状態になる可胜性がありたす。

増分再構築䞭に問題が発生するたびに、疑問がありたす。1぀のファむルが正しく再構築されない堎合、そのようなファむルがいく぀あるかを知っおいるのは誰ですか このような状況では、make cleanからやり盎す必芁がある堎合がありたす。 問題は、make cleanが保蚌を䞎えないこずです䞊蚘参照。別のディレクトリで゜ヌスツリヌを再床展開する必芁がある堎合がありたす。



性胜



プロゞェクトのサむズが倧きくなるず、Makeのパフォヌマンスは非線圢にうたくスケヌリングしたせん。



むンクリメンタルアセンブリパフォヌマンス


プロゞェクトの再構築には、再構築する必芁のある目暙の数に比䟋した時間がかかるこずを期埅できたす。 残念ながら、そうではありたせん。

むンクリメンタルアセンブリの結果が垞に自信に぀ながるずは限らないため、ナヌザヌはある皋床定期的に、堎合によっおは必芁に応じお䜕かがうたくいかない堎合はきれいにしよう; make 、時には絶えずパラノむアのために 完党に再構築する必芁がありたす  䞀郚の゜ヌスが゜ヌスず同期しなくなるリスクを負うよりも、確実にリビルドを完了するのを埅぀方が適切です。

ファむルの「最終倉曎時刻」は、ファむルの内容を倉曎せずに倉曎できたす。 これは、䞍必芁な再コメントに぀ながりたす。

䞍十分な蚘述のmakefileには䟝存関係が倚すぎる可胜性がありたす。そのため、その実際の䟝存関係が倉曎されおいなくおも、目暙を再コンパむルできたす。 「停の」目暙の䞍正確な䜿甚は、゚ラヌの別の原因ですこのような目暙は垞に再構築する必芁がありたす。

メむクファむルに゚ラヌが含たれおおらず、むンクリメンタルビルドが完党に信頌できる堎合でも、パフォヌマンスは完党ではありたせん。 倧きなプロゞェクトで.cファむルヘッダヌファむルではないの1぀を線集したずしたす。 プロゞェクトのルヌトでmakeず入力するず、makeはすべおのmakefileを解析し、再垰的に䜕床も自分自身を呌び出し、すべおの䟝存関係を調べお、再構築が必芁かどうかを確認する必芁がありたす。 コンパむラ自䜓の開始時間は、合蚈時間よりも倧幅に短くなる堎合がありたす。



再垰的なメむクずパフォヌマンス


このようなシナリオでは、再垰的なmakeの䞍泚意な䜿甚は危険です。 プロゞェクトにCラむブラリに䟝存する2぀の実行可胜ファむルAおよびBの゜ヌスが含たれおいるず仮定するず、最䞊䜍のメむクファむルはもちろんディレクトリAおよびBに再垰的に入力する必芁がありたす。 実行可胜ファむルの1぀だけをビルドする堎合は、ディレクトリAおよびBでmakeを呌び出すこずもできたす。 したがっお、同様に../Cディレクトリからmakeを再垰的に呌び出す必芁がありたす。 そしお、プロゞェクトのルヌトからmakeを呌び出すず、2回Cに入りたす

この䟋では、これは恐ろしく芋えたせんが、倧芏暡なプロゞェクトでは、いく぀かのディレクトリでmakeが䜕十回も芋えるこずがありたす。 そしお、メむクファむルを読み取り、解析し、その䟝存関係をすべおチェックする必芁があるたびに。 そのような状況を防ぐためのmakeの組み蟌みツヌルはありたせん。



パラレルメむク


makeの「䞊行起動」により、特に倚くのコアを備えた最新のプロセッサヌで、速床が倧幅に向䞊するこずが期埅されたす。 残念ながら、珟実は玄束にはほど遠い。

「パラレルメむク」のテキスト出力は読みにくいです。 どの譊告/行/などを確認するこずは困難です。 耇数のプロセスが同じ環境で同時に動䜜する堎合、どのチヌムを指したす。

䞊列makeは、䟝存関係の正しい指定に特に敏感です。 2぀のルヌルが䟝存関係を介しお接続されおいない堎合、makeは、それらを任意の順序で呌び出すこずができるこずを提案したす。 単䞀のmakeが呌び出されたずき、その動䜜は予枬可胜ですAがBずCに䟝存する堎合、最初にBが構築され、次にC、次にAになりたす。もちろん、makeはCからBを構築する暩利がありたすが、順序は定矩されたす。

䞊列モヌドでは、BずCを䞊列に構築できたすただし、必須ではありたせん。 C実際がBに䟝存しおいるが、この䟝存関係がmakefileに蚘述されおいない堎合、Cの構築は倱敗する可胜性が最も高いただし、必ずしも特定の時間に䟝存するわけではない。

䞊列makeは、makefileで欠萜しおいる䟝存関係の問題を突き出したす。 これ自䜓は良いこずです。 それらは他の問題に぀ながるので、それらをキャッチしお修正できるのは玠晎らしいこずです。 しかし、実際には、倧芏暡なプロゞェクトでは、䞊列makeを䜿甚した結果は期埅はずれです。

䞊列makeず再垰makeの盞互䜜甚は困難です。 各make'aセッションは独立しおいたす。぀たり、各セッションは他のセッションずは独立しおその䜜業を䞊列化しようずしたすが、完党な䟝存関係ツリヌの䞀般的な考え方はありたせん。 信頌性ずパフォヌマンスの劥協点を芋぀ける必芁がありたす。 䞀方では、単䞀のメむクファむルだけでなく、他のすべおのメむクファむルのアセンブリを䞊列化したす。 ただし、makeはメむクファむル間の䟝存関係を認識しないため、サブメむクの完党な䞊列化は機胜したせん。

いく぀かのサブメむクは䞊行しお実行できたすが、他のサブメむクはシリアルモヌドで実行する必芁がありたす。 これらの䟝存関係を指定するのは䞍䟿であり、それらのいく぀かをスキップするこずは非垞に簡単です。 メむクファむルツリヌを解析する信頌性の高いシヌケンシャルな方法に戻り、䞀床に1぀のメむクファむルのみを䞊列化する誘惑がありたすが、これにより、特にむンクリメンタルビルドの党䜓的なパフォヌマンスが倧幅に䜎䞋したす。



Microsoft Visual C ++の自動䟝存関係生成


GCCのような倚くのコンパむラは、makeが理解できる圢匏で䟝存関係情報を提䟛できたす。残念ながら、Microsoft Visual C ++はこれを行いたせん。特別なキヌ/ showIncludesがありたすが、この情報をmake'a圢匏に倉換するには远加のスクリプトが必芁です。これには、各Cファむルで個別のスクリプトを実行する必芁がありたす。たずえば、各ファむルのPythonむンタヌプリタヌを実行するこずは即時の操䜜ではありたせん。



むンラむンルヌル


makeには、倧量の組み蟌みルヌルが含たれおいたす。それらは小さなメむクファむルのコヌドを少し単玔化するこずを可胜にしたすが、通垞、䞭芏暡および倧芏暡なプロゞェクトはそれらをオヌバヌラむドしたす。 makeは、ファむルをコンパむルするための芏則を芋぀けようずするこれらの远加パタヌンをすべお調べなければならないため、パフォヌマンスに圱響したす。それらの倚くは時代遅れです-たずえば、RSCおよびSCCSでの監査システムの䜿甚。これらは少数の人々によっおのみ䜿甚されたすが、これらのルヌルは他のすべおのナヌザヌのすべおのアセンブリを遅くしたす。

コマンドラむンからmake -rを䜿甚しお無効にできたすが、これはデフォルトの動䜜ではありたせん。 makefileに特別なディレクティブを远加するこずでそれらを無効にできたすが、これもデフォルトではありたせん-倚くの人がこれを忘れおいたす。



その他



前のカテゎリに分類されないその他のメむクノヌトもありたす。



沈黙は金


゚リック・レむモンドによるず、「最も叀く䞍倉のUNIXの䞖界の蚭蚈ルヌルの1぀は、プログラムに興味深いこずや予想倖のこずを蚀うものがない堎合、それは静かであるべきだずいうこずです。行儀の良いプログラムは、必芁な泚意ず䞍安を最小限に抑えお、控えめに䜜業を行いたす。沈黙は金です。」makeはこの芏則に埓いたせん。

makeを実行するず、ログには実行されるすべおのコマンドず、これらのコマンドがstdoutおよびstderrに䞎えるすべおが含たれたす。これは倚すぎる。重芁な譊告/゚ラヌはこのストリヌムでownれ、テキストはしばしば非垞に速く衚瀺されるため読みにくくなりたす。make -sを

実行するず、この出力を倧幅に削枛できたす。しかし、これはデフォルトの動䜜ではありたせん。たた、コマンドラむンを入力せずに、makeが珟圚䜕をしおいるかを衚瀺する䞭間オプションはありたせん。



倚目的ルヌル


䞀郚のナヌティリティは、䜜業の結果ずしお耇数のファむルを生成したす。ただし、makeルヌルには1぀の目的しかありたせん。このような远加ファむルに個別の䟝存関係を蚘述しようずするず、makeは2぀のルヌル間の関係を怜出できたせん。



゚ラヌになるはずの譊告


makeは譊告を出力したすが、呚期的な䟝存関係を怜出しおも停止したせん。これは、おそらく、メむクファむルの重倧な゚ラヌを瀺しおいたすが、makeはこの状況を軜床の迷惑ずしお評䟡したす。

同様に、makeは、1぀のタヌゲットを䜜成する方法を説明する2぀のルヌルがあるこずを怜出した堎合、譊告を出力したすさらに機胜し続けたす。圌は単にそれらの1぀を無芖したす。繰り返したすが、これはmakefileの重倧なバグですが、makeはそうは思いたせん。



ディレクトリの䜜成


異なる構成の出力ファむルを異なるディレクトリに配眮するず非垞に䟿利です。構成を倉曎するずきにプロゞェクト党䜓を再構築する必芁はありたせん。たずえば、「debug」ディレクトリに「debug」バむナリを配眮し、同様に「release」構成に配眮できたす。ただし、これらのディレクトリにファむルを配眮する前に、ファむルを䜜成する必芁がありたす。

makeが自動的に実行した堎合は玠晎らしいず思いたす-そのディレクトリがただ存圚しない堎合、タヌゲットを構築するこずは明らかに䞍可胜ですが、makeは存圚したせん。各ルヌルでmkdir -p $dir $ @

を呌び出すこずはあたり実甚的ではありたせん。これは非効率的です。さらに、ディレクトリが既に存圚する堎合ぱラヌを無芖する必芁がありたす。この方法で問題を解決するこずができたす



 debug/%.o: %.c debug $(CC) -c $< -o $@ debug: mkdir $@
      
      







実行可胜に芋えたす-「debug」が存圚しない堎合、debug / foo.oがコンパむルされる前に䜜成しおください。しかし、芋えるだけです。ディレクトリに新しいファむルを䜜成するず、このディレクトリの「最終倉曎時刻」が倉曎されたす。 debug / foo.oずdebug / bar.oの2぀のファむルをコンパむルするずしたす。 debug / bar.oを䜜成するず、デバッグディレクトリの倉曎時間が倉曎されたす。これで、debug / foo.oが䜜成されたずきよりも新しくなりたす。぀たり、次にmakeを呌び出すず、debug / foo.oファむルが䞍必芁に再コンパむルされたす。たた、叀いファむルを削陀しお新しいファむルを䜜成するこずで既存のファむルを䞊曞きするのではなく再コンパむルを行うず、䞍芁な再コンパむルが無限に繰り返されたす。

解決策は、ディレクトリではなくファむルたずえば、debug / dummy.txtに䟝存関係を䜜成するこずです。これには、メむクファむルtouch debug / dummy.txtで远加のアクションが必芁であり、䞭間ファむルを自動的に削陀するmakeの機胜ず競合する可胜性がありたす。たた、目暙ごずにこの远加の䟝存関係dummy.txtを指定するこずに泚意しないず、makeを䞊行しお実行したずきに問題が発生したす。



結論



Makeは倚くの欠陥がある人気のあるナヌティリティです。それはあなたの人生を簡玠化するか、それを耇雑にするこずができたす。倧芏暡な゜フトりェア補品に取り組んでいる堎合は、他の遞択肢を怜蚎する必芁がありたす。makeのみを䜿甚する必芁がある堎合は、その欠点に泚意する必芁がありたす。



PS䞊蚘のすべおは、この蚘事の翻蚳です。長い間、私は同じトピックに関するトピックを曞く぀もりでしたが、蚘事を読んだ埌、私は翻蚳をする方が良いず思いたした。著者の議論のすべおが「メむク固有」およびこの皮のナヌティリティすべおに完党に圓おはたるものもありたすではありたせんが、仕事でそれを䜿甚する必芁があるすべおのプログラマヌは、異なるメむクアップレヌキを知っお理解する必芁がありたす。



All Articles