Windows でのルールの記述

問題を報告する ソースを表示 ナイトリー · 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.run さんの executable。また、ファイルに付与できる +x 権限もないため、Linux のように任意のファイルを実行することはできません。

  • Bash コマンド: 移植性を高めるため、アクション内で Bash コマンドを直接実行しないでください。

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

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

    テキスト ファイルを比較するときは、この点に注意してください。特に行については、Git の設定に注意してください。 終了することもできます(Git の core.autocrlf 設定をご覧ください)。

ソリューション:

  • Bash を使用しない目的別のルールを使用する。

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

    ビルドルールの例:

    • 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 が使用可能かどうかを確認し、Bash でスクリプトまたはコマンドを実行します。

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

ファイルの削除

問題:

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

    開いているファイルは(デフォルトでは)削除できません。削除しようとすると、「アクセス権が拒否されました」というエラーが発生します。ファイルを削除できない場合は、実行中のプロセスがファイルを開いたままにしている可能性があります。

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

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

ソリューション:

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

    Java では、try-with-resources を使用します。Python では、with open(...) as f: を使用します。原則として、ハンドルはできるだけ早く閉じるようにしてください。