សេចក្តីផ្តើមដើម្បីធ្វើ។ បង្កើតកម្មវិធីដោយប្រើ GNU Make

នៅពេលមួយ ខ្ញុំពិតជានឹកសៀវភៅណែនាំបែបនេះសម្រាប់ការយល់ដឹងអំពីរឿងជាមូលដ្ឋានអំពីការបង្កើត។ ខ្ញុំគិតថាវានឹងគួរឱ្យចាប់អារម្មណ៍យ៉ាងហោចណាស់នរណាម្នាក់។ ថ្វីត្បិតតែបច្ចេកវិទ្យានេះកំពុងរលត់ទៅក៏ដោយ វានៅតែត្រូវបានប្រើប្រាស់ក្នុងគម្រោងជាច្រើន។ មិនមានកម្មផលគ្រប់គ្រាន់សម្រាប់មជ្ឈមណ្ឌល "ការបកប្រែ" ទេ នៅពេលដែលឱកាសកើតឡើង ខ្ញុំនឹងបន្ថែមវានៅទីនោះផងដែរ។ បន្ថែមទៅការបកប្រែ។ ប្រសិនបើមានកំហុសក្នុងការរចនា សូមចង្អុលបង្ហាញពួកគេ។ ខ្ញុំនឹងជួសជុលវា។

អត្ថបទនឹងមានការចាប់អារម្មណ៍ជាចម្បងចំពោះអ្នកដែលសិក្សាកម្មវិធីនៅក្នុង C/C++ លើប្រព័ន្ធដូច UNIX ពីឫសគល់ ដោយគ្មាន ដោយប្រើ IDE.

ការចងក្រងគម្រោងដោយដៃគឺជាកិច្ចការដ៏ធុញទ្រាន់ ជាពិសេសនៅពេលដែលមានឯកសារប្រភពច្រើនជាងមួយ ហើយសម្រាប់ពួកវានីមួយៗ អ្នកត្រូវបញ្ចូលការចងក្រង និងភ្ជាប់ពាក្យបញ្ជារាល់ពេល។ ប៉ុន្តែវាមិនអាក្រក់ទាំងអស់នោះទេ។ ឥឡូវនេះយើងនឹងរៀនពីរបៀបបង្កើត និងប្រើប្រាស់ Makefiles។ Makefile គឺជាសំណុំនៃការណែនាំសម្រាប់កម្មវិធីបង្កើត ដែលជួយអ្នកបង្កើតគម្រោងកម្មវិធីដោយចុចតែម្តង។

ដើម្បីអនុវត្ត អ្នកនឹងត្រូវបង្កើតគម្រោងមីក្រូទស្សន៍ a la Hello World ពីឯកសារចំនួនបួនក្នុងថតតែមួយ៖

main.cpp

# រួមបញ្ចូល #include "functions.h" ដោយប្រើ namespace std; int main())( print_hello(); cout<< endl; cout << "The factorial of 5 is " << factorial(5) << endl; return 0; }


សួស្តី.cpp

# រួមបញ្ចូល #include "functions.h" ដោយប្រើ namespace std; void print_hello())( cout<< "Hello World!"; }


factorial.cpp

#include "functions.h" int factorial(int n)( if(n!=1)( return(n * factorial(n-1)); ) else return 1; )


functions.h

មោឃៈ print_hello(); int factorial(int n);


អ្នកអាចទាញយកអ្វីគ្រប់យ៉ាងជាដុំពីទីនេះ
អ្នកនិពន្ធបានប្រើភាសា C++ ដែលមិនចាំបាច់ដឹងទាល់តែសោះ ហើយកម្មវិធីចងក្រង g++ ពី gcc ។ កម្មវិធីចងក្រងណាមួយផ្សេងទៀតទំនងជានឹងដំណើរការផងដែរ។ ឯកសារ​ត្រូវ​បាន​កែ​សម្រួល​បន្តិច​ដើម្បី​ឱ្យ​ពួក​វា​ត្រូវ​បាន​ចងក្រង​ជាមួយ gcc 4.7.1
បង្កើតកម្មវិធី
ប្រសិនបើអ្នករត់
ធ្វើ
បន្ទាប់មកកម្មវិធីនឹងព្យាយាមស្វែងរកឯកសារដែលមានឈ្មោះលំនាំដើម Makefile នៅក្នុងថតបច្ចុប្បន្ន ហើយប្រតិបត្តិការណែនាំពីវា។ ប្រសិនបើមាន makefiles ជាច្រើននៅក្នុងថតបច្ចុប្បន្ន អ្នកអាចចង្អុលទៅឯកសារដែលអ្នកត្រូវការដូចនេះ៖
បង្កើត -f MyMakefile
មានប៉ារ៉ាម៉ែត្រផ្សេងទៀតជាច្រើនដែលយើងមិនទាន់ត្រូវការ។ អ្នកអាចស្វែងយល់អំពីពួកគេនៅក្នុងទំព័របុរស។
ដំណើរការសាងសង់
កម្មវិធីចងក្រងយកឯកសារកូដប្រភព និងបង្កើតឯកសារវត្ថុពីពួកគេ។ បន្ទាប់មក អ្នកភ្ជាប់នឹងយកឯកសារវត្ថុ ហើយបង្កើតការប្រតិបត្តិពីពួកវា។ សន្និបាត = ការចងក្រង + ការភ្ជាប់។
ការចងក្រងដោយដៃ
វិធីងាយស្រួលបំផុតដើម្បីបង្កើតកម្មវិធី៖
g++ main.cpp hello.cpp factorial.cpp -o ជំរាបសួរ
វាមានការរអាក់រអួលក្នុងការវាយបញ្ចូលរាល់ពេល ដូច្នេះយើងនឹងធ្វើឲ្យវាដោយស្វ័យប្រវត្តិ។
Makefile សាមញ្ញបំផុត។
វាគួរតែមានផ្នែកដូចខាងក្រោមៈ
គោលដៅ៖ ក្រុមពឹងផ្អែក
ឧទាហរណ៍របស់យើង makefile នឹងមើលទៅដូចនេះ:
ទាំងអស់៖ g++ main.cpp hello.cpp factorial.cpp -o ជំរាបសួរ
សូមចំណាំថាបន្ទាត់ពាក្យបញ្ជាត្រូវតែចាប់ផ្តើមដោយផ្ទាំងមួយ! រក្សាទុកវាជា Makefile-1 នៅក្នុងថតគម្រោងរបស់អ្នក ហើយដំណើរការ build ជាមួយ make -f Makefile-1
ក្នុងឧទាហរណ៍ទីមួយ គោលដៅត្រូវបានគេហៅថាទាំងអស់។ នេះគឺជាគោលដៅលំនាំដើមសម្រាប់ makefile ហើយនឹងត្រូវបានប្រតិបត្តិប្រសិនបើគ្មានគោលដៅផ្សេងទៀតត្រូវបានបញ្ជាក់ច្បាស់លាស់។ ផងដែរ គោលដៅនេះក្នុងឧទាហរណ៍នេះមិនមានភាពអាស្រ័យទេ ដូច្នេះហើយចាប់ផ្តើមប្រតិបត្តិពាក្យបញ្ជាដែលចង់បានភ្លាមៗ។ ហើយពាក្យបញ្ជាបើកដំណើរការកម្មវិធីចងក្រង។
ការប្រើប្រាស់ភាពអាស្រ័យ
ការប្រើប្រាស់គោលដៅច្រើនក្នុង makefile មួយគឺមានប្រយោជន៍សម្រាប់គម្រោងធំៗ។ នេះគឺដោយសារតែការពិតដែលថាប្រសិនបើអ្នកផ្លាស់ប្តូរឯកសារមួយ អ្នកនឹងមិនចាំបាច់សាងសង់គម្រោងទាំងមូលឡើងវិញទេ ប៉ុន្តែអ្នកអាចទទួលបានដោយការស្ថាបនាឡើងវិញតែផ្នែកដែលបានផ្លាស់ប្តូរប៉ុណ្ណោះ។ ឧទាហរណ៍៖
ទាំងអស់៖ សួស្តី ជំរាបសួរ៖ main.o factorial.o hello.o g++ main.o factorial.o hello.o -o hello main.o: main.cpp g++ -c main.cpp factorial.o: factorial.cpp g++ -c factorial.cpp hello.o: hello.cpp g++ -c hello.cpp clean: rm -rf *.o ជំរាបសួរ
វាគួរតែត្រូវបានរក្សាទុកនៅក្រោមឈ្មោះ Makefile-2 ទាំងអស់នៅក្នុងថតតែមួយ

ឥឡូវនេះ គោលដៅទាំងអស់មានតែភាពអាស្រ័យ ប៉ុន្តែគ្មានពាក្យបញ្ជាទេ។ ក្នុងករណីនេះ នៅពេលហៅមក make នឹងប្រតិបត្តិជាបន្តបន្ទាប់នូវភាពអាស្រ័យទាំងអស់ដែលបានបញ្ជាក់នៅក្នុងឯកសារសម្រាប់គោលដៅនេះ។
គោលដៅថ្មី ស្អាត ត្រូវបានបន្ថែមផងដែរ។ វាត្រូវបានប្រើប្រាស់ជាប្រពៃណី ដើម្បីសម្អាតលទ្ធផលសាងសង់ទាំងអស់នៃគម្រោងយ៉ាងឆាប់រហ័ស។ ការសម្អាតត្រូវបានចាប់ផ្តើមដូចនេះ៖ ធ្វើឱ្យ -f Makefile-2 ស្អាត

ការប្រើប្រាស់អថេរ និងមតិយោបល់
អថេរត្រូវបានប្រើប្រាស់យ៉ាងទូលំទូលាយនៅក្នុង makefiles។ ជាឧទាហរណ៍ នេះគឺជាមធ្យោបាយងាយស្រួលមួយដើម្បីយកទៅពិចារណាពីលទ្ធភាពដែលគម្រោងនេះនឹងត្រូវបានចងក្រងជាមួយនឹងកម្មវិធីចងក្រងផ្សេង ឬជាមួយជម្រើសផ្សេងៗ។
# នេះជាការអត្ថាធិប្បាយដែលនិយាយថាអថេរ CC បញ្ជាក់អ្នកចងក្រងដែលប្រើសម្រាប់បង្កើត CC=g++ # នេះជាមតិមួយទៀត។ គាត់ពន្យល់ថាអថេរ CFLAGS មានទង់ដែលត្រូវបានបញ្ជូនទៅអ្នកចងក្រង CFLAGS=-c -Wall all: hello hello: main.o factorial.o hello.o $(CC) main.o factorial.o hello.o -o hello main .o: main.cpp $(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp $(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp $(CC) $(CFLAGS ) hello.cpp ស្អាត៖ rm -rf *.o ជំរាបសួរ
នេះគឺជា Makefile-3
អថេរគឺជារឿងងាយស្រួលណាស់។ ដើម្បីប្រើពួកវា អ្នកគ្រាន់តែកំណត់តម្លៃឱ្យពួកគេ មុនពេលប្រើវា។ បន្ទាប់ពីនោះ អ្នកអាចជំនួសតម្លៃរបស់ពួកគេនៅកន្លែងត្រឹមត្រូវតាមវិធីនេះ៖ $(VAR)
អ្វីដែលត្រូវធ្វើបន្ទាប់
បន្ទាប់ពីការណែនាំខ្លីៗនេះ អ្នកអាចព្យាយាមបង្កើត makefiles សាមញ្ញដោយខ្លួនឯងបានហើយ។ បន្ទាប់អ្នកត្រូវអានសៀវភៅសិក្សា និងសៀវភៅណែនាំដ៏ធ្ងន់ធ្ងរ។ ជាអង្កត់ធ្នូចុងក្រោយ អ្នកអាចព្យាយាមរុះរើវាដោយខ្លួនឯង ហើយដឹងពី makefile ជាសកល ដែលអាចសម្របទៅនឹងគម្រោងស្ទើរតែទាំងអស់ដោយប៉ះពីរ៖
CC=g++ CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(ប្រភព:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE ): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@
Makefile-4
សូមសំណាងល្អ!

ខ្ញុំតែងតែត្រូវបានទាក់ទាញទៅតិចតួចបំផុត។ គំនិត​ដែល​ថា​រឿង​មួយ​គួរ​ធ្វើ​រឿង​មួយ ប៉ុន្តែ​ធ្វើ​វា​ឱ្យ​បាន​ល្អ​បំផុត​តាម​ដែល​អាច​ធ្វើ​ទៅ​បាន នាំ​ឱ្យ​មាន​ការ​បង្កើត UNIX ។ ហើយទោះបីជាយូនីកមិនអាចត្រូវបានគេហៅថាជាប្រព័ន្ធសាមញ្ញបានទៀតទេ ហើយភាពតិចតួចបំផុតនៅក្នុងវាមិនងាយស្រួលមើលនោះទេ វាអាចត្រូវបានចាត់ទុកថាជាឧទាហរណ៍ច្បាស់លាស់នៃការផ្លាស់ប្តូរបរិមាណ និងគុណភាពនៃរឿងសាមញ្ញ និងអាចយល់បានជាច្រើនទៅជាស្មុគស្មាញ និងស្រអាប់។ នៅក្នុងការអភិវឌ្ឍន៍របស់វា Make បានឆ្លងកាត់ប្រហែលដូចគ្នា៖ ភាពសាមញ្ញ និងភាពច្បាស់លាស់ ជាមួយនឹងទំហំកើនឡើង ប្រែទៅជាបិសាចដ៏គួរឱ្យភ័យខ្លាច (ចងចាំអារម្មណ៍របស់អ្នកនៅពេលអ្នកបើក makefile ដំបូង)។

ការមិនអើពើនឹងការធ្វើឱ្យអស់រយៈពេលយូររបស់ខ្ញុំគឺដោយសារតែភាពងាយស្រួលនៃ IDEs ដែលបានប្រើ និងការស្ទាក់ស្ទើរក្នុងការយល់ពី "វត្ថុបុរាណ" នេះ (ជាចម្បងខ្ជិល) ។ ទោះយ៉ាងណាក៏ដោយ ប៊ូតុង ម៉ឺនុយ ជាដើម។ គុណលក្ខណៈនៃស្ទូឌីយោគ្រប់ប្រភេទបានបង្ខំខ្ញុំឱ្យស្វែងរកជម្រើសជំនួសវិធីសាស្រ្តការងារដែលខ្ញុំបានអនុវត្តកន្លងមក។ ទេ ខ្ញុំមិនបានក្លាយជាគ្រូបង្កើតទេ ប៉ុន្តែចំណេះដឹងដែលខ្ញុំទទួលបានគឺគ្រប់គ្រាន់សម្រាប់គម្រោងតូចៗរបស់ខ្ញុំ។ អត្ថបទនេះគឺមានគោលបំណងសម្រាប់អ្នកដែលដូចជាខ្ញុំទើបតែថ្មីៗនេះចង់បំបែកចេញពីទាសភាពបង្អួចដ៏កក់ក្ដៅចូលទៅក្នុងពិភព ascetic ប៉ុន្តែមានសេរីភាពនៃសែល។

