1 पॉइंट द्वारा GN⁺ 2024-09-22 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • नए build tools लगातार आते रहने के बावजूद, Makefile अब भी प्रोजेक्ट के दोहराए जाने वाले कामों को बांधने वाला हल्का डिफॉल्ट टूल बना हुआ उपयोगी है
  • make, make build, make install, make dev जैसे परंपरागत commands की वजह से किसी अनजान प्रोजेक्ट में भी build, install और development server चलाने की जल्दी कोशिश की जा सकती है
  • Jekyll, Hugo, 11ty, Python web frameworks, Docker, gulp जैसे अलग-अलग stacks में भी Makefile common execution interface की भूमिका निभाता है
  • व्यक्तिगत प्रोजेक्ट्स में अक्सर conditionals या flags से ज़्यादा dev, build, deploy जैसे कुछ सरल targets ही काफी होते हैं
  • GNU Make व्यापक रूप से उपलब्ध है, और अगर वह न भी हो तो Makefile के shell commands सीधे चलाए जा सकते हैं, इसलिए सीमित environments में भी इसका बोझ कम रहता है

अलग-अलग प्रोजेक्ट commands को एक entry point में बांधना

  • Makefile का उपयोग ऐसे प्रोजेक्ट्स को जाने-पहचाने command set में लपेटने के लिए होता है जिनमें build, run और deploy करने के तरीके अलग होते हैं
  • किसी अनजान प्रोजेक्ट में Makefile दिखे तो आम तौर पर पहले ये commands आज़माए जा सकते हैं
    • make
    • make build
    • make install
  • पुराने व्यक्तिगत प्रोजेक्ट को फिर से खोलते समय भी सिर्फ make dev चलाकर ज़रूरी build steps और development server startup को एक साथ संभालने के लिए इसे सेट किया जा सकता है
  • Jekyll, Hugo, 11ty, कई Python web frameworks जैसे अलग-अलग technology stacks में भी वही entry point बनाए रखा जा सकता है
  • Docker या gulp का उपयोग होने पर भी Makefile उन tools को replace करने के बजाय orchestration layer की तरह काम करता है
    • उदाहरण: make build प्रोजेक्ट के हिसाब से अतिरिक्त arguments पास करते हुए ज़रूरी Docker image build करता है

व्यक्तिगत प्रोजेक्ट्स में इसका सरल उपयोग

  • Makefile का उपयोग जटिल features के बजाय shell commands के समूह पर केंद्रित रहता है
    • conditionals या flags जैसे features का इस्तेमाल नहीं किया जाता
    • make में काम की इकाई तकनीकी रूप से target होती है, लेकिन व्यवहार में इसे task की तरह लिया जाता है
    • यह bash script functions से भी बनाया जा सकता है, लेकिन Makefile को अधिक आसान और तेज़ माना जाता है
  • व्यक्तिगत प्रोजेक्ट्स में अक्सर इस्तेमाल होने वाले काम आम तौर पर 2~3 ही होते हैं
    • dev: development server शुरू करना
    • build: ज़रूरत होने पर प्रोजेक्ट build करना
    • deploy: प्रोजेक्ट deploy या publish करना
    • watch: source files बदलने पर build job को अपने-आप फिर चलाने वाला अतिरिक्त काम
  • मौजूदा ब्लॉग के Makefile में सिर्फ dev target है
    • dev: के नीचे npm run dev चलाया जाता है
  • अधिक जटिल व्यक्तिगत प्रोजेक्ट्स में निम्न कामों को Makefile में बांधा जाता है
    • dev: bundle exec jekyll serve से development server चलाना
    • build: npm run gulp build से assets build करना
    • watch: npm run gulp watch से किसी खास folder पर नज़र रखना
    • deploy: production environment में Jekyll build करने के बाद make encrypt, netlify deploy --prod चलाना
    • encrypt: npx staticrypt से _site folder की HTML files को encrypt करना

