אנגליתצרפתיתספרדי

Ad


סמל OnWorks

makepp_functions - מקוון בענן

הפעל makepp_functions בספק אירוח בחינם של OnWorks על אובונטו מקוון, פדורה מקוון, אמולטור מקוון של Windows או אמולטור מקוון של MAC OS

זוהי הפקודה makepp_functions שניתן להריץ בספק האירוח החינמי של OnWorks באמצעות אחת מתחנות העבודה המקוונות המרובות שלנו, כגון Ubuntu Online, Fedora Online, אמולטור מקוון של Windows או אמולטור מקוון של MAC OS

תָכְנִית:

שֵׁם


makepp_functions -- פונקציות ב-makepp

תיאור


A: absolute_filename,
absolute_filename_nolink,
אבפאת,
addprefix,
הוספה,
ו, B: שם בסיס, C: שִׂיחָה, D: דיר,
dir_noslash, E: שְׁגִיאָה, F: filesubst,
לסנן,
לסנן,
filter_out_dirs,
מצא קובץ,
מצא_תחילה_למעלה,
find_program,
findstring,
מצא_למעלה,
first_available,
מילה ראשונה,
לכל אחד, I: אם,
אם זה נכון,
infer_linker,
להסיק_אובייקטים,
מידע, J: לְהִצְטַרֵף, M: עשה,
makemap,
מייפרל,
מַפָּה,
"mktemp", N: notdir, O: only_generated,
only_nontargets,
only_phony_targets,
רק_מעופש,
only_targets,
או,
מָקוֹר, P: patsubst,
פרל,
מְזוּיָף,
לבנות מראש,
הדפס, R: מסלול אמיתי,
שם קובץ_יחסי,
ביחס ל, S: צדף,
סוג,
לְהִתְפַּשֵׁט,
משנה,
סִיוֹמֶת, T: זמני, W: אַזהָרָה,
תו כללי,
מילה,
רשימת מילים,
מילים, X: קסארגס

כל ביטוי של הפורמט "$(name)", כאשר "שם" אינו שם של משתנה, או
"$(שם arg1 arg2 arg3)" מתפרש כקריאה לפונקציה. השם עשוי להכיל אותיות,
קווים תחתונים, או מקפים; כדי למנוע בלבול, תוכל להשתמש במקפים או בקו תחתון
לסירוגין, שכן מקפים פנימיים מומרים לקו תחתון. מעריכים כאלה
ביטוי פשוט מעורר תת שגרת פרל. אם לפני "שם" מופיע "&" הוא מריץ את
פקודה או סקריפט מובנה בשם זה בתהליך ה-makepp, ומחזירה את התקן
תְפוּקָה. זה דורש ש-perl יהיה בנוי עבור PerlIO. אם השם לא נותן שם לפונקציה
זה הופך לקריאת קריאה.

כמו עם משתנים, יש לך בחירה בין "$(שם ...)" או "${name ...}". אם אתה רוצה
להטמיע את אותו סוגריים, זה חייב להיות מזווג, השני לא משנה: "$(name
...(){..." או "${name ...{}(...}". (עם זאת, עבור מפה ו-perl המסגר הראשון מסתיים
הביטוי.) הכפלה מאפשרת לארגומנטים להשתרע על פני מספר שורות. השורות החדשות הן
אז התייחסו אליו כרווחים, למעט אולי ב"הגדיר". יש גם את התחביר "$[name ...]"
או $[[name ...]], אשר מוערך בזמן קריאת ה-makefile, לפני חוקי גרקינג
ומבנים אחרים.

ל-Makepp יש מספר פונקציות מובנות שעשויות להיות שימושיות. זה תומך כמעט בכל
הפונקציות הטקסטואליות של GNU make (ראה תיעוד של GNU make לפרטים), וכמה מהן
שֶׁלוֹ. אתה יכול להגדיר תתי שגרות של Perl לעשות מה שאתה רוצה. ראה הצהרת "משנה".
והקטע על הרחבת makepp לפרטים נוספים.

מותנה פונקציות
ו מצב1[,מצב2[,מצב3...]]
הפונקציה ו מספקת פעולת "קצר חשמלי" AND. כל טיעון הוא
מורחבת, לפי הסדר. אם ארגומנט מתרחב למחרוזת ריקה, העיבוד נעצר ו
התוצאה של ההרחבה היא המחרוזת הריקה. אם כל הארגומנטים מתרחבים לא-
מחרוזת ריקה אז התוצאה של ההרחבה היא הרחבה של הארגומנט האחרון.

if חוט, תוצאה-אם-מחרוזת-לא-ריק[, תוצאה-אם-מחרוזת-ריק]
אם זה נכון חוט, תוצאה-אם-string-true[, תוצאה-אם-מחרוזת-שקר]
חלופה להצהרות "איפק" וכו'. אם המחרוזת אינה ריקה (כלומר, ה
condition is true), הארגומנט השני (סעיף ה"אז") מוחזר (אחרי
הרחבה משתנה); אם המחרוזת ריקה, הארגומנט השלישי (סעיף ה"אחר") הוא
חזר.

