1

我正在使用 Bazel 构建一个系统,其中我有一个 c++ 目标和一个 emscirpten (emcc) 目标来编译为 Web 程序集。两者都依赖于“myAPI”,它具有外部依赖项 libpng、libz、opencv 和其他一些。

这可以正确编译:

# Development
cc_binary(
    name = "devMain",
    srcs = ["dev/main.cpp"],
    copts = [
        "-w",
        "-g",
        "-O3",
        "--std=c++2a",
        "-pthread",
        "-Iinclude/",
        "-Iexternal/geometryCentralRepo/include",
        "-Iexternal/eigenRepo",
        "-DBUILD_VERSION=devMain",
        ],
    deps = [
        ":myAPI",
    ],
    linkopts = ["-lpthread"],
)

但是,这失败了:

DEFAULT_EMSCRIPTEN_LINKOPTS = [
    "-s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']",
    "-s ALLOW_MEMORY_GROWTH=1",     # Our example doesn't need memory growth
    "-s ASSERTIONS=1",              # Turn off assertions
    "-s EXPORT_ES6=1",              # Export as es6 module, used for rollup
    "-s MODULARIZE=1",              # Allows us to manually invoke the initialization of wasm
    "-s EXPORT_NAME=myAPI",    # Not used, but good to specify
    "-s USE_ES6_IMPORT_META=0",     # Disable loading from import meta since we use rollup
    "-s EXPORT_ALL=1",
    "-s USE_PTHREADS=1",
    "-s ENVIRONMENT=worker",
    "-DNDEBUG",
]

WASM_LINKOPTS = [
    "-s WASM=1",
    "--bind",                    # Specify wasm output
]

cc_binary(
    name = "myAPI.js",
    srcs=["src/myAPI/WASM_bindings.cpp"],
    copts = [
        "-g",
        "-O3",
        "--std=c++2a",
        "-pthread",
        "-Iinclude/",
        ],
    linkopts = DEFAULT_EMSCRIPTEN_LINKOPTS + WASM_LINKOPTS,
    deps = [
        ":myAPI",
    ],

)

wasm_cc_binary(
    name = "setupModel-wasm",        
    cc_target = ":myAPI.js",
)

这是我的API:

cc_library(
    name = "myAPI",
    srcs = glob(["src/**/*.c*"], exclude=["src/myAPI/WASM_bindings.cpp"]),
    hdrs = glob(["include/**/*.h*"]),
    copts = [
        "-w",
        "-g",
        "-O3",
        "--std=c++2a",
        "-pthread",
        "-Iinclude",
        "-Iexternal/geometryCentralRepo/include",
        "-Iexternal/spdlogRepo/include",
        "-Iexternal/libiglRepo/include", 
        "-Iexternal/openCVRepo/include", 
        "-Iexternal/eigenRepo",
        ],
    deps = [
        "@eigenRepo//:eigen",
        "@libiglRepo//:libigl",
        "@geometryCentralRepo//:geoCentral",
        "@openCVRepo//:opencv_core",
        "@openCVRepo//:opencv_imgcodecs",
        "@spdlogRepo//:spdlog",
        "@libpngRepo//:libpng"
    ],      
    visibility = ["//visibility:public"],
)

最后,这些是所有依赖项:

特征:

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "eigen",
    hdrs =  glob(["Eigen/**", "unsupported/**"]),
    copts = ["-w", "-O3", "-pthread"],
    visibility = ["//visibility:public"],
)

图书馆:

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "libigl",
    hdrs =  glob(["**/*.h*", "**/*.c*"]),
    copts = ["-w", "-O3", "-pthread"],
    visibility = ["//visibility:public"],
)

