Yaygın C++ Derleme Kullanım Alanları

Sorun bildir Kaynağı göster

Burada Bazel ile C++ projeleri oluşturmak için en yaygın kullanım alanlarından bazılarını bulacaksınız. Henüz yapmadıysanız Bazel ile C++ projeleri oluşturmaya başlayın ve Bazel'e Giriş: C++ Projesi Oluşturma başlıklı eğiticiyi tamamlayın.

cc_library ve hdrs üst bilgi dosyaları hakkında bilgi edinmek için cc_library bölümüne bakın.

Bir hedefe birden çok dosya ekleme

glob ile tek bir hedefe birden çok dosya ekleyebilirsiniz. Örneğin:

cc_library(
    name = "build-all-the-files",
    srcs = glob(["*.cc"]),
    hdrs = glob(["*.h"]),
)

Bu hedefle Bazel, bulduğu tüm .cc ve .h dosyalarını bu hedefi içeren BUILD dosyasıyla aynı dizinde oluşturur (alt dizinler hariç).

Geçişli kapsamları kullanma

Bir dosyada başlık varsa bu dosyanın kaynak olarak kullanıldığı tüm kurallar (yani, dosyanın srcs, hdrs veya textual_hdrs özelliğinde olması) dahil edilen başlığın kitaplık kuralına bağlı olmalıdır. Öte yandan, yalnızca doğrudan bağımlılıklar bağımlılık olarak belirtilmelidir. Örneğin, sandwich.h değerinin bread.h ve bread.h değerinin flour.h içerdiğini varsayalım. sandwich.h, flour.h ifadesini içermez (sandviçte un isteyen kim?), bu nedenle BUILD dosyası şöyle görünür:

cc_library(
    name = "sandwich",
    srcs = ["sandwich.cc"],
    hdrs = ["sandwich.h"],
    deps = [":bread"],
)

cc_library(
    name = "bread",
    srcs = ["bread.cc"],
    hdrs = ["bread.h"],
    deps = [":flour"],
)

cc_library(
    name = "flour",
    srcs = ["flour.cc"],
    hdrs = ["flour.h"],
)

Burada sandwich kitaplığı, flour kitaplığına bağlı olan bread kitaplığına bağlıdır.

Dahil etme yolları ekleniyor

Bazen çalışma alanı kökündeki yolları rootlamanız mümkün olmaz (veya bunu yapmak istemezsiniz). Mevcut kitaplıklarda, çalışma alanınızdaki yoluyla eşleşmeyen bir "include" (ekleme) dizini halihazırda olabilir. Örneğin, aşağıdaki dizin yapısına sahip olduğunuzu varsayalım:

└── my-project
    ├── legacy
    │   └── some_lib
    │       ├── BUILD
    │       ├── include
    │       │   └── some_lib.h
    │       └── some_lib.cc
    └── WORKSPACE

Bazel, some_lib.h öğesinin legacy/some_lib/include/some_lib.h olarak eklenmesini bekler ancak some_lib.cc öğesinin "some_lib.h" olarak dahil edildiğini varsayalım. Bu dahil etme yolunu geçerli hale getirmek için legacy/some_lib/BUILD özelliğinin some_lib/include dizininin bir dahil etme dizini olduğunu belirtmesi gerekir:

cc_library(
    name = "some_lib",
    srcs = ["some_lib.cc"],
    hdrs = ["include/some_lib.h"],
    copts = ["-Ilegacy/some_lib/include"],
)

Bu, üstbilgi dosyalarının aksi halde / önekiyle eklenmesi gerektiğinden, özellikle harici bağımlılıklar için kullanışlıdır.

Harici kitaplıkları dahil et

Google Test uygulamasını kullandığınızı varsayalım {: .external}. Google Test'i indirmek ve deponuzda kullanıma sunmak için WORKSPACE dosyasındaki depo işlevlerinden birini kullanabilirsiniz:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "gtest",
    url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
    sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
    build_file = "@//:gtest.BUILD",
)

