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

Ad


סמל OnWorks

חסרונות - מקוון בענן

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

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

תָכְנִית:

שֵׁם


חסרונות - מערכת לבניית תוכנה

תיאור


מדריך והפניה לגרסה 2.2.0

זכויות יוצרים (ג) 1996-2000 Free Software Foundation, Inc.

תוכנית זו היא תוכנה חופשית; אתה יכול להפיץ אותו מחדש ו/או לשנות אותו תחת התנאים של
הרישיון הציבורי הכללי של GNU כפי שפורסם על ידי קרן התוכנה החופשית; אוֹ
גרסה 2 של הרישיון, או (לפי בחירתך) כל גרסה מאוחרת יותר.

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

היית צריך לקבל עותק של הרישיון הציבורי הכללי של GNU יחד עם תוכנית זו;
ראה את הקובץ COPYING. אם לא, כתוב ל- Free Software Foundation, Inc., 59 Temple
מקום - סוויטה 330, בוסטון, MA 02111-1307, ארה"ב.

מבוא


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

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

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

למה חסרונות? למה לֹא עשה?


חסרון הוא א לעשות תַחֲלִיף. בפסקאות הבאות, אנו מסתכלים על כמה מה
מאפיינים לא רצויים של יצרן--וסביבות בנייה טיפוסיות המבוססות על יצרן--זה
הניע את התפתחות החסרונות.

לִבנוֹת מורכבות

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

לִבנוֹת שחזור

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

גִרְסָה אַחֶרֶת בונה

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

מאגרים

Make מספקת תמיכה מוגבלת בלבד לבניית תוכנה מקוד שקיים ב-a
מבנה ספריות של מאגר מרכזי. תכונת VPATH של יצרן GNU (ועוד כמה
make implementations) נועד לספק את זה, אבל לא עובד כצפוי: זה
משנה את הנתיב של קובץ היעד לשם VPATH מוקדם מדי בניתוח שלו, ולכן
מחפש את כל התלות בספריית VPATH. כדי להבטיח פיתוח נכון
בונה, חשוב להיות מסוגל ליצור קובץ בספריית בנייה מקומית ויש
כל קבצים במאגר קוד (ספריית VPATH, במונחי make) התלויים במקומון
הקובץ נבנה מחדש כראוי. זה לא אפשרי עם VPATH, בלי קידוד הרבה
ידע מאגר מורכב ישירות לתוך ה-makefiles.

שְׁמִירָה it פשוט


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

פרל סקריפטים

החסרונות הוא מבוסס פרל. כלומר, תסריטים נגד--לְגַיֵס ו לבנות קבצים, המקבילה
ל קובץ Makefile or קובץ מיידי- כולם כתובים בפרל. זה מספק תועלת מיידית: ה
שפה לכתיבת תסריטים היא שפה מוכרת. גם אם אתה לא במקרה פרל
מתכנת, זה עוזר לדעת שפרל היא בעצם רק שפה הצהרתית פשוטה,
עם זרימת שליטה מוגדרת היטב, וסמנטיקה מוכרת. יש לו משתנים שמתנהגים
בעצם כמו שהיית מצפה מהם, תתי שגרות, זרימת שליטה וכו'. שם
לא הוצג תחביר מיוחד עבור Cons. השימוש בפרל כשפת סקריפטים
מפשט את המשימה להביע את הפתרון המתאים למורכב לעתים קרובות
דרישות של מבנה.

שלום, עולם!

כדי לבסס את הדיון הבא, הנה איך אתה יכול לבנות את שלום, עולם! C
יישום עם חסרונות:

$env = new cons();
תוכנית $env 'hello', 'hello.c';

אם תתקין את הסקריפט הזה בספרייה, תן שם לסקריפט לבנות, וצור את
שלום.ג קובץ המקור באותה ספרייה, ואז אתה יכול להקליד `cons hello' כדי לבנות את
יישום:

% חסרונות שלום
cc -c hello.c -o hello.o
cc -o שלום hello.o

בניה סביבות

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

$env = חסרונות חדשים(
CC => 'gcc',
LIBS => 'libworld.a'
);

תוכנית $env 'hello', 'hello.c';

במקרה זה, במקום להשתמש בסביבת הבנייה המוגדרת כברירת מחדל, כפי שהיא, יש לנו
עוקף את הערך של 'CC' כך שבמקום זאת נעשה שימוש המקבילה של GNU C Compiler. מאז
גרסה זו של שלום, עולם! דורש ספרייה, libworld.a, ציינו שכל
תוכנית המקושרת בסביבה זו צריכה להיות מקושרת לאותה ספרייה. אם הספרייה
קיים כבר, טוב ויפה, אבל אם לא, אז נצטרך לכלול גם את ההצהרה:

ספריית $env 'libworld', 'world.c';

כעת, אם תקליד 'חסרונות שלום', הספרייה תיבנה לפני הקישור של התוכנית, וכן,
כמובן, 'gcc' ישמש כדי להרכיב את שני המודולים:

% חסרונות שלום
gcc -c hello.c -o hello.o
gcc -c world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

מכני עם סלילה אוטומטית ו להשלים התלות אנליזה

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

% vi world.c
[לַעֲרוֹך]
% חסרונות שלום
gcc -c world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

זוהי דוגמה פשוטה יחסית: חסרונות ``יודע'' world.o תלוי ב עולם.ג, כי
התלות מוגדרת במפורש בשיטת 'ספרייה'. זה גם יודע את זה libworld.a
תלוי ב world.o וכי שלום תלוי ב libworld.a, הכל מסיבות דומות.

עכשיו מתברר ש שלום.ג כולל גם את קובץ הגדרות הממשק, עולם.ח:

% emacs world.h
[לַעֲרוֹך]
% חסרונות שלום
gcc -c hello.c -o hello.o
gcc -o hello hello.o libworld.a

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

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

מכני עם סלילה אוטומטית גלוֹבָּלִי לִבנוֹת רצף

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

בִּניָן גָדוֹל עצים - עדיין רק as פשוט


A היררכיה of לִבנוֹת סקריפטים

מבנה גדול יותר, ב-Cons, מאורגן על ידי יצירת היררכיה של לִבנוֹת סקריפטים. בחלק העליון
של העץ הוא תסריט שנקרא לבנות. שאר התסריטים, לפי מוסכמה, הם כל אחד
נקרא לְגַיֵס. התסריטים האלה מחוברים זה לזה, פשוט מאוד, על ידי ה-'Build',
הפקודות 'ייצוא' ו'ייבוא'.

אל האני לִבנוֹת הפקודה

הפקודה 'Build' לוקחת רשימה של לְגַיֵס שמות קבצים, ומסדר אותם
כלול במבנה. לדוגמה:

בניית qw(
נהגים/תצוגה/חובה
נהגים/עכבר/חייל
מנתח/חייל חובה
שירותים/חייל
);

זוהי היררכיה פשוטה של ​​שתי רמות של סקריפטים לבנות: כל החברה הבת לְגַיֵס קבצים
מוזכרים ברמה העליונה לבנות קוֹבֶץ. שימו לב שלא כל המדריכים בעץ
בהכרח יש סקריפטים לבנות המשויכים אליהם.

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

בניית qw(
מנתח/חייל חובה
נהגים/חייל חובה
שירותים/חייל
);

ו לְגַיֵס הקובץ נהגים ספרייה עשויה להכיל את זה:

בניית qw(
תצוגה/גיוס
עכבר/חייל חובה
);

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

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

Conscript_chdir 1;

כאשר מופעל, החסרונות ישתנו לחברה הבת לְגַיֵס הקובץ מכיל ספרייה
תוך כדי קריאה בקובץ הזה, ולאחר מכן שנה חזרה לספרייה ברמה העליונה לאחר הקובץ
עבר עיבוד.

צפוי שהתנהגות זו תהפוך לברירת המחדל בגרסה עתידית כלשהי של Cons.
כדי להתכונן למעבר הזה, מבנים שמצפים שהחסרונות יישארו בראש המבנה
בזמן שהוא קורא בחברת בת לְגַיֵס הקובץ צריך להשבית במפורש תכונה זו כ
התעופה

Conscript_chdir 0;

קרוב משפחה, קרוב משפחה העליון, ו מוחלט פילה שמות

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

שימוש מודולים in לִבנוֹת סקריפטים

אתה יכול למשוך מודולים לכל אחד מהם לְגַיֵס קובץ באמצעות Perl 'שימוש' או 'דרוש'
הצהרות:

השתמש באנגלית;
דורש My::Module;

כל 'שימוש' או 'דרוש' משפיע רק על האחד לְגַיֵס הקובץ שבו הוא מופיע. כדי להשתמש ב- a
מודול במספר רב לְגַיֵס קבצים, עליך לשים הצהרת 'use' או 'דרוש' בכל אחד מהם
כזה שצריך את המודול.

היקף of משתנים

הרמה העליונה לבנות קובץ והכל לְגַיֵס קבצים מתחילים את החיים בפרל משותף ונפרד
חֲבִילָה. חסרונות שולט בטבלת הסמלים עבור החבילה כך, בטבלת הסמלים עבור
כל סקריפט ריק, פרט ל- לבנות קובץ, שמקבל חלק משורת הפקודה
טיעונים. כל המשתנים המוגדרים או בשימוש, לפיכך, נקבעים על ידי הסקריפט
עצמו - לא על ידי סקריפט חיצוני כלשהו.

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

אל האני יצוא הפקודה

הפקודה 'ייצוא' משמשת כמו בדוגמה הבאה:

$env = new cons();
$INCLUDE = "#export/include";
$LIB = "#export/lib";
ייצוא qw( env INCLUDE LIB );
Build qw( util/Conscript);

הערכים של המשתנים הפשוטים המוזכרים ברשימת 'ייצוא' יוסרו
על ידי כל פקודות 'Build' עוקבות. הפקודה 'ייצוא' תייצא רק את Perl סקלר
משתנים, כלומר משתנים ששמם מתחיל ב-`$'. משתנים אחרים, אובייקטים וכו'.
ניתן לייצא באמצעות הפניה--אבל כל הסקריפטים יתייחסו לאותו אובייקט, וזה
יש לראות את האובייקט כקריאה בלבד על ידי התסריטים הבתים ועל ידי המקור
ייצוא סקריפט. עם זאת, מקובל להקצות ערך חדש לסקלר המיוצא
משתנה--זה לא ישנה את המשתנה הבסיסי אליו מתייחסים. הרצף הזה, עבור
דוגמה, זה בסדר:

$env = new cons();
ייצוא qw( env INCLUDE LIB );
Build qw( util/Conscript);
$env = new cons(CFLAGS => '-O');
Build qw(אחר/חובה חובה);

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

אל האני תבואו הפקודה

ניתן לייבא משתנים המיוצאים על ידי הפקודה 'ייצוא' לתוך סקריפטים בת על ידי
פקודת 'ייבוא'. הסקריפט הבת תמיד מייבא משתנים ישירות מה-
תסריט מעולה. שקול את הדוגמה הזו:

ייבוא ​​qw( env INCLUDE );

זה חוקי רק אם סקריפט האב ייצא גם `$env' וגם `$INCLUDE'. זה גם חייב
נתנו לכל אחד מהמשתנים הללו ערכים. זה בסדר עבור התסריט הבת בלבד
ייבא קבוצת משנה של המשתנים המיוצאים (בדוגמה זו, `$LIB', אשר יצאה על ידי
הדוגמה הקודמת, אינה מיובאת).

כל המשתנים המיובאים מיוצאים מחדש אוטומטית, כך שהרצף:

ייבוא ​​qw (env INCLUDE);
בניית qw (מתחת לי/חובה);

יספק גם `$env' וגם `$INCLUDE' לקובץ הבת. אם רק '$env' אמור להיות
מיוצא, אז יספיקו הדברים הבאים:

ייבוא ​​qw (env INCLUDE);
ייצוא qw (env);
בניית qw (מתחת לי/חובה);

מיותר לציין שהמשתנים עשויים להשתנות באופן מקומי לפני הפעלת `Build' ב-
תסריט בת.

לִבנוֹת תסריט הערכה להזמין

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

בניית qw(
נהגים/תצוגה/חובה
נהגים/עכבר/חייל
מנתח/חייל חובה
שירותים/חייל
);

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

A מספר סימוכין ל שיתוף קבצים


כמה פשוט אמנות

בכל מערכת תוכנה מורכבת, צריכה להיות שיטה לשיתוף מוצרי בנייה
מְבוּסָס. אנו מציעים קבוצה פשוטה של ​​מוסכמות שטריוויאליות ליישם איתן
חסרונות, אבל מאוד יעיל.

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

ספריות אלו מוגדרות על ידי הרמה העליונה לבנות קוֹבֶץ. פשוט לבנות עבור
a שלום, עולם! יישום, המאורגן באמצעות מספר ספריות, עשוי להיראות כך:

# קובץ בנייה עבור Hello, World!

# איפה לשים את כל המוצרים המשותפים שלנו.
$EXPORT = '#export';

ייצוא qw( חסרונות כוללים LIB BIN);

# ספריות סטנדרטיות לשיתוף מוצרים.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bin";

# סביבת בנייה סטנדרטית.
$CONS = חסרונות חדשים (
CPPPATH => $INCLUDE, # כלול נתיב עבור C Compilations
LIBPATH => $LIB, # נתיב ספרייה לקישור תוכניות
LIBS => '-lworld', # רשימה של ספריות סטנדרטיות
);

בניית qw(
שלום/חייל חובה
עולם/חייל חובה
);

אל האני עוֹלָם של ספרייה לְגַיֵס הקובץ נראה כך:

# קובץ גיוס עבור עולם הספריות
ייבוא ​​qw( CONS INCLUDE LIB);

# התקן את המוצרים של ספרייה זו
התקן את $CONS $LIB, 'libworld.a';
התקן את $CONS $INCLUDE, 'world.h';

# מוצרים פנימיים
ספריית $CONS 'libworld.a', 'world.c';

ו שלום של ספרייה לְגַיֵס הקובץ נראה כך:

# קובץ מתגייס לספרייה שלום
ייבוא ​​qw( CONS BIN );

# מוצרים מיוצאים
התקן $CONS $BIN, 'שלום';

# מוצרים פנימיים
תוכנית $CONS 'hello', 'hello.c';

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

% חסרונות ייצוא
התקן את world/world.h בתור export/include/world.h
cc -Iexport/include -c hello/hello.c -o hello/hello.o
cc -Iexport/include -c world/world.c -o world/world.o
ar r world/libworld.a world/world.o
ar: יצירת עולם/libworld.a
ranlib world/libworld.a
התקן את world/libworld.a בתור export/lib/libworld.a
cc -o hello/hello hello/hello.o -Lexport/lib -lworld
התקן hello/hello בתור ייצוא/bin/hello

לְנַקוֹת, מובן, בלתי תלוי במיקום סקריפטים

תשים לב שהשניים לְגַיֵס הקבצים מאוד נקיים ונוגעים לנקודה. הם פשוט
ציין את המוצרים של הספרייה וכיצד לבנות את המוצרים האלה. הוראות הבנייה
הם מינימליים: הם מציינים באיזו סביבת בנייה להשתמש, שם המוצר,
ושם הכניסות. שים לב גם שהסקריפטים אינם תלויי מיקום: אם אתה
ברצונך לארגן מחדש את עץ המקור שלך, אתה חופשי לעשות זאת: אתה רק צריך לשנות את
לבנות קובץ (בדוגמה זו), כדי לציין את המיקומים החדשים של ה- לְגַיֵס קבצים. ה
השימוש בעץ ייצוא מקל על המטרה הזו.

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

נפרדים מָקוֹר ו לִבנוֹת עצים


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

נפרדים לִבנוֹת ו מָקוֹר ספריות באמצעות מה היא קישור הפקודה

חסרונות מספק מנגנון פשוט המטפל בכל הדרישות הללו. ה'קישור'
הפקודה מופעלת כמו בדוגמה זו:

קישור 'build' => 'src';

הספריות שצוינו "מקושרות" לספריית המקור שצוינה. בואו נניח
שאתה מגדיר ספריית מקור, src, עם ספריות המשנה עוֹלָם ו שלום מתחת,
כמו בדוגמה הקודמת. לאחר מכן תוכל להחליף את קווי הבנייה המקוריים
הבא:

בניית qw(
לבנות/עולם/חייל
לבנות/שלום/חובה
);

שימו לב שאתם מטפלים ב לְגַיֵס קובץ כאילו הוא קיים בספריית ה-build. עכשיו אם
אם תקליד את אותה פקודה כמו קודם, תקבל את התוצאות הבאות:

% חסרונות ייצוא
התקן את build/world/world.h בתור export/include/world.h
cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o
cc -Iexport/include -c build/world/world.c -o build/world/world.o
ar r build/world/libworld.a build/world/world.o
ar: יצירת build/world/libworld.a
ranlib build/world/libworld.a
התקן את build/world/libworld.a בתור export/lib/libworld.a
cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld
התקן את build/hello/hello בתור ייצוא/bin/hello

שוב, Cons דאג לפרטים עבורך. בפרט, תשים לב שהכל
הבנייה מתבצעת באמצעות קובצי מקור וקבצי אובייקט מספריית ה-build. ל
דוגמא, build/world/world.o מורכב מ build/world/world.c, ו
export/include/world.h מותקן מ build/world/world.h. זה מושג על רוב
מערכות על ידי התועלת הפשוטה של ​​קישור ``קשה'' בין הקבצים הנדרשים מכל מקור
ספרייה לתוך ספריית הבנייה המתאימה.

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

אתה גם תשים לב, אגב, לזה לא נדרשו שינויים בבסיס לְגַיֵס
קבצים. ואנחנו יכולים ללכת רחוק יותר, כפי שנראה בסעיף הבא.

גִרְסָה אַחֶרֶת בונה


שלום, עולם! ל בננה ו אפרסק של מערכת הפעלה

גרסאות בנייה דורשות רק עוד הרחבה פשוטה. ניקח כדוגמה את א
הדרישה לאפשר בנייה הן למערכות ההפעלה baNaNa והן ל-peAcH. במקרה הזה,
אנו משתמשים במערכת קבצים מבוזרת, כגון NFS כדי לגשת למערכת המסוימת, ו
יש להרכיב רק אחת או אחרת מהמערכות עבור כל הפעלה נתונה של
'חסרונות'. הנה דרך אחת שנוכל להגדיר את לבנות קובץ עבור שלנו שלום, עולם!
יישום:

# קובץ בנייה עבור Hello, World!

die qq(יש לציין מערכת הפעלה) אלא אם $OS = $ARG{OS};
die qq(מערכת ההפעלה חייבת להיות "אפרסק" או "בננה")
if $OS ne "peach" && $OS ne "banana";

# איפה לשים את כל המוצרים המשותפים שלנו.
$EXPORT = "#export/$OS";

ייצוא qw( חסרונות כוללים LIB BIN);

# ספריות סטנדרטיות לשיתוף מוצרים.
$INCLUDE = "$EXPORT/include";
$LIB = "$EXPORT/lib";
$BIN = "$EXPORT/bin";

# סביבת בנייה סטנדרטית.
$CONS = חסרונות חדשים (
CPPPATH => $INCLUDE, # כלול נתיב עבור C Compilations
LIBPATH => $LIB, # נתיב ספרייה לקישור תוכניות
LIBS => '-lworld', # רשימה של ספריות סטנדרטיות
);

# $BUILD הוא המקום שבו נפיק הכל.
$BUILD = "#build/$OS";

# ספר לחסרונות היכן נמצאים קבצי המקור עבור $BUILD.
קישור $BUILD => 'src';

בנה (
"$BUILD/hello/Conscript",
"$BUILD/world/Conscript",
);

כעת, אם נהתחבר למערכת peAcH, נוכל לבנות את שלנו שלום, עולם! בקשה לכך
פּלַטפוֹרמָה:

% חסרונות לייצא OS=peach
התקן את build/peach/world/world.h בתור export/peach/include/world.h
cc -Iexport/peach/include -c build/peach/hello/hello.c -o build/peach/hello/hello.o
cc -Iexport/peach/include -c build/peach/world/world.c -o build/peach/world/world.o
ar r build/peach/world/libworld.a build/peach/world/world.o
ar: יצירת build/peach/world/libworld.a
ranlib build/peach/world/libworld.a
התקן את build/peach/world/libworld.a בתור export/peach/lib/libworld.a
cc -o build/peach/hello/hello build/peach/hello/hello.o -Lexport/peach/lib -lworld
התקן את build/peach/hello/hello בתור export/peach/bin/hello

וריאציות on a נושא

וריאציות אחרות של דגם זה אפשריות. לדוגמה, אתה עשוי להחליט שאתה רוצה
כדי להפריד את קבצי ה-include שלך ​​לקבצים תלויי פלטפורמה וקבצים בלתי תלויים בפלטפורמה.
במקרה זה, תצטרך להגדיר אלטרנטיבה ל-`$INCLUDE' לתלוי פלטפורמה
קבצים. רוב לְגַיֵס קבצים, שיוצרים קבצי כוללים ללא פלטפורמה בלבד, יעשו זאת
לא צריך לשנות.

אולי תרצה גם להיות מסוגל להדר את כל המערכת שלך עם איתור באגים או פרופיל,
לדוגמה, מופעל. אתה יכול לעשות זאת עם אפשרויות שורת פקודה מתאימות, כגון
`DEBUG=on'. זה יתורגם לאחר מכן לפלטפורמה הספציפית המתאימה
דרישות לאפשר איתור באגים (זה עשוי לכלול כיבוי אופטימיזציה, עבור
דוגמא). אתה יכול לחלופין לשנות את מרחב השמות עבור סוגי המערכות השונות האלה,
אבל, כפי שנראה בסעיף הבא, זה לא חיוני לעשות זאת, מכיוון שחסרונות זה יפה
חכם בבניית דברים מחדש כשאתה משנה אפשרויות.

חתימות


MD5 קריפטוגרפי חתימות

בכל פעם שחסרונות יוצר קובץ נגזר, הוא מאחסן א חֲתִימָה עבור הקובץ הזה. החתימה
מאוחסן בקובץ נפרד, אחד לכל ספרייה. לאחר הידור הדוגמה הקודמת,
מה היא .לִמְסוֹר הקובץ לבנות/אפרסק/עולם הספרייה נראתה כך:

world.o:834179303 23844c0b102ecdc0b4548d1cd1cbd8c6
libworld.a:834179304 9bf6587fa06ec49d864811a105222c00

המספר הראשון הוא חותמת זמן - עבור מערכות UNIX, זה בדרך כלל המספר של
שניות מאז ה-1 בינואר 1970. הערך השני הוא בדיקת MD5. ה הערות נוספות תקציר
אַלגוֹרִיתְם הוא אלגוריתם שבהינתן מחרוזת קלט, מחשב קריפטוגרפיה חזקה
חתימה עבור המחרוזת הזו. סכום הבדיקה של MD5 המאוחסן ב- .לִמְסוֹר הקובץ הוא, למעשה, א
תקציר של כל מידע התלות עבור הקובץ שצוין. אז, למשל, עבור
world.o קובץ, זה כולל לפחות את עולם.ג קובץ, וגם כל קבצי כותרות ש-Cons
יודע על זה נכללים, במישרין או בעקיפין על ידי עולם.ג. לא רק זה, אלא גם
שורת הפקודה בפועל ששימשה ליצירת world.o מוזנת גם לחישוב של
החתימה. באופן דומה, libworld.a מקבל חתימה ש``כוללת'' את כל
חתימות של מרכיביו (ומכאן, באופן טרנזיטיבי, החתימות של שֶׁלָהֶם
מרכיבים), כמו גם שורת הפקודה שיצרה את הקובץ.

החתימה של קובץ שאינו נגזר מחושבת, כברירת מחדל, על ידי לקיחת הזרם
זמן השינוי של הקובץ ושם הערך של הקובץ (אלא אם במקרה יש א
נוֹכְחִי .לִמְסוֹר ערך עבור אותו קובץ, ובמקרה זה נעשה שימוש בחתימה זו).

שימו לב שאין צורך שקובץ נגזר יהיה תלוי בפרט כלשהו לבנות or
לְגַיֵס קובץ - אם שינויים בקבצים אלה משפיעים על הקובץ המדובר, אז זה יהיה
משתקף אוטומטית בחתימתו, מכיוון שחלקים רלוונטיים בשורת הפקודה הם
כלול בחתימה. שינויים לא קשורים לא ישפיעו.

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

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

השימוש בחתימות אלו הוא שיטה פשוטה, יעילה ויעילה ביותר
שיפור דרמטי של יכולת השחזור של מערכת.

נדגים זאת באמצעות דוגמה פשוטה:

# פשוט "שלום, עולם!" קובץ בנייה
$CFLAGS = '-g' אם $ARG{DEBUG} eq 'פועל';
$CONS = new cons(CFLAGS => $CFLAGS);
תוכנית $CONS 'hello', 'hello.c';

שימו לב כיצד Cons מבצע קומפילציה מחדש בזמנים המתאימים:

% חסרונות שלום
cc -c hello.c -o hello.o
cc -o שלום hello.o
% חסרונות שלום
חסרונות: "שלום" מעודכן.
% חסרונות DEBUG=על שלום
cc -g -c hello.c -o hello.o
cc -o שלום hello.o
% חסרונות DEBUG=על שלום
חסרונות: "שלום" מעודכן.
% חסרונות שלום
cc -c hello.c -o hello.o
cc -o שלום hello.o

קופונים מאגרים


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

Repository

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

השורות הבאות בא לבנות הקובץ יורה ל-Cons לחפש תחילה תחת ה-
/usr/experiment/repository ספרייה ולאחר מכן מתחת ל- /usr/product/repository Directory:

מאגר qw (
/usr/experiment/repository
/usr/product/repository
);

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

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

מציאה מה היא לבנות פילה in a Repository

חסרונות יחפשו גם לבנות ו לְגַיֵס קבצים בעץ המאגר או בעצים.
אבל זה מוביל למצב של ביצה ותרנגולת: איך אתה נראה בעץ מאגר
עבור לבנות קובץ אם ה לבנות הקובץ אומר לך היכן נמצא המאגר? להשיג
סביב זה, ניתן לציין מאגרים באמצעות אפשרויות `-R' בשורת הפקודה:

% חסרונות -R /usr/experiment/repository -R /usr/product/repository .

כל ספריות המאגר המצוינות ב- לבנות or לְגַיֵס קבצים יצורפו
לספריות המאגר המצוינות על ידי אפשרויות שורת הפקודה `-R'.

Repository מָקוֹר קבצים

אם קוד המקור (כולל את לְגַיֵס קובץ) עבור גרסת הספרייה של שלום,
עולם! יישום C נמצא במאגר (ללא קבצים נגזרים), חסרונות ישתמשו ב
קבצי מקור של מאגר ליצירת קובצי האובייקט המקומיים וקובץ ההפעלה:

חסרונות % -R /usr/src_only/repository שלום
gcc -c /usr/src_only/repository/hello.c -o hello.o
gcc -c /usr/src_only/repository/world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

יצירת קובץ מקור מקומי תגרום ל-Cons לבנות מחדש את הקובץ הנגזר המתאים או
קבצים:

% pico world.c
[לַעֲרוֹך]
חסרונות % -R /usr/src_only/repository שלום
gcc -c world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

והסרת קובץ המקור המקומי תגרום ל-Cons לחזור לבניית הנגזרת
קבצים ממקור המאגר:

% rm world.c
חסרונות % -R /usr/src_only/repository שלום
gcc -c /usr/src_only/repository/world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

Repository נגזר קבצים

אם עץ מאגר מכיל קבצים נגזרים (בדרך כלל קבצי אובייקט, ספריות או
קבצי הפעלה), Cons יבצע את חישוב החתימה הרגיל שלו כדי להחליט אם
קובץ המאגר מעודכן או שיש לבנות קובץ נגזר באופן מקומי. זה אומר ש,
על מנת להבטיח חישוב נכון של חתימה, עץ מאגר חייב להכיל גם את
.לִמְסוֹר קבצים שנוצרו על ידי Cons בעת יצירת הקבצים הנגזרים.

בדרך כלל זה יבוצע על ידי בניית התוכנה במאגר (או,
לחלופין, בספריית build, ולאחר מכן העתקת התוצאה למאגר):

% cd /usr/all/repository
% חסרונות שלום
gcc -c hello.c -o hello.o
gcc -c world.c -o world.o
ar libworld.a world.o
ar: יצירת libworld.a
ranlib libworld.a
gcc -o hello hello.o libworld.a

(זה בטוח גם אם לבנות הקובץ מפרט את /usr/all/repository ספרייה ב-a
פקודת `Repository' כי Cons יסיר את הספרייה הנוכחית מהמאגר
רשימה.)