ធ្វើ - ព័ត៌មានមូលដ្ឋាន

make គឺជាឧបករណ៍ប្រើប្រាស់ដែលត្រូវបានរចនាឡើងដើម្បីធ្វើស្វ័យប្រវត្តិកម្មការបំប្លែងឯកសារពីទម្រង់មួយទៅទម្រង់មួយទៀត។ ច្បាប់នៃការបំប្លែងត្រូវបានបញ្ជាក់នៅក្នុងស្គ្រីបដែលហៅថា Makefile ដែលត្រូវតែមានទីតាំងនៅឫសនៃថតការងាររបស់គម្រោង។ ស្គ្រីបខ្លួនវាមានសំណុំនៃច្បាប់ដែលនៅក្នុងវេនត្រូវបានពិពណ៌នា:

1) គោលដៅ (អ្វី ច្បាប់នេះ។ធ្វើ);
2) ព័ត៌មានលម្អិត (អ្វីដែលចាំបាច់ដើម្បីបំពេញច្បាប់និងទទួលបានគោលដៅ);
3) ពាក្យបញ្ជា (អនុវត្តការផ្លាស់ប្តូរទាំងនេះ) ។

IN ទិដ្ឋភាពទូទៅវាក្យសម្ព័ន្ធ makefile អាចត្រូវបានតំណាងដូចខាងក្រោម:

# ការកំណត់អត្តសញ្ញាណត្រូវបានអនុវត្តទាំងស្រុងដោយប្រើ តួអក្សរផ្ទាំង, # ពាក្យបញ្ជានីមួយៗត្រូវតែនាំមុខដោយការចូលបន្ទាត់<цели>: <реквизиты> <команда #1> ... <команда #n>

នោះគឺច្បាប់បង្កើតគឺជាចម្លើយចំពោះសំណួរបី៖

(តើយើងបង្កើតវាមកពីអ្វី? (ព័ត៌មានលម្អិត)) ---> [តើយើងបង្កើតវាដោយរបៀបណា? (ពាក្យបញ្ជា)] ---> (តើយើងកំពុងធ្វើអ្វី? (គោលដៅ))
វាងាយមើលឃើញថាដំណើរការបកប្រែ និងការចងក្រងសមគ្នាយ៉ាងល្អនៅក្នុងដ្យាក្រាមនេះ៖

(ឯកសារប្រភព) ---> [ផ្សាយ] ---> (ឯកសារវត្ថុ)
(ឯកសារវត្ថុ) ---> [តំណភ្ជាប់] ---> (ឯកសារដែលអាចប្រតិបត្តិបាន)

Makefile សាមញ្ញបំផុត។

ឧបមាថាយើងមានកម្មវិធីដែលមានឯកសារតែមួយ៖

/* * main.c */ #include int main() ( printf("Hello World!\n"); return 0; )
ដើម្បីចងក្រងវា makefile សាមញ្ញបំផុតគឺគ្រប់គ្រាន់ហើយ៖

ជំរាបសួរ៖ main.c gcc -o ជំរាបសួរ main.c
Makefile នេះមានច្បាប់មួយ ដែលនៅក្នុងវេនមានគោលដៅ - "ជំរាបសួរ", prop - "main.c" និងពាក្យបញ្ជា - "gcc -o hello main.c" ។ ឥឡូវនេះ ដើម្បីចងក្រង គ្រាន់តែចេញពាក្យបញ្ជា make នៅក្នុងថតការងារ។ តាមលំនាំដើម make នឹងប្រតិបត្តិច្បាប់ដំបូងបំផុត ប្រសិនបើគោលដៅប្រតិបត្តិមិនត្រូវបានបញ្ជាក់ច្បាស់នៅពេលហៅ៖

$ បង្កើត<цель>

ការចងក្រងពីប្រភពជាច្រើន។

ឧបមាថាយើងមានកម្មវិធីមួយមាន 2 ឯកសារ៖
main.c
/* * main.c */ int main() ( hello(); return 0; )
និង hello.c
/* * hello.c */ #include void hello() ( printf("Hello World!\n"); )
Makefile ដែលចងក្រងកម្មវិធីនេះអាចមើលទៅដូចនេះ៖

ជំរាបសួរ៖ main.c hello.c gcc -o ជំរាបសួរ main.c hello.c
វាមានមុខងារច្រើន ប៉ុន្តែមានគុណវិបត្តិសំខាន់មួយ៖ យើងនឹងបង្ហាញមួយណាបន្ថែមទៀត។

ការចងក្រងបន្ថែម

ចូរយើងស្រមៃថាកម្មវិធីរបស់យើងមានឯកសារប្រភពជាច្រើនឬពីរ។ យើងធ្វើការផ្លាស់ប្តូរមួយក្នុងចំនោមពួកគេ ហើយចង់កសាងវាឡើងវិញ។ ការប្រើប្រាស់វិធីសាស្រ្តដែលបានពិពណ៌នានៅក្នុងឧទាហរណ៍មុននឹងនាំឱ្យឯកសារប្រភពទាំងអស់ត្រូវបានចងក្រងម្តងទៀត ដែលនឹងជះឥទ្ធិពលអវិជ្ជមានដល់ពេលវេលានៃការចងក្រងឡើងវិញ។ ដំណោះស្រាយគឺត្រូវបែងចែកការចងក្រងជាពីរដំណាក់កាល៖ ដំណាក់កាលបកប្រែ និងដំណាក់កាលតភ្ជាប់។

ឥឡូវនេះបន្ទាប់ពីផ្លាស់ប្តូរឯកសារប្រភពណាមួយវាគ្រប់គ្រាន់ក្នុងការបកប្រែវាហើយភ្ជាប់ឯកសារវត្ថុទាំងអស់។ ក្នុងពេលជាមួយគ្នានេះ យើងរំលងដំណាក់កាលនៃការបកប្រែព័ត៌មានលម្អិតដែលមិនត្រូវបានប៉ះពាល់ដោយការផ្លាស់ប្តូរ ដែលកាត់បន្ថយពេលវេលានៃការចងក្រងជារួម។ វិធីសាស្រ្តនេះត្រូវបានគេហៅថា ការចងក្រងបន្ថែម។ ដើម្បីគាំទ្រវា ធ្វើការប្រៀបធៀបពេលវេលាផ្លាស់ប្តូរគោលដៅ និងព័ត៌មានលម្អិតរបស់វា (ដោយប្រើទិន្នន័យ ប្រព័ន្ធឯកសារ) អរគុណដែលវាសម្រេចដោយឯករាជ្យនូវច្បាប់មួយណាដែលគួរអនុវត្តតាម ហើយដែលអាចត្រូវបានមិនអើពើ៖

Main.o: main.c gcc -c -o main.o main.c hello.o: hello.c gcc -c -o hello.o hello.c hello: main.o hello.o gcc -o ជំរាបសួរមេ។ o hello.o
សាកល្បងសាងសង់គម្រោងនេះ។ ដើម្បី​បង្កើត​វា អ្នក​ត្រូវ​តែ​បញ្ជាក់​ឱ្យ​ច្បាស់​ពី​គោល​ដៅ​, i.e. ផ្តល់ពាក្យបញ្ជាធ្វើឱ្យសួស្តី។
បន្ទាប់មក ផ្លាស់ប្តូរឯកសារប្រភពណាមួយ ហើយបង្កើតវាម្តងទៀត។ សូមចំណាំថាក្នុងអំឡុងពេលចងក្រងទីពីរ មានតែឯកសារដែលបានកែប្រែប៉ុណ្ណោះនឹងត្រូវបានបកប្រែ។

នៅពេលដំណើរការ បង្កើតនឹងព្យាយាមទាញយកគោលដៅ hello ភ្លាមៗ ប៉ុន្តែដើម្បីបង្កើតវា អ្នកត្រូវការឯកសារ main.o និង hello.o ដែលមិនទាន់មាននៅឡើយ។ ដូច្នេះការអនុវត្តច្បាប់នឹងត្រូវពន្យារពេល ហើយនឹងស្វែងរកវិធានដែលពិពណ៌នាអំពីរបៀបទទួលបានព័ត៌មានលម្អិតដែលបាត់។ នៅពេលដែលព័ត៌មានលម្អិតទាំងអស់ត្រូវបានទទួល ធ្វើនឹងត្រលប់ទៅការប្រតិបត្តិគោលដៅដែលបានពន្យារពេល។ នេះមានន័យថា អនុវត្តច្បាប់ឡើងវិញ។

គោលដៅប្រឌិត

ជាការពិត មិនត្រឹមតែឯកសារពិតប៉ុណ្ណោះទេ ដែលអាចដើរតួជាអ្នកបង្កើតគោលដៅ។ អ្នក​ដែល​ត្រូវ​បង្កើត​កម្មវិធី​ពី​កូដ​ប្រភព​គួរតែ​ស្គាល់​ពាក្យ​បញ្ជា​ស្តង់ដារ​ពីរ​ក្នុង​ពិភព​យូនីក៖

$ make $ make install
ពាក្យបញ្ជា make ចងក្រងកម្មវិធី ហើយពាក្យបញ្ជា make install ដំឡើងវា។ វិធីសាស្រ្តនេះគឺងាយស្រួលណាស់ ចាប់តាំងពីអ្វីគ្រប់យ៉ាងដែលត្រូវការដើម្បីបង្កើត និងដាក់ឱ្យប្រើប្រាស់កម្មវិធីនៅក្នុង ប្រព័ន្ធគោលដៅរួមបញ្ចូលក្នុងឯកសារមួយ (សូមភ្លេចអំពីការកំណត់រចនាសម្ព័ន្ធស្គ្រីបមួយភ្លែត)។ សូមចំណាំថាក្នុងករណីដំបូងយើងមិនបញ្ជាក់ពីគោលដៅទេហើយទីពីរគោលដៅគឺមិនមែនដើម្បីបង្កើតទេ។ ដំឡើងឯកសារនិងដំណើរការនៃការដំឡើងកម្មវិធីនៅលើប្រព័ន្ធ។ អ្វីដែលគេហៅថា គោលដៅប្រឌិត (ក្លែងក្លាយ) អនុញ្ញាតឱ្យយើងអនុវត្តល្បិចបែបនេះ។ នេះគឺជាបញ្ជីខ្លីនៃគោលដៅស្តង់ដារ៖

  • ទាំងអស់គឺជាគោលដៅលំនាំដើម។ អ្នកមិនចាំបាច់បញ្ជាក់វាឱ្យច្បាស់លាស់នៅពេលហៅទូរស័ព្ទមកបង្កើតនោះទេ។
  • សម្អាត - ជម្រះថតឯកសារទាំងអស់ដែលទទួលបានជាលទ្ធផលនៃការចងក្រង។
  • ដំឡើង - អនុវត្តការដំឡើង
  • លុប - និងការលុបការដំឡើងរៀងៗខ្លួន។
ដើម្បីទប់ស្កាត់ការស្វែងរកឯកសារដែលមានឈ្មោះបែបនេះ ពួកគេគួរតែត្រូវបានកំណត់នៅក្នុង Makefile ដោយប្រើការណែនាំ .PHONY ។ ខាងក្រោមនេះគឺជាឧទាហរណ៍ Makefile ដែលមានគោលដៅទាំងអស់ សម្អាត ដំឡើង និងលុប៖

PHONY: all clean install uninstall all: hello clean: rm -rf hello *.o main.o: main.c gcc -c -o main.o main.c hello.o: hello.c gcc -c -o hello. o hello.c ជំរាបសួរ៖ main.o hello.o gcc -o hello main.o hello.o ដំឡើង៖ ដំឡើង ./hello /usr/local/bin លុប៖ rm -rf /usr/local/bin/hello
ឥឡូវនេះយើងអាចបង្កើតកម្មវិធីរបស់យើង ដំឡើង/លុបវា ហើយក៏អាចសម្អាតថតការងារដោយប្រើស្តង់ដារបង្កើតគោលដៅផងដែរ។

ចំណាំថាមិនមានពាក្យបញ្ជាដែលបានបញ្ជាក់នៅក្នុងគោលដៅទាំងអស់ទេ។ អ្វីដែលនាងត្រូវការគឺដើម្បីទទួលបានគ្រឿងជំរាបសួរ។ ដោយដឹងពីធម្មជាតិនៃការបង្កើតឡើងវិញ វាមិនពិបាកក្នុងការស្រមៃថាតើស្គ្រីបនេះនឹងដំណើរការយ៉ាងដូចម្តេចនោះទេ។ វាគួរតែត្រូវបានកត់សម្គាល់ផងដែរ។ ការយកចិត្តទុកដាក់ពិសេសនៅលើការពិតដែលថាប្រសិនបើឯកសារសួស្តីមានរួចហើយ (ទុកបន្ទាប់ពីការចងក្រងពីមុន) ហើយព័ត៌មានលម្អិតរបស់វាមិនត្រូវបានផ្លាស់ប្តូរទេនោះពាក្យបញ្ជាបង្កើត គ្មានអ្វីនឹងត្រូវបានរៀបចំឡើងវិញទេ។. នេះគឺជាតុងរួចបុរាណ។ ជាឧទាហរណ៍ តាមរយៈការផ្លាស់ប្តូរឯកសារបឋមកថាដែលមិនបានរួមបញ្ចូលក្នុងបញ្ជីព័ត៌មានលម្អិត អ្នកអាចទទួលបាន ម៉ោងយូរឈឺក្បាល។ ដូច្នេះ ដើម្បីធានាការកសាងឡើងវិញពេញលេញនៃគម្រោង អ្នកត្រូវតែសម្អាតបញ្ជីការងារជាមុនសិន៖

$ ធ្វើឱ្យស្អាត $ ធ្វើឱ្យ
អ្នកនឹងត្រូវប្រើ sudo ដើម្បីបំពេញគោលដៅដំឡើង/លុប។

អថេរ

អស់អ្នកដែលធ្លាប់ស្គាល់ច្បាប់ DRY (កុំធ្វើម្តងទៀតដោយខ្លួនឯង) ប្រហែលជាបានកត់សម្គាល់ឃើញអ្វីមួយខុសហើយ ពោលគឺ Makefile របស់យើងមាន ចំនួនធំបំណែកដដែលៗ ដែលអាចនាំឱ្យមានការភ័ន្តច្រឡំ ក្នុងអំឡុងពេលព្យាយាមពង្រីក ឬផ្លាស់ប្តូរវាជាបន្តបន្ទាប់។ នៅក្នុងភាសាចាំបាច់ យើងមានអថេរ និងថេរសម្រាប់គោលបំណងទាំងនេះ។ make ក៏មានគ្រឿងបរិក្ខារស្រដៀងគ្នាដែរ។ Variables in make ត្រូវបានដាក់ឈ្មោះថា strings ហើយត្រូវបានកំណត់យ៉ាងសាមញ្ញ៖

=
មានច្បាប់ដែលមិននិយាយដែលអ្នកគួរតែដាក់ឈ្មោះអថេរនៅក្នុង អក្សរធំ, ឧទាហរណ៍៖

