I am building a system using Bazel where I have a C++ target and an emscirpten (emcc) target to compile to web assembly. Both depend on "myAPI", which has external dependencies libpng, libz, opencv and some others.
This compiles properly:
# 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"],
)
However, this fails:
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",
)
Here is 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"],
)
Finally, these are all the dependencies:
eigen:
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"],
)
I am getting a bunch of include errors, like: fatal error: 'pnglibconf.h' file not found
As far as I understand, this is a linker issue, where 'pnglibconf.h' should have been created by the compiler and compiled into a library that the linker should be able to link.
What is particularly strange is that ":myAPI", which is the only dependency, compiles properly with g++, so it must be a matter of setting the correct linkoptions?