עכשיו אם אנחנו רוצים לבנות עותק של האפליקציה משלנו שלום.ג קובץ, אנחנו רק צריכים
כדי ליצור את קובץ המקור האחד הדרוש, ולהשתמש באפשרות `-R' כדי שה-Cons ישתמשו באחר
קבצים מהמאגר:

% mkdir $HOME/build1
% cd $HOME/build1
% ed hello.c
[לַעֲרוֹך]
% חסרונות -R /usr/all/repository שלום
gcc -c hello.c -o hello.o
gcc -o hello hello.o /usr/all/repository/libworld.a

שימו לב שחסרונות לא טרחו ליצור מחדש מקומי libworld.a הספרייה (או הידור מחדש של
world.o מודול), אך במקום זאת משתמש בגרסה שכבר הורכבה מהמאגר.

כי חתימות MD5 ש-Cons מכניס את .לִמְסוֹר הקובץ מכיל חותמות זמן עבור
קבצים נגזרים, חותמות הזמן של החתימה חייבות להתאים לחותמות הזמן של הקובץ עבור חתימה
להיחשב תקף.

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

Repository_Sig_Times_OK 0;

זה אומר לחסרונות להתעלם מחותמות זמן כאשר מחליטים אם החתימה תקפה. (הערה
שהימנעות מבדיקת שפיות זו פירושה שחייבת להיות שליטה נאותה על המאגר
עץ כדי להבטיח שלא ניתן לשנות את הקבצים הנגזרים מבלי לעדכן את .לִמְסוֹר
חֲתִימָה.)

מקומי עותקים of קבצים

אם עץ המאגר מכיל את התוצאות המלאות של בנייה, ואנחנו מנסים לבנות ממנה
המאגר ללא קבצים בעץ המקומי שלנו, משהו מפתיע במידה בינונית
קורה:

% mkdir $HOME/build2
% cd $HOME/build2
% חסרונות -R /usr/all/repository שלום
חסרונות: "שלום" מעודכן.

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

עם זאת, ישנם מקרים רבים בהם ראוי לוודא כי עותק מקומי של א
הקובץ תמיד קיים. סקריפט אריזה או בדיקה, למשל, עשויים להניח שזה בטוח
קבצים שנוצרו קיימים באופן מקומי. במקום לגרום לתסריטים של הבת האלה להיות מודעים ל
ספריית המאגר, ניתן להוסיף את הפקודה 'מקומי' ל-a לבנות or לְגַיֵס הקובץ אל
ציין שקובץ או קבצים מסוימים חייבים להופיע בספריית הבנייה המקומית:

qw מקומי(
שלום
);

לאחר מכן, אם נפעיל מחדש את אותה פקודה, Cons ייצור עותק מקומי של התוכנית מה-
עותק מאגר (אומר לך שהוא עושה זאת):

% חסרונות -R /usr/all/repository שלום
עותק מקומי של hello מ-/usr/all/repository/hello
חסרונות: "שלום" מעודכן.

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

יצירת עותקים מקומיים שימושית ביותר עבור קבצים המותקנים ב-
ספריית ביניים (לשיתוף עם ספריות אחרות) באמצעות הפקודה 'התקן'.
מלווה את הפקודה 'התקן' עבור קובץ עם פקודת 'מקומי' נלווית היא כזו
שכיח ש-Cons מספק פקודת 'Install_Local' כדרך נוחה לעשות את שניהם:

Install_Local $env, '#export', 'hello';

שווה בדיוק ל:

התקן את $env '#export', 'hello';
מקומי '#export/hello';

גם הפקודות 'Local' וגם 'Install_Local' מעדכנות את המקומי .לִמְסוֹר להגיש עם
חתימות קבצים מתאימות, כך שבנייה עתידית תתבצע כהלכה.

Repository התלות אנליזה

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

% חסרונות -R /usr/all/repository שלום
gcc -c /usr/all/repository/hello.c -o hello.o
/usr/all/repository/hello.c:1: hello.h: אין קובץ או ספרייה כאלה

פתרון בעיה זו כופה כמה דרישות על האופן שבו סביבות הבנייה הן
מוגדר ועל האופן שבו נעשה שימוש בהנחיית Preprocessor C `#include' כדי לכלול קבצים.

