Windows でのルールの記述

問題を報告 ソースを表示 Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

このページでは、Windows 互換ルールの作成、VM の一般的な問題、 ポータブルなルールの作成、ソリューションなどです。

パス

問題:

  • 長さの上限: パスの最大長は 259 文字です。

    Windows は長いパス(最大 32,767 文字)もサポートしていますが、多くのプログラムは 選択します。

    アクションで実行するプログラムについては、注意が必要です。

  • 作業ディレクトリ: 259 文字以内で指定します。

    プロセスは、259 文字を超えるディレクトリに cd できません。

  • 大文字と小文字の区別: Windows のパスでは大文字と小文字が区別されません。Unix のパスでは大文字と小文字が区別されます。

    アクションのコマンドラインを作成する際は、この点に注意してください。

  • パス区切り文字: バックスラッシュ(\`), not forward slash (/)です。

    Bazel は、/ セパレータを使用して Unix スタイルのパスを保存します。一部の Windows プログラムは Unix スタイルのパスと、そうでないパスを指定できます。cmd.exe の組み込みコマンドには、サポートされているものと、サポートされていないものがあります。

    アクションのコマンドラインと環境変数を作成する場合は、常に \` separators on Windows: replace/with を使用することをおすすめします。

  • 絶対パス: 先頭をスラッシュ(/)にしないでください。

    Windows の絶対パスはドライブ文字で始まります(例: C:\foo\bar.txt)。単一の ID は ファイルシステムのルートです。

    ルールでパスが絶対パスかどうかを確認する場合は、この点に注意してください。絶対パス これらは多くの場合ポータブルではないため、避けてください。

ソリューション:

  • パスを短くします。

    長いディレクトリ名、ネスト構造の深いディレクトリ構造、長いファイル名、長いワークスペース名、長いターゲット名は避けてください。

    これらはすべて、アクションのパスの構成要素になり得ます。そのパスの長さが上限に達する可能性があります。 できます。

  • 短い出力ルートを使用する。

    Bazel 出力の短いパスを指定するには、--output_user_root=<path> フラグを使用します。Bazel の出力専用のドライブ(または仮想ドライブ)を用意することをおすすめします(D:\`), and adding this line to your.bazelrc ファイルなど)。

    build --output_user_root=D:/
    

    または

    build --output_user_root=C:/_bzl
    
  • ジャンクションを使用する。

    ジャンクションとは、大まかに言うと[1]ディレクトリのシンボリック リンクです。ジャンクションを簡単に作成できる 長いパスを持つ(同じコンピュータ上の)ディレクトリを指すことができます。ビルド アクションで、パスは短いがターゲットが長いジャンクションを作成した場合、短いパスの上限があるツールは、ジャンクションされたディレクトリ内のファイルにアクセスできます。

    .bat ファイルまたは cmd.exe で、次のようにジャンクションを作成できます。

    mklink /J c:\path\to\junction c:\path\to\very\long\target\path
    

    [1]: 厳密に言えば、 ジャンクションはシンボリック リンクではありませんが、 ビルド アクションのために、ジャンクションをディレクトリ シンボリック リンクとみなすことができます。

  • アクション / envvars のパス内の / を `` に置き換える。

    アクションのコマンドラインまたは環境変数を作成するときは、パスを Windows スタイル。例:

    def as_path(p, is_windows):
        if is_windows:
            return p.replace("/", "\\")
        else:
            return p
    

環境変数

問題:

  • 大文字と小文字の区別: Windows 環境変数名では、大文字と小文字が区別されません。

    たとえば Java では、System.getenv("SystemRoot")System.getenv("SYSTEMROOT") は次のようになります。 同じ結果になります(これは他の言語にも適用されます)。

  • 密閉性: アクションで使用するカスタム環境変数はできる限り少なくします。

    環境変数は、アクションのキャッシュキーの一部です。アクションで環境変数を使用する場合 ルールがキャッシュされにくくなります。

ソリューション:

  • 大文字の環境変数名のみを使用します。

    これは Windows、macOS、Linux で動作します。

  • アクション環境を最小限に抑える。

    ctx.actions.run を使用する場合は、環境を ctx.configuration.default_shell_env に設定します。アクションにさらに環境変数が必要であれば、それらをすべて辞書に入れてアクションに渡します。例:

    load("@bazel_skylib//lib:dicts.bzl", "dicts")
    
    def _make_env(ctx, output_file, is_windows):
        out_path = output_file.path
        if is_windows:
            out_path = out_path.replace("/", "\\")
        return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
    

操作

問題:

  • 実行可能出力: すべての実行可能ファイルには実行可能拡張子が必要です。

    最も一般的な拡張子は、.exe(バイナリ ファイル)と .bat(バッチ スクリプト)です。

    シェル スクリプト(.sh)は Windows では実行できないため、ctx.actions.runexecutable として指定することはできません。また、ファイルには +x 権限がないため、 Linux のように任意のファイルを実行できません。

  • Bash コマンド: ポータビリティを確保するため、アクションで Bash コマンドを直接実行しないでください。

    Bash は Unix 系システムで広く使用されていますが、Windows では使用できないことがよくあります。Bazel 自体は、 Bash(MSYS2)への依存度が下がっているため、将来的にはユーザーが MSYS2 を使用する可能性が低くなる Bazel と一緒にインストールされます。Windows でルールを使いやすくするには、 できます。

  • 改行: Windows では CRLF(\r\n)、Unix 系システムでは LF(\n)を使用します。

    テキスト ファイルを比較するときは、この点に注意してください。Git の設定に注意してください。特に、チェックアウトや commit 時の行末に注意してください。(Git の core.autocrlf 設定をご覧ください)。

ソリューション:

  • Bash レスの専用ルールを使用する。

    native.genrule() は Bash コマンドのラッパーであり、ファイルのコピーやテキスト ファイルの書き込みなどの簡単な問題の解決によく使用されます。Bash に依存せず(そして車輪の再発明をせずに)、bazel-skylib にニーズに合った専用のルールがあるかどうかを確認できます。いずれも Bash に依存しない Windows でビルド/テストした場合。

    ビルドルールの例:

    • copy_file()出典こちらのドキュメントをご覧ください)。 ファイルを別の場所にコピーし、必要に応じて実行可能にする

    • write_file()ソースドキュメント): 必要な行末(autounixwindows)でテキスト ファイルを書き込み、必要に応じて実行可能にします(スクリプトの場合)。

    • run_binary()ソースドキュメント): 指定された入力と期待される出力を持つバイナリ(または *_binary ルール)をビルドアクションとして実行します(これは ctx.actions.run のビルドルール ラッパーです)。

    • native_binary()ソースドキュメント): ネイティブ バイナリを *_binary ルールでラップします。このルールは、bazel run として使用することも、run_binary()tool 属性または native.genrule()tools 属性で使用することもできます。

    テストルールの例:

  • Windows では、簡単な処理に .bat スクリプトを使用することを検討してください。

    .sh スクリプトの代わりに、.bat スクリプトを使用して簡単なタスクを解決できます。

    たとえば、何もしないスクリプト、メッセージを出力するスクリプト、固定のエラーコードで終了するスクリプトが必要であれば、シンプルな .bat ファイルで十分です。ルールによって DefaultInfo() が返された場合 場合、executable フィールドは Windows 上の .bat ファイルを参照できます。

    また、macOS と Linux ではファイル拡張子は重要ではないため、いつでも .bat を シェル スクリプトに対しても、この拡張機能を使用できます。

    空の .bat ファイルは実行できません。空のスクリプトが必要であれば、1 つのスペースを記述します。

  • 原則に基づいて Bash を使用する。

    Starlark のビルドルールとテストルールで、ctx.actions.run_shell を使用して Bash スクリプトと Bash を実行する 使用できます。

    Starlark マクロで、Bash スクリプトとコマンドを native.sh_binary() でラップするか、 native.genrule()。Bazel は、Bash が使用可能かどうかを確認し、スクリプトまたはコマンドを バッシュ。

    Starlark リポジトリ ルールでは、Bash を完全に避けるようにしてください。Bazel では現在、実行する方法がない リポジトリ ルールの原則に沿った Bash コマンド。

ファイルの削除

問題:

  • 開いている間はファイルを削除できません。

    開いているファイルは(デフォルトでは)削除できず、試行すると「アクセスが拒否されました」と表示されます。 エラーになります。ファイルを削除できない場合、実行中のプロセスがまだそのファイルを保持している可能性があります 表示されます。

  • 実行中のプロセスの作業ディレクトリは削除できません。

    プロセスには作業ディレクトリへのハンドルが開いているため、ディレクトリを削除できません 待機状態を維持します。

ソリューション:

  • コードで、ファイルを積極的に閉じるようにします。

    Java では、try-with-resources を使用します。Python では、with open(...) as f: を使用します。原則として、 なるべく早くハンドルを閉じましょう。