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

Sorun bildir Kaynağı görüntüle Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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 Introduction to Bazel: Build a C++ Project (Bazel'e Giriş: C++ Projesi Oluşturma) adlı eğitime katılarak Bazel ile C++ projeleri oluşturmaya başlayın.

cc_library ve hdrs üstbilgi dosyaları hakkında bilgi edinmek için cc_library başlıklı makaleyi inceleyin.

Bir hedefe birden fazla dosya ekleme

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

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

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

Geçişli dahil etme işlemlerini kullanma

Bir dosya üstbilgi içeriyorsa bu dosyayı kaynak olarak kullanan tüm kurallar (yani srcs, hdrs veya textual_hdrs özelliğinde bu dosyanın bulunduğu kurallar) eklenen üstbilginin kitaplık kuralına bağlı olmalıdır. Buna karşılık, yalnızca doğrudan bağımlılıklar bağımlılık olarak belirtilmelidir. Örneğin, sandwich.h'nın bread.h'ı ve bread.h'ın flour.h'ı içerdiğini varsayalım. sandwich.h içermiyor (sandviçinde un isteyen olur mu?), bu nedenle BUILD dosyası şöyle görünür:flour.h

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ığı, bread kitaplığına, bread kitaplığı ise flour kitaplığına bağlıdır.

Dahil etme yolları ekleme

Bazen yolları çalışma alanı köküne dahil edemezsiniz (veya dahil etmek 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 eklenmesini bekler ancak some_lib.cc öğesinin "some_lib.h" içerdiğini varsayalım. Bu include yolunun geçerli olması için legacy/some_lib/BUILD, some_lib/include dizininin bir include dizini olduğunu belirtmelidir:

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

Bu, özellikle harici bağımlılıklar için kullanışlıdır. Aksi takdirde, bunların başlık dosyaları / önekiyle birlikte eklenmelidir.

Harici kitaplıklar dahil

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 bir gtest.BUILD BUILD dosyası oluşturun. Google Test'in, cc_library kuralını daha karmaşık hale getiren çeşitli "özel" şartları vardır:

  • googletest-release-1.10.0/src/gtest-all.cc #includes all other files in googletest-release-1.10.0/src/: exclude it from the compile to prevent link errors for duplicate symbols.

  • googletest-release-1.10.0/include/ dizinine ("gtest/gtest.h") göre olan başlık dosyalarını kullandığından bu dizini include yollarına eklemeniz gerekir.

  • pthread ile bağlantı oluşturması gerekiyor. Bu nedenle, pthread'yı linkopt olarak ekleyin.

Bu nedenle, nihai 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şık bir durumdur: Arşivin 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 ön ekini kaldırabilirsiniz:

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'e 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 özelliğinin hello-test tarafından görünür olması için ./main/BUILD içindeki 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 aşağıdaki çı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ş bir sürümüne sahip olduğunuz bir kitaplığı (örneğin, başlıklar ve bir .so dosyası) kullanmak istiyorsanız bunu bir cc_library kuralına sarın:

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

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