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

t40tm48m  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(86)

我正在做一个依赖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"
  ]
)

8fsztsew

8fsztsew1#

我不知道是否有一些优雅的方式告诉bazel自己执行wx-config,但在最坏的情况下,您可以将wx-config --cxxflags的输出复制并粘贴到includes赋值中(对于--libs也是如此)。

knsnq2tg

knsnq2tg2#

回答这个问题的困难在于,wxwidgets提供了一种开箱即用的编译和链接方法,这与Bazel的哲学背道而驰。步骤有很大的不同,这取决于你的平台。从本质上讲,当您安装wxwidgets时,无论是从源代码编译还是从预制的OS包编译,它都附带了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时,我们需要将以下repos添加到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,但我希望这个示例可以帮助您入门。

相关问题