make הוא כלי תוכנה, המשמש לבניה אוטומטית של קובצי הרצה (executable) וספריות מקובצי מקור (source code). התכנית בגרסתה הראשונית נבנתה ב-1976 כחלק מסביבת יוניקס והיא נמצאת בשימוש נרחב עד היום. התכנית מקבלת כקלט קובץ מסוג makefile שמכיל הוראות בניה לפרויקט תכנה מסוים ובונה אותו בפועל.
שימוש
השימוש ב-make בא לענות על שתי בעיות עיקריות בפיתוח של פרויקט תכנה המבוסס על קבצים מרובים של קוד מקור. האחת, במקרה של תלות בין קבצים (כלומר שכדי לבנות קובץ אחד צריך להשתמש בקובץ אחר), להבטיח שאם אחד הקבצים השתנה, יבנה מחדש כל קובץ שתלוי בו. תהליך זה ימשיך באופן רקורסיבי בשרשרת התלויות עד שכל הקבצים, ובעיקר קוד הביצוע הסופי יהיו מעודכנים ומתואמים. הבעיה השנייה, במקרה של פרויקט גדול, אם אחד הקבצים השתנה אין צורך לבנות מחדש את כל הקבצים בפרויקט אלא רק את אלה שתלויים בקובץ שהשתנה. make משווה בין קבצים במערכת על פי חותם הזמן (time stamp) שלהם.
במודל הפשוט ביותר פרויקט תכנה מורכב מקבצי קוד מקור. כל אחד מהם עובר הידור כדי ליצור קוד מטרה (object code) תואם בשפת מכונה, ובסופו של דבר קובצי קוד המטרה מקושרים יחד כדי ליצור את התכנית להרצה. אם השתנה אחד מקבצי המקור יש להדר וליצור מחדש את קוד המטרה של אותו קובץ, ולאחר מכן לקחת שוב את כל קובצי המטרה וליצור מחדש את קובץ ההרצה. אין צורך ליצור מחדש את קובצי המכונה האחרים.
make נבנה כדי לשמש בסביבת יוניקס ובשפת הפיתוח C, אך העקרונות שבבסיסו נכונים כמעט לכל סביבה ושפה אחרת ובשל פשטותו קל היה להתאים אותו כמעט לכל סביבת פיתוח אחרת. אף על פי שניתן להשתמש בסביבות פיתוח משולבות לניהול תהליך הבנייה, make עדיין נמצאת בשימוש נרחב, במיוחד במערכות הפעלה דמויות יוניקס.
מלבד בניית תוכניות, ניתן להשתמש ב- Make לניהול כל פרויקט בו יש לעדכן קבצים מסוימים בכל פעם שקבצים אחרים משתנים.
היסטוריה
make נוצר במקור על ידי סטיוארט פלדמן באפריל 1976 במעבדות בל. סטיוארט מספר שעמיתו סטיב ג'והנסון (היוצר של YACC) התפרץ ערב אחד למשרדו והתלונן שבזבז יום שלם בניסיון לאתר באג שכבר תוקן, רק משום שהקובץ המתוקן לא עבר הידור מחדש והתיקון לא בא לידי ביטוי בתוכנית הסופית. פלדמן שנתקל בבעיות דומות בעצמו החליט ליצור כלי שיפתור את הבעיה. במהלך סוף שבוע יצר גרסה פשוטה וקריאה במיוחד. למרות המימוש הפשוט הייתה לתוכנית תרומה רבה ביעילות של עבודת הפיתוח. על בניית make קיבל פלדמן את פרס אגודת ACM למערכת תכנה לשנת 2003.
הפעלה
תוכנית make מופעלת כשורת פקודה במעטפת של מערכת ההפעלה. למרות ההבדלים והגרסאות המרובות, תראה פקודת ההפעלה בערך כך
make -f [makefile] target
make היא הפקודה להפעלה (ויכולה להשתנות, לפי שם הפקודה בגרסה המסוימת, כגון gmake או nmake)
makefile הוא פרמטר אופציונלי שמציין את שם קובץ ה-makefile. אם לא מצוין, ברירת המחדל היא קובץ ששמו makefile.
target הוא שם אופציונלי של היעד לבצוע, המופיע בקובץ ה-makefile. בהיעדרו, יבוצע היעד הראשון בקובץ.
Makefile
תוכנית make קוראת ומבצעת את הוראות הבניה כפי שהן מתוארות בקובץ ה-makefile. makefile מתאר את הפעולות הדרושות באופן של תכנות הצהרתי. קובץ ה-makefile ספציפי לכל פרויקט והוא מכיל את רשימת כל הקבצים הנחוצים לבניה, את קשרי התלויות בין הקבצים ואת ההוראות כיצד לבנות קובץ מתוך הקבצים בהם הוא תלוי. ההוראות יהיו בדרך כלל שורת פקודה במעטפת של מערכת ההפעלה. עיקר העבודה של המשתמשים בתוכנית make יהיה בבניית קובץ ה-makefile. לעיתים קרובות ניתן ליצור קובץ כזה באופן אוטומטי מתוך עץ הפרויקט.
קובץ makefile מכיל בעיקר רשימה של חוקים לבנית יעדים. היעדים ירשמו כך:
target [target ...]: [component ...]
Tab ⇆[command 1]
.
.
.
Tab ⇆[command n]
target
יופיע בתחילת שורה. זה היעד. לעיתים קרובות היעד הוא שם קובץ שצריך לבנות אך אפשרי גם יעד ביניים, שהוא שלב בתהליך הבניה של יעד אחר. ניתן לרשום יחד כמה יעדים אך בדרך כלל יכיל כל חוק יעד יחיד.
component
זו רשימת התלויות. כל פריט ברשימה יהיה שם קובץ כלשהו או יעד אחר בקובץ makefile. אפשר שהרשימה תהיה ריקה. במקרה זה, היעד יבנה בכל מקרה.
command
זו שורת הפקודה שיש להפעיל על מנת ליצור את היעד. השורה חייבת להתחיל ב-TAB. ניתן לרשום מספר פקודות ברצף, שורה אחר שורה.
אם לפחות אחד הפריטים ברשימת התלויות חדש יותר מהיעד, הפקודות יתבצעו.
במקרים רבים, למשל בהידור של קובץ מקור, הפקודה הדרושה לבניה היא קבועה וידועה מראש בתוכנית ה-make, ואז אין צורך לפרט אותה.
שורת ה-command אינה תמיד הכרחית. עצם הבדיקה של כל התלויות בשורת היעד תביא לעדכון של כל אחת מהן. לפעמים זה יכול להספיק ואין צורך בעוד חוק לבניה מיוחדת של היעד.
הפקודה לביצוע יכולה להיות כל פקודה שמאפשרת המעטפת, ולאו דווקא חלק מתהליך הבניה, למשל שליחת הודעת אימייל המעדכנת על ביצוע הפעולה.
גם פקודת make שמבוצעת על makefile אחר היא אפשרית.
כללים נוספים
בין יעד ליעד מפרידה שורה ריקה.
שורה שמתחילה ב-# היא שורת הערה.
פרט ליעדים ניתן להגדיר ב makefile דברים רבים נוספים כגון משתנים פנימיים, סימנים מיוחדים שמשפיעם על אופי ביצוע הפקודה או חוקים כללים לטיפול בקבצים על פי הסיומת שלהם.
קובץ makefile לדוגמה
זו דוגמה לקובץ פשוט במיוחד המשמש לבנית תוכנית בקוד C.
הפרויקט מכיל שלושה קבצים של קוד מקור - x.c, y.c ו-z.c, ושני קובצי כותרות m.h ו-n.h, ויוצר קוד ביצוע בשם p.exe
שם הקובץ הוא makefile
#
# This is a simple stupid makefile example
#
clean:
rm *.o
all: clean prog
prog: p.exe
p.exe: x.o y.o z.o
ln a.o b.o c.o p.exe
x.o: x.c m.h b.h
cc x.c -o x.o
y.o: y.c m.h b.h
cc y.c -o y.o
z.o: z.c m.h b.h
cc z.c -o z.o
מכיוון שהקובץ נקרא בשם makefile הפעלה של פקודת make ללא שום פרמטר תמצא את הקובץ על פי שמו ותבצע את היעד הראשון שמופיע בו. זהו clean, אשר ללא תלות בשום קובץ אחר ימחק (פקודת rm) את כל קובצי המטרה שבתיקיה. שלש שורות ההפעלה הבאות יהיו זהות:
make
make -f makefile
make clean
כדי לבנות את התכנית p.exe נוכל להשתמש למשל בשורת הפקודה הבאה
ראו גם
לקריאה נוספת
- Robert Mecklenburg, Managing Projects with GNU Make, 3rd Edition, O'Reilly Media, 2009
קישורים חיצוניים