如何使用 bazel C++ 添加 wxWidgets 作为依赖项

问题描述 投票:0回答:2

我正在开发一个依赖于 wxWidgets 的 C++ 项目。

我可以使用 wxWidgets 文档中的以下 Makefile 来编译应用程序:

PROGRAM = App
 
OBJECTS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))

# implementation

.SUFFIXES:      .o .cpp

.cpp.o :
    $(CXX) -O2 -g -c `wx-config --cxxflags` -o $@ $<

all:    $(PROGRAM)

$(PROGRAM):    $(OBJECTS)
    $(CXX) -O2 -g -o $(PROGRAM) $(OBJECTS) `wx-config --libs`

clean:
    rm -f *.o $(PROGRAM)

但是,我决定尝试 bazel 作为我的构建系统。

我在运行 `bazel build //src:app --verbose_failures:

时收到以下错误
In file included from external/wx/wx/defs.h:45,
                 from external/wx/wx/memory.h:14,
                 from external/wx/wx/object.h:19,
                 from external/wx/wx/utils.h:18,
                 from external/wx/wx/thrimpl.cpp:344:
external/wx/wx/platform.h:159:10: fatal error: wx/setup.h: No such file or directory
  159 | #include "wx/setup.h"
      |          ^~~~~~~~~~~~

这是我的

WORKSPACE
文件:

new_local_repository(
  name="wx",
  path="/usr/include/wx-3.2",

  build_file_content = """
package(default_visibility = ["//visibility:public"])
cc_library(
    name = "headers",
    hdrs = glob(["**/*.h"]),
    srcs = glob(["**/*.cpp"]),
    includes = ["/usr/include/wx-3.2"],
)
"""
)

new_local_repository(
  name="gtk-unicode",
  path="/usr/lib/wx/include/gtk3-unicode-3.2",

  build_file_content = """
package(default_visibility = ["//visibility:public"])
cc_library(
    name = "headers",
    hdrs = glob(["**/*.h"])
)
"""
)

src/BUILD

cc_library(
  name="agent",
  srcs=["Agent.cpp"],
  hdrs=["Agent.h"],
  deps=[":game"]
)

cc_library(
  name="game",
  srcs=["Game.cpp"],
  hdrs=["Game.h"],
)

cc_binary(
  name="app",
  srcs=["App.cpp"],
  deps=[":agent", ":game", "@wx//:headers", "@gtk-unicode//:headers"],
  copts=[
    "-Iexternal/wx",
    "-Iexternal/gtk-unicode",
    "-DWXUSINGDLL",
    "-D__WXGTK3__",
    "-D__WXGTK__",
    "-pthread",
    "-lwx_gtk3u_xrc-3.2",
    "-lwx_gtk3u_html-3.2",
    "-lwx_gtk3u_qa-3.2",
    "-lwx_gtk3u_core-3.2",
    "-lwx_baseu_xml-3.2",
    "-lwx_baseu_net-3.2",
    "-lwx_baseu-3.2"
  ]
)
c++ wxwidgets bazel
2个回答
0
投票

我不知道是否有一些优雅的方法告诉 bazel 自己执行

wx-config
,但在最坏的情况下,你可以将
wx-config --cxxflags
的输出复制并粘贴到
includes
赋值中(
--libs
也是一样)。


0
投票

回答这个问题的困难在于,wxwidgets 提供了一种开箱即用的编译和链接方式,这违背了 Bazel 的理念。根据您所在的平台,步骤有很大不同。本质上,当您安装 wxwidgets 时,无论是从源代码还是从预制操作系统包进行编译,它都会附带 wx-config 实用程序,该实用程序将通过 shell 命令生成编译器工作所需的标志。

然而,在 Bazel 中,您需要向 Bazel 本身声明源、标头和定义,然后它会推导出编译器标志。为了使其工作,您需要推断 wx-config 生成的标志在您的平台中意味着什么,然后将它们写入 Bazel 中。这是我在 Ubuntu 22.04 中对 wxwidgets 包所做的操作。

wx-config --cxxflags 的输出是:

-I/usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread

请注意,有两个包含文件夹、三个定义和 -pthread 编译器选项。对于 wx-config --libs 我们有:

-L/usr/lib/x86_64-linux-gnu -pthread   -lwx_gtk3u_xrc-3.0 -lwx_gtk3u_html-3.0 -lwx_gtk3u_qa-3.0 -lwx_gtk3u_adv-3.0 -lwx_gtk3u_core-3.0 -lwx_baseu_xml-3.0 -lwx_baseu_net-3.0 -lwx_baseu-3.0

这里我们只有一个库文件夹,Linux 中的标志 -lfoo 会转换为 libfoo.so。

无论如何,当我们将其转换为 Bazel 时,我们需要将以下存储库添加到 WORKSPACE 文件中:

new_local_repository(
    name = "wxheaders",
    build_file = "wxheaders.BUILD",
    path = "/usr/include/wx-3.0",
)

new_local_repository(
    name = "wxwidgets",
    build_file = "wxwidgets.BUILD",
    path = "/usr/lib/x86_64-linux-gnu",
)

对于 wxheaders.BUILD 文件,将您可以在文件夹中找到的所有标头放入:

cc_library(
   name = "wxheaders",
   hdrs = glob(["**"]),
   includes = ["."],
   visibility = ["//visibility:public"],
)

对于wxwidgets.BUILD文件,我们有头文件和共享库,我们可以使用

cc_library(
    name = "wxwidgets",
    srcs = [
        "libwx_gtk3u_xrc-3.0.so",
        "libwx_gtk3u_html-3.0.so",
        "libwx_gtk3u_qa-3.0.so",
        "libwx_gtk3u_adv-3.0.so",
        "libwx_gtk3u_core-3.0.so",
        "libwx_baseu_xml-3.0.so",
        "libwx_baseu_net-3.0.so",
        "libwx_baseu-3.0.so",
    ],
    hdrs = glob(["wx/include/gtk3-unicode-3.0/**"]),
    includes = [
        "wx/include/gtk3-unicode-3.0",
    ],
    defines = [
        "_FILE_OFFSET_BITS=64",
        "WXUSINGDLL",
        "__WXGTK__",
    ],
    linkopts = ["-pthread"],
    deps = [
        "@wxheaders//:wxheaders",
    ],
    visibility = ["//visibility:public"],
)

最后,当您要构建二进制文件时,请在 copts 中添加缺少的 -pthread (我们无法将其添加到依赖项中,因为它不会传播)。 BUILD 文件应如下所示:

cc_binary(
    name = "main",
    srcs = ["main.cpp"],
    copts = [
        "-pthread"
    ],
    deps = [
        "@wxwidgets//:wxwidgets",
    ],
)

另一种选择是在 .bazelrc 文件中添加 -pthread copt(如果您同意在整个项目中使用它)。有几种方法可以解决这个问题。

如前所述,具体步骤很大程度上取决于您的操作系统以及wxwidgets的安装方式,但我希望这个示例可以帮助您入门。

© www.soinside.com 2019 - 2024. All rights reserved.