פונקציות

תוכן עניינים

חבילה

package(default_deprecation, default_testonly, default_visibility, features)

פונקציה זו מצהירה על מטא-נתונים החלים על כל כלל עוקב בחבילה. נעשה בו שימוש לכל היותר פעם אחת בחבילה (קובץ BUILD).

יש להפעיל את הפונקציה package() מיד אחרי כל הצהרות ה-load() בחלק העליון של הקובץ, לפני כל כלל.

ארגומנטים

מאפיין תיאור
default_visibility

List of labels; optional

הרשאות הגישה המוגדרות כברירת מחדל בכללים בחבילה הזו.

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

default_deprecation

String; optional

הגדרת הודעת ברירת המחדל deprecation לכל הכללים בחבילה הזו.

default_testonly

Boolean; optional; default is False except as noted

מגדיר את מאפיין ברירת המחדל testonly לכל הכללים בחבילה הזו.

בחבילות מתחת ל-javatests, ערך ברירת המחדל הוא 1.

features

List strings; optional

המדיניות מגדירה סימונים שונים שמשפיעים על הסמנטיקה של קובץ ה-BUILD הזה.

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

דוגמאות

ההצהרה הבאה מצהירה שהכללים בחבילה זו גלויים רק לחברים בקבוצה בחבילה //foo:target. הצהרות חשיפה בודדות על כלל מסוים, אם קיימות.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

פונקציה זו מגדירה קבוצת חבילות ונותנת תווית לקבוצה. ניתן להפנות לתווית באמצעות המאפיין visibility.

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

ארגומנטים

מאפיין תיאור
name

Name; required

שם ייחודי ליעד הזה.

packages

List of Package; optional

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

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

ניתן גם לציין תווים כלליים לחיפוש: המפרט //foo/... מציין כל חבילה במסגרת //foo, כולל //foo עצמו.

ניתן לציין לפני החבילה את מפרטי החבילות עם - כדי לציין שלילה: המפרט -//foo/bar/... מחריג את כל החבילות במסגרת //foo/bar שאחרת היו מותאמות לדפוסי החבילה בpackage_group הנוכחיים. בשילוב עם includes, קבוצת החבילות של כל קבוצת חבילות מחושבת ולאחר מכן התוצאות משולבות: תבניות שליליות בקבוצת חבילות אחת לא משפיעות על התוצאה של קבוצות בחבילה.

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

includes

List of labels; optional

קבוצות חבילות אחרות הכלולות בקבוצה הזו.

התוויות במאפיין הזה חייבות להתייחס לקבוצות אחרות של חבילות. חבילות בקבוצות חבילות שמשויכות אליהן מועברות כחלק מקבוצת החבילות הזו. כלומר, אם הקבוצה a כוללת את חבילת החבילה b, כאשר b מכיל את קבוצת החבילה c, כל חבילה ב-c תהיה גם חברה ב-a.

דוגמאות

הצהרת ה-package_group הבאה מציינת קבוצת חבילות בשם "טרופי&&; הכוללת פירות טרופיים.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

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

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

מייצא קבצים

exports_files([label, ...], visibility, licenses)

המדיניות exports_files() מציינת רשימה של קבצים ששייכים לחבילה הזו שמיוצאים לחבילות אחרות.

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

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

ארגומנטים

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

דוגמה

בדוגמה הבאה מתבצע ייצוא של golden.txt, קובץ טקסט מהחבילה test_data, כדי שחבילות אחרות יוכלו להשתמש בו, למשל, במאפיין data של בדיקות.

# from //test_data/BUILD

exports_files(["golden.txt"])

גלוב

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

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

תווית מקור מצורפת בתוצאה אם הקובץ של הנתיב יחסי ביחס לחבילה תואם לדפוסים כלשהם של include ובאף אחד מהדפוסים exclude.

הרשימות include ו-exclude מכילות דפוסי נתיב יחסיים לחבילה הנוכחית. כל דפוס עשוי להכיל פלח אחד או יותר של נתיב. כרגיל, בנתיבי Unix, הפלחים האלה מופרדים באמצעות /. פלחים יכולים לכלול את התו הכללי לחיפוש *: התאמה לכל מחרוזת משנה בפלח הנתיב (אפילו מחרוזת המשנה הריקה), למעט מפריד הספרייה /. ניתן להשתמש בתווים כלליים לחיפוש כמה פעמים בפלח נתיב אחד. כמו כן, התו הכללי לחיפוש ** יכול להתאים לקטעי נתיב שלמים או יותר, אבל צריך להצהיר על כך כפלח עצמאי של נתיב.

