makepp_functions - ອອນລາຍໃນຄລາວ

ນີ້ແມ່ນຄໍາສັ່ງ makepp_functions ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍໆບ່ອນເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator

ໂຄງການ:

NAME


makepp_functions -- ຟັງຊັນໃນ makepp

ລາຍລະອຽດ


A: absolute_filename,
absolute_filename_nolink,
abspath,
ຕື່ມຄຳນຳໜ້າ,
ສ່ວນຕື່ມ,
ແລະ, B: ຊື່ພື້ນຖານ, C: ໂທ, D: ແມ່ນ,
dir_noslash, E: ຄວາມ​ຜິດ​ພາດ​, F: ໄຟລ​໌​,
ການກັ່ນຕອງ,
filter_out,
filter_out_dirs,
ຊອກຫາໄຟລ໌,
find_first_upwards,
ໂປຣແກຣມຊອກຫາ,
ຊອກຫາສາຍ,
find_upwards,
first_available,
ຄໍາ​ທໍາ​ອິດ​,
foreach, I: ຖ້າ,
ແທ້ຈິງແລ້ວ,
infer_linker,
infer_objects,
ຂໍ້ມູນ, J: ເຂົ້າຮ່ວມ, M: ເຮັດ,
ແຜນທີ່,
ຜູ້ຜະລິດ,
ແຜນທີ່,
"mktemp", N: notdir, O: only_generated,
only_nontargets,
only_phony_targets,
only_stale,
only_targets,
ຫຼື,
ຕົ້ນ​ກໍາ​ເນີດ​, P: ຊ່ວຍ​ເຫຼືອ​,
perl,
phony,
ສ້າງ​ລ່ວງ​ຫນ້າ​,
ພິມ, R: ເສັ້ນທາງທີ່ແທ້ຈິງ,
relative_filename,
relative_to, S: ຫອຍ,
ຈັດລຽງ,
ລອກ,
ຍ່ອຍ,
ຕໍ່ທ້າຍ, T: ຊົ່ວຄາວ, W: ຄຳ ເຕືອນ,
ຕົວແທນ,
ຄໍາ,
ບັນ​ຊີ​ລາຍ​ຊື່​ຄໍາ​ສັບ​ຕ່າງໆ​,
ຄໍາສັບຕ່າງ, X: xargs

ການສະແດງອອກຂອງຮູບແບບ "$(name)", ບ່ອນທີ່ "ຊື່" ບໍ່ແມ່ນຊື່ຂອງຕົວແປ, ຫຼື
"$(name arg1 arg2 arg3)" ຖືກຕີຄວາມໝາຍວ່າເປັນການເອີ້ນຟັງຊັນ. ຊື່ອາດມີຕົວອັກສອນ,
underscores, ຫຼື hyphens; ເພື່ອຫຼີກເວັ້ນການສັບສົນ, ທ່ານສາມາດໃຊ້ hyphens ຫຼື underscores
ແລກປ່ຽນກັນໄດ້, ເນື່ອງຈາກການຍັບຍັ້ງພາຍໃນຖືກປ່ຽນເປັນຂີດກ້ອງ. ການປະເມີນດັ່ງກ່າວ
ການສະແດງອອກພຽງແຕ່ເອີ້ນໃຊ້ເປັນປະຈຳຍ່ອຍ Perl. ຖ້າ "ຊື່" ຖືກນໍາຫນ້າດ້ວຍ "&" ມັນດໍາເນີນການ
ຄໍາສັ່ງ builtin ຫຼື script ຂອງຊື່ນັ້ນພາຍໃນຂະບວນການ makepp, ແລະສົ່ງຄືນມາດຕະຖານ
ຜົນຜະລິດ. ນີ້ຮຽກຮ້ອງໃຫ້ມີການສ້າງ perl ສໍາລັບ PerlIO. ຖ້າຊື່ບໍ່ຕັ້ງຊື່ຟັງຊັນ
ມັນ​ໄດ້​ຖືກ​ຫັນ​ເປັນ​ການ​ຮຽກ​ຮ້ອງ​ຂອງ​ການ​ໂທ​.

ເຊັ່ນດຽວກັນກັບຕົວແປທີ່ທ່ານເລືອກ "$(name ...)" ຫຼື "${name ...}". ຖ້າທ່ານຕ້ອງການ
ຝັງວົງເລັບດຽວກັນ, ມັນຕ້ອງຖືກຈັບຄູ່, ອັນອື່ນບໍ່ສໍາຄັນ: "$(ຊື່
...(){..." ຫຼື "${name ...{}(...}".
ການສະແດງອອກ.) double ອະນຸຍາດໃຫ້ການໂຕ້ຖຽງທີ່ຈະ span ຫຼາຍເສັ້ນ. ແຖວໃໝ່ແມ່ນ
ຫຼັງຈາກນັ້ນຖືກປະຕິບັດເປັນຊ່ອງຫວ່າງ, ຍົກເວັ້ນບາງທີໃນ "ກໍານົດ". ນອກນັ້ນຍັງມີ syntax "$[name ...]"
ຫຼື $[[name ...]], ເຊິ່ງໄດ້ຮັບການປະເມີນໃນຂະນະທີ່ອ່ານ makefile, ກ່ອນກົດລະບຽບ grokking
ແລະການກໍ່ສ້າງອື່ນໆ.

Makepp ມີຫຼາຍໆຟັງຊັນ builtin ເຊິ່ງອາດຈະເປັນປະໂຫຍດ. ມັນສະຫນັບສະຫນູນເກືອບທັງຫມົດຂອງ
GNU make's textual functions (ເບິ່ງ GNU make's documentation for details), ແລະບາງສ່ວນຂອງມັນ
ຂອງຕົນເອງ. ທ່ານສາມາດກໍານົດ Perl subroutines ເພື່ອເຮັດສິ່ງທີ່ທ່ານຕ້ອງການ. ເບິ່ງຄໍາຖະແຫຼງການ "ຍ່ອຍ".
ແລະພາກສ່ວນກ່ຽວກັບການຂະຫຍາຍ makepp ສໍາລັບລາຍລະອຽດເພີ່ມເຕີມ.

ເງື່ອນໄຂ ຫນ້າທີ່
ແລະ condition1[,condition2[,condition3...]]
ແລະຟັງຊັນສະຫນອງ "ວົງຈອນສັ້ນ" ແລະການດໍາເນີນງານ. ການໂຕ້ຖຽງແຕ່ລະຄົນແມ່ນ
ຂະຫຍາຍ, ໃນຄໍາສັ່ງ. ຖ້າອາກິວເມັນຂະຫຍາຍໄປເປັນສະຕຣິງຫວ່າງເປົ່າ ການປະມວນຜົນຈະຢຸດ ແລະ
ຜົນຂອງການຂະຫຍາຍແມ່ນສາຍທີ່ຫວ່າງເປົ່າ. ຖ້າການໂຕ້ຖຽງທັງຫມົດຂະຫຍາຍໄປສູ່ການບໍ່ເປັນ.
string ຫວ່າງເປົ່າຫຼັງຈາກນັ້ນຜົນໄດ້ຮັບຂອງການຂະຫຍາຍແມ່ນການຂະຫຍາຍຕົວຂອງການໂຕ້ຖຽງສຸດທ້າຍ.

if ສາຍ, result-if-string-not-blank[, result-if-string-blank]
iftrue ສາຍ, result-if-string-true[, result-if-string-false]
ທາງເລືອກສໍາລັບ "ifeq", ແລະອື່ນໆ, ຄໍາຖະແຫຼງການ. ຖ້າສະຕຣິງບໍ່ຫວ່າງເປົ່າ (ie, the
ເງື່ອນໄຂແມ່ນຄວາມຈິງ), ການໂຕ້ຖຽງທີສອງ (ປະໂຫຍກ "ຫຼັງຈາກນັ້ນ") ຖືກສົ່ງຄືນ (ຫຼັງຈາກ
ການຂະຫຍາຍຕົວແປ); ຖ້າສະຕຣິງຫວ່າງເປົ່າ, ການໂຕ້ຖຽງທີສາມ (ຂໍ້ "ອື່ນ") ແມ່ນ
ກັບຄືນມາ.

ຍົກ​ຕົວ​ຢ່າງ,

CFLAGS := $(ຖ້າ $(ການກັ່ນຕອງ gcc egcc, $(CC)), -g -Wall, -g)

ກຳນົດ CFLAGS ເປັນ "-g -Wall" ຖ້າຕົວແປ CC ແມ່ນ "gcc" ຫຼື "egcc", ແລະ "-g"
ຖ້າບໍ່ດັ່ງນັ້ນ. (ນີ້ແມ່ນສິ່ງທີ່ກົດລະບຽບການກໍ່ສ້າງເລີ່ມຕົ້ນເຮັດ.)

"iftrue" ແມ່ນຄ້າຍຄືກັນກັບ "ຖ້າ", ຍົກເວັ້ນວ່າ string 0 ຖືກປະຕິບັດເປັນຫວ່າງເປົ່າ.

or condition1[,condition2[,condition3...]]
ຫຼືຟັງຊັນສະຫນອງການດໍາເນີນການ OR "ວົງຈອນສັ້ນ". ແຕ່ລະການໂຕ້ຖຽງແມ່ນຂະຫຍາຍ,
ໃນຄໍາສັ່ງ. ຖ້າອາກິວເມັນຂະຫຍາຍໄປສູ່ສະຕຣິງທີ່ບໍ່ຫວ່າງເປົ່າ ການປະມວນຜົນຈະຢຸດ ແລະ
ຜົນຂອງການຂະຫຍາຍແມ່ນສາຍນັ້ນ. ຖ້າຫາກວ່າ, ຫຼັງຈາກການໂຕ້ຖຽງທັງຫມົດໄດ້ຖືກຂະຫຍາຍ, ທັງຫມົດຂອງ
ພວກເຂົາແມ່ນບໍ່ຖືກຕ້ອງ (ຫວ່າງເປົ່າ), ຫຼັງຈາກນັ້ນຜົນຂອງການຂະຫຍາຍແມ່ນສາຍທີ່ຫວ່າງເປົ່າ.

ເອກະສານ ແລະ filename ຫນ້າທີ່
absolute_filename ໄຟ
abspath ໄຟ
ປ່ຽນຊື່ໄຟລ໌ທີ່ກ່ຽວຂ້ອງເປັນຢ່າງແທ້ຈິງໂດຍບໍ່ມີ . or ..ທີ່ຢູ່ ຍົກ​ຕົວ​ຢ່າງ,
"$(absolute_filename xyz.c)" ອາດຈະສົ່ງຄືນ "/usr/src/our_project/subdir/xyz.c".

absolute_filename_nolink ໄຟ
ເສັ້ນທາງທີ່ແທ້ຈິງ ໄຟ
ເຊັ່ນດຽວກັນກັບ absolute_filename, ແຕ່ຮັບປະກັນວ່າການເຊື່ອມຕໍ່ສັນຍາລັກໄດ້ຖືກແກ້ໄຂ.

ຊື່ພື້ນຖານ ຊື່ໄຟລ໌
ຊື່ພື້ນຖານແມ່ນຊື່ໄຟລ໌ທັງຫມົດ (ກັບໄດເລກະທໍລີ), ລົບຂໍ້ຄວາມຫຼັງຈາກແລະ
ລວມທັງໄລຍະເວລາສຸດທ້າຍ. ຕົວຢ່າງ, "$(basename myfile/version-1.0-module.c)" ແມ່ນ
"myfile/version-1.0-module"

dir ຊື່ໄຟລ໌
ແຍກສ່ວນໄດເລກະທໍລີຂອງແຕ່ລະໄຟລ໌ໃນລາຍຊື່ໄຟລ໌, ລວມທັງການຕໍ່ທ້າຍ
ທັບ. ຕອບ "./" ຖ້າບໍ່ມີໄດເຣັກທໍຣີໃນຊື່ໄຟລ໌.

