"Make" Biến

Báo cáo sự cố Xem nguồn

Biến "Make" là một lớp đặc biệt của các biến chuỗi có thể mở rộng có sẵn cho các thuộc tính được đánh dấu là "Chủ đề là "Thay thế 'Tạo biến'".

Ví dụ: bạn có thể dùng các lệnh này để chèn đường dẫn chuỗi công cụ cụ thể vào các hành động xây dựng do người dùng tạo.

Bazel cung cấp cả biến xác định trước, có sẵn cho tất cả mục tiêu và biến tuỳ chỉnh. Những biến này được xác định trong các mục tiêu phần phụ thuộc và chỉ có sẵn cho các mục tiêu phụ thuộc vào biến đó.

Lý do cho cụm từ "Make" là trước đây: cú pháp và ngữ nghĩa của các biến này ban đầu là để khớp với GNU Make.

Sử dụng

Các thuộc tính được đánh dấu là "Thay thế cho "Tạo biến" có thể tham chiếu đến biến "Tạo" FOO như sau:

my_attr = "prefix $(FOO) suffix"

Nói cách khác, bất kỳ chuỗi con nào khớp với $(FOO) sẽ được mở rộng thành giá trị của FOO. Nếu giá trị đó là "bar", chuỗi cuối cùng sẽ trở thành:

my_attr = "prefix bar suffix"

Nếu FOO không tương ứng với một biến đã biết đối với mục tiêu sử dụng, Bazel sẽ gặp lỗi.

Biến "Make" có tên là ký hiệu không phải chữ cái, chẳng hạn như @, cũng có thể được tham chiếu chỉ bằng ký hiệu đô la, không có dấu ngoặc đơn. Ví dụ:

my_attr = "prefix $@ suffix"

Để viết $ dưới dạng giá trị cố định kiểu chuỗi (tức là ngăn chặn việc mở rộng biến), hãy viết $$.

Biến được xác định trước

Biến "Make" được xác định trước có thể được tham chiếu bằng bất kỳ thuộc tính nào được đánh dấu là "Chủ đề là "Thay thế 'biến'" trên mục tiêu bất kỳ.

Để xem danh sách các biến này và giá trị của các biến đó cho một tập hợp các tùy chọn bản dựng cụ thể, hãy chạy

bazel info --show_make_env [build options]

và xem các dòng đầu ra trên cùng bằng chữ cái viết hoa.

Xem ví dụ về các biến được xác định trước.

Biến tuỳ chọn chuỗi công cụ

Biến đường dẫn

  • BINDIR: Cơ sở của cây nhị phân được tạo cho cấu trúc mục tiêu.

    Lưu ý rằng có thể sử dụng một cây khác cho các chương trình chạy trong quá trình tạo bản dựng trên cấu trúc máy chủ lưu trữ, để hỗ trợ biên dịch chéo.

    Nếu muốn chạy công cụ từ trong genrule, bạn nên lấy đường dẫn của công cụ đó, trong đó tên công cụ phải được liệt kê trong thuộc tính tools của genrule.

  • GENDIR: Cơ sở của cây mã đã tạo cho cấu trúc mục tiêu.

Biến cấu trúc máy

  • TARGET_CPU: CPU của cấu trúc mục tiêu, chẳng hạn như k8.

Biến genrule quy định sẵn

Thuộc tính sau đây đặc biệt có sẵn cho thuộc tính cmd của genrule và thường quan trọng để thuộc tính đó hoạt động.