דוגמאות:
  • foo/bar.txt תואם בדיוק לקובץ foo/bar.txt בחבילה הזו
  • foo/*.txt תואם לכל קובץ בספריית foo/ אם הקובץ מסתיים ב-.txt (אלא אם foo/ הוא חבילת משנה)
  • foo/a*.htm* תואם לכל קובץ בספרייה foo/ שמתחיל ב-a, ולאחר מכן מכיל מחרוזת שרירותית (יכול להיות ריק), ואז מכיל .htm ומסתיים במחרוזת שרירותית אחרת; כמו foo/axx.htm ו-foo/a.html או foo/axxx.html
  • **/a.txt תואם לכל קובץ a.txt בכל תת-ספרייה של החבילה הזו
  • **/bar/**/*.txt תואם לכל קובץ .txt בכל תת-ספרייה של חבילה זו, אם לפחות ספרייה אחת בנתיב שמתקבלת נקראת bar, כגון xxx/bar/yyy/zzz/a.txt או bar/a.txt (חשוב לזכור שהפרמטר ** תואם גם לאפס פלחים) או bar/zzz/a.txt
  • ** תואם לכל קובץ בכל ספריית משנה של החבילה
  • הדפוס foo**/a.txt אינו חוקי, כי ** חייב לעמוד בפני עצמו כפלח

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

אם הארגומנט allow_empty מוגדר לערך False, הפונקציה glob תטעה אם התוצאה תהיה רשימה ריקה.