dir_noslash ຊື່​ເອ​ກະ​ສານ
ຄືກັນກັບ "$(dir )" ຍົກເວັ້ນວ່າມັນບໍ່ໄດ້ສົ່ງຄ່າຫຍໍ້ໜ້າຕາມຫຼັງ.

ໄຟລ໌ຍ່ອຍ ຮູບແບບ, ແທນ, ຄໍາເວົ້າ
ດໍາເນີນການປ່ຽນຮູບແບບໃນຊື່ໄຟລ໌. ນີ້ແຕກຕ່າງຈາກ pasubst ໃນນັ້ນ
ມັນຈະປະຕິບັດຢ່າງຖືກຕ້ອງເມື່ອຊື່ສະຫຼັບສໍາລັບໄດເລກະທໍລີຖືກມອບໃຫ້ (ຕາບໃດທີ່
ພວກ​ເຂົາ​ເຈົ້າ​ກ່ອນ​ຫນ້າ​ອັດ​ຕາ​ສ່ວນ). ຍົກ​ຕົວ​ຢ່າງ,

$(filesubst ./src/%.c, %.o, $(wildcard src/*.c))

ຈະເຮັດວຽກກັບ filesubst ແຕ່ບໍ່ແມ່ນກັບ pasubst.

filter_out_dirs ຊື່ໄຟລ໌
ສົ່ງຄືນຊື່ໄຟລ໌ທັງໝົດທີ່ບໍ່ອ້າງອີງໃສ່ໄດເລກະທໍລີ.

ຊອກຫາໄຟລ໌ ຊື່​ເອ​ກະ​ສານ, ເສັ້ນທາງ
ຊອກຫາໄຟລ໌ໃນເສັ້ນທາງທີ່ລະບຸ, ຫຼືຢູ່ໃນສະພາບແວດລ້ອມທີ່ປ່ຽນແປງໄດ້ PATH ຖ້າບໍ່ມີຫຍັງເປັນ
ລະບຸ. ນີ້ສາມາດເປັນປະໂຫຍດສໍາລັບການຊອກຫາຖານສອງຫຼືປະກອບມີໄຟລ໌. ຍົກ​ຕົວ​ຢ່າງ,

TCL_INCLUDE := -I$(dir_noslash $(findfile tcl.h,
/usr/local/stow/tcl-8.4.5-nothread/include
/usr/include/tcl8.4 /usr/include/tcl
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))

ອັນນີ້ຊອກຫາໄຟລ໌ tcl.h ໂດຍການຊອກຫາລາຍຊື່ຂ້າງເທິງທັງໝົດ. ຢ່າງແທ້ຈິງ
ເສັ້ນທາງໄປຫາໄຟລ໌ຖືກສົ່ງຄືນ. ຫຼັງຈາກນັ້ນ, "$(dir_noslash )" ສະກັດໄດເລກະທໍລີນັ້ນ, ແລະມັນ
ຖືກໃສ່ເຂົ້າໄປໃນເສັ້ນທາງລວມ.

find_program ຊື່
ກັບຄືນໂຄງການທໍາອິດໃນບັນຊີລາຍຊື່ທີ່ສາມາດພົບເຫັນຢູ່ໃນ PATH. ນີ້ແມ່ນເປັນປະໂຫຍດ
ໃນເວລາທີ່ມີຫຼາຍໂຄງການທຽບເທົ່າທີ່ອາດຈະຖືກນໍາໃຊ້, ແລະທ່ານພຽງແຕ່ຕ້ອງການ
ເລືອກຫນຶ່ງຂອງພວກເຂົາ. ຕົວຢ່າງ, ນີ້ແມ່ນຄໍານິຍາມເລີ່ມຕົ້ນຂອງຫຼາຍທົ່ວໄປ
ຕົວແປທີ່ makepp ສະຫນອງຖ້າທ່ານບໍ່ໃສ່ຫນຶ່ງໃນ makefile ຂອງທ່ານ:

CC = $(find_program gcc egcc pgcc c89 cc) # ແລະອື່ນໆອີກ, ຂຶ້ນກັບເຄື່ອງ.
F77 = $(find_program f77 g77 fort77)
CXX = $(find_program g++ c++ pg++ cxx CC aCC)

ຖ້າບໍ່ມີໂປຣແກຣມໃດຖືກພົບເຫັນ, "$(find_program)" ຈະສົ່ງຄືນສະຕຣິງທີ່ບໍ່ພົບ, ແລະ.
ບັນທຶກສິ່ງທີ່ບໍ່ພົບ. ນີ້ປົກກະຕິແລ້ວຈະບໍ່ສົ່ງຜົນໃຫ້ makefile ທີ່ເປັນປະໂຫຍດ, ແຕ່ມັນ
ມີແນວໂນ້ມທີ່ຈະເຮັດໃຫ້ຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດທີ່ດີກວ່າ. ຕົວຢ່າງ, ຖ້າທ່ານເຮັດບາງສິ່ງບາງຢ່າງເຊັ່ນ:
ນີ້:

%.o : %.c
$(CC) $(inputs) -o $(outputs)

ແລະ makepp ບໍ່ສາມາດຊອກຫາ C compiler ໃນບັນຊີລາຍຊື່ຂ້າງເທິງ, ມັນຈະທົດແທນທີ່ບໍ່ພົບ.
ຖ້າບໍ່ດັ່ງນັ້ນ shell ຈະພະຍາຍາມປະຕິບັດໄຟລ໌ຕົ້ນສະບັບແລະຄວາມຜິດພາດທີ່ເກີດຂື້ນ
ຂໍ້ຄວາມອາດຈະແປກແທ້ໆ.

find_upwards ຊື່​ເອ​ກະ​ສານ
ຄົ້ນ​ຫາ​ໄຟລ​໌​ຂອງ​ຊື່​ທີ່​ໄດ້​ຮັບ​ໃນ​ລະ​ບົບ .,.., ../ ..,../../.., ແລະອື່ນໆ,
ຈົນ​ກ​່​ວາ​ໄຟລ​໌​ໄດ້​ຖືກ​ພົບ​ເຫັນ​ຫຼື​ລະ​ບົບ​ຮາກ​ແມ່ນ​ໄປ​ເຖິງ​ຫຼື​ລະ​ບົບ​ທີ່​ຕັ້ງ​ຢູ່​
ໃນລະບົບໄຟລ໌ທີ່ແຕກຕ່າງກັນ. (ຂໍ້ກໍານົດສຸດທ້າຍນີ້ແມ່ນເພື່ອປ້ອງກັນບັນຫາກັບ
automounters ຫຼື hung network filesystems.) ຖ້າເຈົ້າມີ a RootMakeppfile, ນັ້ນກໍ່ແມ່ນ
ສິ່ງກີດຂວາງທີ່ປ້ອງກັນການຊອກຫາທີ່ສູງຂຶ້ນ.

ຕົວຢ່າງ, ຖ້າທ່ານມີໂຄງການທີ່ມີຫຼາຍລະດັບຂອງ subdirectories, ທ່ານສາມາດເຮັດໄດ້
ລວມເອົາຊິ້ນສ່ວນທົ່ວໄປນີ້ຢູ່ໃນທັງຫມົດຂອງ makefiles (ເຊັ່ນ: ໂດຍໃຊ້ "ລວມ"
ຖະແຫຼງການ):

TOP_LEVEL_INCLUDE_DIR := $(find_upwards ລວມມີ)
# ຄົ້ນຫາໄດເລກະທໍລີທີ່ປະກອບດ້ວຍ
# ປະກອບມີໄດເລກະທໍລີຍ່ອຍ.

%.o : %.c
$(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(input) -o $(output)

ບັນຫາອີກອັນຫນຶ່ງທີ່ "find_upwards" ສາມາດຊ່ວຍແກ້ໄຂໄດ້ແມ່ນການຊອກຫາລາຍຊື່ລະດັບສູງສຸດ
ຂອງການກໍ່ສ້າງ. ເລື້ອຍໆມັນເປັນປະໂຫຍດທີ່ຈະກໍານົດຕົວແປເຊັ່ນນີ້:

ເທິງ :=../../..

ຖ້າທ່ານມີບາງຂໍ້ມູນທີ່ສໍາຄັນທີ່ຕັ້ງຢູ່ໃນໄດເລກະທໍລີລະດັບສູງສຸດເທົ່ານັ້ນ. ແຕ່
ນີ້ແມ່ນຍາກທີ່ຈະຮັກສາ, ເພາະວ່າຈໍານວນຂອງ ".." ແມ່ນແຕກຕ່າງກັນສໍາລັບລະດັບທີ່ແຕກຕ່າງກັນ
ຂອງຕົ້ນໄມ້ໄດເລກະທໍລີ. ແທນທີ່ຈະ, ທ່ານສາມາດນໍາໃຊ້ "find_upwards" ເພື່ອຊອກຫາໄຟລ໌ທີ່ເປັນ
ເປັນທີ່ຮູ້ກັນວ່າມີຢູ່ໃນໄດເລກະທໍລີລະດັບສູງສຸດເທົ່ານັ້ນ. ຍົກ​ຕົວ​ຢ່າງ, ວ່າ
ໄຟລ໌ "ໃບອະນຸຍາດ" ຕັ້ງຢູ່ໃນໄດເລກະທໍລີລະດັບສູງສຸດເທົ່ານັ້ນ. ຫຼັງຈາກນັ້ນ, ທ່ານສາມາດເຮັດສິ່ງນີ້:

ເທິງ := $(dir_noslash $(find_upwards LICENSE))

"$(find_upwards LICENSE)" ສົ່ງຄືນເສັ້ນທາງເຕັມຂອງໄຟລ໌ໃບອະນຸຍາດ;
"$(dir_noslash ...)" ຖອດຊື່ໄຟລ໌ອອກ, ສົ່ງຄືນພຽງແຕ່ໄດເລກະທໍລີ.

(ໃຫ້ສັງເກດວ່າຄໍາຖະແຫຼງທີ່ "ລວມ" ອັດຕະໂນມັດຊອກຫາໄຟລ໌ຂ້າງເທິງ, ດັ່ງນັ້ນຢູ່ທີ່ນັ້ນ
ບໍ່ຈໍາເປັນຕ້ອງເຮັດບາງສິ່ງບາງຢ່າງເຊັ່ນນີ້:

ລວມເອົາ $(find_upwards top_level_rules.mk)

ແທນທີ່ຈະ, ທ່ານພຽງແຕ່ສາມາດເຮັດໄດ້

ລວມເຖິງ top_level_rules.mk

ແລະມັນຈະເຮັດວຽກເຊັ່ນດຽວກັນ.)

ຖ້າບໍ່ພົບໄຟລ໌, "find_upwards" ຈະຍົກເລີກການກໍ່ສ້າງດ້ວຍຂໍ້ຄວາມສະແດງຂໍ້ຜິດພາດ.

ຖ້າທ່ານລະບຸຫຼາຍກວ່າຫນຶ່ງໄຟລ໌, find_upwards ຈະຄົ້ນຫາອັນທໍາອິດ, ຫຼັງຈາກນັ້ນ
ອັນທີສອງ, ແລະອື່ນໆ. ໃນຄໍາສັບຕ່າງໆອື່ນໆ,

$(find_upwards file1 file2)

ເທົ່າກັບ

$(find_upwards file1) $(find_upwards file2)

ຖ້າທ່ານຕ້ອງການຊອກຫາໄຟລ໌ໃດນຶ່ງ, ໃຫ້ໃຊ້ "find_first_upwards" ແທນ.

find_first_upwards ແຟ້ມ 1 ແຟ້ມ 2 ...
ຟັງຊັນນີ້ປະຕິບັດຄືກັບ "find_upwards" ຍົກເວັ້ນວ່າມັນຈະສົ່ງຄືນໄຟລ໌ທໍາອິດຂອງໃດໆ
ໄຟລ໌ໃນບັນຊີລາຍຊື່ທີ່ມັນພົບ. ໂດຍສະເພາະ, ມັນກວດເບິ່ງໄດເລກະທໍລີປະຈຸບັນສໍາລັບ
ໄຟລ໌ໃດນຶ່ງໃນລາຍຊື່, ແລະສົ່ງຄືນໄຟລ໌ທໍາອິດທີ່ມີຢູ່ ຫຼືສາມາດສ້າງໄດ້.
ຖ້າບໍ່ມີໄຟລ໌ໃດໆຫຼືສາມາດສ້າງຢູ່ໃນໄດເລກະທໍລີນັ້ນ, ມັນຈະກວດເບິ່ງ .., ຫຼັງຈາກນັ້ນ
../ .., ແລະອື່ນໆ, ຈົນກ່ວາມັນໄປຮອດໄດເລກະທໍລີຮາກຫຼືໄດເລກະທໍລີທີ່ເປັນ
ຕັ້ງຢູ່ໃນລະບົບໄຟລ໌ທີ່ແຕກຕ່າງກັນ.

first_available ແຟ້ມ 1 ແຟ້ມ 2 ...
ສົ່ງຄືນໄຟລ໌ທໍາອິດໃນບັນຊີລາຍຊື່ທີ່ມີຢູ່ຫຼືສາມາດສ້າງໄດ້. ນີ້ສາມາດເປັນປະໂຫຍດສໍາລັບ
ປັບ makefiles ຂອງທ່ານເພື່ອເຮັດວຽກຢູ່ໃນເຄື່ອງຈັກທີ່ແຕກຕ່າງກັນຫຼາຍຫຼືເຄືອຂ່າຍ, ບ່ອນທີ່
ໄຟລ໌ທີ່ສໍາຄັນອາດຈະຢູ່ໃນສະຖານທີ່ຕ່າງໆ. ຕົວຢ່າງ, ນີ້ແມ່ນເສັ້ນຈາກ
ຫນຶ່ງໃນ makefiles ຂອງຂ້ອຍ:

TCL_LIB = $(first_available
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so
/net/na1/tcl8.4a3/lib/libtcl8.4.a
/net/na1/tcl8.4a3/lib/libtcl8.4.sl)

ເສັ້ນນີ້ຈະກວດເບິ່ງຫ້ອງສະຫມຸດ Tcl ໃນສະຖານທີ່ຂ້າງເທິງ, ຢຸດຢູ່ທີ່
ອັນທໍາອິດທີ່ມັນພົບ. ຄໍາສັ່ງເຊື່ອມຕໍ່ຫຼັງຈາກນັ້ນປະກອບມີ $(TCL_LIB) ດັ່ງນັ້ນພວກເຮົາໄດ້ຮັບ
ຫ້ອງສະຫມຸດ Tcl ທີ່ເຫມາະສົມ.

infer_linker ແຟ້ມ 1 ແຟ້ມ 2 ...
ໃຫ້ບັນຊີລາຍຊື່ຂອງໄຟລ໌ວັດຖຸທໍາອິດສ້າງໃຫ້ເຂົາເຈົ້າຖ້າຫາກວ່າພວກເຂົາເຈົ້າຍັງບໍ່ທັນໄດ້. ຫຼັງຈາກນັ້ນຊອກຫາ
ບໍ່ວ່າຈະຂຶ້ນກັບ Fortran, C ++ ຫຼືແຫຼ່ງ C ແລະສົ່ງຄືນຂໍ້ມູນທີ່ສອດຄ້ອງກັນ
compiler (ເຊິ່ງດີກວ່າຮູ້ວິທີການເຊື່ອມຕໍ່ກ່ວາ "ld").

infer_objects ແຟ້ມ 1 ແຟ້ມ 2 ..., ຮູບແບບ
$(infer_objects object1.o object2.o, *.o)

ຖ້າທ່ານໃຊ້ສົນທິສັນຍາມາດຕະຖານກ່ຽວກັບຊື່ໄຟລ໌ header, makepp ມີຄວາມສາມາດ
ການຄາດເດົາວ່າໄຟລ໌ ".o" ຫຼື ".lo" ຕ້ອງການເຊື່ອມໂຍງກັບໂປຼແກຼມຂອງທ່ານ. ຂ້ອຍໃຊ້ສິ່ງນີ້ເພື່ອ
ເລືອກໄຟລ໌ຈາກໄດເລກະທໍລີຫ້ອງສະຫມຸດທີ່ມີໂມດູນທີ່ໃຊ້ໃນຫຼາຍອັນ
ໂຄງການ. ແທນທີ່ຈະເຮັດໃຫ້ຫ້ອງສະຫມຸດ ".a" ໄຟລ໌ແລະມີຕົວເຊື່ອມຕໍ່ເລືອກເອົາອອກ
ໂມດູນທີ່ກ່ຽວຂ້ອງ, makepp ສາມາດເລືອກເອົາໂມດູນທີ່ກ່ຽວຂ້ອງສໍາລັບທ່ານ. ດ້ວຍວິທີນີ້, ເທົ່ານັ້ນ
ໂມດູນທີ່ກ່ຽວຂ້ອງໄດ້ຮັບການລວບລວມ.

ສູດການຄິດໄລ່ຂອງ Makepp ສໍາລັບ inferring object dependencies ແມ່ນຂຶ້ນກັບສົນທິສັນຍາວ່າ
ການ​ປະ​ຕິ​ບັດ​ຂອງ​ທຸກ​ຊັ້ນ​ຮຽນ​ຫຼື​ຫນ້າ​ທີ່​ກໍາ​ນົດ​ໄວ້​ໃນ​ໄຟລ​໌​ຫົວ "xyz.h​" ແມ່ນ​
ລວບລວມເຂົ້າໄປໃນໄຟລ໌ວັດຖຸທີ່ເອີ້ນວ່າ "xyz.o" (ຫຼື "xyz.lo"). ດັ່ງນັ້ນ algorithm ຂອງ makepp ສໍາລັບ
inferring object dependencies ເລີ່ມຕົ້ນດ້ວຍວັດຖຸອັນໜຶ່ງ ຫຼືສອງສາມອັນທີ່ພວກເຮົາຮູ້ວ່າຕ້ອງມີ
ເຊື່ອມ​ຕໍ່​ກັບ​ໂຄງ​ການ​. ມັນເບິ່ງວ່າໄຟລ໌ໃດໄດ້ຖືກລວມເຂົ້າກັບ "#include" ໃນ
ແຫຼ່ງຂໍ້ມູນເຫຼົ່ານັ້ນ, ແລະພະຍາຍາມຊອກຫາໄຟລ໌ວັດຖຸທີ່ສອດຄ້ອງກັນສໍາລັບແຕ່ລະປະກອບມີ
ໄຟລ໌.

"$(infer_objects )" ຈໍາເປັນຕ້ອງໄດ້ກ່າວເຖິງໃນບັນຊີລາຍຊື່ການເພິ່ງພາອາໄສຂອງໂຄງການ, ເຊັ່ນ
ນີ້:

myprog: $(infer_objects main.o another_object.o,
**/*.o /other/library/dirs/**/*.o)
$(CXX) $(inputs) -o $(output) $(LIBS)

ຟັງຊັນ "$(infer_objects)" ໃຊ້ສອງອາກິວເມັນ (ຂັ້ນດ້ວຍເຄື່ອງໝາຍຈຸດ, ດັ່ງທີ່ສະແດງ).
ທໍາອິດແມ່ນໄຟລ໌ວັດຖຸຫນຶ່ງຫຼືຈໍານວນຫນ້ອຍທີ່ຮູ້ວ່າຕ້ອງການ (ຕົວແທນແມ່ນ
ອະນຸຍາດຢູ່ທີ່ນີ້). ອັນທີສອງແມ່ນບັນຊີລາຍຊື່ຂອງວັດຖຸທີ່ເປັນໄປໄດ້ (ປົກກະຕິທ່ານຈະໃຊ້ a
wildcard here) ທີ່ສາມາດເຊື່ອມຕໍ່ໄດ້ຖ້າຈໍາເປັນ. ມູນຄ່າກັບຄືນຈາກນີ້
function ແມ່ນບັນຊີລາຍຊື່ທີ່ປະກອບດ້ວຍວັດຖຸທໍາອິດທັງຫມົດໃນ argument ທໍາອິດ, ແລະ
ຫຼັງຈາກນັ້ນ, ຫຼັງຈາກນັ້ນ, ວັດຖຸເພີ່ມເຕີມທັງຫມົດທີ່ບັນຈຸຢູ່ໃນການໂຕ້ຖຽງທີສອງ
ທີ່ຕ້ອງການໂດຍວັດຖຸໃນການໂຕ້ຖຽງທໍາອິດ.

ຕົວຢ່າງ, ສົມມຸດວ່າ "main.o" ມາຈາກ "main.cpp", ເຊິ່ງປະກອບມີ "my_class.h".
"$(infer_objects)" ຊອກຫາໄຟລ໌ທີ່ມີຊື່ "my_class.o". ຖ້າແທ້ຫນຶ່ງເຊັ່ນ
ໄຟລ໌ຖືກພົບເຫັນ, ມັນຖືກເພີ່ມເຂົ້າໃນບັນຊີລາຍຊື່. (ຖ້າພົບສອງໄຟລ໌ວັດຖຸ "my_class.o" ຖືກພົບເຫັນ
ໃນໄດເລກະທໍລີທີ່ແຕກຕ່າງກັນ, ຂໍ້ຄວາມເຕືອນຈະຖືກພິມອອກ.) "infer_objects" ຍັງ
ກວດເບິ່ງ "my_class.cpp" ເພື່ອເບິ່ງວ່າມັນປະກອບມີຫຍັງແດ່, ແລະໄຟລ໌ວັດຖຸເພີ່ມເຕີມແມ່ນຫຍັງ
ບົ່ງບອກ.

mktemp
mktemp ຄຳ ນຳ ໜ້າ
mktemp ຄຳ ນຳ ໜ້າXXX
mktemp /
ສົ່ງຄືນຊື່ໄຟລ໌ຊົ່ວຄາວທີ່ບໍ່ສາມາດຄາດເດົາໄດ້, ເຊິ່ງບໍ່ມີຢູ່ໃນປັດຈຸບັນ. ບໍ່​ມີ​ຊື່
ການຊີ້ໄປຫາໄຟລ໌ດຽວກັນຖືກສົ່ງຄືນສອງຄັ້ງ, ເຖິງແມ່ນວ່າມີເສັ້ນທາງທີ່ກ່ຽວຂ້ອງທີ່ແຕກຕ່າງກັນ,
ພາຍ​ໃນ​ການ​ດໍາ​ເນີນ​ການ makepp (ຍົກ​ເວັ້ນ​ບາງ​ຢ່າງ​ທີ່​ເປັນ​ໄປ​ໄດ້​ກັບ recursive ເຮັດ​ໃຫ້​ພື້ນ​ເມືອງ​, ຫຼື​ຖ້າ​ຫາກ​ວ່າ Perl​
ລະ​ຫັດ​ທີ່​ແລ່ນ​ຢູ່​ພາຍ​ໃນ​ການ​ປະ​ຕິ​ບັດ​ກົດ​ລະ​ບຽບ​ເອີ້ນ​ວ່າ "f_mktemp​"​)​. ໃນຕອນທ້າຍຂອງ makepp ດໍາເນີນການທັງຫມົດ
ໄຟລ​໌​ທີ່​ສົ່ງ​ຄືນ​ໂດຍ​ການ​ທໍາ​ງານ​ນີ້​ຈະ​ຖືກ​ລົບ​, ຖ້າ​ຫາກ​ວ່າ​ພວກ​ເຂົາ​ເຈົ້າ​ມີ (ອີກ​ເທື່ອ​ຫນຶ່ງ​ຍົກ​ເວັ້ນ​ສໍາ​ລັບ​ການ​ເຫຼົ່າ​ນີ້​
ສົ່ງຄືນໂດຍຟັງຊັນນີ້ໃນລະຫັດ Perl ທີ່ເຮັດວຽກຢູ່ໃນກົດລະບຽບ).

ຕົວເລກຂອງຕົວພິມໃຫຍ່ "X" ໃນຕອນທ້າຍຂອງການໂຕ້ຖຽງຈະຖືກແທນທີ່ດ້ວຍຈໍານວນຫຼາຍນັ້ນ
ຕົວອັກສອນແລະຕົວເລກແບບສຸ່ມ. ຫຼາຍມີ, ຄວາມເປັນໄປໄດ້ຫນ້ອຍທີ່ຈະ collide
ກັບຂະບວນການອື່ນໆ, ດັ່ງນັ້ນຖ້າທ່ານໃຫ້ຄໍານໍາຫນ້າເຊັ່ນ "/tmp/abc.", ທ່ານຄວນມີພຽງພໍ
"X"s. ຖ້າມີຫຼາຍກວ່າຫນຶ່ງ X, ຕົວອັກສອນທໍາອິດມາຈາກ id ຂະບວນການ. ຖ້າ
ບໍ່ມີ, ມັນຄືກັບວ່າມີສິບ, ເຊິ່ງສົມມຸດວ່າພຽງພໍ (8.4e17.
ຄວາມເປັນໄປໄດ້ຫຼື 3.7e15 ໃນ Windows). ຖ້າບໍ່ມີການໂຕ້ຖຽງ, ຄໍານໍາຫນ້າຈະເລີ່ມຕົ້ນເປັນ
"tmp." ໃນ​ລະ​ບົບ​ປະ​ຈຸ​ບັນ​.

ໃຫ້ສັງເກດວ່າທ່ານບໍ່ຕ້ອງການໃຫ້ຊື່ດັ່ງກ່າວເປັນເປົ້າຫມາຍກົດລະບຽບແລະການຂຶ້ນກັບ. ໄດ້
ຜົນໄດ້ຮັບຈະຖືກຕ້ອງ, ແຕ່ມັນຈະຖືກສ້າງຄືນໃຫມ່ທຸກຄັ້ງທີ່ທ່ານດໍາເນີນການ makepp.

ນອກຈາກນັ້ນ, ຍ້ອນວ່າມັນແຕກຕ່າງກັນສະເຫມີ, ທ່ານຄວນໃຊ້ນີ້ໃນການປະຕິບັດກົດລະບຽບພຽງແຕ່ຖ້າທ່ານໃຊ້
":build_check ignore_action":

TMPFILE ;= $(mktemp) # 1 ໂທ; "=" ຫມາຍຄວາມວ່າ 3 ໂທ: 3 ໄຟລ໌
A-count B-count: :build_check ignore_action
produce-As-and-Bs >$(TMPFILE)
&grep -c /A/ $(TMPFILE) -o A-count
&grep -c /B/ $(TMPFILE) -o B-count

ຫຼືທ່ານຄວນສົ່ງອອກມັນແລະໃຫ້ Shell ປະເມີນມັນ:

ສົ່ງອອກ TMPFILE ;= $(mktemp)
A-count B-ນັບ:
produce-As-and-Bs >$$TMPFILE # makepp ບໍ່ເຫັນຄ່າ var
fgrep -c A $$TMPFILE >A-count
fgrep -c B $$TMPFILE >B-count

ແບບຟອມສຸດທ້າຍເຮັດເລື້ມຄືນຄ່າກັບຄືນທີ່ຜ່ານມາ, ດັ່ງນັ້ນທ່ານສາມາດນໍາໃຊ້ມັນໃນກົດລະບຽບຮູບແບບ:

%.x: %.y
&grep foo $(input) -o $(mktemp)
&sed bar $(mktemp /) -o $(output) # ປະຕິບັດການອອກຂອງ &grep

notdir ຊື່ໄຟລ໌
ສົ່ງຄືນສ່ວນທີ່ບໍ່ແມ່ນໄດເລກະທໍລີຂອງຊື່ໄຟລ໌, ເຊັ່ນ, ທຸກຢ່າງຫຼັງຈາກອັນສຸດທ້າຍ
slash ຖ້າມີຫນຶ່ງ, ຫຼືຊື່ໄຟລ໌ທັງຫມົດຖ້າບໍ່ດັ່ງນັ້ນ.

only_generated ຊື່ໄຟລ໌
ສົ່ງຄືນພຽງແຕ່ຊື່ໄຟລ໌ເຫຼົ່ານັ້ນໃນລາຍຊື່ທີ່ສ້າງຂຶ້ນໂດຍ makepp ແລະບໍ່ແມ່ນຕັ້ງແຕ່ນັ້ນມາ
ດັດແກ້, ອີງຕາມໄຟລ໌ຂໍ້ມູນການກໍ່ສ້າງ.

ຫນ້າທີ່ນີ້ແມ່ນເປັນປະໂຫຍດໃນກົດລະບຽບເປົ້າຫມາຍທີ່ສະອາດ (ເຖິງແມ່ນວ່າແນ່ນອນ "makeppclean" ແມ່ນ
ຕົວແປທີ່ມັກ):

$(ລ້າງ​ຜິດ​ພາດ):
&rm -f $( only_generated **/*)

only_nontargets ຊື່ໄຟລ໌
ສົ່ງຄືນພຽງແຕ່ຊື່ໄຟລ໌ເຫຼົ່ານັ້ນຢູ່ໃນບັນຊີລາຍຊື່ທີ່ບໍ່ແມ່ນເປົ້າຫມາຍຂອງກົດລະບຽບໃດໆ (ບໍ່ວ່າຈະ
ກົດ​ລະ​ບຽບ​ຢ່າງ​ຊັດ​ເຈນ​ຫຼື​ຮູບ​ແບບ​)​. ເຈົ້າອາດຈະລະບຸຕົວແທນ (ເບິ່ງ "$(wildcard)"
ຟັງຊັນສໍາລັບລາຍລະອຽດເພີ່ມເຕີມກ່ຽວກັບຕົວແທນຂອງ makepp). ນີ້ສາມາດຖືກນໍາໃຊ້ສໍາລັບການສ້າງ a
ເປົ້າໝາຍການແຈກຢາຍ, ຕົວຢ່າງ:

.PHONY: ການແຈກຢາຍ

ການແຈກຢາຍ:
&mkdir our_product-$(VERSION)
&cp $(filter-out %~, $(only_nontargets *)) our_product-$(VERSION)
tar cf - our_product-$(VERSION) | gzip -9c > our_product-$(VERSION).tar.gz

ໃນກໍລະນີນີ້, "$(only_nontargets *)" ສົ່ງຄືນທຸກໄຟລ໌ໃນໄດເລກະທໍລີປະຈຸບັນ
ນັ້ນບໍ່ແມ່ນເປົ້າຫມາຍຂອງກົດລະບຽບບາງຢ່າງ. "$(filter_out %~, ...)" ເອົາຕົວແກ້ໄຂອອກ
ສຳ ຮອງ.

ຄ້າຍຄືກັນກັບ "only_targets" (ເບິ່ງຂ້າງເທິງ), "only_nontargets" ພຽງແຕ່ຮູ້ກ່ຽວກັບເປົ້າຫມາຍທີ່
ໄດ້ຖືກກໍານົດໄວ້ແລ້ວ. ນີ້ແມ່ນບັນຫາພຽງແຕ່ຖ້າທ່ານໃຊ້ມັນເພື່ອກໍານົດຕົວແປ
ດ້ວຍການມອບໝາຍ ":="; ຖ້າເຈົ້າໃຊ້ມັນຢູ່ໃນລາຍຊື່ການເພິ່ງພາອາໄສ ຫຼືຢູ່ໃນຕົວຂອງ a
ກົດ​ລະ​ບຽບ​, ກົດ​ລະ​ບຽບ​ອື່ນໆ​ທັງ​ຫມົດ​ຈະ​ໄດ້​ຮັບ​ການ​ເຫັນ​ແລ້ວ​.

only_stale ຊື່ໄຟລ໌
ສົ່ງຄືນພຽງແຕ່ຊື່ໄຟລ໌ເຫຼົ່ານັ້ນໃນລາຍຊື່ທີ່ສ້າງຂຶ້ນໂດຍ makepp ແລະບໍ່ແມ່ນຕັ້ງແຕ່ນັ້ນມາ
ດັດແກ້, ອີງຕາມໄຟລ໌ຂໍ້ມູນການກໍ່ສ້າງ, ແຕ່ບໍ່ແມ່ນເປົ້າຫມາຍຂອງກົດລະບຽບໃດໆ.

ຟັງຊັນນີ້ແມ່ນເປັນປະໂຫຍດສໍາລັບການຮັບປະກັນວ່າບໍ່ມີການຂຶ້ນກັບໄຟລ໌ດັ່ງກ່າວ,
ໂດຍບໍ່ມີການບັງຄັບໃຫ້ມີການກໍ່ສ້າງສະອາດຂອງເປົ້າຫມາຍທັງຫມົດ:

$(phony flush):
&rm -f $(only_stale **/*)

ຕົວຈິງແລ້ວ, ມັນອາດຈະດີກວ່າທີ່ຈະຂຽນສະຄິບທີ່ໂທຫາ makepp ເພື່ອສ້າງ
ບັນຊີລາຍຊື່ຂອງໄຟລ໌ stale, ແລະຫຼັງຈາກນັ້ນມີສະຄິບທີ່ເອົາທັງຫມົດຂອງໄຟລ໌ທີ່ລະບຸໄວ້ວ່າ
ໃນປັດຈຸບັນບໍ່ໄດ້ຢູ່ພາຍໃຕ້ການຄວບຄຸມແຫຼ່ງ, ພຽງແຕ່ໃນກໍລະນີທີ່ໄຟລ໌ທີ່ສ້າງຂຶ້ນກາຍເປັນແຫຼ່ງ
ໄຟລ໌. Makepp ບໍ່ມີຫນ້າທີ່ດັ່ງກ່າວສ້າງຂຶ້ນໃນເພາະວ່າ makepp ແມ່ນ (ແລະອາດຈະເປັນ
ຄວນຈະຍັງຄົງຢູ່) agnostic ກ່ຽວກັບການຄວບຄຸມແຫຼ່ງ.

only_targets ຊື່ໄຟລ໌
ສົ່ງຄືນພຽງແຕ່ຊື່ໄຟລ໌ເຫຼົ່ານັ້ນຢູ່ໃນລາຍຊື່ທີ່ເປັນເປົ້າໝາຍຂອງກົດລະບຽບບາງຢ່າງ
(ທັງກົດລະບຽບທີ່ຈະແຈ້ງ ຫຼືຮູບແບບ). ເຈົ້າອາດຈະລະບຸຕົວແທນ (ລວມທັງ makepp's
ຕົວອັກສອນພິເສດ, "**") ໃນຊື່ໄຟລ໌. (ເບິ່ງຫນ້າທີ່ "$(wildcard )" ສໍາລັບຂໍ້ມູນເພີ່ມເຕີມ
ລາຍລະອຽດ. ນີ້ສາມາດຖືກນໍາໃຊ້ສໍາລັບເປົ້າຫມາຍທີ່ສະອາດ, ຕົວຢ່າງ:

.PHONY: ສະອາດ

ສະອາດ:
&rm -f $(only_targets *)

ຕອນນີ້ຖ້າທ່ານພິມ "makepp clean", ມັນຈະລຶບທຸກສິ່ງທີ່ມັນຮູ້ວິທີການສ້າງ. ແຕ່
ຢ່າສ້າງເປົ້າໝາຍທີ່ສະອາດ, ໃຊ້ "makeppclean" ແທນ!

ສະຖານທີ່ອື່ນທີ່ມັນອາດຈະເປັນປະໂຫຍດແມ່ນເພື່ອຫຼີກເວັ້ນການລວມທັງ stale .o ໄຟລ​໌​ໃນ​ຂອງ​ທ່ານ​
ສ້າງ. ຕົວຢ່າງ, ຖ້າເຈົ້າສ້າງຫ້ອງສະໝຸດແບບນີ້:

mylib.a: *.o
&rm -f $(ຜົນຜະລິດ)
$(AR) cr $(output) $(inputs)

ແລະ​ຫຼັງ​ຈາກ​ນັ້ນ​ທ່ານ​ລຶບ​ບາງ​ໄຟລ​໌​ແຫຼ່ງ​ແຕ່​ລືມ​ທີ່​ຈະ​ລົບ​ທີ່​ສອດ​ຄ້ອງ​ກັນ​ .o ແຟ້ມ,
ໄດ້ .o ໄຟລ໌ຈະຍັງຄົງຢູ່ປະມານ. ນີ້ຫມາຍຄວາມວ່າພວກເຂົາຈະຍັງຖືກລວມເຂົ້າໃນ
ຫ້ອງສະຫມຸດເຖິງວ່າຈະມີຄວາມຈິງທີ່ວ່າພວກມັນບໍ່ມີປະໂຫຍດອີກຕໍ່ໄປ. ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ປັບ​ປຸງ​ແກ້​ໄຂ​ຂອງ​ທ່ານ​
ກົດ​ລະ​ບຽບ​ດັ່ງ​ນີ້​:

mylib.a: $(only_targets *.o)
&rm -f $(ຜົນຜະລິດ)
$(AR) cr $(output) $(inputs)

ແລ້ວບັນຫານີ້ຈະບໍ່ເກີດຂຶ້ນ.

ໃຫ້ສັງເກດວ່ານີ້ຫມາຍເຖິງພຽງແຕ່ໄຟລ໌ທີ່ຮູ້ວ່າເປັນເປົ້າຫມາຍ at ໄດ້ ທີ່ໃຊ້ເວລາ ທ່ານ
ຂໍ "ພຽງແຕ່ເປົ້າຫມາຍ". ຖ້າ "only_targets" ປາກົດຢູ່ໃນການເພິ່ງພາອາໄສຫຼືການກະທໍາຂອງ a
ກົດລະບຽບ, ຫຼັງຈາກນັ້ນເປົ້າຫມາຍທີ່ເປັນໄປໄດ້ທັງຫມົດຈະເປັນທີ່ຮູ້ຈັກເພາະວ່າການເພິ່ງພາອາໄສແລະການກະທໍາບໍ່ແມ່ນ
ປະເມີນຈົນກ່ວາກົດລະບຽບຈະຖືກປະຕິບັດ. ຢ່າງໃດກໍຕາມ, ຖ້າທ່ານປະເມີນ, ພະຍາຍາມປະເມີນມັນ
ກ່ອນຫນ້ານີ້ໃນ makefile ທີ່ມີຕົວແປ ":=" ແບບນີ້:

ALL_TARGETS := $(only_targets *)

ເປົ້າໝາຍທີ 1: ການເພິ່ງພາອາໄສ1
ຫຸ້ນ

ເປົ້າໝາຍທີ 2: ການເພິ່ງພາອາໄສ2
ຫຸ້ນ

ຫຼັງຈາກນັ້ນ, "only_targets" ຈະບໍ່ຮູ້ກ່ຽວກັບກົດລະບຽບຕໍ່ໄປ.

ເຊັ່ນດຽວກັນ, "only_targets" ບໍ່ຮູ້ກ່ຽວກັບເປົ້າຫມາຍທີ່ຜະລິດຢູ່ໃນ makefiles ທີ່ເປັນ
loaded ກັບ recursive make. (ແຕ່ທ່ານບໍ່ຄວນໃຊ້ recursive make ເລີຍ; ໃຊ້
ໃຊ້ຄຳຖະແຫຼງ "load_makefile", ຫຼືການໂຫຼດ makefile implicit ແທນ.)

relative_filename ແຟ້ມ 1 ແຟ້ມ 2 file3[, ທັບ]
ສົ່ງຄືນຊື່ຂອງໄຟລ໌ເຫຼົ່ານັ້ນທີ່ກ່ຽວຂ້ອງກັບໄດເລກະທໍລີປັດຈຸບັນ (ອັນທີ່
makefile ຢູ່ໃນ). ນີ້ຍັງສາມາດຖືກນໍາໃຊ້ເພື່ອເຮັດຄວາມສະອາດທີ່ບໍ່ຈໍາເປັນ "./" ແລະຂີ້ເຫຍື້ອອື່ນໆຈາກ
ເສັ້ນ​ທາງ​:

DIR := .
SUBDIR :=..
FNAME := $(DIR)/../otherdir/$(SUBDIR)/files
X := $(relative_filename $(FNAME))

If slash ເປັນຄວາມຈິງ (ປົກກະຕິແລ້ວ 1) ຊື່ໄຟລ໌ທີ່ສົ່ງຄືນແມ່ນຮັບປະກັນວ່າມີ slash
ໂດຍ prepending "./" ຖ້າຈໍາເປັນ, ດັ່ງນັ້ນທ່ານສາມາດນໍາໃຊ້ມັນເປັນຊື່ປະຕິບັດໄດ້ໂດຍບໍ່ມີການ
ກັງວົນກ່ຽວກັບເສັ້ນທາງຄົ້ນຫາຄໍາສັ່ງ overriding ສະຖານທີ່ໄດເລກະທໍລີ.

ຖ້າເສັ້ນທາງໄປໂດຍໄດເລກະທໍລີຮາກ, ພໍ່ແມ່ຂອງໄດເລກະທໍລີເຮືອນຂອງເຈົ້າຫຼື
"$(ROOT)" ຂອງລະບົບການກໍ່ສ້າງຂອງທ່ານ, ຫຼືຢູ່ໃນ Windows ຮາກຂອງໄດ (ຂຶ້ນກັບ
ສະພາບແວດລ້ອມ, ນີ້ຍັງເກີດຂຶ້ນສໍາລັບ /cygdrive/c or /c), ເສັ້ນທາງຢ່າງແທ້ຈິງຈະເປັນ
ກັບຄືນມາແທນ.

relative_to ແຟ້ມ 1 ແຟ້ມ 2 file3[, ບັນຊີລາຍການ]
ສົ່ງຄືນຊື່ຂອງໄຟລ໌ເຫຼົ່ານັ້ນທີ່ກ່ຽວຂ້ອງກັບໄດເຣັກທໍຣີທີ່ລະບຸ. ນີ້​ແມ່ນ
ປົກກະຕິແລ້ວເປັນປະໂຫຍດໃນເວລາທີ່ສໍາລັບເຫດຜົນໃດກໍ່ຕາມທີ່ທ່ານມີເພື່ອປະຕິບັດຄໍາສັ່ງຈາກ a
ໄດເລກະທໍລີທີ່ແຕກຕ່າງກັນ (ໄດເລກະທໍລີປະຈຸບັນເລີ່ມຕົ້ນ):

source_backup.tar:
cd .. && tar cf $(relative_to $(output), ..) $(relative_to .,..)

បច្ច័យ ຊື່...
ສະກັດເອົາສ່ວນທ້າຍຂອງແຕ່ລະຊື່ໄຟລ໌ໃນຊື່. ຖ້າຊື່ໄຟລ໌ມີໄລຍະເວລາ,
ຄໍາຕໍ່ທ້າຍແມ່ນທຸກສິ່ງທຸກຢ່າງເລີ່ມຕົ້ນດ້ວຍໄລຍະເວລາສຸດທ້າຍ. ຖ້າບໍ່ດັ່ງນັ້ນ, ຄໍາຕໍ່ທ້າຍແມ່ນ
ສະຕຣິງຫວ່າງເປົ່າ. ນີ້ມັກຈະຫມາຍຄວາມວ່າຜົນໄດ້ຮັບຈະຫວ່າງເປົ່າເມື່ອບໍ່ມີຊື່,
ແລະຖ້າຊື່ມີຊື່ໄຟລ໌ຫຼາຍ, ຜົນໄດ້ຮັບອາດມີຊື່ໄຟລ໌ຫນ້ອຍລົງ.

ຍົກ​ຕົວ​ຢ່າງ,

$(suffix src/foo.c src-1.0/bar.c hacks)

ໃຫ້ຜົນໄດ້ຮັບ ".c .c".

ຊົ່ວຄາວ ຄໍາເວົ້າ
ໃຫ້ makepp ຮູ້ວ່າເປົ້າຫມາຍທີ່ກໍານົດໄວ້ອາດຈະຖືກໂຍກຍ້າຍອອກໂດຍກົດລະບຽບທີ່ສ້າງ
ເຂົາເຈົ້າ. ຄ້າຍຄືກັນກັບ "phony", ຍົກເວັ້ນວ່າ makepp ຄາດຫວັງວ່າໄຟລ໌ທີ່ແທ້ຈິງຂອງຊື່ນັ້ນ
ອາດຈະໄດ້ຮັບຜົນກະທົບຈາກກົດລະບຽບ. ກົດລະບຽບບໍ່ໄດ້ຖືກປະຕິບັດຖ້າຫາກວ່າພຽງແຕ່ຊົ່ວຄາວເທົ່ານັ້ນ
ເປົ້າໝາຍແມ່ນລ້າສະໄໝແລ້ວ.

wildcard ຮູບແບບ
ສົ່ງຄືນຊື່ທີ່ຈັດຮຽງຂອງໄຟລ໌ທັງໝົດທີ່ກົງກັບຮູບແບບທີ່ໃຫ້ມາ, ຫຼືອັນນັ້ນ
ໄຟລ໌ທີ່ຍັງບໍ່ທັນມີຢູ່ແຕ່ສາມາດສ້າງໄດ້ໂດຍອີງໃສ່ກົດລະບຽບທີ່ makepp ຮູ້
ກ່ຽວກັບຈຸດໃນເວລາທີ່ມັນປະເມີນການສະແດງອອກ. ໃນຈຸດສຸດທ້າຍນີ້ມັນແຕກຕ່າງກັນ
ຈາກການປ້ອນກົດລະບຽບ, ເຊິ່ງໃຊ້ໄດ້ກັບໄຟລ໌ທີ່ສ້າງໂດຍກົດລະບຽບທີ່ພົບເຫັນໃນພາຍຫຼັງ.

Makepp ສະຫນັບສະຫນູນທັງຫມົດ shell wildcards ປົກກະຕິ ("*", "?", ແລະ "[]"). ມັນຍັງມີ a
wildcard "**" ເຊິ່ງກົງກັບຈໍານວນຂອງໄດເລກະທໍລີແຊກແຊງໃດໆ. (ຄວາມຄິດນີ້ແມ່ນ
ຖືກລັກຈາກ zsh.) ຕົວຢ່າງ, "**/*.c" ກົງກັບທັງໝົດ .c ໄຟລ໌ໃນແຫຼ່ງທັງຫມົດ
ຕົ້ນໄມ້. "objects/**/*.o" ກົງກັບທັງໝົດ .o ໄຟລ໌ທີ່ບັນຈຸຢູ່ທຸກບ່ອນໃນ
ບັນຊີຍ່ອຍ ວັດຖຸ ຫຼື ໄດເລກະທໍລີຍ່ອຍ ຫຼື ໄດເລກະທໍລີຍ່ອຍຂອງມັນ. ໄດ້
"**" wildcard ຈະບໍ່ປະຕິບັດຕາມລິງຄ໌ອ່ອນໆໄປຫາໄດເລກະທໍລີໃນລະດັບໃດກໍ່ຕາມ, ແລະມັນຈະບໍ່ມີ
ພະຍາຍາມໃສ່ໄດເລກະທໍລີທີ່ມີຢູ່ແຕ່ບໍ່ສາມາດອ່ານໄດ້. ໄຟລ໌ແລະ
ໄດເລກະທໍລີທີ່ມີຢູ່ແຕ່ບໍ່ສາມາດອ່ານໄດ້ຈະບໍ່ຖືກສົ່ງຄືນໂດຍ "$(wildcard )".

string ຫນ້າທີ່
ຕື່ມຄຳນຳໜ້າ ຄຳນຳໜ້າ, ຄໍາເວົ້າ
Prepends ຄໍານໍາຫນ້າ string ກັບແຕ່ລະຄໍາ. ນີ້ແມ່ນສ່ວນໃຫຍ່ສໍາລັບ GNU ເຮັດ
ຄວາມເຂົ້າກັນໄດ້; ການນໍາໃຊ້ການຂະຫຍາຍຕົວແບບ rc, ນີ້ສາມາດເຮັດໄດ້ໃນຮູບແບບທີ່ສາມາດອ່ານໄດ້ຫຼາຍ
ເຊັ່ນນີ້:

ໂມດູນ := abcd
X_OLD_STYLE := $(addprefix $(OBJDIR)/, $(addsuffix .o, $(MODULES))))
X_NEW_STYLE := $(OBJDIR)/$(MODULES).o # ມັນບໍ່ງ່າຍກວ່າທີ່ຈະອ່ານບໍ?

ສ່ວນຕື່ມ ຕໍ່ທ້າຍ, ຄໍາເວົ້າ
ຕື່ມຂໍ້ມູນໃສ່ທ້າຍສະຕຣິງໃສ່ແຕ່ລະຄຳສັບ. ນີ້ແມ່ນສ່ວນໃຫຍ່ສໍາລັບ GNU ເຮັດ
ຄວາມເຂົ້າກັນໄດ້; ການນໍາໃຊ້ການຂະຫຍາຍຕົວແບບ rc, ນີ້ສາມາດເຮັດໄດ້ໃນຮູບແບບທີ່ສາມາດອ່ານໄດ້ຫຼາຍ
ເຊັ່ນນີ້:

X_OLD_STYLE := $(addsuffix .o, $(MODULES))
X_NEW_STYLE := $(MODULES).o

ໂທ ຕົວແປ[, ຄໍາ]...
ຟັງຊັນ "ໂທ" ແມ່ນເປັນເອກະລັກທີ່ມັນສາມາດຖືກນໍາໃຊ້ເພື່ອພິຈາລະນາ ຕົວແປ ເປັນຫນຶ່ງ
ການທໍາງານຂອງຕົວກໍານົດການ. ທ່ານສາມາດມອບຫມາຍການສະແດງອອກທີ່ສັບສົນໃຫ້ ຕົວແປ ແລະນໍາໃຊ້
"ໂທຫາ" ເພື່ອຂະຫຍາຍເນື້ອຫາຂອງມັນໃຫ້ກັບຄ່າທີ່ແຕກຕ່າງກັນໂດຍ parameterized ໂດຍ ຄໍາເວົ້າ ຕໍ່ມາ. ໃນ
ລະບົບການຜະລິດອື່ນໆ, ຕົວແປທີ່ຖືກນໍາໃຊ້ຕົ້ນຕໍເພື່ອຈຸດປະສົງທີ່ຈະໄດ້ຮັບການຂະຫຍາຍໂດຍຜ່ານ
"ໂທ", ເອີ້ນວ່າ a ມະຫາພາກ.

ໃນລະຫວ່າງການຂະຫຍາຍມະຫາພາກ, ຕົວແປຊົ່ວຄາວ $1, $2, "... " ອ້າງອີງເຖິງ
ການໂຕ້ຖຽງທີ່ໃຫ້ "ໂທຫາ" ໃນລະຫວ່າງການຮຽກຮ້ອງຂອງມັນ. ຕົວແປ $0 ຈະຖືກຂະຫຍາຍອອກໄປ
ຊື່ຂອງມະຫາພາກ (ie ຕົວແປ) ທີ່ "ໂທ" ກໍາລັງຂະຫຍາຍອອກໄປ.

ບໍ່​ມີ​ຂອບ​ເຂດ​ຈໍາ​ກັດ​, ວິ​ທີ​ການ​ໂຕ້​ຖຽງ​ມະ​ຫາ​ພາກ​ຈໍາ​ນວນ​ຫຼາຍ​ອາດ​ຈະ "ໂທ​" ກັບ​ຫຼື​ຈໍາ​ນວນ​ຫຼາຍ​
ຕົວກໍານົດການ macro ອາດຈະຄາດຫວັງ. ຖ້າທ່ານຜ່ານການໂຕ້ຖຽງເພີ່ມເຕີມເພື່ອ "ໂທຫາ" ເປັນມະຫາພາກ
ຕ້ອງການ, ການໂຕ້ຖຽງທີ່ເກີນທັງຫມົດຈະຖືກຍົກເລີກ. ຖ້າທ່ານຜ່ານການໂຕ້ຖຽງຫນ້ອຍກວ່າ a
macro ຄາດຫວັງວ່າ, ຕົວກໍານົດການທີ່ເກີນທັງຫມົດຕົກລົງເຂົ້າໄປໃນສະຕຣິງຫວ່າງເປົ່າ.

ຫນ້າທໍາອິດຕົວຢ່າງງ່າຍດາຍ:

ສ່ວນທີ່ເຫຼືອ = $(ລາຍການຄຳສັບ 2, $(ຄຳສັບ $(1)), $(1))
list = ABCDE
butfirst := $(ພັກຜ່ອນການໂທ, $(ລາຍຊື່))

ທີ່ນີ້, ຕົວແປ "$(butfirst)" ຈະມີບັນຊີລາຍຊື່ "BCDE".

ແລະໃນປັດຈຸບັນສໍາລັບຕົວຢ່າງທີ່ສັບສົນຫຼາຍເພື່ອສະແດງໃຫ້ເຫັນສິ່ງທີ່ເປັນໄປໄດ້:

ສ່ວນທີ່ເຫຼືອ = $(wordlist 2,$(words $(1)),${1})
mymap = $(ຖ້າ $2,$(ໂທຫາ $1,$(ຄຳທຳອິດ $2)) $(ໂທຫາ $0,$1,$(ໂທອອກ,$2)))
downcase = ${makeperl lc("$1")}

UCWORDS = ຄໍາທັງຫມົດເຫຼົ່ານີ້ແມ່ນ UPCASE
DCWORDS := $(ໂທຫາ mymap, downcase,$(UCWORDS))

ດຽວນີ້ "$(DCWORDS)" ປະກອບມີ "ຄຳສັບທັງໝົດເຫຼົ່ານີ້ເປັນຕົວພິມໃຫຍ່". ໂດຍວິທີທາງການ: ມັນເຮັດໃຫ້ບໍ່ມີ
ຄວາມແຕກຕ່າງ, ບໍ່ວ່າພວກເຮົາເຂົ້າເຖິງການໂຕ້ຖຽງຜ່ານ $1, "${1}" or "$(1)" ພາຍໃນມະຫາພາກ.

ທ່ານສາມາດນໍາໃຊ້ຕົວແປໄດ້ໂດຍກົງຄືກັບວ່າມັນເປັນຫນ້າທີ່, ຖ້າບໍ່ມີ
ຫນ້າທີ່ຂອງຊື່ນັ້ນ. ນີ້ແມ່ນພາຍໃນປ່ຽນເປັນ "ໂທ", ດັ່ງນັ້ນເຫຼົ່ານີ້ແມ່ນ
ທຽບເທົ່າ:

ການສົນທະນາ = $0 ກາຍເປັນ $1 $2.
ໂດຍກົງ = $(ສົນທະນາ,ການໂຕ້ຖຽງ)
ເອີ້ນວ່າ = $(ໂທສົນທະນາ,ອັນ,ການໂຕ້ຖຽງ)

ມັນອາດຈະເບິ່ງຄືວ່າເປັນການໂຕ້ວາທີວ່າ "$[call]" ຄວນຂະຫຍາຍມະຫາພາກ "$[]" ຫຼືບໍ່.
ການສະແດງອອກ, ຫຼືຟັງຊັນໃດໜຶ່ງຄວນເຮັດສິ່ງດຽວກັນສະເໝີ, ບໍ່ວ່າມັນຈະເຮັດແນວໃດ
ເອີ້ນວ່າ. ສຸດທ້າຍໄດ້ຖືກເລືອກ, ເພາະວ່າດ້ວຍ syntax ປົກກະຕິມັນຈະເປັນ
ເປັນ​ໄປ​ບໍ່​ໄດ້​ທີ່​ຈະ​ໄດ້​ຮັບ "$[1], $[2]..." ເປັນ​ຕົວ​ປ່ຽນ (ພວກ​ເຂົາ​ເຈົ້າ​ຈະ​ໄດ້​ຮັບ​ການ​ທົດ​ແທນ​ໂດຍ​ບໍ່​ມີ​ຫຍັງ,
ກ່ອນທີ່ວຽກງານຈະເກີດຂຶ້ນ.) ດັ່ງນັ້ນ, ຖ້າທ່ານມີມະຫາພາກສໍາລັບການກໍານົດ a
ກົດ​ລະ​ບຽບ​, ທ່ານ​ຕ້ອງ​ການ​ການ​ສະ​ແດງ​ອອກ​ເຊັ່ນ "$(output)​" ເພື່ອ​ໃຫ້​ໄດ້​ຮັບ​ການ​ເຫັນ​ໃນ​ເວ​ລາ​ທີ່​ກົດ​ລະ​ບຽບ​ໄດ້​ຮັບ​ການ​ວິ​ເຄາະ​, ສະ​ນັ້ນ​.
ທ່ານຕ້ອງປົກປ້ອງພວກເຂົາຈາກ "ໂທຫາ":

ກໍານົດ myrule
$2: $1
mycommand $$(input) -o $$(output)
ສິ້ນສຸດ
$[myrule myinput,myoutput]

ການກັ່ນຕອງ ຮູບແບບ, ຄໍາເວົ້າ
ສົ່ງຄືນຄຳສັບທັງໝົດໃນລາຍການທີ່ກົງກັບຮູບແບບຕ່າງໆ. ຮູບແບບອາດຈະເປັນແບບອື່ນໆ
ຄໍາສັບຕ່າງໆ, ຫຼືນາມບັດຕົວແທນ (ເຊັ່ນ, "*", "?", ແລະ "[az]" ຖືກຮັບຮູ້), ຫຼືພວກເຂົາອາດຈະ
ມີຕົວອັກສອນ "%", ຊຶ່ງຫມາຍຄວາມວ່າຈະກົງກັບສະຕຣິງໃດນຶ່ງໃນຈຸດນັ້ນ (ຄືກັນກັບ "*").

filter_out ຮູບແບບ, ຄໍາເວົ້າ
ສົ່ງຄືນຄຳສັບທັງໝົດໃນລາຍການທີ່ບໍ່ກົງກັບຮູບແບບ. ຮູບແບບອາດຈະເປັນພຽງແຕ່
ຄໍາສັບອື່ນ, ຫຼື filename wildcards (ເຊັ່ນ, "*", "?", ແລະ "[az]" ຖືກຮັບຮູ້), ຫຼື
ພວກມັນອາດມີຕົວອັກສອນ "%", ເຊິ່ງໝາຍເຖິງການຈັບຄູ່ສະຕຣິງໃດໜຶ່ງຢູ່ໃນຈຸດນັ້ນ (ຄືກັນກັບ
"*").

ຍົກ​ຕົວ​ຢ່າງ:

libproduction.a: $(filter_out test_*, $(wildcard *.o))

ຈະເອົາທັງຫມົດ .o ໄຟລ໌ທີ່ມີຢູ່ຫຼືສາມາດສ້າງໄດ້, ຍົກເວັ້ນໄຟລ໌ທີ່ເລີ່ມຕົ້ນດ້ວຍ ການທົດສອບ_,
ເຂົ້າໄປໃນ libproduction.a.

ຊອກຫາສາຍ ຊອກຫາ, in
Return ຊອກຫາ, ຖ້າມັນເປັນ substring ຂອງ in.

ຄໍາທໍາອິດ ຄໍາເວົ້າ
ກັບຄືນຄໍາທໍາອິດ.

ແຜນທີ່ ຄໍາສັບຕ່າງ, perlcode
ແຜນທີ່ ຄໍາສັບຕ່າງ, perlcode
ຄ້າຍຄືກັນກັບແຜນທີ່ Perl, ນຳໃຊ້ perlcode ໄປຫາແຕ່ລະຄໍາແລະສົ່ງຄືນ
ຜົນໄດ້ຮັບ. ຕົວແປທໍາອິດແມ່ນລະຫັດ Perl ທໍາມະດາ, ໃນຂະນະທີ່ຕົວແປທີສອງຜ່ານຄັ້ງທໍາອິດ
perlcode ໂດຍຜ່ານການຂະຫຍາຍຕົວແປແບບ Make-style. ຄໍາສັບຕ່າງໆໄດ້ຖືກຂະຫຍາຍຢູ່ໃນທັງສອງ
ກໍລະນີ.

ຄໍາສັບຕ່າງໆແມ່ນຢູ່ໃນ $_ ແລະຖືກສົ່ງຄືນເວັ້ນເສຍແຕ່ວ່າທ່ານ undef $_. ນີ້ແມ່ນຈຸດປະສົງສໍາລັບ
ການແກ້ໄຂບໍ່ສາມາດຈັດການໄດ້ງ່າຍໂດຍ "patsubst". ພຽງແຕ່ເຄື່ອງໝາຍຈຸດທຳອິດແມ່ນຕົວແຍກ,
ອື່ນໃດຖືກພິຈາລະນາເປັນສ່ວນຫນຶ່ງຂອງ perlcode.

# ປ່ຽນຄຳສັບ. Double paren, ເພື່ອອະນຸຍາດໃຫ້ paren ໃນ perlcode, ຫຼືໃຊ້ ${}:
X = $((ແຜນທີ່ $(VALUES), s/.+)-.+)/$2-$1/))
# ທ່ານສາມາດນໍາໃຊ້ make expressions, ແຕ່ຫຼັງຈາກນັ້ນທ່ານຕ້ອງໃຊ້ $$ ສໍາລັບ Perl $:
Y = $(makemap $(VALUES), tr/$(OLDCHARS)/$(NEWCHARS)/ ຫຼື $$_ = 'ລົ້ມເຫລວ')
# ທ່ານສາມາດລົບລ້າງຜູ້ສະຫມັກ:
Y = $(ແຜນທີ່ $(VALUES), undef $_ ຖ້າ /no_good/)