SRC = main.c hello.c
នេះជារបៀបដែលយើងកំណត់បញ្ជីឯកសារប្រភព។ ដើម្បី​ប្រើ​តម្លៃ​នៃ​អថេរ វា​ត្រូវ​តែ​ត្រូវ​បាន​បង្វែរ​ដោយ​ប្រើ $(construct ); ឧទាហរណ៍ដូចនេះ៖

Gcc -o ជំរាបសួរ $(SRC)
ខាងក្រោមនេះគឺជា makefile ដែលប្រើអថេរពីរ៖ TARGET - ដើម្បីកំណត់ឈ្មោះកម្មវិធីគោលដៅ និង PREFIX - ដើម្បីកំណត់ផ្លូវសម្រាប់ដំឡើងកម្មវិធីនៅលើប្រព័ន្ធ។

TARGET = hello PREFIX = /usr/local/bin .PHONY: all clean install uninstall all: $(TARGET) clean: rm -rf $(TARGET) *.o main.o: main.c gcc -c -o main. o main.c hello.o: hello.c gcc -c -o hello.o hello.c $(TARGET): main.o hello.o gcc -o $(TARGET) main.o hello.o ដំឡើង៖ ដំឡើង $ (TARGET) $(PREFIX) លុបការដំឡើង៖ rm -rf $(PREFIX)/$(TARGET)
នេះស្អាតជាងហើយ។ ខ្ញុំគិតថាឥឡូវនេះឧទាហរណ៍ខាងលើមិនត្រូវការយោបល់ពិសេសណាមួយសម្រាប់អ្នកទេ។

អថេរស្វ័យប្រវត្តិ

អថេរស្វ័យប្រវត្តិមានគោលបំណងធ្វើឱ្យឯកសារ makefiles មានភាពសាមញ្ញ ប៉ុន្តែតាមគំនិតរបស់ខ្ញុំមានផលប៉ះពាល់អវិជ្ជមានទៅលើការអានរបស់វា។ តាមដែលអាចធ្វើបាន ខ្ញុំនឹងរាយបញ្ជីអថេរដែលប្រើញឹកញាប់បំផុតមួយចំនួននៅទីនេះ ហើយអ្វីដែលត្រូវធ្វើជាមួយពួកវា (ឬថាតើត្រូវធ្វើវាទាំងអស់) គឺអាស្រ័យលើអ្នក៖
  • $@ ឈ្មោះគោលដៅនៃច្បាប់ដែលកំពុងដំណើរការ
  • $< Имя первой зависимости обрабатываемого правила
  • $^ បញ្ជីនៃភាពអាស្រ័យទាំងអស់នៃច្បាប់ដែលបានដំណើរការ
ប្រសិនបើអ្នកណាម្នាក់ចង់បំភាន់ស្គ្រីបរបស់ពួកគេទាំងស្រុង អ្នកអាចទទួលបានការបំផុសគំនិតនៅទីនេះ៖

ខ្ញុំតែងតែត្រូវបានទាក់ទាញទៅតិចតួចបំផុត។ គំនិត​ដែល​ថា​រឿង​មួយ​គួរ​ធ្វើ​រឿង​មួយ ប៉ុន្តែ​ធ្វើ​វា​ឱ្យ​បាន​ល្អ​បំផុត​តាម​ដែល​អាច​ធ្វើ​ទៅ​បាន នាំ​ឱ្យ​មាន​ការ​បង្កើត UNIX ។ ហើយទោះបីជាយូនីកមិនអាចត្រូវបានគេហៅថាជាប្រព័ន្ធសាមញ្ញបានទៀតទេ ហើយភាពតិចតួចបំផុតនៅក្នុងវាមិនងាយស្រួលមើលនោះទេ វាអាចត្រូវបានចាត់ទុកថាជាឧទាហរណ៍ច្បាស់លាស់នៃការផ្លាស់ប្តូរបរិមាណ និងគុណភាពនៃរឿងសាមញ្ញ និងអាចយល់បានជាច្រើនទៅជាស្មុគស្មាញ និងស្រអាប់។ នៅក្នុងការអភិវឌ្ឍន៍របស់វា Make បានឆ្លងកាត់ប្រហែលដូចគ្នា៖ ភាពសាមញ្ញ និងភាពច្បាស់លាស់ ជាមួយនឹងទំហំកើនឡើង ប្រែទៅជាបិសាចដ៏គួរឱ្យភ័យខ្លាច (ចងចាំអារម្មណ៍របស់អ្នកនៅពេលអ្នកបើក makefile ដំបូង)។

ការមិនអើពើនឹងការធ្វើឱ្យអស់រយៈពេលយូររបស់ខ្ញុំគឺដោយសារតែភាពងាយស្រួលនៃ IDEs ដែលបានប្រើ និងការស្ទាក់ស្ទើរក្នុងការយល់ពី "វត្ថុបុរាណ" នេះ (ជាចម្បងខ្ជិល) ។ ទោះយ៉ាងណាក៏ដោយ ប៊ូតុង ម៉ឺនុយ ជាដើម។ គុណលក្ខណៈនៃស្ទូឌីយោគ្រប់ប្រភេទបានបង្ខំខ្ញុំឱ្យស្វែងរកជម្រើសជំនួសវិធីសាស្រ្តការងារដែលខ្ញុំបានអនុវត្តកន្លងមក។ ទេ ខ្ញុំមិនបានក្លាយជាគ្រូបង្កើតទេ ប៉ុន្តែចំណេះដឹងដែលខ្ញុំទទួលបានគឺគ្រប់គ្រាន់សម្រាប់គម្រោងតូចៗរបស់ខ្ញុំ។ អត្ថបទនេះគឺមានគោលបំណងសម្រាប់អ្នកដែលដូចជាខ្ញុំទើបតែថ្មីៗនេះចង់បំបែកចេញពីទាសភាពបង្អួចដ៏កក់ក្ដៅចូលទៅក្នុងពិភព ascetic ប៉ុន្តែមានសេរីភាពនៃសែល។

ធ្វើ - ព័ត៌មានមូលដ្ឋាន

make គឺជាឧបករណ៍ប្រើប្រាស់ដែលត្រូវបានរចនាឡើងដើម្បីធ្វើស្វ័យប្រវត្តិកម្មការបំប្លែងឯកសារពីទម្រង់មួយទៅទម្រង់មួយទៀត។ ច្បាប់នៃការបំប្លែងត្រូវបានបញ្ជាក់នៅក្នុងស្គ្រីបដែលហៅថា Makefile ដែលត្រូវតែមានទីតាំងនៅឫសនៃថតការងាររបស់គម្រោង។ ស្គ្រីបខ្លួនវាមានសំណុំនៃច្បាប់ដែលនៅក្នុងវេនត្រូវបានពិពណ៌នា:

1) គោលដៅ (អ្វីដែលច្បាប់នេះធ្វើ);
2) ព័ត៌មានលម្អិត (អ្វីដែលចាំបាច់ដើម្បីបំពេញច្បាប់និងទទួលបានគោលដៅ);
3) ពាក្យបញ្ជា (អនុវត្តការផ្លាស់ប្តូរទាំងនេះ) ។

ជាទូទៅ វាក្យសម្ព័ន្ធ makefile អាចត្រូវបានតំណាងដូចខាងក្រោមៈ

# ការចូលបន្ទាត់ត្រូវបានអនុវត្តទាំងស្រុងដោយប្រើតួអក្សរផ្ទាំង # ពាក្យបញ្ជានីមួយៗត្រូវតែនាំមុខដោយការចូលបន្ទាត់<цели>: <реквизиты> <команда #1> ... <команда #n>

នោះគឺច្បាប់បង្កើតគឺជាចម្លើយចំពោះសំណួរបី៖

(តើយើងបង្កើតវាមកពីអ្វី? (ព័ត៌មានលម្អិត)) ---> [តើយើងបង្កើតវាដោយរបៀបណា? (ពាក្យបញ្ជា)] ---> (តើយើងកំពុងធ្វើអ្វី? (គោលដៅ))
វាងាយមើលឃើញថាដំណើរការបកប្រែ និងការចងក្រងសមគ្នាយ៉ាងល្អនៅក្នុងដ្យាក្រាមនេះ៖

(ឯកសារប្រភព) ---> [ផ្សាយ] ---> (ឯកសារវត្ថុ)
(ឯកសារវត្ថុ) ---> [តំណភ្ជាប់] ---> (ឯកសារដែលអាចប្រតិបត្តិបាន)

Makefile សាមញ្ញបំផុត។

ឧបមាថាយើងមានកម្មវិធីដែលមានឯកសារតែមួយ៖

/* * main.c */ #include int main() ( printf("Hello World!\n"); return 0; )
ដើម្បីចងក្រងវា makefile សាមញ្ញបំផុតគឺគ្រប់គ្រាន់ហើយ៖

ជំរាបសួរ៖ main.c gcc -o ជំរាបសួរ main.c
Makefile នេះមានច្បាប់មួយ ដែលនៅក្នុងវេនមានគោលដៅ - "ជំរាបសួរ", prop - "main.c" និងពាក្យបញ្ជា - "gcc -o hello main.c" ។ ឥឡូវនេះ ដើម្បីចងក្រង គ្រាន់តែចេញពាក្យបញ្ជា make នៅក្នុងថតការងារ។ តាមលំនាំដើម make នឹងប្រតិបត្តិច្បាប់ដំបូងបំផុត ប្រសិនបើគោលដៅប្រតិបត្តិមិនត្រូវបានបញ្ជាក់ច្បាស់នៅពេលហៅ៖

$ បង្កើត<цель>

ការចងក្រងពីប្រភពជាច្រើន។

ឧបមាថាយើងមានកម្មវិធីមួយមាន 2 ឯកសារ៖
main.c
/* * main.c */ int main() ( hello(); return 0; )
និង hello.c
/* * hello.c */ #include void hello() ( printf("Hello World!\n"); )
Makefile ដែលចងក្រងកម្មវិធីនេះអាចមើលទៅដូចនេះ៖

ជំរាបសួរ៖ main.c hello.c gcc -o ជំរាបសួរ main.c hello.c
វាមានមុខងារច្រើន ប៉ុន្តែមានគុណវិបត្តិសំខាន់មួយ៖ យើងនឹងបង្ហាញមួយណាបន្ថែមទៀត។

ការចងក្រងបន្ថែម

ចូរយើងស្រមៃថាកម្មវិធីរបស់យើងមានឯកសារប្រភពជាច្រើនឬពីរ។ យើងធ្វើការផ្លាស់ប្តូរមួយក្នុងចំនោមពួកគេ ហើយចង់កសាងវាឡើងវិញ។ ការប្រើប្រាស់វិធីសាស្រ្តដែលបានពិពណ៌នានៅក្នុងឧទាហរណ៍មុននឹងនាំឱ្យឯកសារប្រភពទាំងអស់ត្រូវបានចងក្រងម្តងទៀត ដែលនឹងជះឥទ្ធិពលអវិជ្ជមានដល់ពេលវេលានៃការចងក្រងឡើងវិញ។ ដំណោះស្រាយគឺត្រូវបែងចែកការចងក្រងជាពីរដំណាក់កាល៖ ដំណាក់កាលបកប្រែ និងដំណាក់កាលតភ្ជាប់។

ឥឡូវនេះបន្ទាប់ពីផ្លាស់ប្តូរឯកសារប្រភពណាមួយវាគ្រប់គ្រាន់ក្នុងការបកប្រែវាហើយភ្ជាប់ឯកសារវត្ថុទាំងអស់។ ក្នុងពេលជាមួយគ្នានេះ យើងរំលងដំណាក់កាលនៃការបកប្រែព័ត៌មានលម្អិតដែលមិនត្រូវបានប៉ះពាល់ដោយការផ្លាស់ប្តូរ ដែលកាត់បន្ថយពេលវេលានៃការចងក្រងជារួម។ វិធីសាស្រ្តនេះត្រូវបានគេហៅថា ការចងក្រងបន្ថែម។ ដើម្បីគាំទ្រវា ធ្វើការប្រៀបធៀបពេលវេលានៃការផ្លាស់ប្តូរគោលដៅ និងព័ត៌មានលម្អិតរបស់វា (ដោយប្រើទិន្នន័យប្រព័ន្ធឯកសារ) អរគុណដែលវាសម្រេចចិត្តដោយឯករាជ្យថាតើច្បាប់មួយណាគួរត្រូវបានប្រតិបត្តិ ហើយអ្វីដែលអាចត្រូវបានមិនអើពើ៖

Main.o: main.c gcc -c -o main.o main.c hello.o: hello.c gcc -c -o hello.o hello.c hello: main.o hello.o gcc -o ជំរាបសួរមេ។ o hello.o
សាកល្បងសាងសង់គម្រោងនេះ។ ដើម្បី​បង្កើត​វា អ្នក​ត្រូវ​តែ​បញ្ជាក់​ឱ្យ​ច្បាស់​ពី​គោល​ដៅ​, i.e. ផ្តល់ពាក្យបញ្ជាធ្វើឱ្យសួស្តី។
បន្ទាប់មក ផ្លាស់ប្តូរឯកសារប្រភពណាមួយ ហើយបង្កើតវាម្តងទៀត។ សូមចំណាំថាក្នុងអំឡុងពេលចងក្រងទីពីរ មានតែឯកសារដែលបានកែប្រែប៉ុណ្ណោះនឹងត្រូវបានបកប្រែ។

នៅពេលដំណើរការ បង្កើតនឹងព្យាយាមទាញយកគោលដៅ hello ភ្លាមៗ ប៉ុន្តែដើម្បីបង្កើតវា អ្នកត្រូវការឯកសារ main.o និង hello.o ដែលមិនទាន់មាននៅឡើយ។ ដូច្នេះការអនុវត្តច្បាប់នឹងត្រូវពន្យារពេល ហើយនឹងស្វែងរកវិធានដែលពិពណ៌នាអំពីរបៀបទទួលបានព័ត៌មានលម្អិតដែលបាត់។ នៅពេលដែលព័ត៌មានលម្អិតទាំងអស់ត្រូវបានទទួល ធ្វើនឹងត្រលប់ទៅការប្រតិបត្តិគោលដៅដែលបានពន្យារពេល។ នេះមានន័យថា អនុវត្តច្បាប់ឡើងវិញ។

គោលដៅប្រឌិត

ជាការពិត មិនត្រឹមតែឯកសារពិតប៉ុណ្ណោះទេ ដែលអាចដើរតួជាអ្នកបង្កើតគោលដៅ។ អ្នក​ដែល​ត្រូវ​បង្កើត​កម្មវិធី​ពី​កូដ​ប្រភព​គួរតែ​ស្គាល់​ពាក្យ​បញ្ជា​ស្តង់ដារ​ពីរ​ក្នុង​ពិភព​យូនីក៖