על מנת ליידע את המהדר על עצי המאגר, חסרונות יוסיף `-I' מתאים
מסמנים לפקודות הקומפילציה. המשמעות היא שהמשתנה 'CPPPATH' ב-
סביבת construct חייבת לציין במפורש את כל ספריות המשנה שבהן יש לחפש
עבור קבצים כלולים, כולל הספרייה הנוכחית. כתוצאה מכך, אנו יכולים לתקן את האמור לעיל
דוגמה על ידי שינוי יצירת הסביבה ב לבנות הגש כדלקמן:

$env = חסרונות חדשים(
CC => 'gcc',
CPPPATH => '.',
LIBS => 'libworld.a',
);

בשל ההגדרה של המשתנה 'CPPPATH', זה מניב, כאשר אנו מבצעים מחדש את
פקודה:

% חסרונות -R /usr/all/repository שלום
gcc -c -I. -I/usr/all/repository /usr/all/repository/hello.c -o hello.o
gcc -o hello hello.o /usr/all/repository/libworld.a

סדר הדגלים `-I' משכפל, עבור מעבד הקדם C, את אותו מאגר-
נתיב חיפוש ספריות שבו משתמש Cons לניתוח התלות שלו. אם יש
מאגרים מרובים ומספר רב של ספריות 'CPPPATH', חסרונות יצרפו את המאגר
ספריות לתחילת כל ספריית 'CPPPATH', תוך הכפלה מהירה של המספר
של דגלי `-אני'. כדוגמה קיצונית, א לבנות קובץ המכיל:

מאגר qw(
/u1
/u2
);

$env = חסרונות חדשים(
CPPPATH => 'a:b:c',
);

תניב פקודת קומפילציה של:

cc -Ia -I/u1/a -I/u2/a -Ib -I/u1/b -I/u2/b -Ic -I/u1/c -I/u2/c -c hello.c -o שלום.או

מכיוון שחסרונות מסתמכים על דגלי `-I' של המהדר כדי לתקשר את הסדר שבו
יש לחפש ספריות מאגר, הטיפול של Cons בספריות מאגר הוא
אינו תואם ביסודו לשימוש במירכאות כפולות בהנחיות '#include' ב-C שלך
קוד מקור:

#include "file.h" /* אל תשתמש במרכאות כפולות כמו זה */

הסיבה לכך היא שרוב מעבדי הקדם C, כאשר הם מתמודדים עם הנחיה כזו, תמיד יהיו ראשונים
חפש בספרייה המכילה את קובץ המקור. זה מערער את ה'-אני' המשוכלל
אפשרויות ש-Cons בונה כדי לגרום לקדם-מעבד להתאים לחיפוש המועדף עליו
נתיב.

כתוצאה מכך, בעת שימוש בעצי מאגר ב-Cons, תמיד השתמש בסוגריים זווית עבור הכלולים
קבצים:

#לִכלוֹל /* השתמש בסוגרי זווית במקום */

Repository_List

חסרונות מספקת פקודת `Repository_List' כדי להחזיר רשימה של כל ספריות המאגר
בסדר החיפוש הנוכחי שלהם. זה יכול לשמש עבור ניפוי באגים, או לעשות Perl מורכב יותר
דברים:

@list = Repository_List;
print join(' ', @list), "\n";

Repository אינטראקציה עם אַחֵר חסרונות מאפיינים

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

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

בְּרִירַת מֶחדָל מטרות


עד עכשיו, הדגמנו הפעלת חסרונות עם יעד מפורש לבנות:

% חסרונות שלום

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

% חסרונות # לא בונה כלום

% חסרונות. # בונה הכל מתחת לספרייה ברמה העליונה

הוספת שיטת 'ברירת מחדל' לכל לבנות or לְגַיֵס הקובץ יוסיף את המצוין
ממקד לרשימת יעדי ברירת מחדל. חסרונות יבנו את ברירת המחדל האלה אם אין
מטרות שצוינו בשורת הפקודה. אז הוספת השורה הבאה לרמה העליונה
לבנות הקובץ יחקה את ההתנהגות האופיינית של Make לבניית הכל כברירת מחדל:

ברירת המחדל '.';

הדברים הבאים יוסיפו את שלום ו שלום פקודות (באותה ספרייה כמו ה-
לבנות or לְגַיֵס קובץ) לרשימת ברירת המחדל:

ברירת מחדל qw(
שלום
שלום
);

ניתן להשתמש בשיטת 'ברירת מחדל' יותר מפעם אחת כדי להוסיף יעדים לרשימת ברירת המחדל.

סלקטיבי בונה


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

סלקטיבי מיקוד

כמו make, Cons מאפשר את המפרט של ``מטרות'' בשורת הפקודה. מטרות חסרונות
יכולים להיות קבצים או ספריות. כאשר מציינים ספריה, זהו פשוט קצר-
סימון יד עבור כל מוצר נגזר--שחסרונות יודע עליו--במפרט שצוין
ספרייה ומטה. לדוגמה:

% חסרונות build/hello/hello.o

פירושו לבנות שלום.או וכל מה ש שלום.או עשוי להזדקק. זה מקודמו
גרסה של שלום, עולם! תוכנית שבה שלום.או היה תלוי
export/include/world.h. אם הקובץ הזה לא מעודכן (כי מישהו שינה
src/world/world.h), אז הוא ייבנה מחדש, למרות שהוא נמצא בספריה מרוחק מ
לבנות/שלום.

בדוגמה זו:

% חסרונות לבנות

הכל ב לִבנוֹת ספרייה נבנית, במידת הצורך. שוב, זה עלול לגרום ליותר קבצים
להיבנות. בפרט, שניהם export/include/world.h ו export/lib/libworld.a יש לו
נדרש על ידי לבנות/שלום ספרייה, וכך הם ייבנו אם הם לא מעודכנים.

אם נעשה זאת, במקום זאת:

% חסרונות ייצוא

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

לא ``מיוחד'' מטרות

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

% בדיקות חסרונות

יבנה את כל המבחנים.

% חסרונות ייצוא

יבנה את גרסת הייצור של המערכת (אך לא את הבדיקות), וכן:

% חסרונות לבנות

יש להימנע מן הסתם (מכיוון שהוא ירכיב בדיקות שלא לצורך).

אם אתה רוצה לבנות רק מבחן בודד, אתה יכול לתת שם במפורש למבחן (ב
או בדיקות ספרייה או ה לִבנוֹת מַדרִיך). אתה יכול גם לצבור את הבדיקות
לתוך היררכיה נוחה בתוך ספריית הבדיקות. ההיררכיה הזו לא צריכה
בהכרח להתאים את היררכיית המקור, בערך באותו אופן שבו היררכיית הכלולים
כנראה לא תואם את היררכיית המקור (סביר להניח שההיררכיה הכוללת תהיה יותר
עומק משתי רמות, עבור תוכניות C).

אם אתה רוצה לבנות הכל בעץ (בכפוף לכל האפשרויות שאתה
בחר), אתה יכול להשתמש ב:

% חסרונות.

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

לִבנוֹת גיזום


בשילוב עם בחירת יעד, לִבנוֹת גיזום ניתן להשתמש כדי לצמצם את היקף ה
לִבנוֹת. בדוגמה הקודמת של peAcH ו-baNaNa, כבר ראינו כיצד מונעי סקריפט
ניתן להשתמש בגיזום בנייה כדי להפוך רק מחצית מהמבנה הפוטנציאלי זמין לכל נתון
הפעלת 'חסרונות'. חסרונות מספקת גם, לנוחות, קונבנציה של שורת פקודה
מאפשר לך לציין איזה לְגַיֵס קבצים למעשה "נבנים" - כלומר, משולבים
לתוך עץ הבנייה. לדוגמה:

% חסרונות לבנות +עולם

הארגומנט '+' מציג ביטוי רגולרי של Perl. יש לצטט זאת כמובן ב
רמת הקליפה אם יש מטא-תווים של מעטפת בתוך הביטוי. ה
ביטוי מותאם לכל אחד מהם לְגַיֵס קובץ שהוזכר ב-'Build'
הצהרה, ורק אותם סקריפטים עם שמות תואמים משולבים בפועל ב-
לבנות עץ. מותרים מספר טיעונים כאלה, ובמקרה זה התאמה כנגד כל אחד מהם
מספיק כדי לגרום לסקריפט להיכלל.

בדוגמה למעלה, ה שלום התוכנית לא תיבנה, מכיוון שלא יהיו חסרונות
הכרת התסריט שלום/חייל חובה. ה libworld.a ארכיון ייבנה, עם זאת, אם
צריך להיות.

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

זמני מבטל


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

% חסרונות -o על ייצוא

יבנה את יצוא ספרייה, עם כל הקבצים הנגזרים כפופים לעקיפות הקיימות
ב יותר קוֹבֶץ. אם תשאיר את האפשרות '-o', אז כל מה שצריך להסיר
כל העקיפות ייבנו מחדש.

מגבילים סביבה משתנים

קובץ העקיפה יכול להכיל שני סוגים של עקיפות. הראשון הוא הסביבה הנכנסת
משתנים. אלה נגישים בדרך כלל על ידי לבנות קובץ מה-hash `%ENV'
מִשְׁתַנֶה. ניתן לעקוף אותם באופן טריוויאלי בקובץ העקיפה על ידי הגדרת ה-
רכיבים מתאימים של `%ENV' (אפשר גם לעקוף אותם בסביבת המשתמש,
כמובן).

אל האני לעקוף חוק הפקודה

הסוג השני של עקיפה מתבצע עם הפקודה 'עקוף', שנראית כך
זֶה:

ביטול , => , => , ...;

הביטוי הקבוע regexp מותאם לכל קובץ נגזר שהוא מועמד
עבור הבנייה. אם הקובץ הנגזר תואם, אז צמדי המשתנה/ערך משמשים
לעקוף את הערכים בסביבת הבנייה המשויכים לקובץ הנגזר.

נניח שיש לנו סביבת בנייה כזו:

$CONS = חסרונות חדשים(
COPT => '',
CDBG => '-g',
CFLAGS => '%COPT %CDBG',
);

אז אם יש לנו קובץ עוקף יותר המכיל את הפקודה הזו:

עוקף '\.o$', COPT => '-O', CDBG => '';

ואז כל הפצת 'חסרונות' עם '-o over' שיוצרת .o קבצים דרך סביבה זו
לגרום להם להיות קומפילציה עם `-O 'וללא `-g'. העקיפה יכולה להיות, כמובן
מוגבל לספרייה בודדת על ידי הבחירה המתאימה של ביטוי רגולרי.