ध्यान रखने योग्य सीमाएँ और फायदे

  • उदाहरण में phony targets को छोड़ा गया है, लेकिन अगर dev, build, watch, deploy, encrypt जैसे नाम की files मौजूद हों तो Makefile उम्मीद के मुताबिक काम नहीं कर सकता
  • GNU Make वह software है जो makefile चलाता है; Linux में इसके पहले से installed होने की संभावना ज़्यादा रहती है, और MacBook पर भी यह इतना आम है कि अलग से install याद न रहे
  • Make बहुत अधिक अतिरिक्त dependencies नहीं मांगता, इसलिए सुरक्षा कारणों से package install करना मुश्किल या असंभव हो ऐसे सीमित environments में यह उपयोगी हो सकता है
  • अगर Make न भी हो, तब भी Makefile के commands को सीधे shell में copy करके चलाया जा सकता है
    • इसके उलट, अगर server पर gulp न हो तो JavaScript code को सीधे terminal में चिपकाकर चलाना आसान नहीं होता
  • भले ही बाद में कोई बेहतर और तेज़ नया build tool मिल जाए, Make अलग-अलग tools और settings को संभालने वाली common command layer के रूप में आगे भी उपयोगी रह सकता है

2 टिप्पणियां

 
kayws426 2024-09-22