ເຂົ້າຮ່ວມ ຄໍາ​ສັບ​ຕ່າງໆ 1​, ຄໍາ2
ເຮັດການເຂົ້າຮ່ວມຄູ່ຂອງຄໍາທໍາອິດແລະຄໍາທີສອງ.

ຮັບຮອງ ຮູບແບບ, ແທນ, ຄໍາເວົ້າ
ປະຕິບັດການທົດແທນແຕ່ລະຄໍາໃນບັນຊີລາຍຊື່ຄໍາ. ຕົວອັກສອນ "%" ກົງກັບຕົວໃດ
ສາຍ. ນີ້ແມ່ນສະແດງໃຫ້ເຫັນດີທີ່ສຸດໂດຍຕົວຢ່າງ:

OBJS = $(patsubst %.c, object_dir/%.o, $(C_SOURCES))

ເອົາທຸກໄຟລ໌ໃນ C_SOURCES ແລະສົ່ງຄືນຊື່ຂອງໄຟລ໌ວັດຖຸໃນ object_dir.
ບາງຄັ້ງມັນມີຄວາມຊັດເຈນກວ່າທີ່ຈະໃຊ້ການອ້າງອີງການທົດແທນ, ຕົວຢ່າງ, ຂ້າງເທິງນີ້ສາມາດເຮັດໄດ້
ໄດ້ຖືກຂຽນເປັນ

