Bu sayfada, Windows uyumlu kurallar yazma, taşınabilir kurallar yazmayla ilgili yaygın sorunlar ve bazı çözümler ele alınmaktadı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: 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ı 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ılarla Unix tarzında 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ırı ve ortam değişkenleri oluştururken her zaman
\` separators on Windows: replace
/with
` kullanmanızı öneririz.Mutlak yollar: Eğik çizgiyle (
/
) başlamayın.Windows'daki mutlak yollar
C:\foo\bar.txt
gibi bir sürücü harfi ile başlar. Tek bir dosya sistemi kökü yoktur.Kuralınız bir yolun mutlak olup olmadığını kontrol ediyorsa bunu göz önünde bulundurun. Genellikle taşınamadığı için mutlak yollardan kaçınılmalıdır.
Çözümler:
Yolları kısa tutun.
Uzun dizin adları, derin 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ı 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ı 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şak, genel anlamda[1] dizin sembolik bağlantılarıdır. Kavşak oluşturmak kolaydır ve uzun yolları olan dizinleri (aynı bilgisayarda) gösterebilir. 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ı noktaları 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
/
yerine `` yazın.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ı olma: Windows ortam değişkeni adları büyük/küçük harfe duyarlıdır.
Ö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ş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 harflerle 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 hepsini bir sözlüğe koyun 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: 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
(toplu komut dosyaları) şeklindedir.Kabuk komut dosyalarının (
.sh
) Windows'da EXE dosyası OLMADIĞINI unutmayın. Bu dosyalarıctx.actions.run
'unexecutable
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 için Bash komutlarını doğrudan işlemlerde çalıştırmaktan kaçının.
Bash, Unix benzeri sistemlerde yaygın olarak kullanılır ancak genellikle Windows'ta kullanılamaz. Bazel, Bash'e (MSYS2) giderek daha az ihtiyaç duyuyor. Bu nedenle, gelecekte kullanıcıların Bazel ile birlikte MSYS2'yi yükleme olasılığı azalacaktır. 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, özel olarak tasarlanmış bir kural kullanın.
native.genrule()
, Bash komutları için 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, belgelendirme): Bir dosyayı başka bir yere kopyalar ve isteğe bağlı olarak yürütülebilir hale getirirwrite_file()
(source, dokümanlar): İstenen satır sonlarıyla (auto
,unix
veyawindows
) 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
veyarun_binary()
öğesinintool
özelliğinde ya danative.genrule()
tools
özelliğinde kullanabilirsiniz.
Test kuralı örnekleri:
diff_test()
(kaynak, dokümanlar): iki dosyanın içeriğini karşılaştıran testnative_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 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 çıkış yapan bir komut dosyasına ihtiyacınız varsa basit bir
.bat
dosyası yeterli olacaktır. Kuralınız birDefaultInfo()
sağlayıcısı döndürürseexecutable
alanı, Windows'daki söz konusu.bat
dosyasına işaret ediyor olabilir.Ayrıca, macOS ve Linux'ta dosya uzantıları önemli olmadığından, kabuk komut dosyaları için 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çine bir boşluk yazın.Bash'i prensiplere uygun ş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()
veyanative.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 depo kurallarında Bash'ten tamamen kaçının. Bazel şu anda depo kurallarında Bash komutlarını prensipli bir şekilde çalıştırmanın bir yolunu sunmuyor.
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 dosyayı açık tutan çalışan bir işlem olabilir.
Çalışan bir işlemin çalışma dizini silinemez.
İşlemlerin çalışma dizinlerine 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'dawith open(...) as f:
kullanın. Prensip olarak, herkese açık kullanıcı adlarını en kısa sürede kapatmayı deneyin.