地理中心:

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "geoCentral",
    srcs = glob(["src/**/*.cpp"], 
    exclude=["src/utilities/unit_vector3.cpp", "src/surface/mesh_ray_tracer.cpp", "src/surface/detect_symmetry.cpp"]),
    hdrs = glob(["**/*.h", "**/*.ipp"]),
    copts = [
    "-w",
    "-O3",
    "-pthread",
    "-Iexternal/geometryCentralRepo/include", 
    "-Iexternal/geometryCentralRepo/deps", 
    "-Iexternal/geometryCentralRepo/src",
    "-Iexternal/geometryCentralRepo",
    "-Iexternal/geometryCentralRepo/deps/nanort/include",
    "-Iexternal/geometryCentralRepo/deps/happly", 
    "-Iexternal/eigenRepo", 
    "-Iexternal/nanoflann",
    "-Iexternal",
    "-Iexternal/happlyRepo/"],
    deps = ["@eigenRepo//:eigen", "@nanoflann//:nanoflann", "@happlyRepo//:happly"],
    visibility = ["//visibility:public"],
)

开放式简历:

load("@rules_cc//cc:defs.bzl", "cc_library")

package(default_visibility = ["//visibility:private"])


cc_library(
    name = "opencv_core",
    srcs = glob([
        "modules/core/src/**/*.cpp",
        "modules/core/src/**/*.hpp",
        "modules/core/include/**/*.hpp",
        "modules/core/include/**/*.h",
    ]) + [
        "custom_hal.hpp",
        "cvconfig.h",
        "opencl_kernels_core.hpp",
        "opencv2/opencv_modules.hpp",
        "version_string.inc",
    ],
    hdrs = ["modules/core/include/opencv2/core/opencl/ocl_defs.hpp"],
    copts = [
        "-D__OPENCV_BUILD",
        "-Iexternal/zlib",
    ],
    includes = [
        ".",
        "modules/core/include",
    ],
    linkopts = [
        "-ldl",
    ] + select({
        ":arm": ["-llog"],
        "//conditions:default": ["-lpthread"],
    }),
    visibility = ["//visibility:public"],
    deps = [
        "@zlibRepo//:zlib",
    ],
)

genrule(
    name = "opencv_core_kernels",
    outs = ["opencl_kernels_core.hpp"],
    cmd = """
      echo '#include "opencv2/core/ocl.hpp"' > $@
      echo '#include "opencv2/core/ocl_genbase.hpp"' > $@
      echo '#include "opencv2/core/opencl/ocl_defs.hpp"' > $@
    """,
)

genrule(
    name = "cvconfig",
    srcs = select({
        ":arm": ["cvconfig_android.h"],
        "//conditions:default": ["cvconfig_linux.h"],
    }),
    outs = ["cvconfig.h"],
    cmd = "cp $< $@",
)

genrule(
    name = "cvconfig_linux",
    outs = ["cvconfig_linux.h"],
    cmd = """
      echo '#define HAVE_PNG' >> $@
    """,
)

genrule(
    name = "cvconfig_android",
    outs = ["cvconfig_android.h"],
    cmd = """
      echo '#define HAVE_PNG' >> $@
      echo '#define ANDROID' >> $@
    """,
)

genrule(
    name = "custom_hal",
    outs = ["custom_hal.hpp"],
    cmd = "touch $@",
)

genrule(
    name = "version_string",
    outs = ["version_string.inc"],
    cmd = "echo '\"OpenCV 3.1.0\"' > $@",
)

genrule(
    name = "opencv_modules",
    outs = ["opencv2/opencv_modules.hpp"],
    cmd = """
        echo '#define HAVE_OPENCV_CORE' >> $@
        echo '#define HAVE_OPENCV_IMGCODECS' >> $@
        echo '#define HAVE_OPENCV_IMGPROC' >> $@
        echo '#define HAVE_OPENCV_ML' >> $@
        echo '#define HAVE_OPENCV_VIDEOIO' >> $@
    """,
)