$ make $ make install
ពាក្យបញ្ជា make ចងក្រងកម្មវិធី ហើយពាក្យបញ្ជា make install ដំឡើងវា។ វិធីសាស្រ្តនេះគឺងាយស្រួលណាស់ព្រោះអ្វីគ្រប់យ៉ាងដែលត្រូវការដើម្បីបង្កើត និងដាក់ពង្រាយកម្មវិធីនៅលើប្រព័ន្ធគោលដៅត្រូវបានរួមបញ្ចូលក្នុងឯកសារមួយ (សូមភ្លេចអំពីស្គ្រីបកំណត់រចនាសម្ព័ន្ធមួយភ្លែត)។ សូមចំណាំថាក្នុងករណីដំបូងយើងមិនបញ្ជាក់ពីគោលដៅទេហើយទីពីរគោលដៅមិនមែនជាការបង្កើតឯកសារដំឡើងទាល់តែសោះតែជាដំណើរការនៃការដំឡើងកម្មវិធីនៅលើប្រព័ន្ធ។ អ្វីដែលគេហៅថា គោលដៅប្រឌិត (ក្លែងក្លាយ) អនុញ្ញាតឱ្យយើងអនុវត្តល្បិចបែបនេះ។ នេះគឺជាបញ្ជីខ្លីៗនៃគោលដៅស្តង់ដារ៖

  • ទាំងអស់គឺជាគោលដៅលំនាំដើម។ អ្នកមិនចាំបាច់បញ្ជាក់វាឱ្យច្បាស់លាស់នៅពេលហៅទូរស័ព្ទមកបង្កើតនោះទេ។
  • សម្អាត - ជម្រះថតឯកសារទាំងអស់ដែលទទួលបានជាលទ្ធផលនៃការចងក្រង។
  • ដំឡើង - អនុវត្តការដំឡើង
  • លុប - និងការលុបការដំឡើងរៀងៗខ្លួន។
ដើម្បីទប់ស្កាត់ការស្វែងរកឯកសារដែលមានឈ្មោះបែបនេះ ពួកគេគួរតែត្រូវបានកំណត់នៅក្នុង Makefile ដោយប្រើការណែនាំ .PHONY ។ ខាងក្រោមនេះគឺជាឧទាហរណ៍ Makefile ដែលមានគោលដៅទាំងអស់ សម្អាត ដំឡើង និងលុប៖

PHONY: all clean install uninstall all: hello clean: rm -rf hello *.o main.o: main.c gcc -c -o main.o main.c hello.o: hello.c gcc -c -o hello. o hello.c ជំរាបសួរ៖ main.o hello.o gcc -o hello main.o hello.o ដំឡើង៖ ដំឡើង ./hello /usr/local/bin លុប៖ rm -rf /usr/local/bin/hello
ឥឡូវនេះយើងអាចបង្កើតកម្មវិធីរបស់យើង ដំឡើង/លុបវា ហើយក៏អាចសម្អាតថតការងារដោយប្រើស្តង់ដារបង្កើតគោលដៅផងដែរ។

ចំណាំថាមិនមានពាក្យបញ្ជាដែលបានបញ្ជាក់នៅក្នុងគោលដៅទាំងអស់ទេ។ អ្វីដែលនាងត្រូវការគឺដើម្បីទទួលបានគ្រឿងជំរាបសួរ។ ដោយដឹងពីធម្មជាតិនៃការបង្កើតឡើងវិញ វាមិនពិបាកក្នុងការស្រមៃថាតើស្គ្រីបនេះនឹងដំណើរការយ៉ាងដូចម្តេចនោះទេ។ អ្នកក៏គួរយកចិត្តទុកដាក់ជាពិសេសចំពោះការពិតដែលថាប្រសិនបើឯកសារសួស្តីមានរួចហើយ (ទុកបន្ទាប់ពីការចងក្រងពីមុន) ហើយព័ត៌មានលម្អិតរបស់វាមិនត្រូវបានផ្លាស់ប្តូរទេនោះពាក្យបញ្ជាបង្កើត។ គ្មានអ្វីនឹងត្រូវបានរៀបចំឡើងវិញទេ។. នេះគឺជាតុងរួចបុរាណ។ ជាឧទាហរណ៍ ការផ្លាស់ប្តូរឯកសារបឋមកថាដែលមិនបានបញ្ចូលក្នុងបញ្ជីព័ត៌មានលម្អិតអាចបណ្តាលឱ្យមានការឈឺក្បាលជាច្រើនម៉ោង។ ដូច្នេះ ដើម្បីធានាការកសាងឡើងវិញពេញលេញនៃគម្រោង អ្នកត្រូវតែជម្រះបញ្ជីការងារជាមុនសិន៖

$ ធ្វើឱ្យស្អាត $ ធ្វើឱ្យ
អ្នកនឹងត្រូវប្រើ sudo ដើម្បីបំពេញគោលដៅដំឡើង/លុប។

អថេរ

អស់អ្នកដែលធ្លាប់ស្គាល់ច្បាប់ DRY (កុំធ្វើម្តងទៀតដោយខ្លួនឯង) ប្រហែលជាបានកត់សម្គាល់ឃើញអ្វីមួយខុសហើយ ពោលគឺ Makefile របស់យើងមានបំណែកជាច្រើនដដែលៗ ដែលអាចនាំឱ្យមានការភ័ន្តច្រឡំក្នុងការព្យាយាមពង្រីក ឬផ្លាស់ប្តូរវាជាបន្តបន្ទាប់។ នៅក្នុងភាសាចាំបាច់សម្រាប់ទាំងនេះ សម្រាប់គោលបំណងនេះ យើងមាន variables និង constants make ក៏មាន variables នៅក្នុង make ត្រូវបានគេដាក់ឈ្មោះថា strings ហើយត្រូវបានកំណត់យ៉ាងសាមញ្ញ។

=
មានច្បាប់ដែលមិនអាចនិយាយបាន ដែលអថេរគួរត្រូវបានដាក់ឈ្មោះជាអក្សរធំ ឧទាហរណ៍៖

SRC = main.c hello.c
នេះជារបៀបដែលយើងកំណត់បញ្ជីឯកសារប្រភព។ ដើម្បី​ប្រើ​តម្លៃ​នៃ​អថេរ វា​ត្រូវ​តែ​ត្រូវ​បាន​បង្វែរ​ដោយ​ប្រើ $(construct ); ឧទាហរណ៍ដូចនេះ៖

Gcc -o ជំរាបសួរ $(SRC)
ខាងក្រោមនេះគឺជា makefile ដែលប្រើអថេរពីរ៖ TARGET - ដើម្បីកំណត់ឈ្មោះកម្មវិធីគោលដៅ និង PREFIX - ដើម្បីកំណត់ផ្លូវសម្រាប់ដំឡើងកម្មវិធីនៅលើប្រព័ន្ធ។

TARGET = hello PREFIX = /usr/local/bin .PHONY: all clean install uninstall all: $(TARGET) clean: rm -rf $(TARGET) *.o main.o: main.c gcc -c -o main. o main.c hello.o: hello.c gcc -c -o hello.o hello.c $(TARGET): main.o hello.o gcc -o $(TARGET) main.o hello.o ដំឡើង៖ ដំឡើង $ (TARGET) $(PREFIX) លុបការដំឡើង៖ rm -rf $(PREFIX)/$(TARGET)
នេះស្អាតជាងហើយ។ ខ្ញុំគិតថាឥឡូវនេះឧទាហរណ៍ខាងលើមិនត្រូវការយោបល់ពិសេសណាមួយសម្រាប់អ្នកទេ។

អថេរស្វ័យប្រវត្តិ

អថេរស្វ័យប្រវត្តិមានគោលបំណងធ្វើឱ្យឯកសារ makefiles មានភាពសាមញ្ញ ប៉ុន្តែតាមគំនិតរបស់ខ្ញុំមានផលប៉ះពាល់អវិជ្ជមានទៅលើការអានរបស់វា។ តាមដែលអាចធ្វើបាន ខ្ញុំនឹងរាយបញ្ជីអថេរដែលប្រើញឹកញាប់បំផុតមួយចំនួននៅទីនេះ ហើយអ្វីដែលត្រូវធ្វើជាមួយពួកវា (ឬថាតើត្រូវធ្វើវាទាំងអស់) គឺអាស្រ័យលើអ្នក៖
  • $@ ឈ្មោះគោលដៅនៃច្បាប់ដែលកំពុងដំណើរការ
  • $< Имя первой зависимости обрабатываемого правила
  • $^ បញ្ជីនៃភាពអាស្រ័យទាំងអស់នៃច្បាប់ដែលបានដំណើរការ
ប្រសិនបើអ្នកណាម្នាក់ចង់បំភាន់ស្គ្រីបរបស់ពួកគេទាំងស្រុង អ្នកអាចទទួលបានការបំផុសគំនិតនៅទីនេះ៖

នៅក្នុងសៀវភៅនេះ ខ្ញុំបានរៀបរាប់អំពីបទពិសោធន៍របស់ខ្ញុំជាមួយនឹងឧបករណ៍ប្រើប្រាស់ GNU បង្កើតហើយជាពិសេស បច្ចេកទេសរបស់ខ្ញុំសម្រាប់រៀបចំ makefiles។ ខ្ញុំ​ចាត់​ទុក​បច្ចេកទេស​របស់​ខ្ញុំ​ងាយ​ស្រួល​ណាស់ ព្រោះ​វា​រួម​បញ្ចូល៖ ការ​បង្កើត​បញ្ជី​ឯកសារ​ដោយ​ស្វ័យ​ប្រវត្តិ​ជាមួយ​នឹង​កូដ​ប្រភព ការបង្កើតដោយស្វ័យប្រវត្តិការពឹងផ្អែកលើឯកសារដែលបានរួមបញ្ចូល (ដោយប្រើកម្មវិធីចងក្រង GCC) និងការជួបប្រជុំគ្នា "ប៉ារ៉ាឡែល" នៃការបំបាត់កំហុស និងកំណែដំណើរការរបស់កម្មវិធី។

  • ការបង្កើតបញ្ជីឯកសារដោយស្វ័យប្រវត្តិដែលមានអត្ថបទប្រភព
  • ការបង្កើតភាពអាស្រ័យដោយស្វ័យប្រវត្តិលើឯកសារដែលបានរួមបញ្ចូល (ដោយប្រើកម្មវិធីចងក្រង GCC)
  • ការជួបប្រជុំគ្នា "ប៉ារ៉ាឡែល" នៃការបំបាត់កំហុស និងកំណែដំណើរការរបស់កម្មវិធី

សៀវភៅរបស់ខ្ញុំត្រូវបានរៀបចំតាមរបៀបមិនធម្មតា។ តាមក្បួនសៀវភៅត្រូវបានបង្កើតឡើងតាមគោលការណ៍ "ពីសាមញ្ញទៅស្មុគស្មាញ" ។ នេះងាយស្រួលសម្រាប់អ្នកចាប់ផ្តើមដំបូង ប៉ុន្តែអាចជាបញ្ហាប្រឈមសម្រាប់អ្នកជំនាញ។ អ្នកសរសេរកម្មវិធីដែលមានបទពិសោធន៍នឹងត្រូវបង្ខំឱ្យ "ឆ្លងកាត់" សៀវភៅដោយរំលងជំពូកជាមួយនឹងព័ត៌មានដែលគាត់ស្គាល់។ ខ្ញុំ​បាន​សម្រេច​ចិត្ត​បង្កើត​សៀវភៅ​នេះ​តាម​គោលការណ៍​ផ្សេង។ "ភាពសម្បូរបែប" ទាំងមូលនៃសៀវភៅដែលជា "គំនិតចម្បង" របស់វាមាននៅក្នុងជំពូកទីមួយ។ ជំពូក​ដែល​នៅ​សល់​គឺ​ជា​ផ្នែក​បន្ថែម​ច្រើន​ឬ​តិច។

នៅដើមជំពូកនីមួយៗ ខ្ញុំបានរៀបរាប់យ៉ាងខ្លីអំពីអ្វីដែលវានឹងគ្របដណ្តប់ និងចំណេះដឹងអ្វីខ្លះដែលអ្នកត្រូវមាន ដើម្បីអាចយល់បានដោយជោគជ័យនូវសម្ភារៈដែលបង្ហាញនៅក្នុងជំពូក។ សម្រាប់អ្នកដែលយល់ថាខ្លួនមិនសូវពូកែក្នុងប្រធានបទនោះ ខ្ញុំសូមបង្ហាញជំពូកបន្ថែមដែលគួរអានជាមុនសិន។

សម្រាប់ការងារដែលខ្ញុំបានប្រើ GNU បង្កើតកំណែ 3.79.1 ។ កំណែចាស់មួយចំនួន GNU បង្កើត(ឧទាហរណ៍ កំណែ 3.76.1 ពីការចែកចាយ Slackware 3.5) ប្រហែលជាមិនដំណើរការត្រឹមត្រូវជាមួយនឹងឧទាហរណ៍នៃរចនាសម្ព័ន្ធ makefile "ប្រពៃណី" (ជាក់ស្តែងពួកគេមិន "យល់ឃើញ" ឯកសណ្ឋានចាស់កំណត់ត្រានៃច្បាប់គំរូ) ។

1. វិធីសាស្រ្តរបស់ខ្ញុំក្នុងការប្រើ GNU Make

នៅក្នុងជំពូកនេះ ខ្ញុំបានរៀបរាប់អំពីវិធីសាស្រ្តរបស់ខ្ញុំក្នុងការបង្កើត makefiles សម្រាប់ការសាងសង់គម្រោងដោយប្រើកម្មវិធី GNU បង្កើតនិងចងក្រង GCC (ការប្រមូល GNU Compiler) វាត្រូវបានសន្មត់ថាអ្នកស៊ាំជាមួយឧបករណ៍ប្រើប្រាស់ GNU បង្កើត. បើ​មិន​ដូច្នោះ​ទេ សូម​អាន​សិន។

១.១. គម្រោងគំរូ

ជាឧទាហរណ៍ខ្ញុំនឹងប្រើគម្រោង "សម្មតិកម្ម" - កម្មវិធីនិពន្ធអត្ថបទ។ វាមានឯកសារជាច្រើនដែលមានអត្ថបទប្រភពជាភាសា C++ (main.cpp, Editor.cpp, TextLine.cpp) និងមួយចំនួនរួមមានឯកសារ ( main.h,Editor.h, TextLine.h) ប្រសិនបើអ្នកមានសិទ្ធិចូលប្រើអ៊ីនធឺណិត នោះកំណែ "អេឡិចត្រូនិក" នៃឧទាហរណ៍ដែលបានផ្តល់ឱ្យនៅក្នុងសៀវភៅអាចទទួលបាននៅលើទំព័រដើមរបស់ខ្ញុំនៅ www.geocities.com/SiliconValley/Office/6533. ប្រសិនបើអ៊ិនធឺណិតមិនមានសម្រាប់អ្នកទេនោះបញ្ជីនៃឯកសារដែលត្រូវបានប្រើក្នុងឧទាហរណ៍ត្រូវបានផ្តល់ជូន។

១.២. វិធី "ប្រពៃណី" នៃការបង្កើតឯកសារ

