ഗ്നു മേക്കിനൊപ്പം ഓപ്പൺ സോഴ്uസ് സോഫ്റ്റ്uവെയർ ഡെവലപ്uമെന്റിലെ മേക്ക് ഫയലുകളിലേക്കുള്ള ഒരു ഹ്രസ്വ ആമുഖം


GNU Make എന്നത് ഒരു പ്രത്യേക കോഡ് ബേസിന്റെ ഭാഗങ്ങൾ നിർണ്ണയിക്കുകയും കോഡ് ബേസിൽ ആ പ്രവർത്തനങ്ങൾ നടത്താൻ കമാൻഡുകൾ നൽകുകയും ചെയ്യുന്ന ഒരു ഡവലപ്മെന്റ് യൂട്ടിലിറ്റിയാണ്. ഈ പ്രത്യേക make യൂട്ടിലിറ്റി ഏത് പ്രോഗ്രാമിംഗ് ഭാഷയിലും ഉപയോഗിക്കാവുന്നതാണ്, കമാൻഡുകൾ ഇഷ്യൂ ചെയ്യുന്നതിലൂടെ അവയുടെ സമാഹാരം ഷെല്ലിൽ നിന്ന് ചെയ്യാൻ കഴിയും.

ഗ്നു മേക്ക് ഉപയോഗിക്കുന്നതിന്, ഞങ്ങളുടെ പ്രോഗ്രാമിലെ വ്യത്യസ്uത ഫയലുകൾ തമ്മിലുള്ള ബന്ധം നിർവചിക്കുന്ന ചില നിയമങ്ങളും ഓരോ ഫയലും അപ്uഡേറ്റ് ചെയ്യുന്നതിനുള്ള കമാൻഡുകളും നമുക്ക് ഉണ്ടായിരിക്കണം. ഇവ എഴുതിയിരിക്കുന്നത് ‘makefile’ എന്ന പ്രത്യേക ഫയലിലാണ്. എല്ലാ ഫയലുകളും വീണ്ടും കംപൈൽ ചെയ്യണമെന്ന് തീരുമാനിക്കാൻ ‘make’ കമാൻഡ് ‘makefile’ ഡാറ്റാ ബേസും ഫയലുകളുടെ അവസാന പരിഷ്ക്കരണ സമയവും ഉപയോഗിക്കുന്നു.

ഒരു മേക്ക് ഫയലിന്റെ ഉള്ളടക്കം

സാധാരണയായി ‘makefiles’ ൽ 5 തരത്തിലുള്ള കാര്യങ്ങൾ അടങ്ങിയിരിക്കുന്നു: പരോക്ഷമായ നിയമങ്ങൾ, വ്യക്തമായ നിയമങ്ങൾ, വേരിയബിൾ നിർവചനങ്ങൾ, നിർദ്ദേശങ്ങൾ, അഭിപ്രായങ്ങൾ.

  1. ഒരു വ്യക്തമായ നിയമം ഒന്നോ അതിലധികമോ ഫയലുകൾ എങ്ങനെ നിർമ്മിക്കാം/റീമേക്ക് ചെയ്യാം (ലക്ഷ്യങ്ങൾ എന്ന് വിളിക്കപ്പെടുന്നു, പിന്നീട് വിശദീകരിക്കും) അത് എപ്പോൾ ചെയ്യണം എന്ന് വ്യക്തമാക്കുന്നു.
  2. ഒരു വ്യക്തമായ നിയമം അവയുടെ പേരുകൾ അടിസ്ഥാനമാക്കി ഒന്നോ അതിലധികമോ ഫയലുകൾ എങ്ങനെ നിർമ്മിക്കാം/റീമേക്ക് ചെയ്യാം എന്ന് വ്യക്തമാക്കുന്നു. ടാർഗെറ്റിന് സമാനമായ പേരുള്ള ഒരു ഫയലുമായി ടാർഗെറ്റ് ഫയലിന്റെ പേര് എങ്ങനെ ബന്ധപ്പെട്ടിരിക്കുന്നുവെന്ന് ഇത് വിവരിക്കുന്നു.
  3. ഒരു വേരിയബിൾ ഡെഫനിഷൻ എന്നത് ഒരു വേരിയബിളിന് പിന്നീട് പകരം വയ്ക്കാനുള്ള ഒരു സ്ട്രിംഗ് മൂല്യം വ്യക്തമാക്കുന്ന ഒരു വരിയാണ്.
  4. ഒരു നിർദ്ദേശം എന്നത് മേക്ക് ഫയൽ വായിക്കുമ്പോൾ പ്രത്യേകമായി എന്തെങ്കിലും ചെയ്യാനുള്ള നിർദ്ദേശമാണ്.
  5. ഒരു '#' ചിഹ്നം makefiles-ന്റെ ഉള്ളിൽ ഒരു കമൻറിന്റെ ആരംഭത്തെ പ്രതിനിധീകരിക്കുന്നു. ‘#’ എന്നതിൽ തുടങ്ങുന്ന ഒരു ലൈൻ അവഗണിക്കപ്പെട്ടിരിക്കുന്നു.