cc_library(
    name = "opencv_imgproc",
    srcs = glob([
        "modules/imgproc/src/**/*.cpp",
        "modules/imgproc/src/**/*.hpp",
        "modules/imgproc/src/**/*.h",
        "modules/imgproc/include/**/*.hpp",
        "modules/imgproc/include/**/*.h",
    ]) + ["opencl_kernels_imgproc.hpp"],
    copts = ["-D__OPENCV_BUILD"],
    includes = [
        ".",
        "modules/core/include",
        "modules/imgproc/include",
    ],
    visibility = ["//visibility:public"],
    deps = [":opencv_core"],
)

genrule(
    name = "opencv_imgproc_kernels",
    outs = ["opencl_kernels_imgproc.hpp"],
    cmd = """
      echo '#include "opencv2/core/ocl.hpp"' > $@
      echo '#include "opencv2/core/ocl_genbase.hpp"' > $@
      echo '#include "opencv2/core/opencl/ocl_defs.hpp"' > $@
    """,
)

cc_library(
    name = "opencv_ml",
    srcs = glob([
        "modules/ml/src/**/*.cpp",
        "modules/ml/src/**/*.hpp",
        "modules/ml/include/**/*.hpp",
    ]),
    copts = ["-D__OPENCV_BUILD"],
    includes = ["modules/ml/include"],
    visibility = ["//visibility:public"],
    deps = [":opencv_core"],
)

cc_library(
    name = "opencv_imgcodecs",
    srcs = glob([
        "modules/imgcodecs/src/**/*.cpp",
        "modules/imgcodecs/src/**/*.hpp",
        "modules/imgcodecs/include/**/*.hpp",
        "modules/imgcodecs/include/**/*.h",
    ]),
    copts = [
        "-D__OPENCV_BUILD",
        "-Iexternal/libpng_http",
        "-Iexternal/libpng",
        "-Iexternal/zlib",
    ],
    includes = [
        "modules/imgcodecs/include",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":opencv_core",
        ":opencv_imgproc",
        "@libpngRepo//:libpng",
        "@zlibRepo//:zlib",
    ],
)

spd日志:

load("@rules_cc//cc:defs.bzl", "cc_library")

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

库:

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "libpng",
    srcs = glob(["*.c"]), 
    hdrs = glob(["*.h"]),
    copts = [
    "-w",
    "-O3",
    "-pthread",
    "-Iexternal",
    ],
    includes = [
        ".",
    ],
    linkopts = [
        "-lpng", 
        "-lz",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "@zlibRepo//:zlib",
    ],
)

zLib:

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "zlib",
    srcs = glob(["*.cpp"]), 
    hdrs = glob(["*.h"]),
    copts = [
    "-w",
    "-O3",
    "-pthread",
    "-Iexternal",
    ],
    visibility = ["//visibility:public"],
)

我收到一堆包含错误,例如: 致命错误:找不到'pnglibconf.h'文件

据我了解,这是一个链接器问题,其中“pnglibconf.h”应该由编译器创建并编译到链接器应该能够链接的库中。

特别奇怪的是,唯一的依赖“:myAPI”用g++正确编译,所以一定是设置正确的linkoptions的问题?

任何帮助将不胜感激!

谢谢,

4

1 回答 1

1

我终于找到了解决方案:

不出所料,问题不止一个,包括:

  1. 在编译与我正在使用的 openCV 3.1.0 一起提供的 libpng 版本时,Emscripten 不喜欢 c++2a 标准。因此,我最终-std=c++2a使用 g++ 进行编译,而在使用 emcc (emscripten) 进行编译时没有使用它。

  2. 链接器选项也有类似的情况,其中 g++ 需要 -lpng -lz(按此顺序),而 emcc 什么都不需要。

  3. 此外,emscripten在编译 zlib 时需要-s USE_ZLIB=1一个链接器标志(在我的情况下这是一个依赖项) :.

我希望这会有所帮助,也祝你的项目好运......

于 2021-09-29T19:32:39.187 回答