នៅក្នុងឧទាហរណ៍ដំបូង makefile ត្រូវបានសាងសង់តាមវិធី "ប្រពៃណី" ។ ឯកសារប្រភពទាំងអស់នៃកម្មវិធីដែលបានជួបប្រជុំគ្នាមានទីតាំងនៅក្នុងថតតែមួយ៖

  • example_1-ប្រពៃណី/
    • main.cpp
    • main.h
    • Editor.cpp
    • Editor.h
    • TextLine.cpp
    • TextLine.h
    • ធ្វើឯកសារ

វាត្រូវបានសន្មត់ថាកម្មវិធីចងក្រងត្រូវបានប្រើដើម្បីចងក្រងកម្មវិធី GCCហើយឯកសារវត្ថុមានផ្នែកបន្ថែម " .o". ឯកសារ ធ្វើឯកសារមើលទៅដូចនេះ៖

# # example_1-traditional/Makefile # # ឧទាហរណ៍នៃរចនាសម្ព័ន្ធ makefile "ប្រពៃណី" # iEdit: main.o Editor.o TextLine.o gcc $^ -o $@ .cpp.o: gcc -c $< main.o: main.h Editor.h TextLine.h Editor.o: Editor.h TextLine.h TextLine.o: TextLine.h

ច្បាប់ទីមួយបង្ខំ ធ្វើភ្ជាប់កម្មវិធីឡើងវិញនៅពេលដែលឯកសារវត្ថុណាមួយផ្លាស់ប្តូរ។ ច្បាប់ទីពីរចែងថាឯកសារវត្ថុអាស្រ័យលើឯកសារប្រភពដែលត្រូវគ្នា។ រាល់ការផ្លាស់ប្តូរទៅឯកសារប្រភពនឹងធ្វើឱ្យវាត្រូវបានចងក្រងឡើងវិញ។ ច្បាប់មួយចំនួនបន្ទាប់បង្ហាញថាតើឯកសារបឋមកថាណាដែលឯកសារវត្ថុនីមួយៗអាស្រ័យលើ។ វិធីបង្កើត makefile នេះហាក់ដូចជាមិនងាយស្រួលសម្រាប់ខ្ញុំទេ ដោយសារ៖

  • វាត្រូវបានទាមទារដើម្បី "បញ្ជាក់" បញ្ជីឯកសារវត្ថុទាំងអស់ដែលកម្មវិធីត្រូវបានភ្ជាប់
  • វាត្រូវបានទាមទារដើម្បី "បញ្ជាក់" បញ្ជីដែលឯកសារបឋមកថាឯកសារវត្ថុជាក់លាក់អាស្រ័យលើ
  • ឯកសារដែលអាចប្រតិបត្តិបាននៃកម្មវិធីត្រូវបានដាក់ក្នុងថត "បច្ចុប្បន្ន" ។ ប្រសិនបើខ្ញុំត្រូវមានកំណែផ្សេងៗគ្នាជាច្រើននៃកម្មវិធី (ឧទាហរណ៍ បំបាត់កំហុស និងដំណើរការ) បន្ទាប់មករាល់ពេលដែលខ្ញុំផ្លាស់ទីពីកំណែមួយទៅកំណែមួយទៀត ការចងក្រងកម្មវិធីឡើងវិញពេញលេញគឺត្រូវបានទាមទារ ដើម្បីជៀសវាង "ការលាយ" ដែលមិនចង់បាន។ កំណែផ្សេងគ្នាឯកសារវត្ថុ។

វាច្បាស់ណាស់នោះ។ វិធីប្រពៃណីការបង្កើត makefiles គឺនៅឆ្ងាយពីឧត្តមគតិ។ មធ្យោបាយតែមួយគត់ដែលវិធីសាស្រ្តនេះអាចមានភាពងាយស្រួលគឺ "ភាពឆបគ្នា" របស់វា។ ជាក់ស្តែងសូម្បីតែកំណែ "បុរាណ" ឬ "កម្រនិងអសកម្ម" បំផុតនឹងដំណើរការល្អជាមួយឯកសារបែបនេះ ធ្វើ(ឧទាហរណ៍ nmakeក្រុមហ៊ុន ក្រុមហ៊ុន Microsoft) ប្រសិនបើ "ភាពឆបគ្នា" បែបនេះមិនចាំបាច់ទេនោះអ្នកអាចធ្វើឱ្យជីវិតរបស់អ្នកកាន់តែងាយស្រួលដោយប្រើ លទ្ធភាពធំទូលាយឧបករណ៍ប្រើប្រាស់ GNU បង្កើត. ចូរយើងព្យាយាមកម្ចាត់ចំណុចខ្វះខាតនៃវិធីសាស្រ្ត "ប្រពៃណី" ។

១.៣. ការបង្កើតបញ្ជីឯកសារវត្ថុដោយស្វ័យប្រវត្តិ

"ដោយដៃ" ការរាយបញ្ជីឯកសារវត្ថុទាំងអស់ដែលរួមបញ្ចូលក្នុងកម្មវិធីគឺជាការងារដ៏ធុញទ្រាន់ណាស់ ដែលសំណាងល្អអាចដំណើរការដោយស្វ័យប្រវត្តិ។ ជាការពិតណាស់ "ល្បិចសាមញ្ញ" ដូចជា:

កែសម្រួល៖ *.o gcc$< -o $@

នឹងមិនដំណើរការទេព្រោះមានតែ ដែលមានស្រាប់នៅពេលនេះឯកសារវត្ថុ។ ខ្ញុំប្រើវិធីសាស្រ្តស្មុគ្រស្មាញបន្តិច ដែលផ្អែកលើការសន្មត់នោះ។ ទាំងអស់។ឯកសារប្រភពត្រូវតែចងក្រង និងភ្ជាប់ទៅក្នុងកម្មវិធីដែលបានជួបប្រជុំគ្នា។ បច្ចេកទេសរបស់ខ្ញុំមានពីរជំហាន៖

  • ទទួលបានបញ្ជីឯកសារទាំងអស់ដែលមានកូដប្រភពនៃកម្មវិធី (ឯកសារទាំងអស់ដែលមានផ្នែកបន្ថែម " .cpp") ដើម្បីធ្វើដូចនេះអ្នកអាចប្រើមុខងារ អក្សរជំនួស.
  • បំលែងបញ្ជីឯកសារប្រភពទៅជាបញ្ជីឯកសារវត្ថុ (ជំនួសផ្នែកបន្ថែម " .cpp"ពង្រីក" .o") ដើម្បីធ្វើដូចនេះអ្នកអាចប្រើមុខងារ អនុគ្រោះ.

ឧទាហរណ៍ខាងក្រោមមាន កំណែដែលបានកែប្រែ makefile:

  • example_2-auto_obj /
    • main.cpp
    • main.h
    • Editor.cpp
    • Editor.h
    • TextLine.cpp
    • TextLine.h
    • ធ្វើឯកសារ

ឯកសារ ធ្វើឯកសារឥឡូវនេះមើលទៅដូចនេះ៖

# # example_2-auto_obj/Makefile # # ឧទាហរណ៍នៃការកសាងបញ្ជីឯកសារវត្ថុដោយស្វ័យប្រវត្តិ # iEdit៖ $(patsubst %.cpp,%o,$(wildcard *.cpp)) gcc $^ -o $@ %.o ៖ % cpp gcc -c $< main.o: main.h Editor.h TextLine.h Editor.o: Editor.h TextLine.h TextLine.o: TextLine.h

បញ្ជីឯកសារវត្ថុកម្មវិធីត្រូវបានបង្កើតដោយស្វ័យប្រវត្តិ។ ទីមួយដោយប្រើមុខងារ អក្សរជំនួសបង្កើតបញ្ជីឯកសារទាំងអស់ដែលមានផ្នែកបន្ថែម " .cpp" ដែលមានទីតាំងនៅក្នុងថតគម្រោង។ បន្ទាប់មកដោយប្រើមុខងារ អនុគ្រោះបញ្ជីលទ្ធផលនៃឯកសារប្រភពត្រូវបានបំប្លែងទៅជាបញ្ជីឯកសារវត្ថុ។ ឥឡូវនេះ makefile បានក្លាយជាសកលជាងមុន - ជាមួយនឹងការផ្លាស់ប្តូរតិចតួច វាអាចត្រូវបានប្រើដើម្បីបង្កើតកម្មវិធីផ្សេងៗ។

១.៤. ការស្ថាបនាដោយស្វ័យប្រវត្តិនៃភាពអាស្រ័យនៅលើឯកសារបឋមកថា

"ដោយដៃ" ការចុះបញ្ជីភាពអាស្រ័យនៃឯកសារវត្ថុនៅលើឯកសារបឋមកថាគឺកាន់តែធុញទ្រាន់និងមិនរីករាយជាងការចុះបញ្ជីឯកសារវត្ថុ "ដោយដៃ" ។ វាជាការចាំបាច់ដើម្បីបង្ហាញពីភាពអាស្រ័យបែបនេះ - ក្នុងអំឡុងពេលនៃការអភិវឌ្ឍន៍កម្មវិធី ឯកសារបឋមកថាអាចផ្លាស់ប្តូរបានញឹកញាប់ (ឧទាហរណ៍ ការពិពណ៌នាថ្នាក់ត្រូវបានដាក់ជាប្រពៃណីនៅក្នុងឯកសារបឋមកថា)។ ប្រសិនបើអ្នកមិនបញ្ជាក់ភាពអាស្រ័យនៃឯកសារវត្ថុនៅលើឯកសារបឋមកថាដែលត្រូវគ្នានោះ ស្ថានភាពអាចកើតឡើងដែលឯកសារវត្ថុកម្មវិធីផ្សេងគ្នានឹងត្រូវបានចងក្រងដោយប្រើកំណែផ្សេងគ្នានៃឯកសារបឋមកថាដូចគ្នា។ ហើយនេះ, នៅក្នុងវេន, អាចនាំឱ្យមានការបាត់បង់ផ្នែកឬពេញលេញនៃមុខងារនៃកម្មវិធីដែលបានជួបប្រជុំគ្នា។

ការចុះបញ្ជីភាពអាស្រ័យដោយដៃទាមទារនូវការងារដ៏ឧស្សាហ៍ព្យាយាមច្រើន។ វាមិនគ្រប់គ្រាន់ទេក្នុងការគ្រាន់តែបើកឯកសារប្រភព ហើយរាយឈ្មោះឯកសារបឋមកថាទាំងអស់ដែលរួមបញ្ចូលដោយប្រើ # រួមបញ្ចូល. ការពិតគឺថាឯកសារបឋមកថាមួយចំនួនអាចរួមបញ្ចូលឯកសារបឋមកថាផ្សេងទៀត ដូច្នេះអ្នកត្រូវតាមដាន "ខ្សែសង្វាក់" ទាំងមូលនៃភាពអាស្រ័យ។

ឧបករណ៍ប្រើប្រាស់ GNU បង្កើតនឹងមិនអាចបង្កើតបញ្ជីភាពអាស្រ័យដោយឯករាជ្យបានទេព្រោះសម្រាប់រឿងនេះ វានឹងត្រូវ "មើល" នៅក្នុងឯកសារអត្ថបទប្រភព - ហើយនេះជាការពិតគឺហួសពី "សមត្ថភាព" របស់វា។ ជាសំណាងល្អ ដំណើរការដែលពឹងផ្អែកលើកម្លាំងពលកម្មក្នុងការកសាងភាពអាស្រ័យអាចត្រូវបានដោយស្វ័យប្រវត្តិដោយមានជំនួយពីអ្នកចងក្រង GCC. សម្រាប់ ការសហការជាមួយ ធ្វើអ្នកចងក្រង GCCមានជម្រើសជាច្រើន៖

គន្លឹះចងក្រង គោលបំណង
- ម សម្រាប់ឯកសារអត្ថបទប្រភពនីមួយៗ ឧបករណ៍ដំណើរការមុននឹងបញ្ចេញ ទិន្នផលស្តង់ដារបញ្ជីនៃភាពអាស្រ័យនៅក្នុងទម្រង់នៃច្បាប់សម្រាប់កម្មវិធី ធ្វើ. បញ្ជីនៃភាពអាស្រ័យរួមមានឯកសារប្រភពខ្លួនវា ក៏ដូចជាឯកសារទាំងអស់ដែលបានរួមបញ្ចូលដោយប្រើការណែនាំ # រួមបញ្ចូល<имя_файла> និង # រួមបញ្ចូល "ឈ្មោះឯកសារ". បន្ទាប់ពីចាប់ផ្តើមដំណើរការ preprocessor កម្មវិធីចងក្រងឈប់ដំណើរការ ហើយគ្មានឯកសារវត្ថុណាមួយត្រូវបានបង្កើតទេ។
- ម ស្រដៀងនឹងគន្លឹះ - ម # រួមបញ្ចូល "ឈ្មោះឯកសារ"
- វេជ្ជបណ្ឌិត ស្រដៀងនឹងគន្លឹះ - មប៉ុន្តែ​បញ្ជី​នៃ​ភាពអាស្រ័យ​មិនមែន​ជា​លទ្ធផល​ទៅជា​លទ្ធផល​ស្តង់ដារ​ទេ ប៉ុន្តែ​ត្រូវបាន​សរសេរ​ទៅ ឯកសារដាច់ដោយឡែកភាពអាស្រ័យ។ ឈ្មោះឯកសារនេះត្រូវបានបង្កើតឡើងពីឈ្មោះឯកសារប្រភពដោយជំនួសផ្នែកបន្ថែមរបស់វាដោយ " .ឃ"។ ឧទាហរណ៍ ឯកសារអាស្រ័យសម្រាប់ឯកសារ main.cppនឹងត្រូវបានហៅ main.d. មិនដូចគន្លឹះ - មការចងក្រងដំណើរការជាធម្មតា ជាជាងត្រូវបានរំខានបន្ទាប់ពីដំណាក់កាលចាប់ផ្តើមដំណើរការមុន
- MMD ស្រដៀងនឹងគន្លឹះ - វេជ្ជបណ្ឌិតប៉ុន្តែមានតែឯកសារប្រភពខ្លួនវា និងឯកសារដែលបានរួមបញ្ចូលដោយប្រើការណែនាំប៉ុណ្ណោះដែលត្រូវបានបញ្ចូលក្នុងបញ្ជីនៃភាពអាស្រ័យ # រួមបញ្ចូល "ឈ្មោះឯកសារ"

ដូចដែលអាចមើលឃើញពីតារាង កម្មវិធីចងក្រងអាចដំណើរការតាមពីរវិធី - ក្នុងករណីមួយ កម្មវិធីចងក្រងបង្កើតតែបញ្ជីភាពអាស្រ័យ និងបញ្ចប់ការងារ (ជម្រើស - មនិង - ម) ក្នុងករណីផ្សេងទៀត ការចងក្រងកើតឡើងជាធម្មតា មានតែបន្ថែមលើឯកសារវត្ថុប៉ុណ្ណោះ ឯកសារអាស្រ័យក៏ត្រូវបានបង្កើតផងដែរ (ជម្រើស - វេជ្ជបណ្ឌិតនិង - MMD) ខ្ញុំចូលចិត្តប្រើជម្រើសទីពីរ - វាហាក់ដូចជាខ្ញុំកាន់តែងាយស្រួល និងសន្សំសំចៃព្រោះ៖

  • ប្រសិនបើឯកសារប្រភពណាមួយផ្លាស់ប្តូរ មានតែឯកសារអាស្រ័យដែលត្រូវគ្នាមួយប៉ុណ្ណោះដែលនឹងត្រូវបង្កើតឡើងវិញ
  • ការសាងសង់ឯកសារអាស្រ័យកើតឡើង "ស្របគ្នា" ជាមួយនឹងការងារសំខាន់របស់អ្នកចងក្រង ហើយជាក់ស្តែងមិនប៉ះពាល់ដល់ពេលវេលាចងក្រងទេ។