makefile എന്ന ഒരു ഡാറ്റാ ബേസ് വായിക്കുന്നതിൽ നിന്നാണ് ഒരു സിസ്റ്റം വീണ്ടും കംപൈൽ ചെയ്യുന്നതെങ്ങനെയെന്ന് make പറയുന്ന വിവരം ലഭിക്കുന്നു. ഒരു ലളിതമായ makefile ഇനിപ്പറയുന്ന വാക്യഘടനയുടെ നിയമങ്ങൾ ഉൾക്കൊള്ളുന്നു:

target ... : prerequisites ... 
	recipe 
... 
...

ഒരു ലക്ഷ്യം എന്നത് പ്രോഗ്രാം സൃഷ്ടിച്ച ഔട്ട്uപുട്ട് ഫയലാണ്. ഇത് ഫോണി ടാർഗെറ്റുകളും ആകാം, അത് ചുവടെ വിശദീകരിക്കും. ടാർഗെറ്റ് ഫയലുകളുടെ ഉദാഹരണങ്ങളിൽ എക്സിക്യൂട്ടബിളുകൾ, ഒബ്ജക്റ്റ് ഫയലുകൾ അല്ലെങ്കിൽ ക്ലീൻ, ഇൻസ്റ്റാൾ, അൺഇൻസ്റ്റാൾ തുടങ്ങിയ വ്യാജ ടാർഗെറ്റുകൾ ഉൾപ്പെടുന്നു.

ടാർഗെറ്റ് ഫയലുകൾ സൃഷ്ടിക്കുന്നതിനുള്ള ഇൻപുട്ടായി ഉപയോഗിക്കുന്ന ഒരു ഫയലാണ് മുൻകരുതൽ.

ഒരു പാചകക്കുറിപ്പ് എന്നത് മുൻവ്യവസ്ഥകളെ അടിസ്ഥാനമാക്കി ടാർഗെറ്റ് ഫയൽ സൃഷ്uടിക്കുന്നതിന് ഉണ്ടാക്കുന്ന പ്രവർത്തനമാണ്. റെസിപ്പിയുടെ പ്രിഫിക്uസായി മറ്റ് ചില പ്രതീകങ്ങളെ നിർവചിക്കുന്നതിന് ഞങ്ങൾ ‘.RECIPEPREFIX’ വേരിയബിൾ വ്യക്തമാക്കുന്നില്ലെങ്കിൽ makefiles-ന്റെ ഉള്ളിൽ ഓരോ പാചകക്കുറിപ്പിനും മുമ്പായി ടാബ് പ്രതീകം ഇടേണ്ടത് ആവശ്യമാണ്.

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f main.o end.o inter.o start.o

മുകളിലെ ഉദാഹരണത്തിൽ, എക്സിക്യൂട്ടബിൾ ഫൈനൽ സൃഷ്ടിക്കുന്നതിന് ഞങ്ങൾ 4 സി സോഴ്സ് ഫയലുകളും രണ്ട് ഹെഡ്ഡർ ഫയലുകളും ഉപയോഗിച്ചു. ഇവിടെ ഓരോ '.o' ഫയലും makefile-നുള്ളിൽ ഒരു ലക്ഷ്യവും മുൻവ്യവസ്ഥയുമാണ്. ഇപ്പോൾ അവസാന ടാർഗെറ്റ് നാമം ക്ലീൻ നോക്കുക. ഇത് ഒരു ടാർഗെറ്റ് ഫയൽ എന്നതിലുപരി ഒരു പ്രവർത്തനം മാത്രമാണ്.

