Reputation: 61
I'm trying to use Bazel to build a cpp project that use Flatbuffers.
But my map_schema_generated.h
generated with flatc
is not found.
My tree:
|
|_ data
| |_ maps
| |_ BUILD
| |_ map_schema.fbs
|
|_ src
| |_ map
| |_ BUILD
| |_ map.hpp
| |_ map.cpp
|
|_ tools
| |_ BUILD
| |_ generate_fbs.bzl
|
|_ WORKSPACE
tools/generate_fbs.bzl
:
def _impl(ctx):
output = ctx.outputs.out
input = ctx.files.srcs
print("generating", output.basename)
ctx.action(
use_default_shell_env = True,
outputs = [output],
inputs = input,
progress_message="Generating %s with %s" % (output.path, input[0].path),
command="flatc -o %s --cpp %s" % (output.dirname, input[0].path)
)
generate_fbs = rule(
implementation=_impl,
output_to_genfiles = True,
attrs={
"srcs": attr.label_list(allow_files=True, allow_empty=False),
"out": attr.output()
},
)
data/maps/BUILD
:
load("//tools:generate_fbs.bzl", "generate_fbs")
generate_fbs(
name = "schema",
srcs = ["map_schema.fbs"],
out = "map_schema_generated.h",
visibility = ["//visibility:public"]
)
src/map/BUILD
:
cc_library(
name = "map",
srcs = [
"//data/maps:map_schema_generated.h",
"map.hpp",
"map.cpp"
]
)
src/map/map.cc
has #include "map_schema_generated.h"
.
The command line I use to build: bazel build //src/map
.
If I find
in bazel-*
, I got:
bazel-genfiles/data/maps/map_schema_generated.h
bazel-out/k8-fastbuild/genfiles/data/maps/map_schema_generated.h
bazel-my-workspace-name/bazel-out/k8-fastbuild/genfiles/data/maps/map_schema_generated.h
And if I cat
these files, I can see that they are well generated.
All the information that I found are about Tensorflow
, and are not really helpful.
Best regards,
Upvotes: 3
Views: 1941
Reputation: 9664
The problem is that your cc_library
actually doesn't really recognize your generated header as requiring any special action (like adding -I
flag for the location it's in). It gets generate and lives in the build tree, but not anywhere the compiler (preprocessor) would look for it working on map.cpp
. (Run build with -s
for a bit more insight about what and how happened).
Now about how to address this, there might be a better way, but this would appear to work. I guess this functionality could also be rolled into generate_fbs
rule.
In data/maps/BUILD
I've added "header only" library as follows:
cc_library(
name = "map_schema_hdr",
hdrs = [":map_schema_generated.h"],
include_prefix = ".", # to manipulate -I of dependenices
visibility = ["//visibility:public"]
)
In src/map/BUILD
I would then use this header only library as dependency of map
:
cc_library(
name = "map",
srcs = [
"map.cpp"
"map.hpp"
],
deps = [
"//data/maps:map_schema_hdr",
]
)
To play a bit more with the idea of having a single rule (macro) for convenience, I've made the following changes:
tools/generate_fbs.bzl
now reads:
def _impl(ctx):
output = ctx.outputs.out
input = ctx.files.srcs
print("generating", output.basename)
ctx.action(
use_default_shell_env = True,
outputs = [output],
inputs = input,
progress_message="Generating %s with %s" % (output.path, input[0].path),
command="/bin/cp %s %s" % (input[0].path, output.path)
)
_generate_fbs = rule(
implementation=_impl,
output_to_genfiles = True,
attrs={
"srcs": attr.label_list(allow_files=True, allow_empty=False),
"out": attr.output()
},
)
def generate_fbs(name, srcs, out):
_generate_fbs(
name = "_%s" % name,
srcs = srcs,
out = out
)
native.cc_library(
name = name,
hdrs = [out],
include_prefix = ".",
visibility = ["//visibility:public"],
)
With that, I could have data/maps/BUILD
:
load("//tools:generate_fbs.bzl", "generate_fbs")
generate_fbs(
name = "schema",
srcs = ["map_schema.fbs"],
out = "map_schema_generated.h",
)
And src/map/BUILD
contains:
cc_library(
name = "map",
srcs = [
"map.cpp",
"map.hpp",
],
deps = [
"//data/maps:schema",
]
)
And bazel build //src/map
builds bazel-bin/src/map/libmap.a
and bazel-bin/src/map/libmap.so
.
Upvotes: 3
Reputation: 61
Instead of #include "map_schema_generated.h"
in src/map/map.cpp
, I could have write `#include "data/maps/map_schema_generated.h".
I think it is the cleanest way to make it works.
Upvotes: 2