ក្នុងចំណោមជម្រើសពីរដែលអាចធ្វើបាន - វេជ្ជបណ្ឌិតនិង - MMDខ្ញុំចូលចិត្តទីមួយព្រោះ៖

  • ដោយប្រើការណែនាំ # រួមបញ្ចូល<имя_файла> ជារឿយៗខ្ញុំរួមបញ្ចូលមិនត្រឹមតែឯកសារ "ស្តង់ដារ" ប៉ុណ្ណោះទេ ប៉ុន្តែក៏មានឯកសារបឋមកថារបស់ខ្ញុំផងដែរ ដែលជួនកាលអាចផ្លាស់ប្តូរ (ឧទាហរណ៍ ឯកសារបឋមកថានៃបណ្ណាល័យកម្មវិធីរបស់ខ្ញុំ លីប៊ី).
  • ពេលខ្លះវាមានប្រយោជន៍ក្នុងការមើល ពេញបញ្ជីឯកសារបឋមកថាដែលរួមបញ្ចូលក្នុងម៉ូឌុល រួមទាំងឯកសារ "ស្តង់ដារ" ។

បន្ទាប់ពីឯកសារអាស្រ័យត្រូវបានបង្កើត អ្នកត្រូវធ្វើឱ្យពួកវាមាននៅក្នុងឧបករណ៍ប្រើប្រាស់ ធ្វើ. នេះអាចសម្រេចបានដោយប្រើការណែនាំ រួមបញ្ចូល.

រួមបញ្ចូល $(wildcard *.d)

សូមចំណាំការប្រើប្រាស់មុខងារ អក្សរជំនួស. រចនា

រួមបញ្ចូល *.d

នឹងដំណើរការបានត្រឹមត្រូវ លុះត្រាតែថតមានឯកសារយ៉ាងហោចណាស់មួយជាមួយផ្នែកបន្ថែម " .ឃ"។ ប្រសិនបើមិនមានឯកសារបែបនេះទេនោះ។ ធ្វើនឹងគាំងព្រោះវានឹងបរាជ័យនៅពេលព្យាយាម "បង្កើត" ឯកសារទាំងនេះ (វាមិនមានការណែនាំសម្រាប់រឿងនេះទេ!) ប្រសិនបើអ្នកប្រើមុខងារ អក្សរជំនួសបន្ទាប់មក ប្រសិនបើមិនមានឯកសារដែលត្រូវរកមើលទេ មុខងារនេះនឹងត្រឡប់ខ្សែអក្សរទទេវិញ។ បន្ទាប់គឺការណែនាំ រួមបញ្ចូលជាមួយនឹងអាគុយម៉ង់នៃទម្រង់ បន្ទាត់ទទេនឹងត្រូវបានមិនអើពើដោយមិនបង្កឱ្យមានកំហុស។ ឥឡូវនេះអ្នកអាចសរសេរ ជម្រើសថ្មី។ makefile សម្រាប់គម្រោង "សម្មតិកម្ម" របស់ខ្ញុំ៖

  • example_3-auto_depend /
    • main.cpp
    • main.h
    • Editor.cpp
    • Editor.h
    • TextLine.cpp
    • TextLine.h
    • ធ្វើឯកសារ

នេះជាអ្វីដែលវាមើលទៅ ធ្វើឯកសារពីឧទាហរណ៍នេះ៖

# # example_3-auto_depend/Makefile # # ឧទាហរណ៍នៃការកសាងភាពអាស្រ័យដោយស្វ័យប្រវត្តិពីឯកសារបឋមកថា # iEdit៖ $(patsubst %.cpp,%o,$(wildcard *.cpp)) gcc $^ -o $@ %.o: % .cpp gcc -c -MD $< include $(wildcard *.d)

បន្ទាប់ពីបញ្ចប់ការងារ ធ្វើថតគម្រោងនឹងមើលទៅដូចនេះ៖

  • example_3-auto_depend /
    • iEdit
    • main.cpp
    • main.h
    • main.o
    • main.d
    • Editor.cpp
    • Editor.o
    • Editor.d
    • Editor.h
    • TextLine.cpp
    • TextLine.o
    • TextLine.d
    • TextLine.h
    • ធ្វើឯកសារ

ឯកសារដែលមានផ្នែកបន្ថែម " .ឃ"ត្រូវបានបង្កើតកម្មវិធីចងក្រង GCCឯកសារអាស្រ័យ។ ឧទាហរណ៍ នេះជាអ្វីដែលឯកសារមើលទៅ Editor.dដែលរាយបញ្ជីភាពអាស្រ័យសម្រាប់ឯកសារ Editor.cpp

Editor.o: Editor.cpp Editor.h TextLine.h

ឥឡូវនេះនៅពេលផ្លាស់ប្តូរឯកសារណាមួយ - Editor.cpp, Editor.hTextLine.h, ឯកសារ Editor.cppនឹងត្រូវបានចងក្រងឡើងវិញដើម្បីបង្កើតកំណែថ្មីនៃឯកសារ Editor.o.

តើបច្ចេកទេសដែលបានពិពណ៌នាមានគុណវិបត្តិទេ? បាទ ជាអកុសល មានគុណវិបត្តិមួយ។ ជាសំណាងល្អ តាមគំនិតរបស់ខ្ញុំ មិនសំខាន់ពេកទេ។ ចំណុចសំខាន់គឺថាឧបករណ៍ប្រើប្រាស់ ធ្វើដំណើរការ makefile "ជាពីរជំហាន" ។ ការណែនាំនឹងត្រូវដំណើរការជាមុនសិន រួមបញ្ចូលហើយឯកសារអាស្រ័យនឹងត្រូវបានដាក់បញ្ចូលក្នុង makefile ហើយបន្ទាប់មកនៅលើ "ការឆ្លងកាត់ទីពីរ" ពួកគេនឹងត្រូវបានប្រតិបត្តិរួចហើយ សកម្មភាពចាំបាច់ដើម្បីសាងសង់គម្រោង។

វាប្រែថាការបង្កើត "បច្ចុប្បន្ន" ប្រើឯកសារអាស្រ័យដែលបានបង្កើតកំឡុងពេលសាងសង់ "មុន" ។ ជាធម្មតាវាមិនបង្កបញ្ហាទេ។ ភាពលំបាកនឹងកើតឡើងលុះត្រាតែឯកសារបឋមកថាណាមួយឈប់មានសម្រាប់ហេតុផលមួយចំនួន។ សូមក្រឡេកមើលឧទាហរណ៍ដ៏សាមញ្ញមួយ។ ឧបមាថាខ្ញុំមានឯកសារ main.cppនិង main.h:

ឯកសារ main.cpp:

#រួមបញ្ចូល "main.h" ទុកជាមោឃៈ main() ( )

ឯកសារ main.h:

// main.h

ក្នុងករណីនេះឯកសារអាស្រ័យដែលបង្កើតដោយអ្នកចងក្រង main.dនឹងមើលទៅដូចនេះ៖

Main.o៖ main.cpp main.h

ឥឡូវនេះប្រសិនបើខ្ញុំប្តូរឈ្មោះឯកសារ main.hmain_2.hនិងផ្លាស់ប្តូរឯកសារតាម main.cpp

ឯកសារ main.cpp:

#រួមបញ្ចូល "main_2.h" ទុកជាមោឃៈ main() ( )

នោះ។ ការជួបប្រជុំបន្ទាប់គម្រោងនឹងបរាជ័យ ដោយសារឯកសារអាស្រ័យ main.dនឹងយោងទៅឯកសារបឋមកថាដែលលែងមាន main.h.

ដំណោះស្រាយចំពោះស្ថានភាពនេះគឺត្រូវលុបឯកសារអាស្រ័យ main.d. បន្ទាប់មកគម្រោងនឹងសាងសង់ជាធម្មតា ហើយនឹងត្រូវបានបង្កើត កំណែថ្មី។ឯកសារនេះ យោងឯកសារបឋមកថារួចហើយ main_2.h:

Main.o៖ main.cpp main_2.h

ប្រសិនបើអ្នកប្តូរឈ្មោះ ឬលុបឯកសារបឋមកថា "ពេញនិយម" មួយចំនួន អ្នកអាចបង្កើតគម្រោងឡើងវិញម្តងទៀត ដោយដំបូងលុបឯកសារវត្ថុទាំងអស់ និងឯកសារអាស្រ័យ។

១.៥. "ការចែកចាយ" នៃឯកសារដែលមានអត្ថបទប្រភពទៅក្នុងថត

makefile ដែលបានផ្តល់ឱ្យក្នុងកថាខណ្ឌមុនគឺពិតជាមានមុខងារ និងអាចប្រើដោយជោគជ័យក្នុងការបង្កើតកម្មវិធីតូចៗ។ ទោះយ៉ាងណាក៏ដោយ ដោយសារទំហំនៃកម្មវិធីកើនឡើង វាមិនងាយស្រួលទេក្នុងការរក្សាទុកឯកសារប្រភពទាំងអស់ក្នុងថតតែមួយ។ ក្នុងករណីនេះខ្ញុំចូលចិត្ត "ដកឃ្លា" ពួកវានៅក្នុងថតផ្សេងៗគ្នាដោយឆ្លុះបញ្ចាំង រចនាសម្ព័ន្ធឡូជីខលគម្រោង។ ដើម្បីធ្វើដូច្នេះអ្នកត្រូវកែប្រែ makefile បន្តិច។ ទៅនឹងច្បាប់អព្យាក្រឹត

%o: %.cpp gcc -c $<

នៅតែដំណើរការ ខ្ញុំប្រើអថេរ VPATHដែលរាយបញ្ជីថតទាំងអស់ដែលអត្ថបទប្រភពអាចមានទីតាំងនៅ។ ក្នុងឧទាហរណ៍ខាងក្រោមខ្ញុំបានដាក់ឯកសារ Editor.cppនិង Editor.hទៅកាតាឡុក កម្មវិធីនិពន្ធនិងឯកសារ TextLine.cppនិង TextLine.hទៅកាតាឡុក បន្ទាត់អត្ថបទ:

  • example_4-multidir/
    • main.cpp
    • main.h
    • កម្មវិធីនិពន្ធ/
      • Editor.cpp
      • Editor.h
    • បន្ទាត់អត្ថបទ/
      • TextLine.cpp
      • TextLine.h
    • ធ្វើឯកសារ

នេះជាអ្វីដែលវាមើលទៅ ធ្វើឯកសារសម្រាប់ឧទាហរណ៍នេះ៖

# # example_4-multidir/Makefile # # ឧទាហរណ៍នៃ "ការបែងចែក" អត្ថបទប្រភពទៅក្នុងថតផ្សេងៗគ្នា # source_dirs:= . កម្មវិធីនិពន្ធ TextLine search_wildcards:= $(addsuffix /*.cpp,$(source_dirs)) iEdit: $(notdir $(patsubst %.cpp,%o,$(wildcard $(search_wildcards))))) gcc $^ -o $ @VPATH:= $(source_dirs) %.o: %.cpp gcc -c -MD $(addprefix -I,$(source_dirs)) $< include $(wildcard *.d)

បើប្រៀបធៀបទៅនឹងកំណែមុននៃ makefile វាបានឆ្លងកាត់ការផ្លាស់ប្តូរដូចខាងក្រោមៈ

  • ដើម្បីរក្សាទុកបញ្ជីថតជាមួយកូដប្រភព ខ្ញុំបានបង្កើតអថេរដាច់ដោយឡែកមួយ។ source_dirsចាប់តាំងពីបញ្ជីនេះនឹងត្រូវបញ្ជាក់នៅកន្លែងជាច្រើន។
  • ស្វែងរកលំនាំសម្រាប់មុខងារមួយ។ អក្សរជំនួស(អថេរ search_wildcards) ត្រូវបានសាងសង់ "ថាមវន្ត" ដោយផ្អែកលើបញ្ជីនៃថត source_dirs
  • អថេរត្រូវបានប្រើ VPATHដូច្នេះ ច្បាប់គំរូអាចស្វែងរកឯកសារប្រភពនៅក្នុងបញ្ជីថតដែលបានបញ្ជាក់
  • កម្មវិធីចងក្រងត្រូវបានអនុញ្ញាតឱ្យស្វែងរកឯកសារបឋមកថានៅក្នុងថតប្រភពទាំងអស់។ ដើម្បីធ្វើដូចនេះសូមប្រើមុខងារ បន្ថែមបុព្វបទនិងប្រអប់ធីក - ខ្ញុំអ្នកចងក្រង GCC.
  • នៅពេលបង្កើតបញ្ជីឯកសារវត្ថុ ឈ្មោះរបស់ថតដែលពួកគេស្ថិតនៅគឺ "ដកចេញ" ពីឈ្មោះឯកសារប្រភព (ដោយប្រើមុខងារ Notdir)

១.៦. បង្កើតកម្មវិធីដែលមានជម្រើសចងក្រងផ្សេងៗគ្នា

ជារឿយៗវាចាំបាច់ដើម្បីទទួលបានកំណែជាច្រើននៃកម្មវិធីដែលត្រូវបានចងក្រងខុសៗគ្នា។ ឧទាហរណ៍ធម្មតាគឺការបំបាត់កំហុស និងកំណែផលិតកម្មរបស់កម្មវិធី។ ក្នុងករណីបែបនេះខ្ញុំប្រើបច្ចេកទេសសាមញ្ញមួយ:

  • កំណែទាំងអស់នៃកម្មវិធីត្រូវបានបង្កើតដោយប្រើ makefile ដូចគ្នា។
  • ការកំណត់កម្មវិធីចងក្រងចាំបាច់ "ទទួលបាន" ចូលទៅក្នុង makefile តាមរយៈប៉ារ៉ាម៉ែត្រដែលបានបញ្ជូនទៅកម្មវិធី ធ្វើបន្ទាត់ពាក្យបញ្ជា.

សម្រាប់​ការ​កំណត់​រចនាសម្ព័ន្ធ​កម្មវិធី​នីមួយៗ ខ្ញុំ​បង្កើត​ឯកសារ​បាច់​តូច​មួយ​ដែល​ហៅ ធ្វើជាមួយនឹងប៉ារ៉ាម៉ែត្រចាំបាច់៖

  • example_5-multiconfig/
    • main.cpp
    • main.h
    • កម្មវិធីនិពន្ធ/
      • Editor.cpp
      • Editor.h
    • បន្ទាត់អត្ថបទ/
      • TextLine.cpp
      • TextLine.h
    • ធ្វើឯកសារ
    • make_debug
    • make_release