לדוגמה,

CFLAGS := $(if $(filter gcc egcc, $(CC)), -g -Wall, -g)

מגדיר CFLAGS להיות "-g -Wall" אם המשתנה CC הוא "gcc" או "egcc", ו-"-g"
אחרת. (זה מה שעושים כללי הבנייה המוגדרים כברירת מחדל.)

"iftrue" דומה ל-"if", אלא שהמחרוזת 0 מטופלת כריקה.

or מצב1[,מצב2[,מצב3...]]
הפונקציה או מספקת פעולת "קצר חשמלי" או פעולת OR. כל טיעון מורחב,
בסדר. אם ארגומנט מתרחב למחרוזת לא ריקה, העיבוד נעצר וה-
התוצאה של ההרחבה היא המחרוזת הזו. אם, אחרי שכל הטיעונים מורחבים, כל של
הם שקריים (ריקים), ואז התוצאה של ההרחבה היא המחרוזת הריקה.

שלח ו שם הקובץ פונקציות
absolute_filename קבצים
אבפאת קבצים
ממירה שמות קבצים יחסיים למוחלטים ללא . 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 שמות קבצים
מחלץ את חלק הספרייה של כל קובץ ברשימת שמות הקבצים, כולל ה-Tailing
קו נטוי. מחזירה "./" אם אין ספרייה בשם הקובץ.

dir_noslash שם הקובץ
זהה ל-"$(dir )" חוץ מזה שהוא לא מחזיר את הלוכסן האחורי.

filesubst תבנית, תחליף, מילים
בצע החלפת תבנית בשמות קבצים. זה שונה מ-patsubst בכך
הוא יפעל כהלכה כאשר יינתנו שמות חלופיים עבור ספריות (כל עוד
הם קודמים לסימן האחוזים). לדוגמה,

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

יעבוד עם filesubst אבל לא עם patsubst.

filter_out_dir שמות קבצים
מחזירה את כל שמות הקבצים שאינם מתייחסים לספריות.

מצא קובץ שם קובץ, נתיב
מוצא קובץ בנתיב שצוין, או במשתנה הסביבה 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 ברשימה למעלה, הוא יחליף את not-found.
אחרת המעטפת תנסה להפעיל את קובץ המקור ואת השגיאה שנוצרה
ההודעה עשויה להיות ממש מוזרה.

מצא_למעלה שם הקובץ
מחפש קובץ בשם נתון בספרייה ., .., ../ .., ../../.., וכו ',
עד שיימצא הקובץ או שתגיע אל ספריית השורש או שתמצא את הספרייה
במערכת קבצים אחרת. (דרישה אחרונה זו היא למנוע בעיות עם
רכיבים אוטומטיים או מערכות קבצים תלויות ברשת.) אם יש לך א RootMakeppfile, כלומר גם
מחסום שמונע חיפוש גבוה יותר.

לדוגמה, אם יש לך פרויקט עם הרבה רמות של ספריות משנה, אתה יכול
כלול את הפרגמנט הנפוץ הזה בכל קבצי ה-makefiles (למשל, על ידי שימוש ב-"include"
הַצהָרָה):

TOP_LEVEL_INCLUDE_DIR := $(find_upwards כולל)
# מחפש ספרייה המכילה את
# כולל ספריית משנה.

