I am a programmer in an auto-driving company. We use ImGui to draw HMI interface. ImGui's Docking branch is in BETA. We want to use the Docking branch in local testing, and released version branch in online.
We use bazel to build project. How to coexist 2 branches in our project and easy to switch? When compiling online version, type bazel build all. When compiling local testing version, type something like this bazel build all --use_imgui_docking_branch?
Can bazel achive this requirement?
I worked out.
Add imgui_docking in WORKSPACE
http_archive(
name = "imgui_docking",
build_file = "#//:third_party/imgui_docking.BUILD",
sha256 ="...",
strip_prefix = "...",
urls = [...],
)
Use select in cc_library
config_setting(
name = "imgui_docking",
values = {"define": "imgui=docking"},
)
cc_library(
name = "...",
srcs = [...],
hdrs = [...],
deps = [...]
+ select({
"imgui_docking" : [ "#imgui_docking" ],
"//conditions:default" : [ "#imgui" ]
}),
defines = select({
"imgui_docking" : [ "IMGUI_DOCKING" ],
"//conditions:default" : []
}),
)
Use macro control include in header
#ifdef IMGUI_DOCKING
#include "imgui_docking/imgui.h"
#include "imgui_docking/imgui_internal.h"
#else
#include "imgui/imgui.h"
#include "imgui/imgui_internal.h"
#endif
When compiling add --define
--define docking=imgui
Related
I'm trying to build a hello_world cc_grpc_library using bazel 6.0.0 on Ubuntu 22.04, but I'm unable to do so.
Source tree:
WORKSPACE
MODULE.bazel
BUILD
helloworld.proto
.bazelrc
.bazelversion
My WORKSPACE file is empty. WORKSPACE.bzlmod does not exist.
MODULE.bazel contains:
module(name = "helloworld", version = "1.0")
bazel_dep(name = "grpc", version = "1.47.0", repo_name = "com_github_grpc_grpc")
BUILD contains:
load("#rules_proto//proto:defs.bzl", "proto_library")
load("#com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
load("#com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
load("#com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
grpc_deps()
grpc_extra_deps()
proto_library(
name = "helloworld_proto",
srcs = ["helloworld.proto"],
)
cc_proto_library(
name = "helloworld_cc_proto",
deps = [":helloworld_proto"],
)
cc_grpc_library(
name = "helloworld_cc_grpc",
srcs = [":helloworld_proto"],
grpc_only = True,
deps = [":helloworld_cc_proto"],
)
helloworld.proto is a copy of gRPC's helloworld.proto
When I type bazel build :helloworld_cc_grpc I get the following error and don't know how to solve it:
...external/grpc~1.47.0/bazel/grpc_deps.bzl", line 23, column 11, in grpc_bind_deps
native.bind(
Error: no native function or rule 'bind'
Available attributes: aar_import, action_listener, alias, android_binary, android_device, android_device_script_fixture, android_host_service_fixture, android_instrumentation_test, android_library, android_local_test, android_sdk, android_tools_defaults_jar, apple_cc_toolchain, available_xcodes, cc_binary, cc_host_toolchain_alias, cc_import, cc_libc_top_alias, cc_library, cc_proto_library, cc_shared_library, cc_shared_library_permissions, cc_test, cc_toolchain, cc_toolchain_alias, cc_toolchain_suite, config_feature_flag, config_setting, constraint_setting, constraint_value, environment, existing_rule, existing_rules, exports_files, extra_action, fdo_prefetch_hints, fdo_profile, filegroup, genquery, genrule, glob, j2objc_library, java_binary, java_import, java_library, java_lite_proto_library, java_package_configuration, java_plugin, java_plugins_flag_alias, java_proto_library, java_runtime, java_test, java_toolchain, label_flag, label_setting, objc_import, objc_library, package, package_group, package_name, platform, propeller_optimize, proto_lang_toolchain, proto_library, py_binary, py_library, py_runtime, py_test, repository_name, sh_binary, sh_library, sh_test, subpackages, test_suite, toolchain, toolchain_type, xcode_config, xcode_config_alias, xcode_version
bazel version output:
Bazelisk version: v1.15.0
Build label: 6.0.0
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Mon Dec 19 15:52:35 2022 (1671465155)
Build timestamp: 1671465155
Build timestamp as int: 1671465155
I've also found this gRPC github issue but I'm not sure what to do with it.
How to build gRPC's hello world example using bzlmod to manage external dependencies?
I've tried building it with bazel's cc_grpc_library but that wraps actual dependency (gRPC) into yet another layer as it is visible from the comment on the provided link. Either way it wasn't building but I don't recall actual error.
gRPC doesn't yet support Bazel module so it can break but in your case, it looks weird to call grpc_deps() and grpc_extra_deps() functions in BUILD file because those are expected to be called in WORKSPACE file. If it turns out that module doesn't work yet, you may want to use it without module. Please take a look at this example.
I'd like to use google protobuf (master branch) + bazel v4.2.1 to set up communication between C++ and python parts of my program. I've got the following WORKSPACE file:
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_protobuf",
strip_prefix = "protobuf-master",
urls = ["https://github.com/protocolbuffers/protobuf/archive/master.zip"],
)
load("#com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
and the BUILD file:
load("#com_google_protobuf//:protobuf.bzl", "cc_proto_library")
load("#com_google_protobuf//:protobuf.bzl", "py_proto_library")
cc_proto_library(
name = "container_cc_proto",
srcs = ["container.proto"],
visibility = ["//visibility:public"],
deps = ["#com_google_protobuf//:any_proto",],
)
py_proto_library(
name = "container_py_proto",
srcs = ["container.proto"],
visibility = ["//visibility:public"],
deps = ["#com_google_protobuf//:any_proto",],
)
The container.proto tries to include "google/protobuf/any.proto". On my command bazel build //:container_cc_proto I see the following error:
ERROR: /home/*user*/sandbox/bypass/BUILD:31:17: no such target '#com_google_protobuf//:any_proto_genproto': target 'any_proto_genproto' not declared in package '' defined by /home/*some path*/external/com_google_protobuf/BUILD and referenced by '//:container_cc_proto_genproto'
Could anyone please tell me how to include any.proto correctly, or any other known workarounds. Thanks!
I'm using bazel 4.1.0 to build to project.
Current set up:
go.mod file
...
github.com/mwitkow/go-proto-validators v0.3.2 // indirect
...
WORKSPACE file
load("#bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
load("//:repositories.bzl", "go_repositories")
go_repositories()
in repositories.blz file
...
go_repository(
name = "com_github_mwitkow_go_proto_validators",
importpath = "github.com/mwitkow/go-proto-validators",
sum = "h1:qRlmpTzm2pstMKKzTdvwPCF5QfBNURSlAgN/R+qbKos=",
version = "v0.3.2",
)
....
in students/api.v1/api.proto file
import "google/api/annotations.proto";
import "github.com/mwitkow/go-proto-validators/validator.proto";
after running bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=repositories.bzl%go_repositories -prune=true and bazel run //:gazelle
it generate students/api.v1/BUILD.bazel file
proto_library(
name = "api_proto",
srcs = ["api.proto"],
visibility = ["//visibility:public"],
deps = [
"//github.com/mwitkow/go-proto-validators:validators_proto",
"#go_googleapis//google/api:annotations_proto",
],
)
go_proto_library(
name = "api_go_proto",
compilers = ["#io_bazel_rules_go//proto:go_grpc"],
importpath = "students/generated/api",
proto = ":api_proto",
visibility = ["//visibility:public"],
deps = [
"//github.com/mwitkow/go-proto-validators:validator_proto",
"#go_googleapis//google/api:annotations_go_proto",
],
)
When I run bazel build //..., it produces an error
ERROR: /my-app/students/api.v1/BUILD.bazel:15:17: no such package 'github.com/mwitkow/go-proto-validators': BUILD file not found in any of the following directories. Add a BUILD file to a directory to mark it as a package.
- /my-app/github.com/mwitkow/go-proto-validators and referenced by '/students/api.v1:api_go_proto'
ERROR: Analysis of target '//students/api.v1:api' failed; build aborted: Analysis failed
I would like to make the build work without error. Thank you very much for your help.
I think in BUILD.bazel file, //github.com/mwitkow/go-proto-validators:validators_proto should be #github.com/mwitkow/go-proto-validators:validators_proto, like #go_googleapis//google/api:annotations_proto but it's just a vague idea.
My project structure
/PROJECT
WORKSPACE
BUILD
third_party
tensorflow <-- cloned repository
my_files
BUILD
In WORKSPACE file i added this
local_repository(
name = "tensorflow",
path = "third_party/tensorflow",
)
load("#tensorflow//tensorflow:workspace3.bzl", "workspace")
workspace()
load("#tensorflow//tensorflow:workspace2.bzl", "workspace")
workspace()
load("#tensorflow//tensorflow:workspace1.bzl", "workspace")
workspace()
load("#tensorflow//tensorflow:workspace0.bzl", "workspace")
workspace()
Initially, the following was already written in the file
#Tensorflow repo should always go after the other external dependencies.
# 2020-10-30
_TENSORFLOW_GIT_COMMIT = "84384703c0d8b502e33ff6fd7eefd219dca5ff8e"
_TENSORFLOW_SHA256= "23fb322fc15a20f7a7838d9a31f8b16f60700a494ea654311a0aa8621769df98"
http_archive(
name = "org_tensorflow",
urls = [
"https://github.com/tensorflow/tensorflow/archive/%s.tar.gz" % _TENSORFLOW_GIT_COMMIT,
],
patches = [
"#//third_party:org_tensorflow_compatibility_fixes.diff",
],
patch_args = [
"-p1",
],
strip_prefix = "tensorflow-%s" % _TENSORFLOW_GIT_COMMIT,
sha256 = _TENSORFLOW_SHA256,
)
load("#org_tensorflow//tensorflow:workspace.bzl", "tf_workspace")
tf_workspace(tf_repo_name = "org_tensorflow")
Than in my_files/BUILD i wrote following
objc_library(
deps = [
"#tensorflow//tensorflow/lite/objc:TensorFlowLite",
],
)
When building, I get the following error
ERROR: file '_middlemen/TensorFlowLiteCMetal-ObjcCppSemantics_build_arch_ios-arm64-min10.0-
applebin_ios-ios_arm64-dbg_with_suffix__non_objc_arc' is generated by these conflicting actions:
Label: #tensorflow//tensorflow/lite/delegates/gpu:metal_delegate,
#org_tensorflow//tensorflow/lite/delegates/gpu:metal_delegate
ERROR: com.google.devtools.build.lib.skyframe.ArtifactConflictFinder$ConflictException:
com.google.devtools.build.lib.actions.MutableActionGraph$ActionConflictException: for
_middlemen/TensorFlowLiteCMetal-ObjcCppSemantics_build_arch_ios-arm64-min10.0-applebin_ios-
ios_arm64-dbg_with_suffix__non_objc_arc, previous action: ObjcCppSemantics_build_arch_ios-
arm64-min10.0-applebin_ios-ios_arm64-dbg_with_suffix__non_objc_arc for #org_tensorflow//tensorflow/lite/delegates/gpu:metal_delegate, attempted action:
ObjcCppSemantics_build_arch_ios-arm64-min10.0-applebin_ios-ios_arm64-
dbg_with_suffix__non_objc_arc for #tensorflow//tensorflow/lite/delegates/gpu:metal_delegate
Maybe I somehow incorrectly add tensorlow, but I do not know how to fix it
This issue solved my problem:
https://github.com/tensorflow/tensorflow/issues/46144
I want to conditionally enable run-time checks and logging, independently from each other and from debug and release mode. So I've started adding two features to my project, one called "invariant-checking" and one called "logging". Ultimately i want their use to be through macros I define in a crate which is visible project-wide.
I had assumed that if I filled out the features section the same way in all of the crates the same way then when I activated the feature while compiling the bin crate, then all the lib crates would also have the feature enabled, but this is not the case! How can I enable and disable features across multiple crates? Hopefully this can be done by only changing one thing like the command-line arguments to cargo.
To clarify exactly what I want, here's an example, which I will also reproduce below:
There are three crates, the main, bin, crate, and two lib crates, called "middle" and "common". Here are the relevant parts of the relevant files:
main.rs
extern crate common;
extern crate middle;
fn main() {
common::check!();
middle::run();
println!("done");
}
the main Cargo.toml
[dependencies]
[dependencies.common]
path = "libs/common"
[dependencies.middle]
path = "libs/middle"
[features]
default = []
invariant-checking = []
logging = []
middle's lib.rs
extern crate common;
pub fn run() {
common::check!();
common::run();
}
middle's Cargo.toml
[dependencies]
[dependencies.common]
path = "../common"
[features]
default = []
invariant-checking = []
logging = []
common's lib.rs
#[macro_export]
macro_rules! check {
() => {{
if cfg!(feature = "invariant-checking") {
println!("invariant-checking {}:{}", file!(), line!());
}
if cfg!(feature = "logging") {
println!("logging {}:{}", file!(), line!());
}
}};
}
pub fn run() {
check!()
}
and finally common's Cargo.toml
[dependencies]
[features]
default = []
invariant-checking = []
logging = []
When i run cargo run --features "invariant-checking,logging" I get the following output
invariant-checking src\main.rs:5
logging src\main.rs:5
done
but want it to log in middle and common as well. How can I transform this project such that it will do that, and still allow me to get only "done" as output by changing only one place?
How can I enable and disable features across multiple crates?
A Cargo.toml can add features that transitively enable other features which are allowed to belong to dependencies.
For example, in the Cargo.toml of a crate which depends on crates foo and bar:
[dependencies]
foo = "0.1"
bar = "0.1"
[features]
default = []
invariant-checking = [ "foo/invariant-checking", "bar/invariant-checking" ]
logging = [ "foo/logging", "bar/logging" ]
This crate adds the invariant-checking and logging features. Enabling them transitively enables the respective features of the crates foo and bar, so that
cargo build --features=logging,invariant-checking
will enable the logging and invariant-checking features in this crate and also in its dependencies foo and bar as well.
In your particular case, you probably want main to transitively enable the features of middle and common, and for middle to transitively enable the features of common.
The macro definitions in their current form have a problem: The code inside the macro gets inlined whenever the macro is used, and then compiled in the context where it got inlined. Since you use runtime feature checks like
if cfg!(feature = "invariant-checking")
this means that you need to define the features in every crate where you are using the macro. In the common crate itself, on the other hand, the feature is never queried and thus redundant.
This seems completely backwards to me. The feature flag should be only queried in the common crate, and using the macro should not require first defining a feature flag in the crate that uses it. For this reason, I suggest using compile-time checks to select what macro to define:
#[cfg(feature = "invariant-checking")]
macro_rules! check_invariant {
() => ( println!("invariant-checking {}:{}", file!(), line!()); )
}
#[cfg(not(feature = "invariant-checking"))]
macro_rules! check_invariant {
() => ()
}
#[cfg(feature = "logging")]
macro_rules! logging {
() => ( println!("logging {}:{}", file!(), line!()); )
}
#[cfg(not(feature = "logging"))]
macro_rules! logging {
() => ()
}
#[macro_export]
macro_rules! check {
() => ( check_invariant!(); logging!(); )
}
This way, you will only need to define the feature in the common crate, as it should be. As long as you only use a single version of that crate, switching the flag on and off has global effect.