Ardından, Google Test'i derlemek için kullanılan BUILD dosyası olan gtest.BUILD oluşturun. Google Test'in cc_library kuralını daha karmaşık hale getiren bazı "özel" şartlar vardır:

  • googletest-release-1.10.0/googletest/src/gtest-all.cc, googletest-release-1.10.0/googletest/src/ içindeki diğer tüm dosyaları #includeler: Yinelenen simgelerde bağlantı hatalarını önlemek için bunu derlemeden hariç tutun.

  • googletest-release-1.10.0/googletest/include/ diziniyle ("gtest/gtest.h") göreli üstbilgi dosyaları kullandığından, bu dizini dahil etme yollarına eklemeniz gerekir.

  • Hesabın pthread içinde bağlanması gerekir, bu nedenle linkopt olarak ekleyin.

Dolayısıyla, son kural şöyle görünür:

cc_library(
    name = "main",
    srcs = glob(
        ["googletest-release-1.10.0/googletest/src/*.cc"],
        exclude = ["googletest-release-1.10.0/googletest/src/gtest-all.cc"]
    ),
    hdrs = glob([
        "googletest-release-1.10.0/googletest/include/**/*.h",
        "googletest-release-1.10.0/googletest/src/*.h"
    ]),
    copts = [
        "-Iexternal/gtest/googletest-release-1.10.0/googletest/include",
        "-Iexternal/gtest/googletest-release-1.10.0/googletest"
    ],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

Bu biraz karmaşıktır: Arşiv yapısının bir yan ürünü olarak her şeyin önüne googletest-release-1.10.0 eklenir. strip_prefix özelliğini ekleyerek http_archive önekinin bu ön eki çıkarmasını sağlayabilirsiniz:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "gtest",
    url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
    sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
    build_file = "@//:gtest.BUILD",
    strip_prefix = "googletest-release-1.10.0",
)

Bu durumda gtest.BUILD şöyle görünür:

cc_library(
    name = "main",
    srcs = glob(
        ["googletest/src/*.cc"],
        exclude = ["googletest/src/gtest-all.cc"]
    ),
    hdrs = glob([
        "googletest/include/**/*.h",
        "googletest/src/*.h"
    ]),
    copts = [
      "-Iexternal/gtest/googletest/include",
      "-Iexternal/gtest/googletest",
    ],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

Artık cc_ kuralları @gtest//:main metriğine bağlı olabilir.

C++ testlerini yazma ve çalıştırma

Örneğin, aşağıdaki gibi bir test ./test/hello-test.cc oluşturabilirsiniz:

#include "gtest/gtest.h"
#include "main/hello-greet.h"

TEST(HelloTest, GetGreet) {
  EXPECT_EQ(get_greet("Bazel"), "Hello Bazel");
}

Daha sonra, testleriniz için ./test/BUILD dosyası oluşturun:

cc_test(
    name = "hello-test",
    srcs = ["hello-test.cc"],
    copts = [
      "-Iexternal/gtest/googletest/include",
      "-Iexternal/gtest/googletest",
    ],
    deps = [
        "@gtest//:main",
        "//main:hello-greet",
    ],
)

hello-greet öğesini hello-test tarafından görünür hale getirmek için ./main/BUILD içinde visibility özelliğine "//test:__pkg__", eklemeniz gerekir.

Artık testi çalıştırmak için bazel test uygulamasını kullanabilirsiniz.

bazel test test:hello-test

Bu, aşağıdaki çıkışı verir:

INFO: Found 1 test target...
Target //test:hello-test up-to-date:
  bazel-bin/test/hello-test
INFO: Elapsed time: 4.497s, Critical Path: 2.53s
//test:hello-test PASSED in 0.3s

Executed 1 out of 1 tests: 1 test passes.

Önceden derlenmiş kitaplıklara bağımlılık ekleme

Yalnızca derlenmiş sürümüne sahip olduğunuz bir kitaplığı kullanmak istiyorsanız (örneğin, başlıklar ve bir .so dosyası) kitaplığı cc_library kuralıyla sarmalayın:

cc_library(
    name = "mylib",
    srcs = ["mylib.so"],
    hdrs = ["mylib.h"],
)

Bu şekilde, çalışma alanınızdaki diğer C++ hedefleri bu kurala bağlı olabilir.