यदि makefile में dependencies परिभाषित नहीं हैं, तो उसे justfile से बदलने पर बेहतर usability मिलती है.

 
GN⁺ 2024-09-22
Hacker News की राय
  • इस thread में “आप make का गलत इस्तेमाल कर रहे हैं” जैसी बातों से हतोत्साहित होने की ज़रूरत नहीं है। Make के अच्छे tool होने की एक वजह यह है कि यह जितना दिखता है, उससे भी सरल तरीके से शुरू किया जा सकता है
    अगर आप .PHONY इस्तेमाल नहीं करते तो समस्या आ सकती है, लेकिन छोटे project में हो सकता है वह जाल आप एक साल बाद ही छुएँ, और तब भी शायद एक घंटे तक सिर खुजलाने से बात बन जाए। 99% मामलों में “सही तरीका” की चिंता किए बिना तुरंत शुरू किया जा सकता है, और Make सिर्फ उतनी ही complexity मांगता है जितनी उसे ढहने से बचाने के लिए ज़रूरी हो

    • Make की सबसे खराब बातों में से एक यह है कि यह ऊपर से सरल दिखता है
      Make input files और dependencies लेकर ठीक एक output file बनाने का काम करता है। install, all, clean जैसी rules जो output नहीं बनातीं, या लेख के सभी targets को .PHONY जैसे खास magic target पर निर्भर होना चाहिए, लेकिन .PHONY 2017 के POSIX (IEEE Std 1003.1-2017, https://pubs.opengroup.org/onlinepubs/9699919799/utilities/m...) में नहीं था और अब जाकर मौजूदा standard (IEEE Std 1003.1-2024, https://pubs.opengroup.org/onlinepubs/9799919799/utilities/m...) में शामिल हुआ है। अगर आप object files, modules, precompiled headers जैसी कई files बनाना चाहते हैं, तो आपको खुद नाज़ुक hacks लिखने पड़ते हैं। हर Make, GNU Make नहीं होता, और BSD, Solaris/Illumos जैसे nix family के systems अब भी मौजूद हैं
      इसका मतलब यह नहीं कि Make बेकार है। यह उन projects में उपयोगी है जो काफ़ी complex हैं, लेकिन अभी इतने नहीं कि “बेहतर” build system की ज़रूरत पड़े। समस्या यह है कि ऐसे projects code बढ़ने के साथ और complex हो जाते हैं, और आखिर में Makefile या उसके कुछ हिस्से generate करने वाली scripts/programs रखने लगते हैं, जिससे एक अस्थायी meta build system बन जाता है
      इससे भी बड़ी समस्या उसका इस्तेमाल नहीं, बल्कि उसे “सबके लिए” solution के तौर पर सुझाना है। और जैसे ही project root में build या dev जैसी directory या file बनती है, वह Makefile काम करना बंद कर देता है
    • नया TypeScript project शुरू करते समय इस्तेमाल होने वाले थोड़े ज्यादा complex Makefile का उदाहरण यहाँ है: https://github.com/borisovg/node-ts-template/blob/main/Makef...
      आजकल मैं pnpm पर बदल तो जाता हूँ, फिर भी इसे बहुत complex नहीं मानता। syntax कुछ हद तक जानना पड़ता है, लेकिन दूसरे tools को शुरू से ठीक से चलाने की तुलना में यह कम मुश्किल है
    • 20 साल से ज़्यादा समय से कई projects और कई languages में make का अच्छा इस्तेमाल किया है, और लोगों को जिस .PHONY काम की इतनी चिंता रहती है, उससे कभी समस्या नहीं हुई
      यह simple, पढ़ने में आसान, modify करने योग्य, composable है, और लगभग हर जगह पहले से installed होता है। सतह पर जो लिखा है वही करता है और उससे ज़्यादा लगभग कुछ नहीं करता
      वैसे, जब दूसरे projects में trendy build systems या किसी nightmare जैसे build systems से निपटना पड़ता है, तब भी उन्हें make से wrap करके इस्तेमाल करता हूँ
    • पूरी तरह सहमत हूँ। काम के हिसाब से सही tool इस्तेमाल करना बेहतर है, और expert न होने पर भी perfectionist criticism से बचने के लिए गलत tool चुनने से कहीं बेहतर है
      हर किसी को कहीं न कहीं से शुरू करना होता है, और एक बार चीज़ चलने लगे तो incremental improvements आसानी से जोड़ी जा सकती हैं
    • हर makefile recipe को ठीक एक output, यानी $@, बनाना चाहिए। पूरा Makefile मनचाही संख्या में outputs बना सकता है, क्योंकि rules दूसरी rules पर depend कर सकती हैं
      यहीं से phony targets के लिए एक साफ़ rule of thumb मिलता है। अगर कोई recipe सिर्फ $@ को नहीं छूती, तो $@ को phony के रूप में mark करना चाहिए। phony targets को list के रूप में manage करना कहीं आसान है
      phonies :=
      phonies += something
      something:
      ./do-something
      phonies += something-else
      something-else: something
      ./do-something-else
      # touches $@ and thus does not need to be phony
      create-file:
      ./generate-some-output > $@
      .PHONY: $(phonies)
  • Makefile एक खराब तकनीक है। बस इतना है कि हमारे बनाए ज़्यादातर दूसरे build systems से थोड़ा कम खराब है, इसलिए आत्म-पीड़क अर्थ में उपयोगी हो जाता है
    Build systems आम तौर पर या तो इतने basic होते हैं कि खिलौने से ज़्यादा कुछ build करते ही अफरा-तफरी हो जाती है, या इतने जटिल कि पहले से knowledge, bureaucracy, synchronization और boilerplate बहुत ज़्यादा हो जाते हैं, या standard library नहीं होती इसलिए वही build patterns 10,000 असंगत implementations में बिखर जाते हैं, या इतने restrictive होते हैं कि ज़रूरतें बढ़ने पर migration करनी पड़ती है, या बहुत ज़्यादा magic होता है, या syntax कठिन और inconsistent होता है

    • मेरे हिसाब से Makefile एक बेहतरीन तकनीक है, बस बहुत लोगों ने इसे ठीक से सीखा नहीं है या intended तरीके से इस्तेमाल नहीं किया है
      मैं जो software इस्तेमाल करता हूँ, उसमें आधे से ज़्यादा सिर्फ साधारण Makefile और कभी-कभी configure script का इस्तेमाल करते हैं। autotools के बिना वैकल्पिक रूप से ./configure चलाते हैं और make, make install करते हैं, तो बस काम हो जाता है। यह बिल्कुल भी खिलौना setup नहीं है, और यह एक काम अच्छी तरह करने वाले छोटे programs से बना है
      Make और उसका काम करने का तरीका, कम-से-कम मेरे लिए, समझना आसान है। मुझे लगता है लोगों के खराब अनुभव अक्सर Make खुद के बजाय जटिल projects की खराब build settings या जरूरी knowledge की कमी की वजह से होते हैं
      Standard library का न होना जानबूझकर tool independence के लिए है, और इसी वजह से यह अलग-अलग tools, languages और use cases पर सामान्य रूप से लागू हो सकता है। इसे defect नहीं, feature मानता हूँ। simple layer dependency tracking है, और targets और dependencies भी साफ हैं, इसलिए इसे magical कहना मुश्किल है। Syntax निश्चित रूप से बेहतर हो सकता है
    • सबसे खराब build systems वे हैं जो किसी खास programming language को केंद्र में रखकर बनाए गए हैं। अगर languages N>>1 हैं, तो build systems भी N>>1 हो जाते हैं, और cognitive load इतना बढ़ जाता है कि scale नहीं होता
      कई languages को cover करने वाले general-purpose build systems सिर्फ make या CMake जैसे वे systems हैं जो make को target करते हैं। यह बेकार इसलिए है क्योंकि make बेकार है। make को सही तरीके से इस्तेमाल करना सचमुच मुश्किल है, recursive make और non-recursive make जैसी समस्याएँ हैं, और Unix/POSIX make, BSD make, GNU make, Windows nmake जैसे कई incompatible variants हैं, और यह काफी बदसूरत भी है
      फिर भी सही तरीके से लिखा गया make काफी अच्छा है। least common denominator के रूप में make का होना सचमुच बड़ी राहत है
    • सहमत हूँ। Alternatives में से काफी सारे भी Make जैसे general-purpose “कुछ चलाने वाले” tools नहीं, बल्कि किसी खास language पर focused हैं
      Make का subdirectories तक को साफ-सुथरे ढंग से handle न कर पाना काफी अजीब है। जानना चाहता हूँ कि Make से बेहतर कुछ है क्या। Ninja तो है, लेकिन उसे इंसानों के सीधे इस्तेमाल के लिए design नहीं किया गया है
    • क्या यह कहा जा सकता है कि वह confusion “बहुत hypothetical तौर पर” compiler या modules न होने वाली languages की वजह से बिल्कुल नहीं है
      तुम्हारे हिसाब से कितना? क्या 20%, 40%, 70% के आसपास तो सही नहीं होगा
    • “एक से ज्यादा” कहा जाए तो काफी गुंजाइश है। मेरा अनुमान यह है: Makefile बहुत basic नहीं है। यह बहुत complex हो सकता है, लेकिन इस पर निर्भर है कि आप इसे कैसे बनाते हैं। Standard library के तौर पर built-in functions तो हैं। यह बहुत restrictive मुझे कभी नहीं लगा, इसलिए नहीं मानता। Targets और dependencies साफ हैं, इसलिए magic भी ज्यादा नहीं है। लेकिन syntax निश्चित रूप से बेहतर हो सकता है, और सिर्फ एक साधारण JSON file भी हो तो बेहतर लगेगा
  • मुझे Make सचमुच पसंद है। पिछले 20 सालों में जिस भी काम या project को छुआ है, हर एक के लिए एक या अधिक लिखे हैं
    इसमें कोई चतुराई नहीं होती, बस कुछ variables वाले snippets का संग्रह होता है। जैसे make run, make test, make lint
    make recent lint के बाद सबसे हाल में modified script को चलाता है। Bash या दूसरे shell से भी कर सकते हैं, लेकिन तब developer-world में खिंच जाते हैं और complexity ही बढ़ती है, extra value नहीं मिलती। Make बस एक domain-specific language है: “इस तरह की file इस तरह की file से बनती है, और तब ये एक-दो commands चलाओ।” इसलिए यह बेहद powerful है

    • “इस तरह की file इस तरह की file से बनती है, और तब ये एक-दो commands चलाओ” वाली अभिव्यक्ति अच्छी है
      कई दशक पहले Java में test framework बनाया था, जिसमें make जैसी syntax से tests और dependent classes specify किए जा सकते थे। “baseline test set” define करने वाली test classes का set रखा था, और उस पर निर्भर दूसरी test class layers तभी चलती थीं जब पहले वाली सफल हो जाती थीं
      आजकल लोग हर चीज़ को इतना complex क्यों बना देते हैं, समझ नहीं आता। मैंने हमेशा सलाह दी है कि standard Unix tools और उनके तरीके, यानी time-tested तरीके, पर टिके रहो। जब तक ऐसी स्थिति न हो जहाँ वैसा करना बिल्कुल संभव न हो। समय सीमित है, इसलिए उसे problem solving के मूल हिस्सों—system/program design, modeling, structure, patterns आदि—पर लगाना चाहता हूँ, बाकी सब secondary है
    • असल में जितने भी Makefile सामने आए, वे “बस इतना ही” कहने से कहीं ज्यादा काम कर रहे थे
    • मेरा भी कुछ ऐसा ही है। पहले ज़्यादा इस्तेमाल नहीं करता था, लेकिन अभी की नौकरी में लगभग हर repository में Makefile है
      stack, language, repository चाहे कुछ भी हो, make test चलाने पर काम करेगा—यह जानना बड़ी राहत है
    • Make की समस्या Make नहीं है, बल्कि वे चीजें हैं जिन्हें Make call करता है और जो अब उस model के अनुसार काम नहीं करतीं
      पिछले project के Makefile में चार main commands थीं: build, test, frontend, deploy। build और test maven को call करते थे, frontend npm को, और deploy docker और aws को call करता था
      ये सभी tools अपनी state tracking, caching और incremental processing करते हैं, लेकिन यह report नहीं करते कि उन्होंने क्या किया। इसलिए “build update हुआ हो तभी deploy करो” जैसे molecular-level rules नहीं लिख सकते। क्योंकि maven/cargo/dotnet/npm/go वह information expose नहीं करते
  • लेखक mtime-आधारित dependency tracking तक इस्तेमाल नहीं करता। targets को भी .PHONY होना चाहिए था, लेकिन उन्हें मार्क नहीं किया गया है। इसे ऐसे shell script से भी बदला जा सकता था जो $1 पढ़कर match करे और तय करे कि क्या करना है

    • या फिर just जैसे simple command runner से भी बदला जा सकता है
      https://just.systems/
    • जिस project पर सच में काम चल रहा है, वहाँ से निकली एक लाइन की डरावनी कहानी है: .PHONY: $(MAKECMDGOALS)
      ./build.sh dev, make dev से कम स्पष्ट तो है। बिना किसी non-phony step के भी Make इस्तेमाल करने की एक और वजह यह है कि बाद में जरूरत पड़े तो ऐसे steps जोड़े जा सकते हैं। बेशक, मैं इस बात से सहमत हूँ कि लेखक को {dev,build,deploy} को phony के रूप में mark करना चाहिए
    • तकनीकी तौर पर यह सही है, लेकिन लेख से मिली मुख्य बात यह है कि अपने project ही नहीं, third-party projects में भी इस्तेमाल के तरीके की consistency मिलती है
      उसका अपना Makefile तकनीकी रूप से बेहतर किया जा सकता है, लेकिन ज्यादा अहम बात यह है कि किसी project में जाकर “शुरू करने” का experience consistent रहता है
    • हम सभी कभी न कभी beginner थे। कोई tool सीखने के लिए, भले ही beginner-style इस्तेमाल perfect न हो, उसे सच में इस्तेमाल करना मददगार होता है। सीखते हुए धीरे-धीरे सुधार सकते हैं
    • make और shell की खूबसूरती इसमें है कि वे simple हैं और Unix principle का पालन करते हैं—एक काम अच्छी तरह करना
      लोग चाहते हैं कि यह scripting language, dependency tracker वगैरह जैसे कई दूसरे काम भी करे, और फिर bloated tools ले आते हैं। नया होना हमेशा बेहतर होना नहीं है। Autoconf और automake, make नहीं हैं
  • तकनीकी तौर पर ये सभी make targets target name जैसे ही file को ढूँढते हैं। हर target को असल में .PHONY के रूप में define किया जाना चाहिए
    पहले मैं भी ऐसे Makefile हमेशा इस्तेमाल करता था, लेकिन पिछले कुछ सालों में just और justfile पर shift हो गया हूँ। यह behavior वहाँ default है और कुल मिलाकर इस्तेमाल करना आसान है। parameters जैसी चीजें भी ज्यादा simple हैं
    https://github.com/casey/just

    • ऐसे make-जैसे systems काफी अच्छे हैं, लेकिन एक समस्या है। Make सभी Linux और Mac में पहले से होता है, और Windows पर भी काफी आसानी से मिल जाता है। Git Bash में इसका शामिल न होना सच में अफसोसजनक है। lowest common denominator इस्तेमाल करना ही Make का बड़ा फायदा है, ऐसा मुझे लगता है
    • Make की बड़ी गलती यह थी कि उसने phony targets और file targets को एक ही namespace में मिला दिया। उदाहरण के लिए, phony targets : से शुरू हों—ऐसा कुछ होना चाहिए था, ताकि नाम देखकर ही फर्क पता चल जाए
      बेशक अब बहुत देर हो चुकी है
    • just सच में अच्छा है, लेकिन आम तौर पर installed नहीं होता, इसलिए थोड़ा झंझट है
      लगता है कि अब just, ripgrep जैसे नए और useful tools को bundle करके एक नए coreutils distribution जैसा कुछ आने का समय हो गया है, जो जहाँ चाहें वहाँ install हो जाए
  • यह मजेदार है कि make इतनी तीखी debate पैदा करता है। पुराने vi बनाम emacs वाली आधी धार्मिक लड़ाई जैसी बहसों से मिलता-जुलता है
    मैं original post से पूरी तरह सहमत हूँ, और खासकर यह तरीका smart लगता है कि ज्यादा sophisticated build tool इस्तेमाल करने पर भी उसे top-level Makefile से wrap किया जाए। फायदा standardization है। कुछ याद रखने की जरूरत नहीं—अगर यह मेरा लिखा project है, तो बस make टाइप करूँगा और पता है कि काम करेगा
    उदाहरण के लिए, C इस्तेमाल करने वाला कोई व्यक्ति Rust project compile करना चाहे, तो cargo usage खोजने की जरूरत नहीं; बस make या gmake टाइप कर दे। GNU-specific features नहीं इस्तेमाल करता और POSIX compliance की कोशिश करता हूँ, लेकिन यह भी सच है कि practically लगभग 100% make, gmake ही होता है
    समय की कसौटी पर खरे उतरे make को एक तरह के top-level build system driver की तरह इस्तेमाल करने का सुझाव शायद 250 साल बाद भी काम करेगा

    • इतना simple title flame war खड़ा कर गया, यह मजेदार है। लेख खुद make का बेहद simple use case है, और 2024 में gulp इस्तेमाल करने की बात है, लेकिन साफ है कि किसी ने पढ़ा ही नहीं
    • cargo खराब उदाहरण है। क्योंकि आम तौर पर cargo build ही इस्तेमाल होता है
      Make खुद शानदार है, लेकिन C projects में जिन ज्यादातर cases में मैंने काम किया, वे cmake/autotools और global package installs के combination थे, और ऐसी चीजें बार-बार lookup करनी पड़ती थीं
    • उससे पहले अगर bazel/blaze हावी हो गया तो शायद ऐसा न हो। शक हो तो Chrome बनाम Firefox, या Kubernetes बनाम docker-compose देख लें
  • यहाँ की भावना से सहमत हूँ, लेकिन कई चीजों को Justfile में फिर से लिख रहा हूँ
    https://github.com/casey/just
    Makefile की खास किस्म की कई अजीब चीजों से बचा जा सकता है

    • GPT ने Makefile लिखने में मदद करके Makefile को दूसरी जिंदगी दी है, और यह सच है कि उसकी मौत को देर से आने दिया
    • मैं भी यही। वही file Windows पर भी चलती है, यह bonus है
  • हाँ, Make शानदार है। मैं इसे सच में बहुत सारे कामों में इस्तेमाल करता हूँ। task automation के लिए अच्छा तरीका है
    उदाहरण के लिए, मेरी personal website में Makefile bash script call करके updated web pages फिर से बनाता है, server पर git push करता है, और फिर server का git hook Make को call करके deploy करता है। हालांकि lecture material PDFs जैसे अक्सर बदलने वाले binary blobs को मैं Git repository में नहीं रखना चाहता। कोई बात नहीं। Makefile में uploads target है जो सिर्फ modified PDFs को server पर upload करता है, और यह target git push करने वाले deploy target की dependency है, इसलिए मुझे इसकी चिंता नहीं करनी पड़ती
    साथ ही, lecture material के updated PDFs को एक दूसरा Makefile website source tree में automatically डाल देता है। उस Makefile से मैं LaTeX source से अपने इस्तेमाल की PDF बना सकता हूँ, या उसी source से students के लिए alternate version—जैसे exercise answers के बिना version—बना सकता हूँ, उसे local website version पर auto-publish कर सकता हूँ, और जब चाहूँ updated website पर upload कर सकता हूँ
    यह एक तरह की Makefiles की अंतहीन chain है। Makefile अच्छे हैं

  • इस case में लेखक को सच में make नहीं, just चाहिए
    https://just.systems/man/en/

    • just बस एक और dependency है। make हर जगह है
  • task runner के रूप में make बुरा नहीं है, लेकिन आजकल बाकी टिप्पणियों की तरह just जैसे बेहतर विकल्प मौजूद हैं
    build system के रूप में make तब तक ठीक है जब तक आप इसकी कमियों से नहीं टकराते। make/Makefile standardized नहीं हैं, इसलिए automake मौजूद है। इसलिए आप सीधे Makefile नहीं लिखते, बल्कि template इस्तेमाल करते हैं और असली makefile generate करवाते हैं। अगर आप पूरे tool chain के मालिक हैं तो कोई दिक्कत नहीं, लेकिन ज़्यादातर मामलों में ऐसा नहीं होता, इसलिए portable Makefile सुनिश्चित करने के लिए ऐसा किया जाता है
    make किसी भी तरह की dependency resolution नहीं कर पाता और मान लेता है कि जो चाहिए वह वहीं मौजूद है। इसलिए configure scripts आए, और configure scripts भी standard नहीं हैं, इसलिए make targets चलाने से पहले autoconf/autoreconf से configure script generate करवाई जाती है
    make और automake/autoconf/autoreconf जैसे आस-पास के tools यह तय करने के लिए mtime का इस्तेमाल करते हैं कि inputs पुराने हैं या नहीं। autoconf/autoreconf/automake/configure चलाने के बाद भी inputs स्थायी रूप से पुराने state में रह सकते हैं और आप ऐसी स्थिति में फँस सकते हैं जहाँ कुछ भी build नहीं हो पाता। संदर्भ के तौर पर, कई build systems में अगर dependency tracking सही हो तो mtime इस्तेमाल करना ठीक रहता है
    कुल मिलाकर make की मूल design flaw यह है कि यह Unix philosophy, यानी “एक काम करो और उसे अच्छी तरह करो” के हिसाब से बना है। वह एक काम है “अगर inputs पुराने हैं तो target को फिर से build करो”, लेकिन यह बहुत सीमित tool है, इसलिए modern build systems को इसे basic task runner से आगे उपयोगी बनाने के लिए इसके ऊपर बहुत सारा काम जोड़ना पड़ता है

    • make dependency resolution नहीं कर सकता?
      dependency:
      ...
      target: dependency
      ...
    • शायद यह अनजान सवाल हो, लेकिन dependency resolution ही make का core नहीं है? यहाँ ठीक-ठीक क्या मतलब है?
    • उस तरफ़ की पुरानी convention make configure है। यह make [build] के लिए ज़रूरी चीज़ें set up करता है
    • make में सच में जिस चीज़ की कमी खलती है, वह है mtime के अलावा किसी और आधार से mtime को interpret करने की क्षमता
      इसलिए touchfile इस्तेमाल करने पड़ते हैं; गंदा तो है, लेकिन कई दूसरी चीज़ों से अभी भी बेहतर चलता है। मैं खास तौर पर docker build caching की बात कर रहा हूँ