OBJS = $(C_SOURCES:%.c=object_dir/%.o)

ການຈັດລຽງ ຄໍາ1 ຄໍາ2 ຄໍາ3 ...
ຄັດ​ຄໍາ​ສັບ​ຕ່າງໆ​ໃນ​ລໍາ​ດັບ lexical ແລະ​ລົບ​ການ​ຊ​້​ໍາ​ກັນ​.

ອອກ string
ເອົາຊ່ອງຫວ່າງທາງໜ້າ ແລະຕໍ່ທ້າຍອອກຈາກສະຕຣິງ ແລະແທນທີ່ແຕ່ລະພາຍໃນ
ລຳດັບຂອງໜຶ່ງ ຫຼືຫຼາຍຕົວອັກສອນທີ່ມີຊ່ອງຫວ່າງດຽວ. ດັ່ງນັ້ນ, "$(strip ab
c )" ຜົນໄດ້ຮັບໃນ "abc".

ຍ່ອຍ ຈາກ, ເຖິງ, ຂໍ້ຄວາມ
ປະຕິບັດການປ່ຽນແທນຂໍ້ຄວາມໃນຂໍ້ຄວາມ: ແຕ່ລະປະກົດການມາຈາກແມ່ນແທນທີ່
ໂດຍ. ຜົນໄດ້ຮັບແມ່ນທົດແທນສໍາລັບການເອີ້ນຟັງຊັນ. ຍົກ​ຕົວ​ຢ່າງ,