ឯកសារ make_debugនិង make_release- ទាំងនេះគឺជាឯកសារបាច់ដែលប្រើសម្រាប់បង្កើតកម្មវិធីបំបាត់កំហុស និងកំណែការងាររបស់កម្មវិធីរៀងៗខ្លួន។ ជាឧទាហរណ៍ ខាងក្រោមនេះជាអ្វីដែលឯកសារបាច់មើលទៅដូច make_release

បង្កើត compile_flags="-O3 -funroll-loops -fomit-frame-pointer"

សូមចំណាំថាបន្ទាត់ដែលមានតម្លៃអថេរ compile_flagsត្រូវបានរុំព័ទ្ធក្នុងសម្រង់ព្រោះវាមានចន្លោះ។ ឯកសារបាច់ make_debugមើលទៅស្រដៀងគ្នា៖

បង្កើត compile_flags="-O0 -g"

នេះជាអ្វីដែលវាមើលទៅ ធ្វើឯកសារសម្រាប់ឧទាហរណ៍នេះ៖

# # example_5-multiconfig/Makefile # # ឧទាហរណ៍នៃការទទួលបានកំណែច្រើននៃកម្មវិធីដោយប្រើ makefile មួយ # source_dirs:= . កម្មវិធីនិពន្ធ TextLine search_wildcards:= $(addsuffix /*.cpp,$(source_dirs)) បដិសេធ compile_flags += -pipe iEdit: $(notdir $(patsubst %.cpp,%o,$(wildcard $(search_wildcards)))) gcc $^ -o $@ VPATH:= $(source_dirs) %.o: %.cpp gcc -c -MD $(addprefix -I,$(source_dirs)) $(compile_flags) $< include $(wildcard *.d)

អថេរ compile_flagsទទួលបានតម្លៃរបស់វាពីបន្ទាត់ពាក្យបញ្ជា ហើយបន្ទាប់មកត្រូវបានប្រើនៅពេលចងក្រងកូដប្រភព។ ដើម្បីបង្កើនល្បឿនកម្មវិធីចងក្រង ទង់មួយត្រូវបានបន្ថែមទៅប៉ារ៉ាម៉ែត្រចងក្រង - បំពង់. សូមកត់សម្គាល់ពីតម្រូវការប្រើប្រាស់ការណែនាំ បដិសេធដើម្បីផ្លាស់ប្តូរអថេរ compile_flagsនៅខាងក្នុង makefile ។

១.៧. "ការចែកចាយ" នៃកំណែផ្សេងគ្នានៃកម្មវិធីទៅក្នុងថតដាច់ដោយឡែក

ក្នុងករណីដែលខ្ញុំចងក្រងកំណែជាច្រើននៃកម្មវិធីដូចគ្នា (ឧទាហរណ៍ កំណែបំបាត់កំហុស និងកំណែផលិតកម្ម) វាក្លាយជាការរអាក់រអួលក្នុងការដាក់លទ្ធផលចងក្រងនៅក្នុងថតតែមួយ។ នៅពេលផ្លាស់ប្តូរពីកំណែមួយទៅកំណែមួយទៀត អ្នកត្រូវតែចងក្រងកម្មវិធីឡើងវិញទាំងស្រុង ដើម្បីជៀសវាង "ការលាយ" ឯកសារវត្ថុនៃកំណែផ្សេងៗគ្នាដែលមិនចង់បាន។

ដើម្បីដោះស្រាយបញ្ហានេះ ខ្ញុំដាក់លទ្ធផលចងក្រងនៃកំណែនីមួយៗនៃកម្មវិធីនៅក្នុងថតដាច់ដោយឡែករបស់វា។ ដូច្នេះ ជាឧទាហរណ៍ កំណែបំបាត់កំហុសរបស់កម្មវិធី (រួមទាំងឯកសារវត្ថុទាំងអស់) ត្រូវបានដាក់ក្នុងថត បំបាត់កំហុសហើយកំណែដំណើរការរបស់កម្មវិធីត្រូវបានដាក់ក្នុងថត ដោះលែង:

    • បំបាត់កំហុស/
    • ចេញផ្សាយ/
    • main.cpp
    • main.h
    • កម្មវិធីនិពន្ធ/
      • Editor.cpp
      • Editor.h
    • បន្ទាត់អត្ថបទ/
      • TextLine.cpp
      • TextLine.h
    • ធ្វើឯកសារ
    • make_debug
    • make_release

ការលំបាកចម្បងគឺដើម្បីទទួលបានកម្មវិធី ធ្វើដាក់លទ្ធផលនៃការងាររបស់អ្នកនៅក្នុងថតផ្សេងៗគ្នា។ ដោយបានព្យាយាម ជម្រើសផ្សេងគ្នាខ្ញុំបានឈានដល់ការសន្និដ្ឋានថាច្រើនបំផុត វិធីងាយស្រួល- ការប្រើប្រាស់ប្រអប់ធីក -- ថតនៅពេលហៅ ធ្វើ. ទង់នេះបណ្តាលឱ្យឧបករណ៍ប្រើប្រាស់ដើម្បីធ្វើឱ្យថតដែលបានបញ្ជាក់នៅលើបន្ទាត់ពាក្យបញ្ជា "បច្ចុប្បន្ន" មុនពេលដំណើរការ makefile ។

ជាឧទាហរណ៍ ខាងក្រោមនេះជាអ្វីដែលឯកសារបាច់មើលទៅដូច make_releaseដែលចងក្រងកំណែការងាររបស់កម្មវិធី (លទ្ធផលនៃការចងក្រងត្រូវបានដាក់ក្នុងថតឯកសារ ដោះលែង):

ការចេញផ្សាយ Mkdir ធ្វើឱ្យ compile_flags="-O3 -funroll-loops -fomit-frame-pointer" \ --directory=release \ --makefile=../Makefile

ក្រុម mkdirបញ្ចូលដើម្បីភាពងាយស្រួល - ប្រសិនបើអ្នកលុបថត ដោះលែងបន្ទាប់មកវានឹងត្រូវបានបង្កើតម្តងទៀតក្នុងអំឡុងពេលសាងសង់បន្ទាប់។ ក្នុងករណីឈ្មោះថត "សមាសធាតុ" (ឧទាហរណ៍។ bin/release) អ្នកក៏អាចប្រើប្រអប់ធីកផងដែរ។ - ទំ. ប្រអប់ធីក -- ថតកងកម្លាំង ធ្វើមុនពេលចាប់ផ្តើមការងារធ្វើថតដែលបានបញ្ជាក់ ដោះលែងបច្ចុប្បន្ន។ ប្រអប់ធីក --makefileនឹងចង្អុលបង្ហាញកម្មវិធី ធ្វើដែលជាកន្លែងដែល makefile របស់គម្រោងស្ថិតនៅ។ ទាក់ទងទៅនឹងថត "បច្ចុប្បន្ន" ដោះលែងវានឹងមានទីតាំងនៅក្នុងថត "មេ" ។

ឯកសារបាច់សម្រាប់ដំឡើងកំណែបំបាត់កំហុសរបស់កម្មវិធី ( make_debug) មើលទៅស្រដៀងគ្នា។ ភាពខុសគ្នាតែមួយគត់គឺនៅក្នុងឈ្មោះនៃថតដែលលទ្ធផលនៃការចងក្រងត្រូវបានដាក់ ( បំបាត់កំហុស) និងបណ្តុំទង់ចងក្រងមួយទៀត៖

ការបំបាត់កំហុស Mkdir បង្កើត compile_flags="-O0 -g" \ --directory=debug \ --makefile=../Makefile

នេះគឺជា makefile ចុងក្រោយដើម្បីសាងសង់គម្រោង "សម្មតិកម្ម" កម្មវិធីនិពន្ធអត្ថបទ:

# # example_6-multiconfig-multidir/Makefile # # ឧទាហរណ៍នៃ "ការបំបែក" កំណែផ្សេងគ្នានៃកម្មវិធីចូលទៅក្នុងថតដាច់ដោយឡែក # program_name:= iEdit source_dirs:= ។ កម្មវិធីនិពន្ធ TextLine source_dirs:= $(addprefix ../,$(source_dirs)) search_wildcards:= $(addsuffix /*.cpp,$(source_dirs)) $(program_name):$(notdir$(patsubst %.cpp,%. o,$(wildcard $(search_wildcards)))) gcc $^ -o $@ VPATH:= $(source_dirs) %o: %.cpp gcc -c -MD $(compile_flags) $(addprefix -I,$( source_dirs))$< include $(wildcard *.d)

នៅក្នុងកំណែចុងក្រោយនេះ ខ្ញុំបាន "ផ្លាស់ទី" ឈ្មោះនៃឯកសារដែលអាចប្រតិបត្តិបានរបស់កម្មវិធីទៅជាអថេរដាច់ដោយឡែកមួយ។ ឈ្មោះកម្មវិធី. ឥឡូវនេះ ដើម្បីសម្រប makefile នេះដើម្បីបង្កើតកម្មវិធីមួយផ្សេងទៀត អ្នកគ្រាន់តែត្រូវផ្លាស់ប្តូរបន្ទាត់ពីរបីដំបូងប៉ុណ្ណោះ។

បន្ទាប់ពីដំណើរការឯកសារបាច់ make_debugនិង make_releaseថតដែលមានឧទាហរណ៍ចុងក្រោយមើលទៅដូចនេះ៖

  • example_6-multiconfig-multidir/
    • បំបាត់កំហុស/
      • iEdit
      • main.o
      • main.d
      • Editor.o
      • Editor.d
      • TextLine.o
      • TextLine.d
    • ចេញផ្សាយ/
      • iEdit
      • main.o
      • main.d
      • Editor.o
      • Editor.d
      • TextLine.o
      • TextLine.d
    • main.cpp
    • main.h
    • កម្មវិធីនិពន្ធ/
      • Editor.cpp
      • Editor.h
    • បន្ទាត់អត្ថបទ/
      • TextLine.cpp
      • TextLine.h
    • makefile
    • make_debug
    • make_release

វាអាចត្រូវបានគេមើលឃើញថាឯកសារវត្ថុសម្រាប់ការកំណត់រចនាសម្ព័ន្ធដំណើរការនិងបំបាត់កំហុសរបស់កម្មវិធីត្រូវបានដាក់ក្នុងថតផ្សេងៗគ្នា។ នោះហើយជាកន្លែងដែលអ្នកផលិតរួចរាល់ ឯកសារដែលអាចប្រតិបត្តិបាន។និងឯកសារអាស្រ័យ។

នៅក្នុងជំពូកនេះ ខ្ញុំបានរៀបរាប់អំពីវិធីសាស្រ្តរបស់ខ្ញុំសម្រាប់ធ្វើការជាមួយ makefiles។ ជំពូកដែលនៅសេសសល់គឺច្រើនឬតិច "បន្ថែម" នៅក្នុងធម្មជាតិ។

2. GNU Make

ក្នុង​ជំពូក​នេះ ខ្ញុំ​នឹង​រៀបរាប់​ដោយ​សង្ខេប​អំពី​លក្ខណៈ​ពិសេស​មួយ​ចំនួន​របស់​កម្មវិធី។ GNU បង្កើតដែលខ្ញុំប្រើនៅពេលសរសេរ makefiles របស់ខ្ញុំ ហើយនឹងចង្អុលបង្ហាញពីភាពខុសគ្នារបស់វាពីកំណែ "ប្រពៃណី" ធ្វើ. វាត្រូវបានសន្មត់ថាអ្នកស៊ាំនឹងគោលការណ៍ប្រតិបត្តិការ កម្មវិធីស្រដៀងគ្នា. បើមិនដូច្នោះទេសូមអានជាមុនសិន

GNU បង្កើត- នេះគឺជាកំណែកម្មវិធី ធ្វើចែកចាយ មូលនិធិឥតគិតថ្លៃ កម្មវិធី (ឥតគិតថ្លៃ មូលនិធិកម្មវិធី - អេហ្វអេសអេហ្វ) នៅក្នុងគម្រោង GNU ( www.gnu.org) អ្នកអាចទទួលបានកំណែចុងក្រោយបំផុតនៃកម្មវិធី និងឯកសារនៅលើ "ទំព័រដើម" របស់កម្មវិធី www.gnu.org/software/makeឬនៅលើទំព័រ Paul D. Smith- អ្នកនិពន្ធម្នាក់ GNU បង្កើត ( www.paulandlesley.org/gmake).

កម្មវិធី GNU បង្កើតមានឯកសារលម្អិត និងសរសេរយ៉ាងល្អ ដែលខ្ញុំសូមផ្តល់អនុសាសន៍យ៉ាងខ្លាំងឱ្យពិនិត្យមើល។ ប្រសិនបើអ្នកមិនមានសិទ្ធិចូលប្រើអ៊ីនធឺណិតទេនោះ សូមប្រើឯកសារក្នុងទម្រង់ ព័ត៌មានដែលគួរតែត្រូវបានរួមបញ្ចូលនៅក្នុងការចែកចាយរបស់អ្នក។ លីនុច. សូមប្រយ័ត្នជាមួយឯកសារ man page ( បុរសធ្វើ) - តាមក្បួនវាមានតែព័ត៌មានដែលបែកខ្ញែក និងហួសសម័យប៉ុណ្ណោះ។

២.១. អថេរពីរប្រភេទ

GNU បង្កើតគាំទ្រវិធីពីរយ៉ាងនៃការកំណត់អថេរ ដែលខុសគ្នាបន្តិចបន្តួចនៅក្នុងអត្ថន័យ។ វិធីទីមួយគឺបែបប្រពៃណី ដោយប្រើប្រតិបត្តិករ " = ":

Compile_flags = -O3 -funroll-loops -fomit-frame-pointer

វិធីសាស្រ្តនេះត្រូវបានគាំទ្រដោយកំណែទាំងអស់នៃឧបករណ៍ប្រើប្រាស់។ ធ្វើ. ជាឧទាហរណ៍ វាអាចប្រៀបធៀបជាមួយនឹងការកំណត់ម៉ាក្រូជាភាសា ស៊ី

#define compile_flags "-O3 -funroll-loops -fomit-frame-pointer"

តម្លៃ​នៃ​អថេរ​ដែល​បាន​បញ្ជាក់​ដោយ​ប្រើ​ប្រតិបត្តិករ " = " នឹងត្រូវបានគណនានៅពេលប្រើប្រាស់របស់វា។ ឧទាហរណ៍ នៅពេលដំណើរការ makefile៖

Var1 = មួយ var2 = $(var1) two var1 = three all: @echo $(var2)

បន្ទាត់ "បីពីរ" នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់។ តម្លៃអថេរ var2នឹងត្រូវបានគណនាភ្លាមៗ នៅពេលដែលពាក្យបញ្ជាត្រូវបានប្រតិបត្តិ បន្ទរហើយនឹងតំណាង បច្ចុប្បន្នតម្លៃអថេរ var1ដែលបន្ទាត់ត្រូវបានបន្ថែម "ពីរ". ជាលទ្ធផល អថេរដូចគ្នាមិនអាចបង្ហាញក្នុងពេលដំណាលគ្នានៅក្នុងផ្នែកខាងឆ្វេង និងខាងស្តាំនៃកន្សោមបានទេ ព្រោះវាអាចនាំទៅរកការកើតឡើងដដែលៗគ្មានកំណត់។ GNU បង្កើតទទួលស្គាល់ស្ថានភាពបែបនេះ និងបោះបង់ដំណើរការ makefile ។ ឧទាហរណ៍ខាងក្រោមនឹងបង្ហាញកំហុស៖