Xem ví dụ về các biến genrule đã xác định trước.

  • OUTS: Danh sách outs của genrule. Nếu chỉ có một tệp đầu ra, bạn cũng có thể sử dụng $@.
  • SRCS: Danh sách srcs của genrule (hoặc chính xác hơn là: tên đường dẫn của các tệp tương ứng với nhãn trong danh sách srcs). Nếu chỉ có một tệp nguồn, bạn cũng có thể sử dụng $<.
  • <: SRCS, nếu đó là một tệp đơn lẻ. Nếu không, hệ thống sẽ kích hoạt lỗi bản dựng.
  • @: OUTS, nếu đó là một tệp đơn lẻ. Nếu không, hệ thống sẽ kích hoạt lỗi bản dựng.
  • RULEDIR: Thư mục đầu ra của mục tiêu, nghĩa là thư mục tương ứng với tên gói chứa mục tiêu trong cây genfiles hoặc bin. Đối với //my/pkg:my_genrule, giá trị này luôn kết thúc bằng my/pkg, ngay cả khi kết quả của //my/pkg:my_genrule nằm trong các thư mục con.

  • @D: Thư mục đầu ra. Nếu out (mục đầu ra) có một mục, thì mục này sẽ mở rộng tới thư mục chứa tệp đó. Nếu có nhiều mục, tệp này sẽ mở rộng tới thư mục gốc của gói trong cây genfiles, ngay cả khi tất cả các tệp đầu ra nằm trong cùng một thư mục con!

    Lưu ý: Sử dụng RULEDIR thay vì @DRULEDIR có ngữ nghĩa đơn giản hơn và hoạt động theo cách giống nhau bất kể số lượng tệp đầu ra.

    Nếu genrule cần tạo các tệp trung gian tạm thời (có thể do sử dụng một số công cụ khác như trình biên dịch), thì công cụ này nên cố gắng ghi các tệp đó vào @D (mặc dù /tmp cũng có thể ghi) và xoá các tệp này trước khi hoàn tất.

    Đặc biệt là tránh ghi vào các thư mục chứa thông tin đầu vào. Các tệp này có thể nằm trên hệ thống tệp chỉ có thể đọc. Ngay cả khi không, làm như vậy sẽ rác vào cây nguồn.

Biến đường dẫn nguồn/đầu ra được xác định trước