%.o : %.c
$(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(קלט) -o $(פלט)

בעיה נוספת ש"find_upwards" יכולה לעזור לפתור היא איתור הספרייה ברמה העליונה
של מבנה. לעתים קרובות כדאי להגדיר משתנה כך:

למעלה := ../../..

אם יש לך מידע חשוב שנמצא רק בספרייה ברמה העליונה. אבל
קשה לשמור על זה, כי המספר של ".." שונה עבור רמות שונות
של עץ הספריות. במקום זאת, אתה יכול להשתמש ב-"find_upwards" כדי לאתר קובץ שהוא
ידוע כנמצא רק בספרייה ברמה העליונה. נניח, למשל, שה
הקובץ "LICENSE" ממוקם רק בספרייה ברמה העליונה. אז אתה יכול לעשות את זה:

TOP := $(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".

מצא_ראשון_למעלה file1 file2 ...
פונקציה זו מתנהגת כמו "find_upwards" אלא שהיא מחזירה את הקובץ הראשון מכל אחד
קבצים ברשימה שהוא מוצא. באופן ספציפי, הוא בודק את הספרייה הנוכחית עבור
כל אחד מהקבצים ברשימה, ומחזיר את הקובץ הראשון שקיים או ניתן לבנות.
אם אף אחד מהקבצים לא קיים או ניתן לבנות אותו בספרייה, הוא בודק .., לאחר מכן
../ .., וכו', עד שהוא מגיע לספריית הבסיס או לספרייה שהיא
ממוקם במערכת קבצים אחרת.

first_available file1 file2 ...
החזר את הקובץ הראשון ברשימה שקיימת או שניתן לבנות. זה יכול להיות שימושי עבור
התאמת ה-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 file1 file2 ...
בהינתן רשימה של קבצי אובייקט תחילה בנה אותם אם הם עדיין לא היו. ואז מצא
אם הם תלויים במקור Fortran, C++ או C ומחזירים את המתאים
מהדר (שיודע יותר לקשר מאשר "ld").

להסיק_אובייקטים file1 file2 ..., דפוס
$(infer_objects object1.o object2.o, *.o)

אם אתה משתמש במוסכמות סטנדרטיות לגבי שמות קבצי כותרות, makepp מסוגל
מנחש אילו קבצי ".o" או ".lo" צריכים להיות מקושרים לתוכנית שלך. אני משתמש בזה כדי
בחר קבצים מספריית ספרייה המכילה מודולים המשמשים במגוון רחב
תוכניות. במקום ליצור קובץ ".a" בספרייה ולבקש שהמקשר יבחר את
מודולים רלוונטיים, makepp יכול לבחור את המודולים הרלוונטיים עבורך. רק ככה
המודולים הרלוונטיים יורכבו.

האלגוריתם של Makepp להסקת תלות באובייקט תלוי במוסכמה ש
היישום של כל המחלקות או הפונקציות המוגדרות בקובץ כותרת "xyz.h" הם
הידור לקובץ אובייקט בשם "xyz.o" (או "xyz.lo"). אז האלגוריתם של makepp עבור
הסקת תלות באובייקט מתחילה באובייקט אחד או כמה אובייקטים שאנו יודעים שהם חייבים להיות
מקושר לתוכנית. זה בוחן אילו קבצים נכללו עם "#include" ב
מקורות אלה, ומנסה למצוא קבצי אובייקט תואמים עבור כל אחד מה-include
קבצים.

"$(infer_objects )" צריך להיות מוזכר ברשימת התלות של תוכנית, כמו
זֶה:

myprog: $(infer_objects main.o another_object.o, \
**/*.o /other/library/dirs/**/*.o)
$(CXX) $(כניסות) -o $(פלט) $(LIBS)

הפונקציה "$(infer_objects)" לוקחת שני ארגומנטים (מופרדים בפסיק, כפי שמוצג).
הראשון הוא קובץ אובייקט אחד או כמה שידוע שהם נדרשים (תווים כלליים הם
מותר כאן). השני הוא רשימה של אובייקטים אפשריים (בדרך כלל היית משתמש ב-a
תווים כלליים כאן) שניתן לקשר אליו במידת הצורך. ערך ההחזר מזה
פונקציה היא רשימה המכילה תחילה את כל האובייקטים בארגומנט הראשון, ו
ואז אחרי אלה, כל האובייקטים הנוספים שהיו כלולים בארגומנט השני
הנדרשים על ידי האובייקטים בארגומנט הראשון.

לדוגמה, נניח ש-"main.o" מגיע מ-"main.cpp", הכולל את "my_class.h".
"$(infer_objects)" מחפש קבצים עם השם "my_class.o". אם בדיוק אחד כזה
הקובץ נמצא, הוא נוסף לרשימה. (אם נמצאו שני קבצי אובייקט "my_class.o".
בספריות שונות מודפסת הודעת אזהרה.) גם "מסיק_אובייקטים".
בוחן את "my_class.cpp" כדי לראות מה הוא כולל, ומהם קבצי אובייקט נוספים
מְרוּמָז.

mktemp
mktemp קידומת
mktemp קידומתXXX
mktemp /
מחזירה שם קובץ זמני בלתי צפוי, שאינו קיים כעת. ללא שם
הצבעה על אותו קובץ מוחזרת פעמיים, אפילו עם נתיבים יחסיים שונים,
בתוך ריצת מייקאפ אחת (למעט אולי עם תוצרת רקורסיבית מסורתית, או אם Perl
קוד הפועל בתוך פעולת כלל קורא "f_mktemp"). בסוף המייקאפ הרץ הכל
קבצים המוחזרים על ידי פונקציה זו נמחקים, אם הם קיימים (שוב למעט אלה
מוחזרת על ידי פונקציה זו בקוד Perl הפועל בתוך כלל).

כל מספר של "X" באותיות גדולות בסוף הטיעון מוחלפים במספר כזה
אותיות וספרות אקראיות. ככל שיש יותר, כך יש פחות סיכוי שזה יתנגש
עם תהליכים אחרים, אז אם אתה נותן קידומת כמו "/tmp/abc.", אתה צריך להספיק
"X"ים. אם יש יותר מ-X אחד, התו הראשון מגיע ממזהה התהליך. אם
אין כאלה, זה כאילו היו עשרה, וזה כביכול מספיק (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

או שאתה צריך לייצא אותו ולתת למעטפת להעריך אותו:

ייצוא TMPFILE ;= $(mktemp)
ספירת A ספירת B:
produce-As-and-Bs >$$TMPFILE # makepp לא רואה את ערך ה-var
fgrep -c A $$TMPFILE > A-count
fgrep -c B $$TMPFILE >B-count

הטופס האחרון חוזר על ערך ההחזרה הקודם, כך שתוכל להשתמש בו בכלל דפוס:

%.x: %.y
&grep foo $(קלט) -o $(mktemp)
&sed bar $(mktemp /) -o $(output) # פעל על הפלט של &grep

notdir שמות קבצים
מחזירה את החלק הלא-ספרייה של שמות הקבצים, כלומר, הכל אחרי השם האחרון
נטוי אם יש כזה, או את כל שם הקובץ אחרת.

only_generated שמות קבצים
מחזירה רק את שמות הקבצים ברשימה שנוצרו על ידי makepp ולא מאז
שונה, בהתאם לקובץ מידע הבנייה.

פונקציה זו שימושית בחוקי יעד נקיים (אם כי כמובן "makeppclean" הוא ה-
גרסה מועדפת):

$(נקי מזויף):
&rm -f $(only_generated **/*)

only_nontargets שמות קבצים
מחזירה רק את שמות הקבצים ברשימה שאינם יעדים של אף כלל (או
חוקים מפורשים או דפוסים). אתה יכול לציין תו כללי (ראה "$(תו כללי )"
פונקציה לפרטים נוספים על התווים הכלליים של makepp). זה יכול לשמש ליצירת א
יעד הפצה, למשל:

.PHONY: הפצה

הפצה:
&mkdir our_product-$(VERSION)
&cp $(סינון %~, $(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" יודע רק על יעדים
כבר הוגדרו. זו בעיה רק ​​אם אתה משתמש בה כדי להגדיר משתנים
עם המטלה ":="; אם אתה משתמש בו ברשימת התלות או בגוף א
כלל, כל שאר הכללים כבר נראו.

רק_מעופש שמות קבצים
מחזירה רק את שמות הקבצים ברשימה שנוצרו על ידי makepp ולא מאז
שונה, על פי קובץ המידע של ה-build, אך אינם עוד יעדים של כלל כלשהו.

פונקציה זו שימושית כדי להבטיח שאין תלות בקבצים כאלה,
מבלי לאלץ בנייה נקייה של כל המטרות:

$(שטיפה מזויפת):
&rm -f $(only_stale **/*)

למעשה, כנראה שעדיף במקום לכתוב סקריפט שקורא ל-makepp להפיק
את רשימת הקבצים המעופשים, ולאחר מכן בקש מהסקריפט הזה להסיר את כל הקבצים הרשומים
אינם תחת בקרת מקור כרגע, למקרה שקובץ שנוצר הופך למקור
קוֹבֶץ. ל-Makepp אין פונקציה כזו מובנית כי makepp הוא (וכנראה
צריך להישאר) אגנוסטי לגבי בקרת מקור.

only_targets שמות קבצים
מחזירה רק את שמות הקבצים ברשימה שהם למעשה יעדים של כלל כלשהו
(חוקים מפורשים או תבניתיים). אתה יכול לציין תווים כלליים (כולל Makepp's
תו כללי מיוחד, "**") בשמות הקבצים. (ראה את הפונקציה "$(Wildcard )" למידע נוסף
פרטים. זה יכול לשמש למטרה נקייה, למשל:

.PHONY: נקי

לְנַקוֹת:
&rm -f $(only_targets *)

עכשיו אם תקלידו "makepp clean", זה ימחק את כל מה שהוא יודע לבנות. אבל
אל תיצור מטרה נקייה, השתמש ב-"makeppclean" במקום זאת!

מקום נוסף שבו זה עשוי להיות שימושי הוא להימנע מלהכליל מיושן .o קבצים אצלך
לִבנוֹת. לדוגמה, אם אתה בונה ספרייה כך:

mylib.a: *.o
&rm -f $(פלט)
$(AR) cr $(פלט) $(כניסות)

ואז אתה מוחק כמה קבצי מקור אבל שוכחים למחוק את הקבצים המתאימים .o קבצים,
מה היא .o קבצים עדיין יהיו בסביבה. זה אומר שהם עדיין ישולבו ב
הספרייה למרות העובדה שהם אינם שימושיים יותר. אם תשנה את שלך
כלל כך:

mylib.a: $(only_targets *.o)
&rm -f $(פלט)
$(AR) cr $(פלט) $(כניסות)

אז הבעיה הזו לא תתרחש.

שים לב שזה מתייחס רק לקבצים שידוע שהם יעדים at מה היא זמן אתה
לעורר "רק-מטרות". אם "רק_מטרות" מופיע בתלות או בפעולות של א
כלל, אז כל היעדים האפשריים יהיו ידועים כי אין תלות ופעולות
מוערך עד לביצוע הכלל. עם זאת, אם אתה מעריך נסה להעריך את זה
מוקדם יותר בקובץ makefile עם משתנה ":=" כמו זה:

ALL_TARGETS := $(only_targets *)

יעד1: תלות1
פעולות

יעד2: תלות2
פעולות

אז "רק_מטרות" לא יידע על הכללים הבאים.

באופן דומה, "only_targets" לא יודע על מטרות המיוצרות בקבצי makefile שכן
עמוס ב-make רקורסיבי. (אבל בכל מקרה לא כדאי להשתמש ב-recursive make; השתמש
השתמש בהצהרה "load_makefile", או טעינת makefile מרומזת במקום זאת.)

relative_filename file1 file2 קובץ 3[, קו נטוי]
מחזירה את השם של אותם קבצים ביחס לספרייה הנוכחית (זו של
makefile נמצא). זה יכול לשמש גם כדי לנקות "./" מיותר וזבל אחר
הנתיב:

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

If לקצץ נכון (בדרך כלל 1) מובטח ששמות הקבצים המוחזרים מכילים קו נטוי
על ידי הקדמת "./" במידת הצורך, כך שתוכל להשתמש בו כשם הפעלה ללא
לדאוג שנתיב החיפוש של הפקודה יעקוף את מיקום הספרייה.

אם הנתיב עובר לפי ספריית הבסיס, האב של ספריית הבית שלך או
ה-"$(ROOT)" של מערכת הבנייה שלך, או ב-Windows שורש של כונן (בהתאם ל-
סביבה, זה קורה גם עבור /cygdrive/c or /c), נתיב מוחלט יהיה
חזר במקום.

ביחס ל file1 file2 קובץ 3[, מַדרִיך]
מחזירה את השם של הקבצים האלה ביחס לספרייה שצוינה. זה
שימושי בדרך כלל כאשר מכל סיבה שתצטרך לבצע פקודה מ-a
ספרייה שונה (ספרייה נוכחית כברירת מחדל):

source_backup.tar:
cd .. && tar cf $(relative_to $(פלט), ..) $(relative_to ., ..)

סִיוֹמֶת שמות...
מחלץ את הסיומת של כל שם קובץ בשמות. אם שם הקובץ מכיל נקודה,
הסיומת היא הכל מתחיל מהמחזור האחרון. אחרת, הסיומת היא
מחרוזת ריקה. זה אומר לעתים קרובות שהתוצאה תהיה ריקה כאשר השמות אינם,
ואם שמות מכילים מספר שמות קבצים, התוצאה עשויה להכיל פחות שמות קבצים.

לדוגמה,

$(סיומת src/foo.c src-1.0/bar.c hacks)

מייצר את התוצאה ".c .c".

זמני מילים
הודע ל-makepp שייתכן שהמטרות שצוינו יוסרו על ידי הכלל שיוצר
אוֹתָם. דומה ל"מזויף", אלא ש-makepp מצפה לקובץ אמיתי בשם זה
הרצון עשוי להיות מושפע מהכלל. כלל אינו מבוצע אם הוא רק זמני
היעדים לא מעודכנים.

כלליים דפוס
מחזירה את השמות הממוינים של כל הקבצים התואמים לדפוס הנתון הקיים, או אלה
קבצים שעדיין לא קיימים אך ניתן לבנות על סמך הכללים ש-makepp מכיר
בערך בנקודה שבה הוא מעריך את הביטוי. בנקודה האחרונה זה שונה
מתוך תווים כלליים של קלט כללים, החלים אפילו על קבצים שנוצרו על ידי כללים שנמצאו מאוחר יותר.

Makepp תומך בכל תווי הפגז הרגילים ("*", "?" ו-"[]"). יש לו גם א
תו כללי "**" שמתאים לכל מספר של ספריות מתערבות. (הרעיון הזה היה
נגנב מ-zsh.) לדוגמה, "**/*.c" מתאים לכל ה- .c קבצים במקור כולו
עֵץ. "objects/**/*.o" תואם את כל .o קבצים הכלולים בכל מקום ב-
ספריית משנה אובייקטים או כל אחת מספריות המשנה שלה או כל אחת מספריות המשנה שלהן. ה
התו הכללי "**" לא יעקוב אחר קישורים רכים לספריות בשום רמה, וגם לא
נסה להזין ספריות שקיימות אך לא ניתנות לקריאה. גם קבצים ו
ספריות שקיימות אך לא ניתנות לקריאה לא יוחזרו על ידי "$(Wildcard )".

מחרוזת פונקציות
addprefix קידומת, מילים
מקדים את מחרוזת הקידומת לכל אחת מהמילים. זה בעיקר עבור 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

שיחה מִשְׁתַנֶה[, מילים]...
הפונקציה "קריאה" היא ייחודית בכך שניתן להשתמש בה כדי להתייחס משתנה בתור
פונקציה עם פרמטרים. אתה יכול להקצות ביטוי מורכב ל משתנה ואת השימוש
"קריאה" להרחיב את תוכנו לערכים שונים המוגדרים על ידי מילים מאוחר יותר. ב
other make systems, משתנה המשמש בעיקר למטרה להרחיב באמצעות
"התקשר", נקרא א מאקרו.

במהלך הרחבת המאקרו, המשתנים הזמניים $1, $2, "..." עיין ב
טיעונים שניתנו ל"התקשרות" במהלך הזמנתו. המשתנה $0 יורחב ל
שם המאקרו (כלומר משתנה) שה"קריאה" מתרחבת כעת.

אין הגבלה, עם כמה ארגומנטים אפשר "להתקשר" למאקרו או עם כמה
פרמטרים שמאקרו עשוי לצפות. אם תעביר ארגומנטים נוספים ל"התקשר" בתור המאקרו
צריך, כל הטיעונים החורגים יימחקו. אם תעביר פחות טיעונים מא
macro expect, כל הפרמטרים החורגים קורסים לתוך המחרוזת הריקה.

ראשית דוגמה פשוטה:

rest = $(wordlist 2, $(words $(1)),$(1))
רשימה = ABCDE
butfirst := $(התקשר מנוחה,$(רשימה))

כאן, המשתנה "$(butfirst)" יכיל את הרשימה "BCDE".

ועכשיו לדוגמא מורכבת יותר כדי להראות מה אפשרי:

rest = $(wordlist 2,$(words $(1)),${1})
mymap = $(if $2,$(call $1,$(firstword $2)) $(call $0,$1,$(call rest,$2)))
downcase = ${makeperl lc("$1")}

UCWORDS = כל המילים הללו הן תקינות
DCWORDS := $(call mymap,downcase,$(UCWORDS))

כעת "$(DCWORDS)" מכיל את "כל המילים האלה הן אקזיסטיות". אגב: זה עושה לא
ההבדל, האם אנו ניגשים לטיעונים באמצעות $1, "${1}" or "$(1)" בתוך מאקרו.

אתה יכול להשתמש ישירות במשתנה כאילו הוא פונקציה, אם אין
פונקציה של השם הזה. זה מומר באופן פנימי ל"התקשר", אז אלה הם
שווה ערך:

דיון = $0 הפך ל$1 $2.
ישיר = $(דיון,טיעון)
call = $(call discussion,an,argument)

זה אולי נראה שנוי במחלוקת אם "$[call]" צריך גם להרחיב את "$[]" של המאקרו
ביטויים, או האם פונקציה צריכה תמיד לעשות את אותו הדבר, לא משנה איך היא
נקרא. זה האחרון נבחר, כי עם תחביר לעשות רגיל זה יהיה
בלתי אפשרי להכניס את "$[1], $[2]..." למשתנה (הם יוחלפו בכלום,
לפני שההקצאה מתרחשת.) לפיכך, אם יש לך מאקרו להגדרת א
כלל, אתה רוצה שביטויים כמו "$(פלט)" ייראו כאשר הכלל מנותח, אז
עליך להגן עליהם מפני "קריאה":

להגדיר את מירול
$2: $1
mycommand $$(input) -o $$(output)
endef
$[myrule myinput,myoutput]

לסנן דפוסים, מילים
מחזירה את כל המילים ברשימה התואמות לתבניות. דפוסים עשויים להיות פשוט אחרים
מילים, או תווים כלליים של שמות קבצים (כלומר, "*", "?" ו-"[az]" מזוהים), או שהם עשויים
יש תו "%", שפירושו להתאים לכל מחרוזת באותה נקודה (זהה כמו "*").

לסנן דפוסים, מילים
מחזירה את כל המילים ברשימה שאינן תואמות לתבניות. דפוסים עשויים להיות פשוט
מילים אחרות, או תווים כלליים של שם קובץ (כלומר, "*", "?" ו-"[az]" מזוהים), או
יכול להיות שיש להם תו "%", שפירושו להתאים לכל מחרוזת באותה נקודה (זהה כמו
"*").

לדוגמה:

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

ישים הכל .o קבצים שקיימים או שניתן לבנות, למעט אלה שמתחילים ב מבחן_,
אל תוך libproduction.a.

findstring למצוא, in
לחזור למצוא, אם היא מחרוזת משנה של in.

מילה ראשונה מילים
החזר את המילה הראשונה.

מַפָּה מילים, perlcode
makemap מילים, perlcode
בדומה למפה של פרל, חל perlcode לכל מילה בתורה ומחזירה את
תוצאות. הגרסה הראשונה היא קוד פרל רגיל, בעוד שהגרסה השנייה עוברת תחילה
ה-perlcode באמצעות הרחבת משתנה בסגנון Make. המילים מורחבות בשניהם
במקרים.

המילים מופיעות ב-$_ ומוחזרות אלא אם תבטל את $_. זה מיועד ל
שינויים שלא טופלו בקלות על ידי "patsubst". רק הפסיק הראשון הוא מפריד,
כל אחרים נחשבים לחלק מה perlcode.

# החלף מילים. Parens כפול, כדי לאפשר Parens ב-perlcode, או השתמש ב-${}:
X = $((מפה $(VALUES), s/(.+)-(.+)/$2-$1/)))
# אתה יכול להשתמש בביטויי make, אבל אז אתה חייב להשתמש ב-$$ עבור Perl $:
Y = $(makemap $(VALUES), tr/$(OLDCHARS)/$(NEWCHARS)/ או $$_ = 'נכשל')
# אתה יכול לסלק מועמדים:
Y = $(מפה $(VALUES), undef $_ if /no_good/)

להצטרף מילים 1, מילים 2
בצע צירוף זוגי של המילים הראשונות והמילים השניות.

patsubst תבנית, תחליף, מילים
מבצע החלפה בכל מילה ברשימת המילים. תו "%" מתאים לכל אחד
חוּט. זה מומחש בצורה הטובה ביותר על ידי דוגמה:

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

לוקח כל קובץ ב-C_SOURCES ומחזיר את השם של קובץ אובייקט ב-object_dir.
לפעמים זה יותר תמציתי להשתמש בהפניה להחלפה, למשל, האמור לעיל יכול
נכתבו כ

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

sort word1 word2 word3 ...
ממיין את המילים לפי סדר מילוני ומסיר כפילויות.

להפשיט מחרוזת
מסיר רווח לבן מוביל ונגרר מהמחרוזת ומחליף כל רווח פנימי
רצף של תו רווח אחד או יותר עם רווח בודד. לפיכך, "$(strip ab
c )" מביא ל-"abc".

שם עצם מ,to,טקסט
מבצע החלפה טקסטואלית בטקסט הטקסט: כל מופע של מ- מוחלף
על ידי ל. התוצאה מחליפה את קריאת הפונקציה. לדוגמה,

$(subst ee,EE,רגליים ברחוב)

מחליף את המחרוזת "fEEt on the strEEt".

מילה n,טקסט
מחזירה את nהמילה של טֶקסט. הערכים הלגיטימיים של n להתחיל מ-1 בהתחלה
או אחורה מ-1 בסוף. אם n גדול ממספר המילים ב טֶקסט, ה
הערך ריק.

רשימת מילים רשימת אינדקס, מילים
רשימת מילים אינדקס ראשון, lastindex, מילים
בטופס הראשון אתה מספק רשימה של מדדים (לספור מ-1 בהתחלה או
אחורה מ-1 בסוף) כדי לבחור את המילים הרצויות. בטופס השני אתה
ציין את טווח המילים שברצונך להחזיר.

מילים טֶקסט
מחזירה את מספר המילים ב טֶקסט.

שונות פונקציות
foreach var, list, text
שני הטיעונים הראשונים, היה ו רשימה, מורחבים לפני שנעשה כל דבר אחר; הערה
שהטיעון האחרון, טקסט, אינו מורחב בו-זמנית. ואז לכל מילה של
הערך המורחב של list, המשתנה שנקרא על ידי הערך המורחב של var מוגדר ל
המילה הזו, והטקסט מורחב. יש להניח שהטקסט מכיל הפניות למשתנה הזה,
כך שההרחבה שלו תהיה שונה בכל פעם.

דוגמה פשוטה זו מגדירה את המשתנה קבצים לרשימת כל הקבצים ב-
ספריות ברשימה דירס:

dirs := abcd
קבצים := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

כאן הטקסט הוא "$(Wildcard $(dir)/*)". החזרה הראשונה מוצאת את הערך "a" עבור dir,
כך שהוא מייצר את אותה תוצאה כמו "$(תו כללי a/*)"; החזרה השנייה מייצרת
התוצאה של "$(תו כללי b/*)"; והשלישי, זה של "$(Wildcard c/*)".

לדוגמא זו יש את אותה תוצאה (למעט הגדרת "dirs") כמו הדוגמה הבאה:

files := $(Wildcard a/* b/* c/* d/*)

כאשר הטקסט מסובך, אתה יכול לשפר את הקריאות על ידי מתן שם, עם an
משתנה נוסף:

find_files = $(Wildcard $(dir)/*)
dirs := abcd
קבצים := $(foreach dir,$(dirs),$(find_files))

כאן אנו משתמשים במשתנה find_files בצורה זו. אנו משתמשים ב"=" רגיל כדי להגדיר את a
משתנה המתרחב רקורסיבית, כך שהערך שלו מכיל קריאת פונקציה בפועל אל
להרחיב מחדש תחת שליטת foreach; משתנה מורחב פשוט לא יתאים,
מכיוון שהתו כללי ייקרא פעם אחת בלבד בזמן הגדרת find_files.

הערה: אל תבלבל את זה עם המשתנה המיוחד "$(foreach)".

מידע טֶקסט
אזהרה טֶקסט
שגיאה טֶקסט
פלט טקסט המחזיר את הכלום. הראשון עובר ל-STDOUT, השני ל-STDERR,
השלישי מבטל בנוסף את העיבוד.

לבנות מראש מטרות
לעשות מטרות
מחזיר את הארגומנט שלו מילה במילה, אבל תחילה בונה את כל הקבצים הרשומים. זה שימושי
כאשר יש צורך בקובץ נתון בעת ​​הערכת ביטוי לעשות. זה קורה בדרך כלל
כאשר יש לך מבנה שבו קבוצת הקבצים המעורבים מחושבת על ידי מעטפת כלשהי
פקודות. לדוגמה,

file_list :
# פקודות מעטפת לחישוב רשימה של קבצים להכנס לתוכנית

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 מנסה
לבנות "קובץ_רשימת".

only_phony_targets שמות
מחזירה רק את השמות ברשימה שהם יעדים מזויפים של כלל כלשהו (או
חוקים מפורשים או דפוסים). אתה יכול לציין תווים כלליים (כולל הספיישל של makepp
תו כללי, "**") בשמות הקבצים. (ראה את הפונקציה "$(Wildcard )" לפרטים נוספים.
זה יכול לשמש לקיבוץ יעדים, למשל:

$(בדיקות מזויפות): $(only_phony_targets */**/tests)

מקור משתנה
בהינתן שם של משתנה, אומר לך מהיכן מגיע הערך שלו.

פרל perlcode
makeperl perlcode
מעריך perlcode בבלוק ומחזיר את התוצאה. הגרסה הראשונה היא פרל רגיל
קוד, בעוד שהווריאציה השנייה תחילה מעביר את ה-perlcode דרך המשתנה בסגנון Make
הַרחָבָה.

שימו לב, כמו בכל הפונקציות, ייתכן שמפריד הפונקציות בשימוש לא יופיע בתוכו
ה-perlcode מחוץ למחרוזות במירכאות בודדות או כפולות. אבל אתה יכול להכפיל את זה כמו ב
הדוגמה האחרונה:

VAR = 1
VAR1 = ${perl ($VAR + 1) * 3}
VAR2 = $(perl do { $VAR *= 3; החזר $VAR + 1 } אם $VAR)
VAR3 = $(makeperl $(VAR1) * 3 + $$VAR) # אחד Make var ואחד Perl var
VAR = $((perl if( ... ) { ... }))

מְזוּיָף מילים
מציין שרשימת המילים הן למעשה מטרות מזויפות, ומחזירה את רשימת המילים
מטרות. זה נועד לשמש כך:

$(הכל מזויף): my_program

$(נקי מזויף):
&rm -f *.o my_program

אתה יכול גם להכריז על יעד אחד או יותר כמזויף עם קו כזה בכל מקום בפנים
ה-makefile שלך:

.PHONY: הכל נקי

הדפסה טֶקסט
מוציא את הטקסט ומחזיר אותו. זה שימושי בעיקר עבור ניפוי באגים, כאשר אתה לא עושה זאת
להבין מדוע החלפת משתנים מביאה לתוצאה שכן. לדוגמה,

XYZ := $(הדפס $(patsubst %.c, %o, $(SOURCE_FILES)))

ידפיס את התוצאה של הקריאה "patsubst".

XYZ := $(patsubst %.c, %o, $(הדפס $(SOURCE_FILES))))

ידפיס את הארגומנט האחרון לקריאה "patsubst".

פָּגָז פקודת מעטפת
מחזיר את הפלט מפקודת המעטפת הנתונה, כאשר שורות חדשות מוחלפות ברווחים.

שימו לב, כמו בכל הפונקציות, ייתכן שמפריד הפונקציות בשימוש לא יופיע בתוכו
פקודת המעטפת מחוץ למחרוזות במירכאות בודדות או כפולות. אבל אתה יכול להכפיל את זה
כמו בדוגמה השנייה:

תאריך = $(תאריך מעטפת) # טוב יותר: $(perl scalar localtime)
VAR = ${{shell f() { echo hello; }; f}}

קסארגס פקודה,טיעונים[,סיומת[,אורך]]
מחזירה רשימה מופרדת בשורה חדשה של פקודות שכל אחת מהן מתחילה במצוין
פקודה, ולסיים עם כמה שיותר אלמנטים מהרשימה מבלי לעבור
אורך (ברירת מחדל 1000) תווים.

המטרה של זה היא למנוע זליגה מעל מגבלת אורך הפקודה במערכת שלך.
לדוגמה, אם יש הרבה קבצים שנוצרו, אז כנראה שתרצה את שלך
מטרה נקייה (שאסור לך, כי "makeppclean" יעיל יותר) ל
נראה משהו כזה:

$(נקי מזויף):
$(xargs $(RM), $(only_targets **/*))

יש לזה גם תופעת לוואי שלא נוצרת שום פקודה אם הרשימה
במקרה ריק. אבל במקרה זה עדיף להשתמש ב-&rm המובנה,
מכיוון שהארגומנטים לפקודות המובנות מוגבלים רק על ידי הזיכרון של פרל:

$(נקי מזויף):
&rm -f $(only_targets **/*)

אם צוין ארגומנט שלישי, הוא משמש ל-postfix כל פקודה. זה
שימושי לציון מפנים מחדש, למשל (אם כי כאן שוב &echo יעזור):

לְהַפְגִין:
&rm -f $@
&גע ב$@
$(xargs echo, $(only_nontargets **/*), >> $@)

חלק מהתיעוד הזה מבוסס על התיעוד של GNU.

שים לב שאם פונקציה נקראת במהלך אתחול makefile, למשל
הרחבת משתני ייצוא, הודעות שגיאה או אזהרה תדווח על שורה מספר 0.

השתמש ב-makepp_functions באופן מקוון באמצעות שירותי onworks.net


שרתים ותחנות עבודה בחינם

הורד אפליקציות Windows & Linux

פקודות לינוקס

Ad