$(subst ee,EE,ຕີນຢູ່ຖະໜົນ)

ແທນ string "fEEt on the strEEt".

ຄໍາ n, ຂໍ້ຄວາມ
ກັບຄືນ nth ຄໍາ​ຂອງ​ ຂໍ້ຄວາມ. ຄຸນຄ່າທີ່ຖືກຕ້ອງຂອງ n ເລີ່ມຕົ້ນຈາກ 1 ໃນຕອນເລີ່ມຕົ້ນ
ຫຼືຖອຍຫຼັງຈາກ -1 ໃນຕອນທ້າຍ. ຖ້າ n ແມ່ນໃຫຍ່ກວ່າຈໍານວນຄໍາທີ່ຢູ່ໃນ ຂໍ້ຄວາມ, ການ
ຄ່າຫວ່າງເປົ່າ.

ລາຍການຄຳສັບ ບັນຊີລາຍການດັດສະນີ, ຄໍາເວົ້າ
ລາຍການຄຳສັບ ດັດ​ຊະ​ນີ​ທໍາ​ອິດ​, ດັດຊະນີສຸດທ້າຍ, ຄໍາເວົ້າ
ໃນຮູບແບບທໍາອິດທີ່ທ່ານສະຫນອງບັນຊີລາຍຊື່ຂອງດັດຊະນີ (ນັບຈາກ 1 ໃນຕອນເລີ່ມຕົ້ນຫຼື
ຖອຍຫຼັງຈາກ -1 ໃນຕອນທ້າຍ) ເພື່ອເລືອກຄໍາທີ່ທ່ານຕ້ອງການ. ໃນຮູບແບບທີສອງທ່ານ
ລະບຸຂອບເຂດຂອງຄໍາທີ່ທ່ານຕ້ອງການສົ່ງຄືນ.