הנה הגרסה המקורית של Hello, World! תוכנית, שנבנתה עם סביבה זו.
שים לב שחסרונות בונה מחדש את החלקים המתאימים כאשר העקיפה מוחלת או מוסרת:

% חסרונות שלום
cc -g -c hello.c -o hello.o
cc -o שלום hello.o
% חסרונות -o על שלום
cc -O -c hello.c -o hello.o
cc -o שלום hello.o
% חסרונות -o על שלום
חסרונות: "שלום" מעודכן.
% חסרונות שלום
cc -g -c hello.c -o hello.o
cc -o שלום hello.o

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

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

עוד on בניה סביבות


בְּרִירַת מֶחדָל בניה משתנים

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

$env = new cons();

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

CC => 'cc',
CFLAGS => '',
CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
INCDIRPREFIX => '-אני',
CXX => '%CC',
CXXFLAGS => '%CFLAGS',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
LINK => '%CXX',
LINKCOM => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD -r -o %> %<',
LIBDIRPREFIX => '-L',
AR => 'ar',
ARFLAGS => 'r',
ARCOM => "%AR %ARFLAGS %> %<\n%RANLIB %>",
RANLIB => 'ranlib',
AS => 'כמו',
ASFLAGS => '',
ASCOM => '%AS %ASFLAGS %< -o %>',
LD => 'ld',
LDFLAGS => '',
PREFLIB => 'lib',
SUFLIB => '.a',
SUFLIBS => '.so:.a',
SUFOBJ => '.o',
ENV => { 'PATH' => '/ סל:/ usr / bin'},

במערכות Win32 (Windows NT), משתני הבנייה הבאים מוחקים ב-
ברירת מחדל:

CC => 'cl',
CFLAGS => '/nologo',
CCCOM => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
INCDIRPREFIX => '/I',
LINK => 'קישור',
LINKCOM => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD /r /o %> %<',
LIBDIRPREFIX => '/LIBPATH:',
AR => 'lib',
ARFLAGS => '/nologo ',
ARCOM => "%AR %ARFLAGS /out:%> %<",
RANLIB => '',
LD => 'קישור',
LDFLAGS => '/nologo ',
PREFLIB => '',
SUFEXE => '.exe',
SUFLIB => '.lib',
SUFLIBS => '.dll:.lib',
SUFOBJ => '.obj',

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

אובייקטים $env 'foo.c', 'bar.c';

זה יסדר לייצר, במידת הצורך, foo.o ו bar.o. הפקודה המופעלת היא פשוטה
`%CCCOM', שמתרחב באמצעות החלפה, לפקודה החיצונית המתאימה הנדרשת
לבנות כל חפץ. נחקור את כללי ההחלפה עוד יותר תחת ה'פקודה'
שיטה, להלן.

משתני הבנייה משמשים גם למטרות אחרות. לדוגמה, `CPPPATH' הוא
משמש לציון נתיב מופרד בנקודתיים של ספריות include. אלה נועדו להיות
מועברים ל-C preprocessor ומשמשים גם את מכונות סריקת קבצי C ל
לקבוע את התלות הכרוכה בקומפילציה C. משתנים שמתחילים ב
קו תחתון, נוצרים בשיטות שונות, ובדרך כלל יש לראות בהם "פנימי"
משתנים. למשל, כאשר נקראת שיטה שקוראת ליצירת אובייקט
ממקור C, המשתנה `_IFLAGS' נוצר: זה מתאים למתגי `-I'
נדרש על ידי מהדר C כדי לייצג את הספריות שצוינו על ידי 'CPPPATH'.

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

המשתנים 'CFLAGS', 'LDFLAGS' ו-'ARFLAGS' כולם מספקים מקום להעברת אפשרויות ל
המהדר, המטען והארכיון, בהתאמה. פחות ברור, 'INCDIRPREFIX'
משתנה מציין את מחרוזת האפשרויות שתצורף לתחילת כל include
ספרייה כך שהמהדר ידע היכן למצוא .h קבצים. באופן דומה, ה
משתנה `LIBDIRPREFIX' מציין את מחרוזת האפשרויות שיש להוסיף לתחילתה של
כל ספרייה שהמקשר צריך לחפש ספריות.

משתנה אחר, `ENV', משמש לקביעת סביבת המערכת במהלך הביצוע
של פקודה חיצונית. כברירת מחדל, משתנה הסביבה היחיד שהוגדר הוא `PATH',
שהוא נתיב הביצוע של פקודת UNIX. כדי לשחזר את מירב, אתה צריך
באמת קבעו את נתיב הביצוע שלכם, ברמה העליונה שלכם לבנות קובץ (או
אולי על ידי ייבוא ​​חבילת בנייה מתאימה עם הפקודה Perl `use'). ה
משתני ברירת המחדל נועדו להוציא אותך מהקרקע.

אינטרפולציה בניה משתנים

משתני סביבת בנייה עשויים להיות משולבים בשמות קבצי המקור והיעד
על ידי הקדמת שם משתנה הבנייה ב-%'.

$env = חסרונות חדשים(
DESTDIR => 'תוכניות',
SRCDIR => 'src',
);
תוכנית $env '%DESTDIR/hello', '%SRCDIR/hello.c';

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

בְּרִירַת מֶחדָל בניה שיטות


רשימת שיטות הבנייה המוגדרות כברירת מחדל כוללת את הדברים הבאים:

אל האני 'חדש' בנאי

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

$env = חסרונות חדשים( );

הסביבה שאתה מקבל בחזרה מבורכת בחבילה `חסרונות', מה שאומר שכן
קישרו אליו את שיטות ברירת המחדל המתוארות להלן. בנייה פרטנית
ניתן לעקוף משתנים על ידי מתן צמדי שם/ערך ברשימת עקיפה. ציין זאת
כדי לעקוף כל משתנה סביבת פקודה (כלומר כל דבר תחת `ENV'), תצטרך
לעקוף את כולם. אתה יכול לעקוף את הקושי הזה על ידי שימוש בשיטת 'העתק' ב-an
סביבת בנייה קיימת.

אל האני 'שיבוט' שיטה

שיטת ה'clone' יוצרת שיבוט של סביבת בנייה קיימת, ויכולה להיות
נקרא כמו בדוגמה הבאה:

$env2 = $env1->clone( );

אתה יכול לספק דרישות באופן הרגיל כדי ליצור סביבה שונה מה-
מְקוֹרִי. אם אתה רק רוצה שם חדש לאותה סביבה (מה שעשוי להיות מועיל כאשר
ייצוא סביבות לרכיבים קיימים), אתה יכול פשוט להשתמש בהקצאה פשוטה.

אל האני 'העתק' שיטה

שיטת `העתק' מחלצת את משתני הבנייה המוגדרים חיצונית מ-an
סביבה ומחזיר אותם כרשימה של צמדי שם/ערך. גם עקיפות יכולות להיות
בתנאי, ובמקרה זה, הערכים שנעקפו יוחזרו, לפי הצורך. ה
ניתן להקצות את הרשימה המוחזרת ל-hash, כפי שמוצג באב הטיפוס, למטה, אבל היא יכולה גם
לתמרן בדרכים אחרות:

%env = $env1->copy( );

הערך של `ENV', שהוא בעצמו גיבוב, מועתק גם ל-hash חדש, כך שזה עשוי להיות
השתנה ללא חשש להשפיע על הסביבה המקורית. אז, למשל, אם אתה באמת
רוצה לעקוף רק את המשתנה 'PATH' בסביבת ברירת המחדל, אתה יכול לעשות את
הבא:

%cons = new cons()->copy();
$cons{ENV}{PATH} = " ";
$cons = new cons(%cons);

זה ישאיר כל דבר אחר שעשוי להיות בסביבת ברירת המחדל לביצוע
ללא הפרעה.

אל האני 'התקן' שיטה

שיטת 'התקן' מסדרת את התקנת הקבצים שצוינו בקובץ שצוין
מַדרִיך. ההתקנה מותאמת: הקובץ אינו מועתק אם ניתן לקשר אותו. אם
זו לא ההתנהגות הרצויה, תצטרך להשתמש בשיטה אחרת כדי להתקין את
קוֹבֶץ. זה נקרא כך:

התקן את $env , ;

שימו לב שבעוד שהקבצים שיותקנו עשויים לקבל שם שרירותי, רק האחרונים
רכיב של כל שם משמש עבור שם היעד המותקן. אז, למשל, אם אתה
לארגן התקנה פו בר in באז, זה ייצור א בָּר הקובץ באז ספרייה (לא
פו בר).

אל האני 'InstallAs' שיטה

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

`InstallAs' פועל בשתי דרכים:

התקנת קובץ בודד:

InstallAs $env TgtFile, SrcFile;

התקנת קבצים מרובים:

InstallAs $env ['tgt1', 'tgt2'], ['src1', 'src2'];

או, אפילו בתור:

@srcs = qw(src1 src2 src3);
@tgts = qw(tgt1 tgt2 tgt3);
InstallAs $env [@tgts], [@srcs];

גם רשימות היעד וגם רשימות המקורות צריכות להיות באותו אורך.

אל האני 'יקר' שיטה

שיטת 'יקר' מבקשת חסרונות לא למחוק את הקובץ או את רשימת הקבצים שצוינו לפני כן
לבנות אותם שוב. זה מופעל כ:

יקר ערך ;

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

אל האני 'פקודה' שיטה

שיטת `פקודה' היא שיטת catchall אשר ניתן להשתמש בה כדי לארגן עבור כל חיצוני
פקודה שתיקרא כדי לעדכן את היעד. עבור פקודה זו, קובץ יעד ורשימה של
מסופקות תשומות. בנוסף שורת פקודה בנייה, או שורות, מסופקת בתור
מחרוזת (מחרוזת זו עשויה לכלול מספר פקודות מוטבעות בתוכה, מופרדות על ידי חדש
שורות). 'פקודה' נקראת כך:

הפקודה $env , , ;

המטרה תלויה ברשימת קבצי הקלט שצוינה, והקלטים חייבים
ייבנה בהצלחה או שחסרונות לא ינסו לבנות את היעד.

בתוך פקודת הבנייה, כל משתנה מסביבת הבנייה עשוי להיות
הוכנס על ידי הקדמת שם משתנה הבנייה ב-%'. זה רקורסיבי:
הפקודה מורחבת עד שלא ניתן לבצע החלפות נוספות. אם בנייה
המשתנה אינו מוגדר בסביבה, אז מחרוזת null תוחלף. א
כפול `%%' יוחלף ב`%' בודד בפקודת הבנייה.

ישנם מספר משתני פסאודו שיורחבו גם הם:

%> שם קובץ היעד (בפקודה מרובת יעדים, זה תמיד היעד הראשון
מוּזְכָּר).

%0 זהה ל-%>'.

%1,%2, ...,%9
אלה מתייחסים לקובץ הקלט הראשון עד התשיעי, בהתאמה.

%< ערכת הקלט המלאה. אם נעשה שימוש באחד מאלה בכל מקום אחר ב
שורת הפקודה הנוכחית (דרך `%1', `%2' וכו'), אז אלה יימחקו מה-
רשימה מסופקת על ידי `%<'. שקול את הפקודה הבאה שנמצאת ב-a לְגַיֵס פילה
ב מבחן Directory:

הפקודה $env 'tgt', qw(foo bar baz), qq(
echo %< -i %1 > %>
echo %< -i %2 >> %>
echo %< -i %3 >> %>
);

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

echo test/bar test/baz -i test/foo > test/tgt
echo test/foo test/baz -i test/bar >> test/tgt
echo test/foo test/bar -i test/baz >> test/tgt

כל אחד ממשתני הפסאודו לעיל עשוי להיות אחריו מיד באחד מהמשתנים הבאים
סיומות לבחירת חלק משם הנתיב המורחב:

:a הנתיב המוחלט לשם הקובץ
:b הספרייה בתוספת שם הקובץ מופשט מכל סיומת
:d הספרייה
:f שם הקובץ
:s סיומת שם הקובץ
:F שם הקובץ הוסר מכל סיומת

בהמשך לדוגמא שלמעלה, `%<:f' יתרחב ל-`foo bar baz', ו-`%':d>
הרחב ל'בדיקה'.

אפשר לכתוב מחדש חלק מהפקודה באופן תוכניתי על ידי סגירת חלק ממנה
בין `%[' ל-`%]'. זה יקרא למשתנה הבנייה בשם המילה הראשונה
מוקף בסוגריים כהפניה לקוד Perl; התוצאות של שיחה זו ישמשו
כדי להחליף את תוכן הסוגריים בשורת הפקודה. לדוגמה, בהינתן an
קובץ קלט קיים בשם tgt.in:

@keywords = qw(foo bar baz);
$env = new cons(X_COMMA => sub { join(",", @_) });
הפקודה $env 'tgt', 'tgt.in', qq(
echo '# מילות מפתח: %[X_COMMA @keywords %]' > %>
חתול %> %>
);

זה יבצע:

echo '# מילות מפתח: foo,bar,baz' > tgt
cat tgt.in >> tgt

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

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

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

ההנחה היא שהמילה הראשונה של כל מחרוזת פקודה, לאחר הרחבה, היא קובץ הפעלה
הפקודה חיפשה את משתנה הסביבה 'PATH' (שמצוין בתורו על ידי ה-
משתנה בנייה של `ENV'). אם פקודה זו נמצאת על הנתיב, אז המטרה תהיה
תלוי בו: לפיכך הפקודה תיבנה אוטומטית, לפי הצורך. שֶׁלָה
אפשר לכתוב פקודות מרובות חלקים לכמה קונכיות, מופרדות על ידי נקודה-פסיק. רק ה
עם זאת, מילת הפקודה הראשונה תהיה תלויה, אז אם תכתוב את מחרוזות הפקודה שלך
בדרך זו, עליך להגדיר תלות במפורש (בשיטת 'תלוי'), או
ודא שהפקודה שבה אתה משתמש היא פקודת מערכת שצפויה להיות
זמין. אם הוא לא זמין, כמובן שתקבל שגיאה.

אם פקודה כלשהי (אפילו אחת בתוך פקודה מרובת שורות) מתחילה ב- `[perl]', השאר
של שורת הפקודה הזו יוערך על ידי Perl הפועל במקום להיות מזולג על ידי ה-
צדף. אם מתרחשת שגיאה בניתוח ה-Perl או אם הביטוי Perl מחזיר 0 או
undef, הפקודה תיחשב ככשלה. לדוגמה, הנה פשוט
פקודה שיוצרת קובץ 'foo' ישירות מפרל:

$env = new cons();
הפקודה $env 'foo',
qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);

שים לב שכאשר הפקודה מבוצעת, אתה נמצא באותה חבילה כמו כאשר לבנות
or לְגַיֵס הקובץ נקרא, אז אתה יכול לקרוא לפונקציות Perl שהגדרת באותו
לבנות or לְגַיֵס קובץ שבו מופיעה ה'פקודה':

$env = new cons();
sub create_file {
שלי $file = shift;
open(FILE, ">$file");
הדפס קובץ "היי\n";
close(FILE);
1 לחזור;
}
הפקודה $env 'foo', "[perl] &create_file('%>')";

מחרוזת Perl תשמש ליצירת החתימה עבור הקובץ הנגזר, אז אם אתה
שנה את המחרוזת, הקובץ ייבנה מחדש. התוכן של כל תת-שגרה שאתה מתקשר אליה,
עם זאת, אינם חלק מהחתימה, כך שאם תשנה תת-שגרה שנקראה כגון
`create_file' למעלה, המטרה תהיה לֹא להיבנות מחדש. משתמש אזהרה.

חסרונות בדרך כלל מדפיס פקודה לפני ביצועה. התנהגות זו מדוכאת אם
התו הראשון של הפקודה הוא `@'. שים לב שייתכן שתצטרך להפריד בין ה-'@'
שם הפקודה או בריחה ממנו כדי למנוע מ-`@cmd' להיראות כמו מערך לציטוט פרל
אופרטורים שמבצעים אינטרפולציה:

# שורת הפקודה הראשונה שגויה,
# כי "@cp" נראה כמו מערך
# לפונקציה Perl qq//.
# השתמש בטופס השני במקום זאת.
הפקודה $env 'foo', 'foo.in', qq(
@cp %< קובץ זמני
@ cp tempfile %>
);

אם יש תווי מטא של מעטפת בכל מקום בשורת הפקודה המורחבת, כגון `<',
`>', מרכאות או נקודה-פסיק, אז הפקודה תבוצע בפועל על ידי הפעלת
צדף. המשמעות היא שפקודה כגון:

CD foo

לבד בדרך כלל ייכשל, מכיוון שאין פקודה 'cd' בנתיב. אבל הפקודה
חוּט:

cd $:f $<:f

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

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

הפקודה $env ['foo.h', 'foo.c'], 'foo.template', q(
gen% 1
);

יכול לשמש במקרה שבו הפקודה 'gen' יוצרת שני קבצים, שניהם foo.h ו foo.c.

אל האני 'חפצים' שיטה

שיטת 'אובייקטים' מסדרת ליצור את קבצי האובייקטים המתאימים לצוין
קבצי המקור. זה מופעל כפי שמוצג להלן:

@files = אובייקטים $env ;

תחת Unix, קבצי מקור המסתיימים ב .s ו .c נתמכים כעת, ויורכבו
לשם של אותו קובץ המסתיים ב .o. כברירת מחדל, כל הקבצים נוצרים על ידי הפעלה
הפקודה החיצונית הנובעת מהרחבת משתנה הבנייה `CCCOM', עם
`%' מוגדרים לקבצי המקור והאובייקט, בהתאמה (ראה את שיטת ה'פקודה'
לפרטי הרחבה). המשתנה `CPPPATH' משמש גם בעת סריקת קבצי מקור
עבור תלות. זוהי רשימה מופרדת בנקודתיים של שמות נתיבים, והיא משמשת גם ליצירה
משתנה הבנייה `_IFLAGS', שיכיל את הרשימה המתאימה של -`I'
אפשרויות הקומפילציה. כל שמות הנתיבים היחסיים ב-'CPPPATH' מתפרשים כיחסיים
לספרייה שבה נוצרה סביבת הבנייה המשויכת (אבסולוט
ניתן להשתמש גם בשמות קרובי משפחה). משתנה זה משמש את `CCCOM'. ההתנהגות
של פקודה זו ניתן לשנות על ידי שינוי של כל אחד מהמשתנים המשולבים
לתוך `CCCOM', כגון `CC', `CFLAGS', ובעקיפין, `CPPPATH'. אפשר גם
להחליף את הערך של `CCCOM', עצמו. מטעמי נוחות, קובץ זה מחזיר את הרשימה של
שמות קבצים של אובייקטים.

אל האני 'תוכנית' שיטה

שיטת 'תוכנית' מסדרת לקשר את התוכנית שצוינה עם האובייקט שצוין
קבצים. הוא מופעל באופן הבא:

תוכנית $env , ;

לשם התוכנית יצורף הערך של משתנה הבנייה `SUFEXE' (על ידי
ברירת מחדל, '.exe' במערכות Win32, שום דבר במערכות Unix) אם הסיומת עדיין לא
מתנה.

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