സമാഹരിക്കുന്ന സമയത്ത് ഞങ്ങൾക്ക് സാധാരണയായി ഇത് ആവശ്യമില്ലാത്തതിനാൽ, മറ്റേതെങ്കിലും നിയമങ്ങളിൽ ഇത് ഒരു മുൻവ്യവസ്ഥയായി എഴുതിയിട്ടില്ല. ഫയലുകളെ പരാമർശിക്കാത്തതും എന്നാൽ പ്രവർത്തനങ്ങൾ മാത്രമുള്ളതുമായ ടാർഗെറ്റുകളെ വ്യാജ ടാർഗെറ്റുകൾ എന്ന് വിളിക്കുന്നു. മറ്റ് ടാർഗെറ്റ് ഫയലുകൾ പോലെ അവയ്ക്ക് മുൻവ്യവസ്ഥകളൊന്നും ഉണ്ടാകില്ല.

ഡിഫോൾട്ടായി make എന്നത് ‘makefile’ ലെ ആദ്യ ലക്ഷ്യത്തോടെ ആരംഭിക്കുന്നു, അതിനെ ‘default ലക്ഷ്യം’ എന്ന് വിളിക്കുന്നു. ഞങ്ങളുടെ ഉദാഹരണം പരിഗണിക്കുമ്പോൾ, ഞങ്ങളുടെ ആദ്യ ലക്ഷ്യം ഫൈനൽ ആണ്. അതിന്റെ മുൻവ്യവസ്ഥകളിൽ മറ്റ് ഒബ്uജക്റ്റ് ഫയലുകൾ ഉൾപ്പെടുന്നതിനാൽ ഫൈനൽ സൃഷ്uടിക്കുന്നതിന് മുമ്പ് അവ അപ്uഡേറ്റ് ചെയ്യണം. ഈ മുൻവ്യവസ്ഥകൾ ഓരോന്നും സ്വന്തം നിയമങ്ങൾക്കനുസൃതമായി പ്രോസസ്സ് ചെയ്യുന്നു.

സോഴ്സ് ഫയലുകളിലോ ഹെഡർ ഫയലുകളിലോ മാറ്റങ്ങൾ വരുത്തിയാലോ ഒബ്ജക്റ്റ് ഫയൽ നിലവിലില്ലെങ്കിലോ വീണ്ടും കംപൈലേഷൻ സംഭവിക്കുന്നു. ആവശ്യമായ ഒബ്uജക്uറ്റ് ഫയലുകൾ വീണ്ടും കംപൈൽ ചെയ്uത ശേഷം, ഫൈനൽ റീലിങ്ക് ചെയ്യണോ വേണ്ടയോ എന്ന് നിർമ്മാണം തീരുമാനിക്കുന്നു. ഫയൽ ഫൈനൽ നിലവിലില്ലെങ്കിലോ അല്ലെങ്കിൽ ഏതെങ്കിലും ഒബ്ജക്റ്റ് ഫയലുകൾ അതിലും പുതിയതാണെങ്കിൽ ഇത് ചെയ്യണം.

അതിനാൽ നമ്മൾ inter.c എന്ന ഫയൽ മാറ്റുകയാണെങ്കിൽ, make റൺ ചെയ്യുമ്പോൾ അത് ഒബ്uജക്റ്റ് ഫയൽ അപ്uഡേറ്റ് ചെയ്യുന്നതിനായി സോഴ്uസ് ഫയൽ വീണ്ടും കംപൈൽ ചെയ്യും inter.o ഒപ്പം തുടർന്ന് ഫൈനൽ ലിങ്ക് ചെയ്യുക.

ഞങ്ങളുടെ ഉദാഹരണത്തിൽ, താഴെ കാണിച്ചിരിക്കുന്നതുപോലെ ഫൈനൽ എന്ന റൂളിൽ എല്ലാ ഒബ്ജക്റ്റ് ഫയലുകളും രണ്ടുതവണ ലിസ്റ്റ് ചെയ്യേണ്ടതുണ്ട്.