ຄໍາເວົ້າ ຂໍ້ຄວາມ
ຕອບຈຳນວນຄຳສັບໃນ ຂໍ້ຄວາມ.

Miscellaneous ຫນ້າທີ່
foreach var,ລາຍຊື່,ຂໍ້ຄວາມ
ສອງ​ການ​ໂຕ້​ຖຽງ​ທໍາ​ອິດ​, var ແລະ ບັນຊີລາຍຊື່, ຖືກຂະຫຍາຍອອກກ່ອນທີ່ຈະເຮັດຫຍັງອີກ; ຫມາຍ​ເຫດ​
ວ່າການໂຕ້ຖຽງສຸດທ້າຍ, ຂໍ້ຄວາມ, ບໍ່ໄດ້ຖືກຂະຫຍາຍໃນເວລາດຽວກັນ. ຫຼັງຈາກນັ້ນ, ສໍາລັບແຕ່ລະຄໍາສັບຂອງ
ມູນຄ່າການຂະຫຍາຍຂອງບັນຊີລາຍຊື່, ຕົວແປທີ່ຕັ້ງຊື່ໂດຍຄ່າຂະຫຍາຍຂອງ var ຖືກກໍານົດເປັນ
ຄໍານັ້ນ, ແລະຂໍ້ຄວາມຖືກຂະຫຍາຍອອກ. ຂໍ້ຄວາມທີ່ສົມມຸດວ່າມີການອ້າງອີງເຖິງຕົວແປນັ້ນ,
ດັ່ງນັ້ນການຂະຫຍາຍຕົວຂອງມັນຈະແຕກຕ່າງກັນໃນແຕ່ລະຄັ້ງ.