יש כמה מגבלות ואזהרות חשובות:

  1. מכיוון ש-glob() פועל במהלך הערכת קובץ BUILD, glob() תואם לקבצים רק בעץ המקור שלך, ואף פעם לא נוצרו קבצים. אם אתם בונים יעד שמחייב גם קובצי מקור וגם קבצים שנוצרו, עליך לצרף ל-glob רשימה מפורשת של קבצים שנוצרו. כדאי לעיין בדוגמה שבהמשך עם :mylib ועם :gen_java_srcs.

  2. אם לכלל יש שם זהה לזה של קובץ מקור מותאם, הכלל יפיק את הקובץ "צל&גר;

    כדי להבין זאת, חשוב לזכור שהפונקציה glob() מחזירה רשימה של נתיבים, כך שהשימוש במאפיין glob() בכללים אחרים' (למשל srcs = glob(["*.cc"])) זהה להשפעה של ציון הנתיבים התואמים באופן מפורש. אם, לדוגמה, glob() יש תפוקה ["Foo.java", "bar/Baz.java"] אבל יש גם כלל בחבילה ששמו "Foo.Java" (מותר, אבל באזל מתריע על כך), אז הצרכן של glob() ישתמש בפרמטר ""foo.javascript"quot" המוצגות פרטים נוספים זמינים בקטע בעיה ב-GitHub 10395.

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

    לדוגמה, הביטוי כדור הארץ **/*.cc בחבילה x לא כולל את x/y/z.cc אם x/y קיים כחבילה (למשל x/y/BUILD או במקום אחר בנתיב החבילה). כלומר, התוצאה של ביטוי ה-גלובוס תלויה בקיומו של קובצי BUILD. כלומר, אותו ביטוי בגלובוס יכלול גם את החבילה x/y, אם היא לא סומנה כחבילה שנמחקה או באמצעות הסימון --delete_packages .

  5. ההגבלה שלמעלה חלה על כל הביטויים של גלובוס, לא משנה באילו תווים כלליים לחיפוש הם משתמשים.
  6. קובץ מוסתר עם שם קובץ שמתחיל ב-. מותאם במלואו באמצעות התווים הכלליים לחיפוש ** וגם *. כדי להתאים קובץ מוסתר לתבנית מורכבת, הדפוס צריך להתחיל ב-.. לדוגמה, * ו-.*.txt יתאימו ל-.foo.txt, אבל *.txt לא יתאימו. גם ספריות מוסתרות מוסתרות באותו אופן. ספריות מוסתרות עשויות לכלול קבצים שאינם נדרשים כקלט, ועלולים להגדיל את מספר הקבצים המצופנים והצורכים בזיכרון. כדי להחריג ספריות מוסתרות, יש להוסיף אותן לארגומנט רשימה "excluded"
  7. בתו ה-"**" יש תו אחד פינתי: הדפוס "**" לא תואם לנתיב של החבילה&&39;. כלומר, glob(["**"], exclude_directories = 0) מכיל את כל הקבצים והספריות שבאופן זמני הועברו למאגר הנוכחי של הספרייה בחבילה (אבל כמובן שלא עוברים לספריות של חבילות משנה – יש לעיין בהערה הקודמת בנושא).

באופן כללי, צריך לנסות לספק תוסף מתאים (למשל *.html) במקום להשתמש בבלוק =33;*' עבור דפוס גלוב. השם הבוטה יותר הוא תיעוד עצמי שמבטיח שלא תתאים בטעות קבצים לגיבוי, או emacs/vi/... יש לשמור קבצים באופן אוטומטי.

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

דוגמאות לגלובוס

צור ספריית Java שנוצרה מכל קובצי Java בספרייה הזו, ומכל הקבצים שנוצרו על ידי הכלל :gen_java_srcs.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

יש לכלול את כל קובצי ה-txt בנתוני בדיקה של ספריות, פרט ל-Experiment.txt. לתשומת ליבך, קבצים בספריות משנה של נתוני בדיקה לא ייכללו. כדי לכלול את הקבצים האלה, יש להשתמש בגלובוס רקורסיבי (**).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

דוגמאות לגלובוסים רקורסיביים

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

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

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

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

דוגמאות ל-Glob מורחב

צריך ליצור דור נפרד ל-*_test.cc בספרייה הנוכחית שסופרת את מספר השורות בקובץ.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

אם קובץ ה-BUILD שלמעלה נמצא בחבילה //foo והחבילה מכילה שלושה קבצים תואמים, a_test.cc, b_test.cc ו-c_test.cc יפעלו: bazel query '//foo:all' יפורטו כל הכללים שנוצרו:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

בחירה

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() היא פונקציית העזרה שיוצרת מאפיין כלל שניתן להגדיר. הוא יכול להחליף את הצד השמאלי של כמעט כל הקצאת מאפיין, כך שהערך שלו תלוי בסימונים של Bazel בשורת הפקודה. ניתן להשתמש בכך, למשל, כדי להגדיר יחסי תלות ספציפיים לפלטפורמה או להטמיע משאבים שונים אם הכלל מובנה במצב {0} "developer" לעומת "release".

השימוש הבסיסי הוא:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

כך ניתן להגדיר את המאפיין srcs של sh_binary על ידי החלפת ההקצאה של רשימת התוויות הרגילה בקריאה של select. המיפוי הזה ממפה את תנאי התצורה לערכים תואמים. כל תנאי הוא הפניה לתווית config_setting או constraint_value. התנאי "matchs" אם ההגדרה של יעד' תואמת לקבוצת ערכים צפויה. הערך של mytarget#srcs הופך לכל רשימת התוויות התואמת את ההפעלה הנוכחית.

הערות:

  • בכל הפעלה מופעל תנאי אחד בדיוק.
  • אם יש התאמה לכמה תנאים, ואחד מהם הוא התמחות של האחרים, ההתמחות הזו מקבלת עדיפות. תנאי ב' נחשב להתמחות של תנאי א' אם ב' כולל את כל אותם הסימונים וערכי האילוצים כמו א', וגם סימונים או ערכי אילוץ נוספים. המשמעות היא גם שפתרון ההתמחות השיווקית לא נועד ליצור הזמנה, כפי שמתואר בדוגמה 2 שבהמשך.
  • אם כמה תנאים תואמים ואחד מהם לא התמחות של כל התנאים האחרים, Bazel נכשל עם שגיאה.
  • הפסאודו-תווית המיוחדת //conditions:default נחשבת כהתאמה אם אין תנאי אחר שתואם. אם התנאי הזה לא מתקיים, כלל אחר חייב להתאים כדי למנוע שגיאה.
  • אפשר להטמיע את select בתוך הקצאת מאפיינים גדולה יותר. לכן srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) ו- srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) הם ביטויים חוקיים.
  • המאפיין select פועל עם רוב המאפיינים, אבל לא עם כולם. מאפיינים לא תואמים מסומנים בתיעוד של nonconfigurable.

    חבילות משנה

    subpackages(include, exclude=[], allow_empty=True)

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

    הרשימה של חבילות המשנה שהוחזרו מופיעה בסדר ממוין ומכילה נתיבים ביחס לחבילת הטעינה הנוכחית שתואמת לתבניות הנתונות ב- include ולא לאלו של exclude.

    דוגמה

    בדוגמה הבאה מפורטות כל חבילות המשנה הישירות של החבילה foo/BUILD

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    באופן כללי, רצוי שבמקום לקרוא לפונקציה הזו ישירות שמשתמשים משתמשים במודול 'subpackages' של skylib.