הקישור בפועל של התוכנית יטופל על ידי פקודה חיצונית שתוצאתה
מהרחבת משתנה הבנייה `LINKCOM', כאשר `%<' מוגדר לקבצי האובייקט ל
להיות מקושר (בסדר המוצג), ו-%>' מוגדר למטרה (ראה שיטת 'פקודה'
לפרטי הרחבה). המשתמש רשאי להגדיר משתנים נוספים בבנייה
סביבה, כולל `LINK', כדי להגדיר באיזו תוכנית להשתמש לקישור, `LIBPATH', א
רשימה מופרדת בנקודתיים של נתיבי חיפוש בספרייה, לשימוש עם מפרטי הספרייה של
טופס -ליב, ו-'LIBS', המציינים את רשימת הספריות שיש לקשר איתן (בשתיהן -ליב
טופס או רק בתור שמות נתיבים. שמות נתיבים יחסיים ב-'LIBPATH' וגם ב-'LIBS' מתפרשים
ביחס לספרייה שבה נוצרת סביבת הבנייה המשויכת
(ניתן להשתמש גם בשמות אבסולוטיים ובשמות יחסיים עליונים). חסרונות מוגדרים אוטומטית
תלות בספריות כלשהן המוזכרות ב-'LIBS': ספריות אלו ייבנו לפני כן
הפקודה מקושרת.

אל האני 'ספרייה' שיטה

שיטת `Library' מסדרת ליצור את הספרייה שצוינה מהאובייקט שצוין
קבצים. זה מופעל באופן הבא:

ספרייה $env , ;

לשם הספרייה יצורף הערך של משתנה הבנייה `SUFLIB' (על ידי
ברירת מחדל, `.lib' במערכות Win32, `.a' במערכות Unix) אם הסיומת עדיין לא
מתנה.

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

היצירה בפועל של הספרייה תטופל על ידי פקודה חיצונית שתוצאתה
מהרחבת משתנה הבנייה `ARCOM', כאשר `%<' מוגדר לחברי הספרייה (ב
הסדר המוצג), ו-%>' לספרייה שתיווצר (ראה את שיטת ה'פקודה' עבור
פרטי הרחבה). המשתמש יכול להגדיר משתנים בסביבת הבנייה אשר יעשו זאת
להשפיע על פעולת הפקודה. אלה כוללים את 'AR', תוכנית הארכיון לשימוש,
`ARFLAGS', שניתן להשתמש בו כדי לשנות את הדגלים שניתנו לתוכנית שצוינה על ידי `AR',
ו-'RANLIB', שמה של תוכנית ליצירת אינדקס ארכיון, במידת הצורך (אם הפרט
need אינו דורש את הפונקציונליות האחרונה, אז יש להגדיר מחדש את 'ARCOM' כך שלא
הפניה `RANLIB').

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

אל האני 'מודול' שיטה

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

מודול $env , , ;

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

אל האני 'תלוי' שיטה

השיטה 'תלוי' מאפשרת לך לציין תלות נוספת עבור יעד. זה
מופעל כדלקמן:

תלוי ב-$env , ;

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

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

תלוי ב-$env ['foo', 'bar'], 'input_file_1', 'input_file_2';

מציין כי גם ה Foo ו בָּר הקבצים תלויים בקבצי הקלט הרשומים.

אל האני 'התעלם' שיטה

שיטת 'התעלם' מאפשרת להתעלם מתלות מפורשות ש-Cons מסיק לגביה
שֶׁלוֹ. זה מופעל באופן הבא:

התעלם מ;

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

אם, למשל, תוכנית בנויה בספרייה המותקנת ב-NFS על מספר מערכות
יש עותקים שונים של stdio.h, ההבדלים ישפיעו על החתימות של כולם
מטרות נגזרות שנבנו מקובצי מקור ש-'#include '. זה יגרום לכל
מטרות אלה שייבנו מחדש בעת שינוי מערכות. אם זו לא התנהגות רצויה,
אז השורה הבאה תסיר את התלות ב- stdio.h קובץ:

התעלם '^/usr/include/stdio\.h$';

שימו לב שהארגומנטים לשיטת 'התעלם' הם ביטויים רגולריים, כל כך מיוחדים
תווים חייבים להיות escaped וייתכן שתרצה לעגן את ההתחלה או הסוף של
ביטוי עם תווים `^' או `$'.

אל האני 'מלח' שיטה

שיטת `מלח' מוסיפה ערך קבוע לחישוב החתימה עבור כל נגזרת
קוֹבֶץ. זה מופעל באופן הבא:

מלח $מחרוזת;

שינוי ערך ה-Salt יאלץ בנייה מחדש מלאה של כל קובץ נגזר. זה יכול להיות
משמש לאלץ בנייה מחדש בנסיבות רצויות מסוימות. לדוגמה,

מלח `uname -s`;

יאלץ בנייה מחדש מלאה של כל קובץ נגזר בכל פעם שמערכת ההפעלה מופעלת
אשר הבנייה מבוצעת (כפי שדווח על ידי `uname -s') שינויים.

אל האני 'UseCache' שיטה

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

UseCache("cache/") ⎪⎪ warn("ספריית המטמון לא נמצאה");

אל האני 'נתיב מקור' שיטה

מתודה `SourcePath' מחזירה את שם נתיב המקור האמיתי של קובץ, בניגוד ל-
שם נתיב בתוך ספריית build. זה מופעל באופן הבא:

$path = SourcePath ;

אל האני 'ConsPath' שיטה

שיטת 'ConsPath' מחזירה true אם הנתיב שסופק הוא קובץ הנגזר, ומחזירה
undef (false) אחרת. זה מופעל באופן הבא:

$result = ConsPath ;

אל האני 'SplitPath' שיטה

שיטת 'SplitPath' מחפשת מספר שמות נתיבים במחרוזת המופרדת על ידי ברירת המחדל
מפריד נתיבים עבור מערכת ההפעלה (':' במערכות UNIX, ';' ב-Windows NT), וכן
מחזירה את השמות המלאים. זה מופעל באופן הבא:

@paths = SplitPath ;

שיטת 'SplitPath' תמיר שמות עם קידומת '#' למבנה המתאים ברמה העליונה
שם (ללא '#') וימיר שמות יחסיים לשמות ברמה העליונה.

אל האני `DirPath' שיטה

שיטת `DirPath' מחזירה את נתיב הבנייה שם(ים) של ספרייה או רשימה של ספריות.
זה מופעל באופן הבא:

$cwd = DirPath ;

השימוש הנפוץ ביותר בשיטת 'DirPath' הוא:

$cwd = DirPath '.';

כדי להביא את הנתיב לספרייה הנוכחית של חברת בת לְגַיֵס קובץ.

אל האני `FilePath' שיטה

שיטת `FilePath' מחזירה את נתיב הבנייה שם(ים) של קובץ או רשימה של קבצים. זה
מופעל כדלקמן:

$file = FilePath ;

אל האני 'עזרה' שיטה

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

עזרה ;

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

מאריך חסרונות


מגבילים בניה משתנים

ישנן מספר דרכים להרחיב את החסרונות, המשתנים בדרגת הקושי. הכי פשוט
השיטה היא להגדיר את סביבת הבנייה שלך, בהתבסס על סביבת ברירת המחדל,
אך שונה כדי לשקף את הצרכים המיוחדים שלך. לרוב זה יספיק עבור מבוססי C
יישומים. אתה יכול להשתמש בבנאי ה'חדש', ובשיטות ה'שכפול' ו'העתק' כדי
ליצור סביבות היברידיות. שינויים אלה יכולים להיות שקופים לחלוטין כלפי הבסיס
לְגַיֵס קבצים.

מוסיף חדש שיטות

לשינויים קצת יותר תובעניים, ייתכן שתרצה להוסיף שיטות חדשות ל'חסרונות'
חֲבִילָה. הנה דוגמה להרחבה פשוטה מאוד, `InstallScript', שמתקין את a
סקריפט tcl במיקום מבוקש, אך עורך את הסקריפט תחילה כדי לשקף פלטפורמה-
נתיב תלוי שצריך להתקין בסקריפט:

# cons::InstallScript - צור גרסה תלוית פלטפורמה של מעטפת
# סקריפט על ידי החלפת המחרוזת ``#!הנתיב שלך-כאן'' בפלטפורמה ספציפית
# נתיב $BIN_DIR.

חסרונות משנה::InstallScript {
my ($env, $dst, $src) = @_;
הפקודה $env $dst, $src, qq(
sed s+your-path-here+$BIN_DIR+ % %>
chmod oug+x %>
);
}

שימו לב ששיטה זו מוגדרת ישירות בחבילת `חסרונות' (על ידי קידומת השם
עם `חסרונות::'). שינוי שנעשה בצורה זו יהיה גלוי גלובלי לכל הסביבות,
ויכול להיקרא כמו בדוגמה הבאה:

InstallScript $env "$BIN/foo", "foo.tcl";

לשיפור קטן בכלליות, ניתן להעביר את המשתנה 'BINDIR' בתור an
ארגומנט או נלקח מסביבת הבנייה - בתור `%BINDIR'.

מגבילים שיטות

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

הדוגמה הבאה מגדירה חבילה חדשה `cons::switch' אשר עוקפת את התקן
שיטת 'ספרייה'. השיטה הנעקפת בונה מודולי ספרייה מקושרים, במקום ספרייה
אַרְכִיוֹן. בנאי חדש מסופק. סביבות שנוצרו עם הקונסטרוקטור הזה יהיו
יש את שיטת הספרייה החדשה; אחרים לא.

חסרונות החבילה::switch;
התחל {@ISA = 'חסרונות'}

משנה חדש {
מִשׁמֶרֶת;
ברך חסרונות חדשים(@_);
}

ספריית משנה {
my($env) = shift;
my($lib) = shift;
my(@objs) = אובייקטים $env @_;
הפקודה $env $lib, @objs, q(
%LD -r %LDFLAGS %
);
}

ניתן להפעיל פונקציונליות זו כמו בדוגמה הבאה:

$env = new cons::switch(@overrides);
...
ספריית $env 'lib.o', 'foo.c', 'bar.c';

מזמין חסרונות


הפקודה `חסרונות' מופעלת בדרך כלל מהשורש של עץ הבנייה. א לבנות פילה
חייב להתקיים בספרייה הזו. אם נעשה שימוש בארגומנט `-f', אז ארגומנט חלופי לבנות
ניתן להשתמש בקובץ (ואולי, בשורש חלופי, מכיוון ש-'cons' יעשה cd to לבנות
הקובץ מכיל ספרייה).

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

% cd libfoo/subdir
% חסרונות -ט יעד

שווה בדיוק ל:

% חסרונות libfoo/subdir/target

אם יש יעדי 'ברירת מחדל' שצוינו בהיררכיית הספריות לבנות or
לְגַיֵס קבצים, רק יעדי ברירת המחדל נמצאים או מתחת לספרייה שממנה `cons -t'
הופעל ייבנה.

הפקודה מופעלת באופן הבא:

חסרונות --

איפה טיעונים יכול להיות כל אחד מהבאים, בכל סדר:

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

+דפוס להגביל את לְגַיֵס קבצים נחשבים רק לאלו התואמים דפוס, שהוא
ביטוי רגולרי של Perl. ארגומנטים מרובים של '+' מתקבלים.

שם=
סטים שם להעריך val ב-'ARG' ה-hash עבר לרמה העליונה לבנות קובץ.

`-cc' הצג פקודה שהייתה מבוצעת בעת אחזור מהמטמון. לא
ניתן ציון שהקובץ אוחזר; זה שימושי עבור
יצירת יומני בנייה שניתן להשוות עם יומני בנייה אמיתיים.

`-cd' השבת את כל האחסון במטמון. אין לאחזר מהמטמון ולא לשטוף למטמון.

`-c' בנה תלות בסדר אקראי. זה שימושי בעת בניית מרובה
עצים דומים עם אחסון במטמון מופעל.

`-cs' סנכרן יעדי בנייה קיימים שנמצאו מעודכנים עם המטמון.
זה שימושי אם האחסון במטמון הושבת עם -cc או מופעל לאחרונה
עם UseCache.

`-d' אפשר איתור באגים בתלות.

`-f'
השתמש בקובץ שצוין במקום לבנות (אבל תחילה שנה להכיל
מדריך של פילה).

`-h' הצג הודעת עזרה מקומית למבנה הנוכחי אם הוגדר אחד כזה, וצא.

`-k' המשיכו ללכת רחוק ככל האפשר לאחר שגיאות.

`-o'
קרא קובץ ביטול פילה.

`-p' הצג מוצרי בנייה בעצים שצוינו. אין ניסיון לבנות.

`-pa' הצג מוצרי בנייה ופעולות נלוות. אין ניסיון לבנות.

`-pw' הצג מוצרים והיכן הם מוגדרים. אין ניסיון לבנות.

`-q' אל תדבר במילים לגבי התקנה והסרה של מטרות.

`-r' הסר מוצרי בנייה המשויכים ל-. אין ניסיון לבנות.

`-R'
חפש קבצים ב שאר. מרובות -R שאר מחפשים ספריות ב-
הסדר שצוין.

`-t' חצו במעלה היררכיית הספריות בחיפוש אחר א לבנות קובץ, אם לא קיים
בספרייה הנוכחית. היעדים ישונו כך שיהיו ביחס ל-
לבנות קובץ.

`-v' הצג את גרסת 'חסרונות' והמשך בעיבוד.

`-V' הצג גרסת 'חסרונות' וצא.

`-wf'
כתוב את כל שמות הקבצים הנחשבים לתוך פילה.

`-x' הצג הודעת עזרה דומה לזו וצא.

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

עיבוד של construct-args יכול להיעשות על ידי כל חבילה סטנדרטית כמו Getopt או שלה
גרסאות, או כל חבילה המוגדרת על ידי המשתמש. חסרונות יעבור ב construct-args as @ARGV ו
לא ינסה לפרש שום דבר אחרי ה --.

% cons -R /usr/local/repository -d os=solaris +driver -- -c test -f DEBUG

יעביר את הדברים הבאים לחסרונות

-R /usr/local/repository -d os=solaris +driver

והבאים, לרמה העליונה לבנות קובץ כ @ARGV

-c test -f DEBUG

שים לב ש-'cons -r .' שווה ערך רקורסיבי מלא 'לעשות נקי', אבל דורש לא
תמיכה ב לבנות קובץ או כל דבר אחר לְגַיֵס קבצים. זה הכי שימושי אם כן
קומפילציה של קבצים לתוך ספריות מקור (אם תפריד את לִבנוֹת ו יצוא ספריות,
אז אתה יכול פשוט להסיר את הספריות).

האפשרויות `-p', `-pa' ו-`-pw' שימושיות ביותר לשימוש כעזר בקריאה
סקריפטים או ניפוי באגים. אם אתה רוצה לדעת איזה סקריפט מותקן export/include/foo.h,
לדוגמה, פשוט הקלד:

% חסרונות -pw export/include/foo.h

שימוש ו כתיבה התלות סורקים


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

QuickScan מופעל באופן הבא:

QuickScan CONSENV CODEREF, FILENAME [, PATH]

תת-השגרה שאליה מתייחס CODEREF צפויה להחזיר רשימה של שמות קבצים הכלולים
ישירות על ידי FILE. שמות קבצים אלה, בתורם, ייסרקו. הארגומנט האופציונלי PATH
מספק נתיב חיפוש למציאת FILENAME ו/או קבצים שהוחזרו על ידי המשתמש שסופק
תת שגרה. ה-PATH עשוי להיות הפניה למערך של שמות ספריות חיפוש, או א
מחרוזת שמות מופרדת באמצעות תו המפריד של המערכת (':' במערכות UNIX, ';' ב-
Windows NT).

תת-השגרה נקראת פעם אחת עבור כל שורה בקובץ, כאשר $_ מוגדר לשורה הנוכחית.
אם תת-השגרה צריכה להסתכל על שורות נוספות, או, לצורך העניין, את הקובץ כולו,
אז הוא עשוי לקרוא אותם בעצמו, מ- filehandle SCAN. זה עשוי גם לסיים את הלולאה, אם
הוא יודע שאין מידע נוסף זמין על-ידי סגירת ה-filehandle.

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

הנה דוגמה אמיתית, שנלקחה מא לבנות קובץ כאן:

חסרונות משנה::SMFgen {
my($env, @tables) = @_;
foreach $t (@tables) {
$env->QuickScan(sub { /\b\S*?\.smf\b/g }, "$t.smf",
$env->{SMF_INCLUDE_PATH});
$env->פקודה(
["$t.smdb.cc","$t.smdb.h","$t.snmp.cc","$t.ami.cc", "$t.http.cc"],
"$t.smf",
q(
smfgen %( %SMF_INCLUDE_OPT %) %
)
);
}
}

[שים לב שהטופס `$env->QuickScan ...' ו-`$env->Command ...' לא אמורים להיות
הכרחי, אבל, מסיבה כלשהי, נדרש עבור קריאה מסוימת זו. זה מופיע
להיות באג בפרל או אי הבנה מצידי; סגנון הקריאה הזה לא
תמיד נראה הכרחי.]

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

