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

Sorun bildirin Kaynağı göster

Burada, Bazel ile C++ projeleri oluşturmaya yönelik en yaygın kullanım alanlarından bazılarını bulabilirsiniz. Henüz yapmadıysanız Bazel'e giriş: C++ projesi oluşturma konulu eğitimi tamamlayarak Bazel ile C++ projeleri oluşturmaya başlayın.

cc_library ve hdrs üstbilgisi dosyaları hakkında bilgi için cc_library sayfasına göz atın.

Bir hedefe birden fazla 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 (alt dizinler hariç) aynı dizinde oluşturur.

Geçişli dahil etme özelliğini kullanma

Bir dosyada başlık varsa kaynak olarak bu dosyayı içeren tüm kurallar (yani o dosyayı srcs, hdrs veya textual_hdrs özelliğinde içeren) başlık, dahil edilen başlığın kitaplık kuralına bağlı olmalıdır. Öte yandan, sadece doğrudan bağımlılıklar bağımlılık olarak belirtilmelidir. Örneğin, sandwich.h öğesinin bread.h içerdiğini ve bread.h öğesinin flour.h içerdiğini varsayalım. sandwich.h flour.h (kim sandviçinde un istiyor?) içermez. Bu nedenle BUILD dosyası şu şekilde 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ı

Bazen, çalışma alanı kökündeki yollar için root erişimi sağlayamazsınız (veya bunu yapmak istemezsiniz). Mevcut kitaplıklarda, çalışma alanınızdaki yoluyla eşleşmeyen bir "include" dizini 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 dahil edilmesini bekleyecek ancak some_lib.cc öğesinin "some_lib.h" içerdiğini varsayalım. Bu dahil etme yolunun geçerli olması için legacy/some_lib/BUILD, 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"],
)

Başlık dosyalarının aksi halde bir / önekiyle eklenmesi gerektiğinden bu, özellikle harici bağımlılıklar için yararlıdır.

Harici kitaplıklar ekleme

Google Test'i kullandığınızı varsayalım. Google Test'i indirip deponuzda kullanılabilir hale getirmek 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ını gtest.BUILD oluşturun. Google Test'in, cc_library kuralını daha karmaşık hale getiren bazı "özel" gereksinimleri vardır:

  • googletest-release-1.10.0/src/gtest-all.cc, googletest-release-1.10.0/src/ içindeki diğer tüm dosyaları #includes: yinelenen simgelerle ilgili bağlantı hatalarını önlemek için bu dosyaları derlemeden hariç tutun.

  • googletest-release-1.10.0/include/ dizini ("gtest/gtest.h") ile göreli başlık dosyaları kullanır. Bu nedenle, bu dizini dahil etme yollarına eklemeniz gerekir.

  • pthread içinde bağlanması gerekiyor. Bunu linkopt olarak ekleyin.

Dolayısıyla son kural şu şekilde görünür:

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

Bu, biraz karmaşıktır: Arşiv yapısının bir sonucu olarak her şeyin önünde googletest-release-1.10.0 bulunur. strip_prefix özelliğini ekleyerek http_archive ürününün bu ön eki göstermesini 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(
        ["src/*.cc"],
        exclude = ["src/gtest-all.cc"]
    ),
    hdrs = glob([
        "include/**/*.h",
        "src/*.h"
    ]),
    copts = ["-Iexternal/gtest/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

Artık cc_ kuralları @gtest//:main kaynağına bağlı olabilir.

C++ testleri 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");
}

Ardından testleriniz için ./test/BUILD dosyası oluşturun:

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

hello-greet öğesinin hello-test tarafından görülebilmesini sağlamak için ./main/BUILD öğesindeki visibility özelliğine "//test:__pkg__", eklemeniz gerekir.

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

bazel test test:hello-test

Bu işlem şu çıkışı üretir:

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ığı (örneğin, başlıklar ve .so dosyası) kullanmak istiyorsanız kitaplığı bir cc_library kuralına 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.