Windows'da Yazma Kuralları

Sorun bildirin Kaynağı göster

Bu sayfada Windows ile uyumlu kurallar yazmaya, taşınabilir kural yazmayla ilgili sık karşılaşılan sorunlara ve bazı çözümlere odaklanılmaktadır.

Yollar

Sorunlar:

  • Uzunluk sınırı: Maksimum yol uzunluğu 259 karakterdir.

    Windows, daha uzun yolları da (32767 karaktere kadar) desteklese de birçok program alt sınırla oluşturulur.

    İşlemlerde çalıştırdığınız programlarla ilgili bu hususa dikkat edin.

  • Çalışma dizini: Ayrıca 259 karakterle sınırlıdır.

    İşlemler, 259 karakterden uzun bir dizin için cd işlemi yapamaz.

  • Büyük/küçük harfe duyarlılık: Windows yolları büyük/küçük harfe duyarlı değildir, Unix yolları büyük/küçük harfe duyarlıdır.

    İşlemler için komut satırları oluştururken bunu göz önünde bulundurun.

  • Yol ayırıcıları: ters eğik çizgidir (\`), not forward slash (/).

    Bazel, yolları / ayırıcılarıyla Unix stilinde depolar. Bazı Windows programları Unix stili yolları desteklerken bazıları desteklemez. cmd.exe'deki bazı yerleşik komutlar bunları destekler, bazıları desteklemez.

    İşlemler için komut satırları ve ortam değişkenleri oluştururken her zaman \` separators on Windows: replace/with" kullanmanız önerilir.

  • Mutlak yollar: Eğik çizgiyle (/) başlamayın.

    Windows'da mutlak yollar bir sürücü harfiyle başlar (ör. C:\foo\bar.txt). Tek bir dosya sistemi kökü yoktur.

    Kuralınız bir yolun mutlak olup olmadığını kontrol ediyorsa bunu göz önünde bulundurun. Çoğunlukla taşınamadığı için mutlak yollardan kaçınılmalıdır.

Çözümler:

  • Yolları kısa tutun.

    Uzun dizin adları, derinlemesine iç içe yerleştirilmiş dizin yapıları, uzun dosya adları, uzun çalışma alanı adları, uzun hedef adları kullanmaktan kaçının.

    Bunların tümü, işlemlerin giriş dosyalarının yol bileşenleri haline gelebilir ve yol uzunluğu sınırını tükenebilir.

  • Kısa bir çıkış kökü kullanın.

    Bazel çıkışları için kısa bir yol belirtmek isterseniz --output_user_root=<path> işaretini kullanın. Yalnızca Bazel çıkışları için bir sürücüye (veya sanal sürücüye) sahip olmak iyi bir fikirdir (D:\`), and adding this line to your.bazelrc dosyası gibi:

    build --output_user_root=D:/
    

    veya

    build --output_user_root=C:/_bzl
    
  • Kavşakları kullanın.

    Kavşaklar, genel anlamda [1], dizin sembolik bağlantılarıdır. Kavşaklar kolayca oluşturulabilir ve uzun yolları olan dizinlere (aynı bilgisayarda) işaret edebilir. Bir derleme işlemi, yolu kısa ancak hedefi uzun olan bir bağlantı oluşturursa kısa yol sınırına sahip araçlar, bağlantı verilen dizindeki dosyalara erişebilir.

    .bat dosyalarında veya cmd.exe'de aşağıdaki gibi bağlantılar oluşturabilirsiniz:

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

    [1]: Kavşaklar Sembolik Bağlantılar değildir ancak derleme işlemleri açısından Kavşakları Dizin Sembolleri olarak kabul edebilirsiniz.

  • İşlemlerdeki / ortamlardaki yollarda / öğesini `` ile değiştirin.

    Bir işlem için komut satırı veya ortam değişkenleri oluşturduğunuzda, yolları Windows stilinde yapın. Örnek:

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

Ortam değişkenleri

Sorunlar:

  • Büyük/küçük harfe duyarlılık: Windows ortam değişkeni adları büyük/küçük harfe duyarlı değildir.

    Örneğin, Java'da System.getenv("SystemRoot") ve System.getenv("SYSTEMROOT") aynı sonucu verir. (Bu, diğer diller için de geçerlidir.)

  • Hermetiklik: İşlemlerde mümkün olduğunca az özel ortam değişkeni kullanılmalıdır.

    Ortam değişkenleri, işlemin önbellek anahtarının bir parçasıdır. Bir işlem sık sık değişen veya kullanıcılara özel ortam değişkenleri kullanıyorsa bu durum, kuralın önbelleğe alınabilirliğinin azalmasını sağlar.

Çözümler:

  • Ortam değişkeni adlarını yalnızca büyük harfle kullanın.

    Bu özellik Windows, macOS ve Linux'ta çalışır.

  • İşlem ortamlarını en aza indirin.

    ctx.actions.run kullanırken ortamı ctx.configuration.default_shell_env olarak ayarlayın. İşlem için daha fazla ortam değişkeni gerekiyorsa bunların tümünü bir sözlüğe yerleştirin ve işleme aktarın. Örnek:

    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})
    

İşlemler

Sorunlar:

  • Yürütülebilir çıkışlar: Yürütülebilir her dosyanın yürütülebilir bir uzantısı olmalıdır.

    En yaygın uzantılar .exe (ikili dosyalar) ve .bat'dır (Toplu komut dosyaları).

    Kabuk komut dosyalarının (.sh) Windows'da yürütülebilir OLMADIĞINI unutmayın. Bunları ctx.actions.run executable olarak belirtemezsiniz. Ayrıca, dosyaların sahip olabileceği +x izni yoktur. Bu nedenle, Linux'ta olduğu gibi rastgele dosyaları yürütemezsiniz.

  • Bash komutları: Taşınabilirlik açısından, Bash komutlarını doğrudan işlemlerde çalıştırmaktan kaçının.

    Unix benzeri sistemlerde Bash yaygın olarak kullanılsa da Windows'da kullanılamaz. Bazel'in kendisi Bash'e (MSYS2) gittikçe daha az ihtiyaç duyuyor. Bu nedenle, gelecekte kullanıcılara Bazel ile birlikte MSYS2 yükleme olasılığı azalacak. Kuralların Windows'da kullanımını kolaylaştırmak için işlemlerde Bash komutlarını çalıştırmaktan kaçının.

  • Satır uzantıları: Windows CRLF (\r\n), Unix benzeri sistemlerde LF (\n) kullanılır.

    Metin dosyalarını karşılaştırırken bunu göz önünde bulundurun. Ödeme yaparken veya taahhütte bulunurken Git ayarlarınıza, özellikle de satır sonlarına dikkat edin. (Git'in core.autocrlf ayarına bakın.)

Çözümler:

  • BAsh içermeyen, amaca yönelik bir kural kullanın.

    native.genrule(), Bash komutlarına yönelik bir sarmalayıcıdır ve genellikle dosya kopyalama veya metin dosyası yazma gibi basit sorunları çözmek için kullanılır. Bash'e güvenmekten kurtulabilirsiniz. Tekerleği yeniden icat etmekten kurtulabilirsiniz. Bunun için bazel-skylib'in ihtiyaçlarınız için özel bir kural olup olmadığına bakın. Bunların hiçbiri Windows'da derlendiğinde/test edildiğinde Bash'e bağlı değildir.

    Derleme kuralı örnekleri:

    • copy_file() (kaynak, dokümanlar): dosyayı başka bir yere kopyalar ve isteğe bağlı olarak yürütülebilir hale getirir

    • write_file() (source, dokümanlar): İstenen satır sonlarıyla (auto, unix veya windows) bir metin dosyası yazar ve isteğe bağlı olarak dosyayı yürütülebilir hale getirir (komut dosyasıysa)

    • run_binary() (kaynak, dokümanlar): Derleme işlemi olarak belirli girişlere ve beklenen çıkışlara sahip bir ikili program (veya *_binary kuralı) çalıştırır (bu, ctx.actions.run için bir derleme kuralı sarmalayıcıdır)

    • native_binary() (source, documentation): *_binary kuralında yerel ikili programı sarmalar. Bu ikili programı bazel run veya run_binary() öğesinintool özelliğinde ya da native.genrule() tools özelliğinde kullanabilirsiniz.

    Test kuralı örnekleri:

    • diff_test() (kaynak, dokümanlar): iki dosyanın içeriğini karşılaştıran test

    • native_test() (source, dokümanlar): *_test kuralına yerel ikili programı sarmalar. Bu ikili programı bazel test

  • Windows'da .bat komut dosyalarını önemsiz işlemler için kullanabilirsiniz.

    .sh komut dosyası yerine, .bat komut dosyasıyla basit görevleri çözebilirsiniz.

    Örneğin, hiçbir şey yapmayan, bir mesajı yazdıran veya sabit bir hata koduyla çıkış yapan bir komut dosyasına ihtiyacınız varsa basit bir .bat dosyası yeterli olacaktır. Kuralınız bir DefaultInfo() sağlayıcısı döndürürse executable alanı, Windows'daki söz konusu .bat dosyasına işaret ediyor olabilir.

    Dosya uzantıları macOS ve Linux'ta önemli olmadığından, kabuk komut dosyalarında bile uzantı olarak her zaman .bat kullanabilirsiniz.

    Boş .bat dosyalarının yürütülemeyeceğini unutmayın. Boş bir komut dosyasına ihtiyacınız varsa içinde bir boşluk yazın.

  • Bash'i prensipli bir şekilde kullanın.

    Starlark derleme ve test kurallarında, Bash komut dosyalarını ve Bash komutlarını işlem olarak çalıştırmak için ctx.actions.run_shell kullanın.

    Starlark makrolarında, Bash komut dosyalarını ve komutları native.sh_binary() veya native.genrule() ile sarmalayın. Bazel, Bash'in kullanılabilir olup olmadığını kontrol eder ve komut dosyasını veya komutu Bash aracılığıyla çalıştırır.

    Starlark deposu kurallarında Bash'ten tamamen kaçınmayı deneyin. Bazel şu anda depo kurallarında Bazel komutlarını prensipli bir şekilde çalıştırmak için herhangi bir yöntem sunmamaktadır.

Dosyalar siliniyor

Sorunlar:

  • Dosyalar açıkken silinemez.

    Açık dosyalar silinemez (varsayılan olarak), denemeler "Erişim Reddedildi" hatalarıyla sonuçlanır. Bir dosyayı silemiyorsanız, çalışan bir işlem dosyayı hâlâ açık tutuyor olabilir.

  • Çalışan bir işlemin çalışma dizini silinemez.

    İşlemlerin çalışma dizinlerinde açık bir herkese açık kullanıcı adı vardır ve işlem sona erene kadar dizin silinemez.

Çözümler:

  • Kodunuzda, dosyaları hızlı şekilde kapatmayı deneyin.

    Java'da try-with-resources ifadesini kullanın. Python'da with open(...) as f: kullanın. Prensip olarak, herkese açık kullanıcı adlarını en kısa sürede kapatmayı deneyin.