Bu sayfada, Windows ile uyumlu kurallar yazma, taşınabilir kurallar yazmayla ilgili yaygın sorunlar ve bazı çözümler üzerinde durulmaktadır.
Yollar
Sorunlar:
Uzunluk sınırı: Maksimum yol uzunluğu 259 karakterdir.
Windows daha uzun yolları (32.767 karaktere kadar) desteklese de birçok program daha düşük bir sınırla oluşturulur.
İşlemlerde çalıştırdığınız programlarla ilgili olarak şunlara dikkat edin.
Çalışma dizini: 259 karakterle sınırlıdır.
İşlemler, 259 karakterden uzun bir dizine
cd
olamaz.Büyük/küçük harfe duyarlılık: Windows yolları büyük/küçük harfe duyarlı değildir, Unix yolları ise büyük/küçük harfe duyarlıdır.
İşlemler için komut satırları oluştururken bu durumu 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 tarzında depolar. Bazı Windows programları Unix tarzı yolları desteklese de bazıları desteklemez. cmd.exe'deki bazı yerleşik komutlar bunları destekler, bazıları ise 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şlamaz.Windows'daki mutlak yollar,
C:\foo\bar.txt
gibi bir sürücü harfiyle başlar. Tek bir dosya sistemi kökü yoktur.Kuralınız bir yolun mutlak olup olmadığını kontrol ediyorsa bu durumun farkında olun. Mutlak yollar genellikle taşınabilir olmadıkları için kullanılmamalıdır.
Çözümler:
Yolları kısa tutun.
Uzun dizin adları, iç içe geçmiş dizin yapıları, uzun dosya adları, uzun çalışma alanı adları ve 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ı aşabilir.
Kısa bir çıkış kökü kullanın.
Bazel çıkışları için kısa bir yol belirtmek üzere
--output_user_root=<path>
işaretini kullanın. Yalnızca Bazel çıkışları (ör.D:\`), and adding this line to your
.bazelrc` dosyası) için bir sürücü (veya sanal sürücü) kullanmak iyi bir fikirdir:build --output_user_root=D:/
veya
build --output_user_root=C:/_bzl
Kavşakları kullanma
Birleşme noktaları, kabaca[1] dizin sembolik bağlantılarıdır. Birleşim noktaları kolayca oluşturulabilir ve uzun yollara sahip dizinleri (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ı olan araçlar, bağlantılı dizindeki dosyalara erişebilir.
.bat
dosyalarında veya cmd.exe'de aşağıdaki gibi birleşimler oluşturabilirsiniz:mklink /J c:\path\to\junction c:\path\to\very\long\target\path
[1]: Açıkçası Birleşimler Sembolik Bağlantılar Değildir ancak derleme işlemleri için Birleşimleri Dizin Sembolik Bağlantıları olarak değerlendirebilirsiniz.
İşlemlerdeki / ortam değişkenlerindeki yollarda
/
yerine `` kullanın.Bir işlem için komut satırı veya ortam değişkenleri oluşturduğunuzda yolları Windows tarzında 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")
veSystem.getenv("SYSTEMROOT")
aynı sonucu verir. (Bu durum diğer diller için de geçerlidir.)Hermeticity: İş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şlemde sık sık değişen veya kullanıcılara özel ortam değişkenleri kullanılıyorsa bu durum, kuralın daha az önbelleğe alınabilir olmasına neden olur.
Çözümler:
Yalnızca büyük harfli ortam değişkeni adları kullanın.
Bu özellik Windows, macOS ve Linux'ta kullanılabilir.
İşlem ortamlarını en aza indirin.
ctx.actions.run
kullanırken ortamıctx.configuration.default_shell_env
olarak ayarlayın. İşlemin daha fazla ortam değişkenine ihtiyacı varsa bunların hepsini bir sözlüğe yerleştirin ve sözlüğü işleme iletin. Ö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: Her yürütülebilir dosyanın yürütülebilir uzantısı olmalıdır.
En yaygın uzantılar
.exe
(ikili dosyalar) ve.bat
(toplu iş komut dosyaları) uzantılarıdır.Kabuk komut dosyalarının (
.sh
) Windows'da yürütülebilir OLMADIĞINI unutmayın. Bunlarıctx.actions.run
'ninexecutable
olarak belirtemezsiniz. Dosyaların sahip olabileceği bir+x
izni de 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.
Bash, Unix benzeri sistemlerde yaygın olarak kullanılır ancak Windows'da genellikle kullanılamaz. Bazel'in kendisi Bash'e (MSYS2) giderek daha az bağımlı hale geliyor. Bu nedenle, gelecekte kullanıcıların Bazel ile birlikte MSYS2'yi yükleme olasılığı daha düşük olacak. Windows'da kuralların daha kolay kullanılabilmesi için eylemlerde Bash komutlarını çalıştırmayın.
Satır sonları: Windows, CRLF (
\r\n
), Unix benzeri sistemler ise LF (\n
) kullanır.Metin dosyalarını karşılaştırırken bu durumu göz önünde bulundurun. Git ayarlarınıza, özellikle de satır sonlarına göz atarken veya değişiklikleri kaydederken dikkat edin. (Git'in
core.autocrlf
ayarına bakın.)
Çözümler:
Bash içermeyen, amaca uygun bir kural kullanın.
native.genrule()
, Bash komutları için bir sarmalayıcıdır ve genellikle bir dosyayı kopyalama veya metin dosyası yazma gibi basit sorunları çözmek için kullanılır. Bash'e güvenmekten (ve tekerleği yeniden icat etmekten) kaçınabilirsiniz: bazel-skylib'de ihtiyaçlarınız için özel olarak tasarlanmış bir kural olup olmadığını kontrol edin. Bunların hiçbiri, Windows'da oluşturulup test edilirken Bash'e bağlı değildir.Kural oluşturma örnekleri:
copy_file()
(kaynak, belge): Bir dosyayı başka bir yere kopyalar ve isteğe bağlı olarak yürütülebilir hale getirir.write_file()
(source, documentation): İstenen satır sonlarıyla (auto
,unix
veyawindows
) bir metin dosyası yazar, isteğe bağlı olarak yürütülebilir hale getirir (komut dosyasıysa)run_binary()
(source, documentation): Belirli girişler ve beklenen çıkışlarla bir ikili (veya*_binary
kuralı) oluşturma işlemi olarak çalıştırır (Bu,ctx.actions.run
için bir oluşturma kuralı sarmalayıcısıdır)native_binary()
(kaynak, belgeleme): Yerel bir ikiliyi,*_binary
kuralına sarar. Bu kuralıbazel run
veyarun_binary()
'nintool
ya danative.genrule()
'nintools
özelliğinde kullanabilirsiniz.
Test kuralı örnekleri:
diff_test()
(kaynak, belge): İki dosyanın içeriğini karşılaştıran testnative_test()
(source, documentation): yerel bir ikili programı,bazel test
*_test
kuralına sarar.
Windows'da önemsiz işlemler için
.bat
komut dosyalarını kullanabilirsiniz..sh
komut dosyaları yerine.bat
komut dosyalarıyla basit görevleri çözebilirsiniz.Örneğin, hiçbir şey yapmayan, bir mesaj yazdıran veya sabit bir hata koduyla çıkan bir komut dosyasına ihtiyacınız varsa basit bir
.bat
dosyası yeterli olacaktır. KuralınızDefaultInfo()
sağlayıcı döndürüyorsaexecutable
alanı, Windows'daki.bat
dosyasına atıfta bulunabilir.Dosya uzantıları macOS ve Linux'ta önemli olmadığından, kabuk komut dosyaları için bile her zaman
.bat
uzantısını kullanabilirsiniz.Boş
.bat
dosyaların yürütülemeyeceğini unutmayın. Boş bir komut dosyasına ihtiyacınız varsa içine bir boşluk yazın.Bash'i ilkeli bir şekilde kullan.
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ını
native.sh_binary()
veyanative.genrule()
içine alın. Bazel, Bash'in kullanılabilir olup olmadığını kontrol eder ve komut dosyasını veya komutu Bash üzerinden çalıştırır.Starlark deposu kurallarında Bash'ten tamamen kaçınmaya çalışın. Bazel şu anda depo kurallarında Bash komutlarını ilkeli bir şekilde çalıştırmanın bir yolunu sunmuyor.
Dosyalar siliniyor
Sorunlar:
Dosyalar açıkken silinemez.
Açık dosyalar (varsayılan olarak) silinemez. Silmeye çalışıldığında "Erişim Reddedildi" hataları oluşur. Bir dosyayı silemiyorsanız çalışan bir işlem dosyayı açık tutuyor olabilir.
Çalışan bir işlemin çalışma dizini silinemez.
İşlemlerin çalışma dizinleriyle açık bir tutamağı vardır ve işlem sonlandırılana kadar dizin silinemez.
Çözümler:
Kodunuzda dosyaları hemen kapatmayı deneyin.
Java'da
try-with-resources
kullanın. Python'dawith open(...) as f:
kullanın. Prensip olarak, en kısa sürede kapatmaya çalışın.