ຕົວຢ່າງງ່າຍດາຍນີ້ກໍານົດຕົວແປ ໄຟ ບັນຊີລາຍຊື່ຂອງໄຟລ໌ທັງຫມົດໃນ
ລາຍ​ການ​ໃນ​ບັນ​ຊີ​ລາຍ​ການ​ ທີ່ຢູ່:

dirs := abcd
ໄຟລ໌ := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

ຂໍ້ຄວາມນີ້ແມ່ນ "$(wildcard $(dir)/*)". ການຄ້າງຫ້ອງທໍາອິດຊອກຫາຄ່າ "a" ສໍາລັບ dir,
ສະນັ້ນມັນຜະລິດຜົນດຽວກັນກັບ "$(wildcard a/*)"; ການຄ້າງຫ້ອງທີສອງຜະລິດ
ຜົນຂອງ "$(wildcard b/*)"; ແລະອັນທີສາມ, ຂອງ "$(wildcard c/*)".

ຕົວຢ່າງນີ້ມີຜົນໄດ້ຮັບດຽວກັນ (ຍົກເວັ້ນການຕັ້ງຄ່າ "dirs") ເປັນຕົວຢ່າງຕໍ່ໄປນີ້:

ໄຟລ໌ := $(wildcard a/* b/* c/* d/*)

ເມື່ອຂໍ້ຄວາມມີຄວາມສັບສົນ, ທ່ານສາມາດປັບປຸງການອ່ານໄດ້ໂດຍການໃຫ້ຊື່, ກັບ
ຕົວແປເພີ່ມເຕີມ:

find_files = $(wildcard $(dir)/*)
dirs := abcd
ໄຟລ໌ := $(foreach dir,$(dirs),$(find_files))

ໃນທີ່ນີ້ພວກເຮົາໃຊ້ find_files ຕົວແປດ້ວຍວິທີນີ້. ພວກເຮົາໃຊ້ "=" ທໍາມະດາເພື່ອກໍານົດ a
ຕົວແປ recursively-expanding, ດັ່ງນັ້ນມູນຄ່າຂອງມັນປະກອບດ້ວຍການໂທຫາຫນ້າທີ່ຕົວຈິງ
ໄດ້ຮັບການຂະຫຍາຍຄືນພາຍໃຕ້ການຄວບຄຸມຂອງ foreach; ຕົວແປທີ່ຂະຫຍາຍແບບງ່າຍໆຈະບໍ່ເຮັດ,
ເນື່ອງຈາກວ່າ wildcard ຈະຖືກເອີ້ນພຽງແຕ່ຄັ້ງດຽວໃນເວລາກໍານົດ find_files.

ໝາຍເຫດ: ຢ່າສັບສົນກັບຕົວແປພິເສດ "$(foreach)".

ຂໍ້ມູນ ຂໍ້ຄວາມ
ການເຕືອນໄພ ຂໍ້ຄວາມ
ຄວາມຜິດພາດ ຂໍ້ຄວາມ
ພິມຂໍ້ຄວາມທີ່ສົ່ງຄືນບໍ່ມີຫຍັງ. ອັນທໍາອິດໄປ STDOUT, ອັນທີສອງໄປຫາ STDERR,
ອັນທີສາມນອກຈາກນັ້ນຍົກເລີກການປຸງແຕ່ງ.

ສ້າງກ່ອນ ເປົ້າຫມາຍ
ເຮັດໃຫ້ ເປົ້າຫມາຍ
ສົ່ງຄືນການໂຕ້ແຍ້ງຂອງມັນ verbatim, ແຕ່ທໍາອິດສ້າງໄຟລ໌ທັງຫມົດທີ່ລະບຸໄວ້. ນີ້ແມ່ນເປັນປະໂຫຍດ
ເມື່ອເອກະສານທີ່ໃຫ້ມາແມ່ນຕ້ອງການເມື່ອປະເມີນການສະແດງອອກ. ໂດຍປົກກະຕິນີ້ເກີດຂຶ້ນ
ເມື່ອທ່ານມີການກໍ່ສ້າງທີ່ຊຸດຂອງໄຟລ໌ທີ່ກ່ຽວຂ້ອງໄດ້ຖືກຄິດໄລ່ໂດຍແກະບາງ
ຄໍາສັ່ງ. ຍົກ​ຕົວ​ຢ່າງ,

file_list :
# ຄຳສັ່ງ shell ເພື່ອຄຳນວນລາຍການໄຟລ໌ທີ່ຈະໃສ່ເຂົ້າໃນໂປຣແກຣມ

my_program : $(&cat $(prebuild file_list))

ຖ້າທ່ານຕ້ອງການລາຍຊື່ໃນຫຼາຍກວ່າຫນຶ່ງກົດລະບຽບ, ມັນຈະມີປະສິດທິພາບຫຼາຍທີ່ຈະໃຊ້
ຂະຫຍາຍຕົວແປຫຼາຍຄັ້ງ:

file_list ;= $(&cat $(prebuild file_list))

my_program1 : ao $(file_list)

my_program2 : bo $(file_list)

ຖ້າແທນທີ່ທ່ານລະບຸພຽງແຕ່ "$(&cat file_list)", ຫຼັງຈາກນັ້ນ makepp ຈະບໍ່ບັງຄັບ
file_list ເພື່ອໃຫ້ທັນສະໄຫມກ່ອນທີ່ມັນຈະປະຕິບັດຄໍາສັ່ງ shell. ການໃຊ້ "$(prebuild)"
ເປັນວິທີທີ່ດີທີ່ສຸດເພື່ອແກ້ໄຂບັນຫານີ້. ທ່ານອາດຈະຖືກລໍ້ລວງໃຫ້ລອງສິ່ງອື່ນເຊັ່ນ
ນີ້:

my_program : file_list $(&cat file_list)

ແຕ່ນີ້ຈະບໍ່ເຮັດວຽກເພາະວ່າ "$(&cat file_list)" ຖືກປະເມີນກ່ອນທີ່ makepp ພະຍາຍາມ
ສ້າງ "file_list".

only_phony_targets ຊື່
ສົ່ງຄືນພຽງແຕ່ຊື່ເຫຼົ່ານັ້ນຢູ່ໃນບັນຊີລາຍຊື່ທີ່ເປັນເປົ້າຫມາຍທີ່ຫຼອກລວງຂອງກົດລະບຽບບາງຢ່າງ (ບໍ່ວ່າຈະ
ກົດ​ລະ​ບຽບ​ຢ່າງ​ຊັດ​ເຈນ​ຫຼື​ຮູບ​ແບບ​)​. ເຈົ້າອາດຈະລະບຸຕົວແທນ (ລວມທັງການພິເສດຂອງ makepp
wildcard, "**") ໃນຊື່ໄຟລ໌. (ເບິ່ງຫນ້າທີ່ "$(wildcard )" ສໍາລັບລາຍລະອຽດເພີ່ມເຕີມ.
ນີ້ສາມາດຖືກນໍາໃຊ້ສໍາລັບການຈັດກຸ່ມເປົ້າຫມາຍ, ຕົວຢ່າງ:

$(ການທົດສອບ phony): $(only_phony_targets */**/tests)

