[英]Google test using Bazel error - `symbol not found in flat namespace`
我最近開始學習 C++(來自 Python 背景)和 Bazel 構建系統。 我有一個非常簡單的玩具設置來習慣在 Bazel 上使用 GoogleTest。 這是我的文件 -
我的文件和目錄結構如下——
.
WORKSPACE
main/
shape.cc
shape.h
BUILD
test/
shape_test.cc
BUILD
文件內容如下——
# WORKSPACE file - from http://google.github.io/googletest/quickstart-bazel.html
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_googletest",
urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
)
# main/BUILD
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
package(default_visibility = ["//visibility:public"])
cc_library(
name = "shape",
srcs = ["shape.cc"],
hdrs = ["shape.h"],
)
// main/shape.h
#include <string>
#include <vector>
class AbstractShape
{
protected:
float area;
float perimeter;
std::string shape_name;
public:
float get_area();
void describe();
virtual std::string get_description();
};
AbstractShape factory_method(float h, float w, std::string colour = "", std::string surface = "");
float calculate_area(std::vector<AbstractShape> shape_arr);
class Rectangle : public AbstractShape
{
public:
Rectangle(float h, float w);
std::string get_description();
};
class ColourAndSurfaceRectangle : public AbstractShape
{
private:
std::string colour;
std::string surface;
public:
ColourAndSurfaceRectangle(float h, float w, std::string colour = "", std::string shape = "");
std::string get_description();
};
// main/shape.cc
#include "shape.h"
#include <vector>
#include <string>
#include <iostream>
float calculate_area(std::vector<AbstractShape> shape_arr)
{
float sum = 0;
for (AbstractShape shape : shape_arr)
{
sum += shape.get_area();
}
return sum;
}
float AbstractShape::get_area()
{
return area;
}
void AbstractShape::describe()
{
std::string description = this->get_description();
std::cout << description << std::endl;
}
Rectangle::Rectangle(float h, float w)
{
this->shape_name = "Rectangle";
this->area = h * w;
this->perimeter = 2 * (h + w);
}
std::string Rectangle::get_description()
{
std::string description = "Shape:" + this->shape_name + "\n" +
"Perimeter: " + std::to_string(this->perimeter) + "\n" +
"Area: " + std::to_string(this->area) + "\n";
return description;
}
ColourAndSurfaceRectangle::ColourAndSurfaceRectangle(float h, float w, std::string colour, std::string shape)
{
this->shape_name = "Rectangle";
this->area = h * w;
this->perimeter = 2 * (h + w);
this->colour = colour;
this->surface = surface;
}
std::string ColourAndSurfaceRectangle::get_description()
{
std::string description = "Shape:" + this->shape_name + "\n" +
"Perimeter: " + std::to_string(this->perimeter) + "\n" +
"Area: " + std::to_string(this->area) + "\n";
if (this->colour != "")
{
description += "Colour: " + this->colour + "\n";
}
if (this->surface != "")
{
description += "Surface: " + this->surface + "\n";
}
return description;
}
AbstractShape factory_method(float h, float w, std::string colour, std::string surface)
{
if (colour != "" || surface != "")
{
return ColourAndSurfaceRectangle(h, w, colour, surface);
}
return Rectangle(h, w);
}
最后是測試文件夾
# test/BUILD
cc_test(
name = "shape_test",
size = "small",
srcs = ["shape_test.cc"],
deps = [
"//main:shape",
"@com_google_googletest//:gtest_main",
],
)
// test/shape_test.cc
#include <gtest/gtest.h>
#include "main/shape.h"
#include <string>
TEST(ColourAndSurfaceRectangleTest, ShapeTest)
{
std::string expected_str = "Shape: Rectangle\n"
"Perimeter: 10\n"
"Area: 6\n"
"Colour: Blue\n"
"Surface: Stained\n";
AbstractShape shape = factory_method(3, 2, "Blue", "Stained");
EXPECT_EQ(shape.get_description(), expected_str);
}
我現在運行以下命令 - bazel test --test_output=all //test:shape_test
,但我得到了這個無法辨認的錯誤 -
INFO: From Testing //test:shape_test:
==================== Test output for //test:shape_test:
dyld[37648]: symbol not found in flat namespace (__ZTV13AbstractShape)
================================================================================
“找不到符號”是什么意思? 以前有人在 macOS 上遇到過與 Bazel/cpp 類似的問題嗎?
該錯誤意味着並非所有虛擬方法都已定義。 確切的一個虛擬AbstractShape::get_description
未定義。 我猜從類名來看,成員函數一定是純虛的
virtual std::string get_description() = 0;
// ^
該類必須具有虛擬析構函數
virtual ~AbstractShape() = default;
謝謝。 原來我缺少一個虛擬析構函數,而且我沒有將成員函數設為純虛擬。
這是有效的最終 cpp 文件 -
#include "shape.h"
#include <vector>
#include <string>
#include <iostream>
#include <cmath>
#include "fmt/core.h"
float calculate_area(std::vector<AbstractShape *> shape_arr)
{
float sum = 0;
for (AbstractShape *shape : shape_arr)
{
sum += shape->get_area();
}
return sum;
}
float AbstractShape::get_area()
{
return area;
}
void AbstractShape::describe()
{
std::string description = this->get_description();
std::cout << description << std::endl;
}
Rectangle::Rectangle(float h, float w)
{
this->shape_name = "Rectangle";
this->area = h * w;
this->perimeter = 2 * (h + w);
}
std::string Rectangle::get_description()
{
std::string description = "Shape:" + this->shape_name + "\n" +
"Perimeter: " + fmt::format("{:.2f}", this->perimeter) + "\n" +
"Area: " + fmt::format("{:.2f}", this->area) + "\n";
return description;
}
ColourAndSurfaceRectangle::ColourAndSurfaceRectangle(float h, float w, std::string colour, std::string surface)
{
this->shape_name = "Rectangle";
this->area = h * w;
this->perimeter = 2 * (h + w);
this->colour = colour;
this->surface = surface;
}
std::string ColourAndSurfaceRectangle::get_description()
{
std::string description = "Shape:" + this->shape_name + "\n" +
// "Perimeter:" + std::to_string(this->perimeter) + "\n" +
"Perimeter:" + fmt::format("{:.2f}", this->perimeter) + "\n" +
"Area:" + fmt::format("{:.2f}", this->area) + "\n";
if (this->colour != "")
{
description += "Colour:" + this->colour + "\n";
}
if (this->surface != "")
{
description += "Surface:" + this->surface + "\n";
}
return description;
}
AbstractShape *factory_method(float h, float w, std::string colour, std::string surface)
{
if (colour != "" || surface != "")
{
return new ColourAndSurfaceRectangle(h, w, colour, surface);
}
return new Rectangle(h, w);
}
和頭文件 -
#ifndef MAIN_SHAPE_H_
#define MAIN_SHAPE_H_
#include <string>
#include <vector>
class AbstractShape
{
protected:
float area;
float perimeter;
std::string shape_name;
public:
float get_area();
void describe();
virtual std::string get_description() = 0;
virtual ~AbstractShape() = default;
};
AbstractShape *factory_method(float h, float w, std::string colour = "", std::string surface = "");
float calculate_area(std::vector<AbstractShape*> shape_arr);
class Rectangle : public AbstractShape
{
public:
Rectangle(float h, float w);
std::string get_description();
};
class ColourAndSurfaceRectangle : public AbstractShape
{
private:
std::string colour;
std::string surface;
public:
ColourAndSurfaceRectangle(float h, float w, std::string colour = "", std::string shape = "");
std::string get_description();
};
#endif
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.