Các biến được xác định trước execpath, execpaths, rootpath, rootpaths, locationlocations sẽ lấy các thông số nhãn (ví dụ: $(execpath //foo:bar)) và thay thế các đường dẫn tệp được biểu thị bằng nhãn đó.

Đối với các tệp nguồn, đây là đường dẫn tương ứng với thư mục gốc của không gian làm việc. Đối với các tệp là kết quả của các quy tắc, đây là đường dẫn đầu ra của tệp (xem nội dung giải thích về tệp đầu ra bên dưới).

Xem ví dụ về các biến đường dẫn được xác định trước.

  • execpath: Mô tả đường dẫn bên dưới thực thi nơi Bazel chạy hành động tạo bản dựng.

    Trong ví dụ trên, Bazel chạy tất cả các hành động của bản dựng trong thư mục được liên kết bằng đường liên kết tượng trưng bazel-myproject trong thư mục gốc của không gian làm việc. Tệp nguồn empty.source được liên kết tại đường dẫn bazel-myproject/testapp/empty.source. Vì vậy, đường dẫn thực thi của đường dẫn này (là đường dẫn con bên dưới thư mục gốc) là testapp/empty.source. Đây là các thao tác tạo bản dựng đường dẫn có thể sử dụng để tìm tệp.

    Các tệp đầu ra được phân đoạn theo giai đoạn tương tự, nhưng cũng có tiền tố là đường dẫn con bazel-out/cpu-compilation_mode/bin hoặc (cho kết quả của công cụ: bazel-out/cpu-opt-exec-hash/bin). Trong ví dụ trên, //testapp:app là một công cụ vì nó xuất hiện trong thuộc tính tools của show_app_output. Vì vậy, tệp đầu ra của tệp app được ghi vào bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app. Do đó, đường dẫn thực thi là bazel-out/cpu-opt-exec-hash/bin/testapp/app. Tiền tố bổ sung này giúp bạn có thể tạo cùng một mục tiêu cho hai CPU khác nhau trong cùng một bản dựng mà không ảnh hưởng đến kết quả của nhau.

    Nhãn được truyền đến biến này phải đại diện cho đúng một tệp. Đối với các nhãn đại diện cho các tệp nguồn, điều này sẽ tự động đúng. Đối với các nhãn đại diện cho quy tắc, quy tắc phải tạo chính xác một kết quả. Nếu điều này là sai hoặc nhãn không đúng định dạng, thì bản dựng sẽ không hoạt động do lỗi.

  • rootpath: Mô tả đường dẫn mà một tệp nhị phân tạo có thể sử dụng để tìm phần phụ thuộc trong thời gian chạy liên quan đến thư mục con của thư mục runfiles tương ứng với kho lưu trữ chính. Lưu ý: Tính năng này chỉ hoạt động nếu bạn bật --enable_runfiles nhưng tuỳ chọn này không hoạt động trên Windows theo mặc định. Thay vào đó, hãy sử dụng rlocationpath để được hỗ trợ trên nhiều nền tảng.

    Chính sách này tương tự như execpath nhưng xoá các tiền tố cấu hình như mô tả ở trên. Trong ví dụ ở trên, cả empty.sourceapp đều sử dụng đường dẫn thuần tuý tương đối trong không gian làm việc: testapp/empty.sourcetestapp/app.

    rootpath của một tệp trong kho lưu trữ bên ngoài repo sẽ bắt đầu bằng ../repo/, theo sau là đường dẫn tương đối của kho lưu trữ.

    Điều này có cùng yêu cầu "chỉ một kết quả đầu ra" với execpath.

  • rlocationpath: Đường dẫn của tệp nhị phân được tạo có thể chuyển đến hàm Rlocation của thư viện runfiles để tìm phần phụ thuộc trong thời gian chạy, trong thư mục runfiles (nếu có) hoặc sử dụng tệp kê khai runfiles.

    Điều này tương tự như rootpath vì nó không chứa tiền tố cấu hình, nhưng khác ở chỗ nó luôn bắt đầu bằng tên của kho lưu trữ. Trong ví dụ trên, empty.sourceapp dẫn đến các đường dẫn sau: myproject/testapp/empty.source myproject/testapp/app.

    rlocationpath của một tệp trong kho lưu trữ bên ngoài repo sẽ bắt đầu bằng repo/, theo sau là đường dẫn tương đối của kho lưu trữ.

    Việc chuyển đường dẫn này đến một tệp nhị phân và phân giải đường dẫn đó đến một đường dẫn hệ thống tệp bằng cách sử dụng thư viện runfiles là phương pháp ưu tiên để tìm các phần phụ thuộc trong thời gian chạy. So với rootpath, tính năng này có lợi thế là hoạt động trên tất cả các nền tảng và ngay cả khi không có thư mục runfiles.

    Điều này có cùng yêu cầu "chỉ một kết quả đầu ra" với execpath.

  • location: Từ đồng nghĩa của execpath hoặc rootpath, tuỳ thuộc vào thuộc tính đang được mở rộng. Đây là hành vi cũ của Starlark và không được đề xuất trừ khi bạn thực sự biết chức năng của nó đối với một quy tắc cụ thể. Hãy xem #2475 để biết thông tin chi tiết.

execpaths, rootpaths, rlocationpathslocations là các biến thể số nhiều của execpath, rootpath, rlocationpathslocation tương ứng. Hỗ trợ các nhãn tạo ra nhiều dữ liệu đầu ra. Trong trường hợp đó, mỗi đầu ra được liệt kê riêng biệt với một dấu cách. Quy tắc dữ liệu đầu ra bằng không và nhãn không đúng định dạng sẽ tạo ra lỗi bản dựng.

Tất cả nhãn được tham chiếu phải xuất hiện trong srcs, tệp đầu ra hoặc deps của mục tiêu sử dụng. Nếu không, bản dựng sẽ không thể hoạt động. Các mục tiêu C++ cũng có thể tham chiếu các nhãn trong data.

Nhãn không nhất thiết phải ở dạng chính tắc: foo, :foo//somepkg:foo đều được.

Biến tùy chỉnh

Bạn có thể tham chiếu các biến "Make" tuỳ chỉnh bằng bất kỳ thuộc tính nào được đánh dấu là "Subject to 'Makebiến' replace", nhưng chỉ những mục tiêu phụ thuộc vào các mục tiêu khác định nghĩa các biến này.

Tốt nhất là bạn nên tuỳ chỉnh tất cả các biến trừ phi có lý do thực sự phù hợp để tích hợp các biến đó vào Bazel cốt lõi. Điều này giúp Bazel không phải tải các phần phụ thuộc có thể tốn kém để cung cấp các biến sử dụng taret.

Biến chuỗi công cụ C++

Quy tắc sau đây được xác định trong các quy tắc của chuỗi công cụ C++ và có sẵn cho mọi quy tắc đặt toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"] (hoặc "@bazel_tools//tools/cpp:current_cc_host_toolchain" cho chuỗi công cụ lưu trữ tương đương). Một số quy tắc (như java_binary) ngầm chứa chuỗi công cụ C++ trong định nghĩa quy tắc. Chúng kế thừa các biến này một cách tự động.

Các quy tắc C++ tích hợp sẵn phức tạp hơn nhiều so với "chạy trình biên dịch trên đó". Để hỗ trợ các chế độ biên dịch đa dạng như *SAN, ThinLTO, có/không có mô-đun và các tệp nhị phân được tối ưu hoá cẩn thận cùng lúc với các thử nghiệm chạy nhanh trên nhiều nền tảng, các quy tắc tích hợp sẵn sẽ có độ dài tuyệt vời để đảm bảo các đầu vào, đầu ra và cờ dòng lệnh chính xác được đặt trên từng hành động có thể được tạo nội bộ.

Những biến này là cơ chế dự phòng để các chuyên gia ngôn ngữ sử dụng trong một số ít trường hợp. Nếu bạn muốn sử dụng các ứng dụng này, vui lòng liên hệ với nhà phát triển Bazel trước.

  • ABI: Phiên bản C++ ABI.
  • AR: Lệnh "ar" trong crosstool.
  • C_COMPILER: Giá trị nhận dạng trình biên dịch C/C++, ví dụ: llvm.
  • CC: Lệnh biên dịch C và C++.

    Bạn nên luôn sử dụng kết hợp CC_FLAGS với CC. Nếu không, bạn sẽ phải tự chịu rủi ro.

  • CC_FLAGS: Một tập hợp cờ tối thiểu để trình biên dịch C/C++ có thể sử dụng được theo quy tắc gen. Cụ thể, thao tác này sẽ chứa cờ để chọn đúng cấu trúc nếu CC hỗ trợ nhiều cấu trúc.
  • NM: Lệnh "nm" từ crosstool.
  • OBJCOPY: Lệnh objcopy trong cùng một bộ với trình biên dịch C/C++.
  • STRIP: Lệnh thoát khỏi cùng bộ với trình biên dịch C/C++.

Biến chuỗi công cụ Java

Các quy tắc sau đây được xác định trong các quy tắc chuỗi công cụ Java và có sẵn cho bất kỳ quy tắc nào đặt toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"] (hoặc "@bazel_tools//tools/jdk:current_host_java_runtime" cho chuỗi công cụ lưu trữ tương đương).

Hầu hết các công cụ trong JDK không được sử dụng trực tiếp. Các quy tắc Java tích hợp sử dụng nhiều phương pháp biên dịch và đóng gói Java phức tạp hơn so với cách sử dụng các công cụ ngược dòng (chẳng hạn như Lọ giao diện, Lọ giao diện tiêu đề và Tính năng đóng gói và hợp nhất Jar được tối ưu hoá).

Những biến này là cơ chế dự phòng để các chuyên gia ngôn ngữ sử dụng trong một số ít trường hợp. Nếu bạn muốn sử dụng các ứng dụng này, vui lòng liên hệ với nhà phát triển Bazel trước.

  • JAVA: Lệnh "java" (máy ảo Java). Hãy tránh điều này và sử dụng quy tắc java_binary nếu có thể. Có thể là đường dẫn tương đối. Nếu phải thay đổi thư mục trước khi gọi java, bạn cần chụp thư mục đó trước khi thay đổi.
  • JAVABASE: Thư mục cơ sở chứa các tiện ích Java. Có thể là đường dẫn tương đối. Tệp này sẽ có thư mục con "bin".

Biến do Starlark xác định

Tác giả quy tắc và chuỗi công cụ có thể xác định các biến hoàn toàn tùy chỉnh bằng cách trả về một nhà cung cấp TemplateVariableInfo. Sau đó, bất kỳ quy tắc nào tuỳ thuộc vào các quy tắc này thông qua thuộc tính toolchains đều có thể đọc giá trị của chúng:

Xem ví dụ về các biến do Starlark xác định.