ຕົ້ນກໍາເນີດ ຕົວແປ
ໂດຍໃຫ້ຊື່ຂອງຕົວແປ, ບອກທ່ານວ່າຄ່າຂອງມັນມາຈາກໃສ.

perl perlcode
ຜູ້ຜະລິດ perlcode
ປະເມີນ perlcode ໃນບລັອກແລະສົ່ງຜົນໄດ້ຮັບ. ຕົວແປທໍາອິດແມ່ນ Perl ທໍາມະດາ
ລະຫັດ, ໃນຂະນະທີ່ຕົວແປທີສອງທໍາອິດຜ່ານ perlcode ຜ່ານຕົວແປແບບ Make-style
ການຂະຫຍາຍຕົວ.

ໝາຍເຫດ, ເຊັ່ນດຽວກັບຟັງຊັນທັງໝົດ, ຕົວຂັ້ນຟັງຊັນທີ່ໃຊ້ອາດຈະບໍ່ປາກົດຢູ່ພາຍໃນ
perlcode ຢູ່ນອກສະຕຣິງທີ່ອ້າງອີງດຽວ ຫຼືຄູ່. ແຕ່ທ່ານສາມາດ double ມັນຄືກັບໃນ
ຕົວຢ່າງສຸດທ້າຍ:

VAR = 1
VAR1 = ${perl ($VAR + 1) * 3}
VAR2 = $(perl do { $VAR *= 3; ສົ່ງຄືນ $VAR + 1 } ຖ້າ $VAR)
VAR3 = $(makeperl $(VAR1) * 3 + $$VAR) # ຫນຶ່ງເຮັດໃຫ້ var ແລະຫນຶ່ງ Perl var
VAR = $((perl ຖ້າ(... ) { ... }))

phony ຄໍາເວົ້າ
ຊີ້ໃຫ້ເຫັນວ່າບັນຊີລາຍຊື່ຂອງຄໍາສັບຕ່າງໆແມ່ນເປົ້າຫມາຍ phony, ແລະສົ່ງຄືນບັນຊີລາຍຊື່ຂອງ
ເປົ້າໝາຍ. ມັນມີຈຸດປະສົງເພື່ອໃຊ້ແບບນີ້:

$(phony all): my_program

$(ລ້າງ​ຜິດ​ພາດ):
&rm -f *.o my_program

ນອກນັ້ນທ່ານຍັງສາມາດປະກາດຫນຶ່ງຫຼືຫຼາຍເປົ້າຫມາຍເປັນ phony ກັບເສັ້ນເຊັ່ນນີ້ທຸກບ່ອນໃນ
makefile ຂອງ​ທ່ານ​:

PHONY: ທັງໝົດສະອາດ

ພິມ ຂໍ້ຄວາມ
ສົ່ງຂໍ້ຄວາມອອກ ແລະສົ່ງຄືນມັນ. ນີ້ສ່ວນຫຼາຍແມ່ນເປັນປະໂຫຍດສໍາລັບການ debugging, ໃນເວລາທີ່ທ່ານບໍ່ໄດ້
ເຂົ້າໃຈວ່າເປັນຫຍັງການປ່ຽນຕົວແປຈຶ່ງໄດ້ຜົນທີ່ມັນເຮັດ. ຍົກ​ຕົວ​ຢ່າງ,

XYZ := $(ພິມ $(patsubst %.c, %o, $(SOURCE_FILES)))

ຈະພິມຜົນຂອງການໂທຫາ "patsubst".

XYZ := $(patsubst %.c, %o, $(ພິມ $(SOURCE_FILES)))

ຈະພິມອອກການໂຕ້ຖຽງສຸດທ້າຍໃຫ້ກັບການໂທ "patsubst".

ຫອຍ shell-ຄໍາສັ່ງ
ສົ່ງຄືນຜົນໄດ້ຮັບຈາກຄຳສັ່ງ shell ທີ່ໃຫ້, ໂດຍມີແຖວໃໝ່ແທນທີ່ດ້ວຍຍະຫວ່າງ.

ໝາຍເຫດ, ເຊັ່ນດຽວກັບຟັງຊັນທັງໝົດ, ຕົວຂັ້ນຟັງຊັນທີ່ໃຊ້ອາດຈະບໍ່ປາກົດຢູ່ພາຍໃນ
shell-command ພາຍນອກຂອງສະຕຣິງດຽວຫຼືສອງວົງຢືມ. ແຕ່ທ່ານສາມາດສອງເທົ່າ
ໃນຕົວຢ່າງທີສອງ:

date = $(shell date) # ດີກວ່າ: $(perl scalar localtime)
VAR = ${{shell f() { echo ສະບາຍດີ; }; f}}

xargs ຄໍາສັ່ງ, arguments[,suffix[,length]]
ສົ່ງຄືນລາຍຊື່ຄຳສັ່ງທີ່ຂັ້ນດ້ວຍແຖວໃໝ່ຂອງຄຳສັ່ງທີ່ແຕ່ລະອັນເລີ່ມຕົ້ນດ້ວຍການລະບຸໄວ້
ຄໍາສັ່ງ, ແລະສິ້ນສຸດດ້ວຍອົງປະກອບຂອງບັນຊີລາຍຊື່ຫຼາຍເທົ່າທີ່ເປັນໄປໄດ້ໂດຍບໍ່ມີການໄປ
ຄວາມຍາວ (ຄ່າເລີ່ມຕົ້ນ 1000) ຕົວອັກສອນ.

ຈຸດປະສົງຂອງການນີ້ແມ່ນເພື່ອຫຼີກເວັ້ນການ spilling ເກີນຂອບເຂດຈໍາກັດຄວາມຍາວຄໍາສັ່ງໃນລະບົບຂອງທ່ານ.
ຕົວຢ່າງ, ຖ້າມີຫຼາຍໄຟລ໌ທີ່ສ້າງຂຶ້ນ, ຫຼັງຈາກນັ້ນທ່ານອາດຈະຕ້ອງການຂອງທ່ານ
ເປົ້າຫມາຍທີ່ສະອາດ (ທີ່ທ່ານບໍ່ຄວນມີ, ເພາະວ່າ "makeppclean" ມີປະສິດທິພາບຫຼາຍ) ກັບ
ເບິ່ງບາງສິ່ງບາງຢ່າງເຊັ່ນນີ້:

$(ລ້າງ​ຜິດ​ພາດ):
$(xargs $(RM), $(only_targets **/*))

ນີ້ຍັງມີຜົນຂ້າງຄຽງທີ່ບໍ່ມີຄໍາສັ່ງໃດໆທີ່ຖືກສ້າງຂຶ້ນຖ້າຫາກວ່າບັນຊີລາຍຊື່
ເກີດ​ຂຶ້ນ​ເປັນ​ຫວ່າງ​ເປົ່າ​. ແຕ່ໃນກໍລະນີນີ້ມັນຈະດີກວ່າທີ່ຈະໃຊ້ buildin & rm,
ເນື່ອງຈາກວ່າການໂຕ້ຖຽງກັບຄໍາສັ່ງ builtin ແມ່ນຈໍາກັດພຽງແຕ່ຄວາມຊົງຈໍາຂອງ Perl:

$(ລ້າງ​ຜິດ​ພາດ):
&rm -f $(ພຽງ_ເປົ້າໝາຍ **/*)

ຖ້າມີການລະບຸການໂຕ້ຖຽງທີສາມ, ຫຼັງຈາກນັ້ນມັນຖືກນໍາໃຊ້ເພື່ອ postfix ແຕ່ລະຄໍາສັ່ງ. ນີ້​ແມ່ນ
ທີ່ເປັນປະໂຫຍດສໍາລັບການລະບຸຕົວຊີ້ທິດທາງ, ຕົວຢ່າງ (ເຖິງແມ່ນວ່າຢູ່ທີ່ນີ້ອີກເທື່ອຫນຶ່ງ & echo ຈະຊ່ວຍ):

manifest:
&rm -f $@
&ແຕະ $@
$(xargs echo, $(only_nontargets **/*), >> $@)

ບາງເອກະສານນີ້ແມ່ນອີງໃສ່ GNU ເຮັດເອກະສານ.

ກະ​ລຸ​ນາ​ສັງ​ເກດ​ວ່າ​ຖ້າ​ຫາກ​ວ່າ​ການ​ທໍາ​ງານ​ໄດ້​ຮັບ​ການ​ເອີ້ນ​ໃນ​ລະ​ຫວ່າງ​ການ​ເລີ່ມ​ຕົ້ນ makefile​, ຕົວ​ຢ່າງ​
ການຂະຫຍາຍຕົວຂອງຕົວແປການສົ່ງອອກ, ຂໍ້ຜິດພາດຫຼືຂໍ້ຄວາມເຕືອນຈະລາຍງານຕົວເລກ 0.

ໃຊ້ makepp_functions ອອນໄລນ໌ໂດຍໃຊ້ບໍລິການ onworks.net



ລ່າສຸດ Linux ແລະ Windows ໂຄງການອອນໄລນ໌