我正在使用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",
)
myAPI:
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"],
)
libigl:
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "libigl",
hdrs = glob(["**/*.h*", "**/*.c*"]),
copts = ["-w", "-O3", "-pthread"],
visibility = ["//visibility:public"],
)
geoCentral:
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"],
)
openCV:
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",
],
)
spdLog:
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "spdlog",
hdrs = glob(["include/**/*.h"]),
includes = ["include"],
visibility = ["//visibility:public"],
)
libpng:
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++中可以正确编译,所以它必须是设置正确的链接选项的问题?
我终于找到了一个解决方案:
不出所料,有不止一个问题,包括以下内容:
-
Emscripten在编译与我使用的openCV 3.1.0一起发布的libpng版本时不喜欢c++2a标准。因此,我最终使用g++编译
-std=c++2a
,而使用emcc (emscripten)编译时不使用它。 -
类似的情况也适用于g++要求的链接器选项
-lpng -lz
(按此顺序),而emcc不需要。 -
此外,emscripten在编译zlib时需要一个链接器标志(这在我的情况下是一个依赖项):
-s USE_ZLIB=1
.
我希望这对你有帮助,祝你的项目顺利…