סורק מופעל רק עבור קובץ מקור נתון אם הוא נחוץ על ידי יעד כלשהו ב-
עֵץ. הוא מופעל רק פעם אחת עבור קובץ מקור נתון.

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

sub myscan {
my(@includes);
עשה {
push(@includes, /\b\S*?\.smf\b/g);
} בזמן ;
@כולל
}

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

QuickScan $env \myscan, "$_.smf";

תמיכה ו הצעות


החסרונות נשמרים על ידי קהילת המשתמשים. כדי להירשם, שלח דואר אל חסרונות-לדון-
[מוגן בדוא"ל] עם הגוף הירשמו.

אנא דווח על כל הצעה דרך [מוגן בדוא"ל] רשימת תפוצה.

השתמש בחסרונות באינטרנט באמצעות שירותי onworks.net


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

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

  • 1
    turkdevops
    turkdevops
    TurkDevOps a ?k kaynak yaz?l?m
    geli?tirici topluluklar? DevTurks-Team
    Taraf?ndan desteklenmektedir..
    תכונות: https://github.com/turkdevopshttps://turkdevops.g...
    הורד את turkdevops
  • 2
    asammdf
    asammdf
    *asammdf* הוא מנתח פייתון מהיר ו
    עורך עבור ASAM (איגוד ל
    סטנדרטיזציה של אוטומציה ו
    מערכות מדידה) MDF / MF4
    (פורמט נתוני מדידה...
    הורד asammdf
  • 3
    LAME (Lame Aint an MP3 Encoder)
    LAME (Lame Aint an MP3 Encoder)
    LAME הוא כלי חינוכי לשימוש
    ללימוד על קידוד MP3. ה
    המטרה של פרויקט LAME היא לשפר
    האקוסטיקה הפסיכוטית, האיכות והמהירות
    של MP...
    הורד את LAME (Lame Aint an MP3 Encoder)
  • 4
    wxPython
    wxPython
    קבוצה של מודולי הרחבה של Python ש
    לעטוף את שיעורי GUI חוצי הפלטפורמות
    wxWidgets.. קהל: מפתחים. מִשׁתַמֵשׁ
    ממשק: X Windows System (X11), Win32 ...
    הורד את wxPython
  • 5
    packfilemanager
    packfilemanager
    זהו מנהל הקבצים של חבילת Total War
    פרויקט, החל מגרסה 1.7. א
    היכרות קצרה עם Warscape
    מודינג:...
    הורד את packfilemanager
  • 6
    IPerf2
    IPerf2
    כלי תעבורת רשת למדידה
    ביצועי TCP ו-UDP עם מדדים
    סביב תפוקה והשהייה כאחד. ה
    היעדים כוללים שמירה על פעילות פעילה
    קוד iperf...
    הורד את IPerf2
  • עוד »

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

Ad