Compile_flags = -pipe $(compile_flags)

GNU បង្កើតក៏​គាំទ្រ​វិធី​ទីពីរ​ថ្មី​នៃ​ការ​បញ្ជាក់​អថេរ - ដោយ​ប្រើ​ប្រតិបត្តិករ " := ":

Compile_flags:= -O3 -funroll-loops -fomit-frame-pointer

ក្នុងករណីនេះ អថេរដំណើរការដូចជាអថេរអត្ថបទ "ធម្មតា" នៅក្នុងភាសាសរសេរកម្មវិធីណាមួយ។ នេះគឺជា analogue ប្រហាក់ប្រហែលនៃកន្សោមនេះជាភាសា C++

String compile_flags = "-O3 -funroll-loops -fomit-frame-pointer";

តម្លៃនៃអថេរត្រូវបានគណនានៅពេលដែល assignment operator ត្រូវបានដំណើរការ។ ឧទាហរណ៍ប្រសិនបើយើងសរសេរ

Var1:= មួយ var2:= $(var1) two var1:= three all: @echo $(var2)

បន្ទាប់មកនៅពេលដំណើរការ makefile នោះបន្ទាត់ "មួយពីរ" នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់។

អថេរអាច "ផ្លាស់ប្តូរ" ឥរិយាបទរបស់វា អាស្រ័យទៅលើប្រតិបត្តិករកិច្ចការណាមួយដែលត្រូវបានអនុវត្តចុងក្រោយចំពោះវា។ អថេរដូចគ្នាអាចមានឥរិយាបថល្អទាំងពីរជា "ម៉ាក្រូ" និងជា "អថេរអត្ថបទ" ពេញមួយជីវិតរបស់វា។

ខ្ញុំសរសេរឯកសាររបស់ខ្ញុំទាំងអស់ដោយប្រើប្រតិបត្តិករ " := "។ វិធីសាស្ត្រនេះហាក់ដូចជាខ្ញុំកាន់តែងាយស្រួល និងអាចទុកចិត្តបាន។ លើសពីនេះ វាមានប្រសិទ្ធភាពជាង ដោយសារតម្លៃនៃអថេរមិនត្រូវបានគណនាឡើងវិញរាល់ពេលដែលវាត្រូវបានប្រើ។ ព័ត៌មានបន្ថែមអំពីវិធីទាំងពីរដើម្បីកំណត់អថេរអាចរកបាននៅក្នុងឯកសារ នៅលើ GNU បង្កើតនៅក្នុងផ្នែក " រសជាតិពីរនៃអថេរ" .

២.២. មុខងាររៀបចំអត្ថបទ

ឧបករណ៍ប្រើប្រាស់ GNU បង្កើតមានមុខងារមានប្រយោជន៍មួយចំនួនធំដែលរៀបចំ ខ្សែអក្សរនិងឈ្មោះឯកសារ។ ជាពិសេសនៅក្នុង makefiles ខ្ញុំប្រើមុខងារ បន្ថែមបុព្វបទ, បច្ច័យបន្ថែម, អក្សរជំនួស, Notdirនិង អនុគ្រោះ. វាក្យសម្ព័ន្ធដែលប្រើដើម្បីហៅមុខងារគឺ

$(function_name parameter1, parameter2 ...)

មុខងារ បន្ថែមបុព្វបទចាត់ទុកប៉ារ៉ាម៉ែត្រទីពីរជាបញ្ជីពាក្យដែលបំបែកដោយដកឃ្លា។ នៅដើមពាក្យនីមួយៗ វាបន្ថែមខ្សែអក្សរដែលបានឆ្លងកាត់ទៅវាជាប៉ារ៉ាម៉ែត្រទីមួយ។ ឧទាហរណ៍ ជាលទ្ធផលនៃការប្រតិបត្តិ makefile៖

Src_dirs:= កម្មវិធីនិពន្ធ TextLine src_dirs:= $(addprefix ../../, $(src_dirs)) ទាំងអស់៖ @echo $(src_dirs)

នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់

../../Editor ../../TextLine

អ្នកអាចមើលឃើញថាឈ្មោះថតនីមួយៗមានបុព្វបទ " ../../ ". មុខងារ បន្ថែមបុព្វបទត្រូវបានពិភាក្សានៅក្នុងផ្នែក "មុខងារសម្រាប់ឈ្មោះឯកសារ" នៃសៀវភៅណែនាំ។ GNU បង្កើត.

មុខងារ បច្ច័យបន្ថែមដំណើរការស្រដៀងនឹងមុខងារ បន្ថែមបុព្វបទបន្ថែមតែខ្សែអក្សរដែលបានបញ្ជាក់ទៅចុងបញ្ចប់នៃពាក្យនីមួយៗ។ ឧទាហរណ៍ ជាលទ្ធផលនៃការប្រតិបត្តិ makefile៖

Source_dirs:= កម្មវិធីនិពន្ធ TextLine search_wildcards:= $(addsuffix /*.cpp, $(source_dirs)) ទាំងអស់៖ @echo $(search_wildcards)

នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់

កម្មវិធីនិពន្ធ/*.cpp TextLine/*.cpp

អ្នកអាចមើលឃើញថាឈ្មោះថតនីមួយៗមានបច្ច័យ " /*.cpp". មុខងារ បច្ច័យបន្ថែមត្រូវបានពិភាក្សានៅក្នុងផ្នែក "មុខងារសម្រាប់ឈ្មោះឯកសារ" នៃសៀវភៅណែនាំ។ GNU បង្កើត.

មុខងារ អក្សរជំនួស"ពង្រីក" គំរូ ឬគំរូជាច្រើនបានបញ្ជូនទៅវាទៅក្នុងបញ្ជីឯកសារដែលត្រូវគ្នានឹងគំរូទាំងនេះ។ អនុញ្ញាតឱ្យនៅក្នុងថត កម្មវិធីនិពន្ធមានឯកសារមួយ។ Editor.cppនិងនៅក្នុងថតឯកសារ បន្ទាត់អត្ថបទ- ឯកសារ TextLine.cpp:

  • wildcard_example/
    • កម្មវិធីនិពន្ធ/
      • Editor.cpp
    • បន្ទាត់អត្ថបទ/
      • TextLine.cpp
    • makefile

បន្ទាប់មកជាលទ្ធផលនៃការប្រតិបត្តិ makefile នេះ៖

Search_wildcards:= Editor/*.cpp TextLine/*.cpp source_files:= $(wildcard $(search_wildcards)) ទាំងអស់៖ @echo $(source_files)

នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់

កម្មវិធីនិពន្ធ/Editor.cpp TextLine/TextLine.cpp

អ្នក​អាច​មើល​ឃើញ​ថា​គំរូ​ត្រូវ​បាន​បំប្លែង​ទៅ​ជា​បញ្ជី​ឯកសារ។ មុខងារ អក្សរជំនួសបានពិភាក្សាលម្អិតនៅក្នុងផ្នែក "មុខងារ" អក្សរជំនួស" ណែនាំ GNU បង្កើត.

មុខងារ Notdirអនុញ្ញាតឱ្យអ្នក "លុប" ឈ្មោះនៃថតដែលជាកន្លែងដែលវាមានទីតាំងនៅពីឈ្មោះឯកសារ។ ឧទាហរណ៍ ជាលទ្ធផលនៃការប្រតិបត្តិ makefile៖

Source_files:= Editor/Editor.cpp TextLine/TextLine.cpp source_files:= $(notdir $(source_files)) ទាំងអស់៖ @echo $(source_files)

នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់

Editor.cpp TextLine.cpp

វាអាចត្រូវបានគេមើលឃើញថា "ផ្លូវ" ទៅកាន់ឯកសារទាំងនេះត្រូវបានដកចេញពីឈ្មោះឯកសារ។ មុខងារ Notdirត្រូវបានពិភាក្សានៅក្នុងផ្នែក "មុខងារសម្រាប់ឈ្មោះឯកសារ" នៃសៀវភៅណែនាំ។ GNU បង្កើត.

មុខងារ អនុគ្រោះអនុញ្ញាតឱ្យអ្នកផ្លាស់ប្តូរ តាមរបៀបដែលបានបង្ហាញពាក្យដែលត្រូវនឹងលំនាំ។ វាត្រូវការប៉ារ៉ាម៉ែត្របី - លំនាំមួយ វ៉ារ្យ៉ង់ថ្មីនៃពាក្យ និងខ្សែអក្សរដើម។ ខ្សែអក្សរប្រភពត្រូវបានចាត់ទុកជាបញ្ជីពាក្យដែលបំបែកដោយដកឃ្លា។ ពាក្យនីមួយៗដែលត្រូវនឹងលំនាំដែលបានបញ្ជាក់ត្រូវបានជំនួសដោយកំណែថ្មីនៃពាក្យ។ គំរូអាចត្រូវបានប្រើ តួអក្សរពិសេស"%" ដែលមានន័យថា "ចំនួនតួអក្សរបំពានណាមួយ" ។ ប្រសិនបើតួអក្សរ "%" កើតឡើងនៅក្នុងវ៉ារ្យ៉ង់ពាក្យថ្មី (ប៉ារ៉ាម៉ែត្រទីពីរ) នោះវាត្រូវបានជំនួសដោយអត្ថបទដែលត្រូវនឹងតួអក្សរ "%" នៅក្នុងគំរូ។ ឧទាហរណ៍ ជាលទ្ធផលនៃការប្រតិបត្តិ makefile៖

Source_files:= Editor.cpp TextLine.cpp object_files:= $(patsubst %.cpp, %o, $(source_files)) ទាំងអស់៖ @echo $(object_files)

នឹងត្រូវបានបង្ហាញនៅលើអេក្រង់

Editor.o TextLine.o

វាច្បាស់ណាស់ថាពាក្យទាំងអស់មានចុងបញ្ចប់ " .cpp"ជំនួសដោយ" .o". មុខងារ អនុគ្រោះមានទីពីរ ច្រើនទៀត កំណែខ្លីធាតុ​សម្រាប់​ករណី​ទាំង​នោះ​នៅ​ពេល​ដែល​អ្នក​ត្រូវ​ការ​ផ្លាស់​ប្តូ​រ​បច្ច័យ​នៃ​ពាក្យ​មួយ (ឧទាហរណ៍ ជំនួស​ផ្នែក​បន្ថែម​នៅ​ក្នុង​ឈ្មោះ​ឯកសារ) ។ កំណែខ្លីមើលទៅដូចនេះ៖

$(variable_name:.old_suffix=.new_suffix)

ដោយប្រើសញ្ញា "ខ្លី" ឧទាហរណ៍មុនអាចត្រូវបានសរសេរដូចនេះ:

Source_files:= Editor.cpp TextLine.cpp object_files:= $(source_files:.cpp=.o) all: @echo $(object_files)

មុខងារ អនុគ្រោះត្រូវបានពិភាក្សានៅក្នុងផ្នែក "មុខងារសម្រាប់ការជំនួសខ្សែ និងការវិភាគ" នៃសៀវភៅណែនាំ GNU បង្កើត.

២.៣. វិធីថ្មីដើម្បីកំណត់ច្បាប់គំរូ

នៅក្នុងកំណែ "ប្រពៃណី" ធ្វើច្បាប់គំរូត្រូវបានបញ្ជាក់ដោយប្រើសំណង់ដូចជា៖

Cpp.o: gcc $^ -o $@

នោះគឺឯកសារដែលមានផ្នែកបន្ថែមជាក់លាក់ (" .cpp"ហើយ" .o" ក្នុងករណីនេះ) ។

GNU បង្កើតគាំទ្រវិធីសាស្រ្តសកលបន្ថែមទៀត - ដោយប្រើគំរូឈ្មោះឯកសារ។ និមិត្តសញ្ញាត្រូវបានប្រើដើម្បីបញ្ជាក់លំនាំ "%" ដែលមានន័យថា "លំដាប់នៃតួអក្សរណាមួយនៃប្រវែងបំពាន" ។ និមិត្តសញ្ញា "%" នៅជ្រុងខាងស្តាំនៃច្បាប់ត្រូវបានជំនួសដោយអត្ថបទដែលត្រូវនឹងនិមិត្តសញ្ញា "%" នៅផ្នែកខាងឆ្វេង។ ទាញយកប្រយោជន៍ ទម្រង់ថ្មី។កំណត់ត្រា, ឧទាហរណ៍ខាងលើអាចត្រូវបានសរសេរដូចនេះ:

%o: %cpp gcc $^ -o $@

នៅក្នុង makefiles របស់ខ្ញុំ ខ្ញុំប្រើទម្រង់ថ្មីនៃការសរសេរច្បាប់ template ព្រោះខ្ញុំចាត់ទុកថាវាងាយស្រួលជាង (ច្បាប់ template និង non-template ឥឡូវនេះមានវាក្យសម្ព័ន្ធស្រដៀងគ្នា) និងជាសកល (អ្នកអាចបញ្ជាក់មិនត្រឹមតែឯកសារដែលខុសគ្នានៅក្នុងផ្នែកបន្ថែមរបស់វា)។

២.៤. អថេរ VPATH

ដោយប្រើអថេរ VPATHអ្នក​អាច​បញ្ជាក់​បញ្ជី​ថត​ដែល​ច្បាប់​គំរូ​នឹង​ស្វែងរក​ភាពអាស្រ័យ។ ក្នុងឧទាហរណ៍ខាងក្រោម៖

VPATH:= កម្មវិធីនិពន្ធ TextLine %o: %cpp gcc -c $<

ធ្វើនឹងស្វែងរកឯកសារដែលមានផ្នែកបន្ថែម " .cpp" ទីមួយនៅក្នុងថតបច្ចុប្បន្ន ហើយបន្ទាប់មក បើចាំបាច់នៅក្នុងថតរង កម្មវិធីនិពន្ធនិង បន្ទាត់អត្ថបទ. ជាញឹកញាប់ខ្ញុំប្រើលក្ខណៈពិសេសនេះព្រោះខ្ញុំចូលចិត្តដាក់កូដប្រភពនៅក្នុងឋានានុក្រមនៃថតដែលឆ្លុះបញ្ចាំងពីរចនាសម្ព័ន្ធឡូជីខលនៃកម្មវិធី។

អថេរ VPATHត្រូវបានពិពណ៌នានៅក្នុងជំពូក "VPATH: ផ្លូវស្វែងរកសម្រាប់ភាពអាស្រ័យទាំងអស់" នៃសៀវភៅណែនាំ GNU បង្កើត. នៅលើទំព័រ Paul D. Smithមានអត្ថបទមួយហៅថា "របៀបមិនប្រើ VPAT