final: main.o end.o inter.o start.o
	gcc -o final main.o end.o inter.o start.o

അത്തരം തനിപ്പകർപ്പുകൾ ഒഴിവാക്കാൻ, makefile-നുള്ളിൽ ഉപയോഗിക്കുന്ന ഒബ്uജക്റ്റ് ഫയലുകളുടെ ലിസ്റ്റ് സംഭരിക്കുന്നതിന് നമുക്ക് വേരിയബിളുകൾ അവതരിപ്പിക്കാം. OBJ എന്ന വേരിയബിൾ ഉപയോഗിച്ച് നമുക്ക് സാമ്പിൾ makefile താഴെ കാണിച്ചിരിക്കുന്ന സമാനമായ ഒന്നിലേക്ക് മാറ്റിയെഴുതാം.

OBJ = main.o end.o inter.o start.o
final: $(OBJ)
	gcc -o final $(OBJ)
main.o: main.c global.h
	gcc -c main.c
end.o: end.c local.h global.h
	gcc -c end.c
inter.o: inter.c global.h
	gcc -c inter.c
start.o: start.c global.h
	gcc -c start.c
clean:
	rm -f $(OBJ)

makefile എന്ന ഉദാഹരണത്തിൽ നമ്മൾ കണ്ടതുപോലെ, സമാഹരിച്ചതിന് ശേഷം ആവശ്യമില്ലാത്ത ഒബ്uജക്റ്റ് ഫയലുകൾ നീക്കം ചെയ്തുകൊണ്ട് ഉറവിട ഡയറക്ടറി വൃത്തിയാക്കുന്നതിനുള്ള നിയമങ്ങൾ നമുക്ക് നിർവചിക്കാം. നമുക്ക് ക്ലീൻ എന്ന ടാർഗെറ്റ് ഫയൽ ഉണ്ടെന്ന് കരുതുക. മേൽപ്പറഞ്ഞ രണ്ട് സാഹചര്യങ്ങളെയും എങ്ങനെ ഉണ്ടാക്കാം വേർതിരിക്കാം? ഇവിടെയാണ് വ്യാജ ലക്ഷ്യങ്ങൾ എന്ന ആശയം വരുന്നത്.

ഒരു വ്യാജ ടാർഗെറ്റ് എന്നത് യഥാർത്ഥത്തിൽ ഒരു ഫയലിന്റെ പേരല്ല, പകരം makefile-ൽ നിന്ന് വ്യക്തമായ ഒരു അഭ്യർത്ഥന നടത്തുമ്പോഴെല്ലാം അത് ഒരു പാചകക്കുറിപ്പിന്റെ പേര് മാത്രമാണ്. വ്യാജ ടാർഗെറ്റ് ഉപയോഗിക്കുന്നതിനുള്ള ഒരു പ്രധാന കാരണം അതേ പേരിലുള്ള ഒരു ഫയലുമായുള്ള വൈരുദ്ധ്യം ഒഴിവാക്കുക എന്നതാണ്. പ്രകടനം മെച്ചപ്പെടുത്തുക എന്നതാണ് മറ്റൊരു കാരണം.

ഈ കാര്യം വിശദീകരിക്കാൻ, ഞാൻ ഒരു അപ്രതീക്ഷിത ട്വിസ്റ്റ് വെളിപ്പെടുത്തും. ക്ലീൻ എന്നതിനായുള്ള പാചകക്കുറിപ്പ് നിർമ്മാണം പ്രവർത്തിപ്പിക്കുമ്പോൾ സ്ഥിരസ്ഥിതിയായി നടപ്പിലാക്കില്ല. പകരം, make clean എന്ന കമാൻഡ് നൽകി അത് അഭ്യർത്ഥിക്കേണ്ടതുണ്ട്.

.PHONY: clean
clean:
	rm -f $(OBJ)

ഇപ്പോൾ നിങ്ങളുടെ സ്വന്തം കോഡ് ബേസിനായി makefiles സൃഷ്ടിക്കാൻ ശ്രമിക്കുക. നിങ്ങളുടെ സംശയങ്ങൾ ഇവിടെ കമന്റ് ചെയ്യാൻ മടിക്കേണ്ടതില്ല.