├── .gitattributes ├── .gitignore ├── CcToolchainConfigInfo ├── BUILD ├── WORKSPACE ├── explore_cc_toolchain.bzl ├── library.cpp ├── library.h └── main.cpp ├── PyInfoProvider ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── a │ └── sub │ │ └── package │ │ ├── BUILD │ │ └── example_module │ │ └── __init__.py ├── app.py ├── app_test.py ├── gen_py_lib.bzl └── inspect_native_pyinfo.bzl ├── README.md ├── alot_of_files ├── .gitignore ├── BUILD ├── BUILD.template ├── README.md ├── WORKSPACE ├── create_files.zsh ├── source_file.cpp.template └── source_file.h.template ├── aspects ├── .bazelrc ├── .bazelversion ├── .clang-tidy ├── BUILD ├── README.md ├── WORKSPACE ├── legacy_cc_provider.bzl ├── main │ ├── BUILD │ └── main.cpp ├── module1 │ ├── BUILD │ ├── source1.cpp │ └── source1.hpp ├── module2 │ ├── BUILD │ ├── source2.cpp │ └── source2.hpp ├── module3 │ ├── BUILD │ ├── source3.cpp │ └── source3.hpp ├── module4 │ ├── BUILD │ ├── source4.cpp │ └── source4.hpp ├── module5 │ ├── BUILD │ ├── source5.cpp │ └── source5.hpp ├── module_with_strip_includes │ ├── BUILD │ ├── include_dir │ │ └── source6.hpp │ └── source6.cpp ├── static_analysis │ ├── BUILD │ ├── clang_tidy.bzl │ └── command_wrapper.sh └── third_party │ ├── BUILD │ ├── BUILD.clang │ └── dependencies.bzl ├── bazel_cquery_tag_filter ├── .gitignore ├── BUILD ├── README.md ├── WORKSPACE ├── bisect.bat ├── output.txt ├── package_a │ └── BUILD ├── package_b │ └── BUILD ├── reproduce ├── run_tests └── run_tests.bat ├── bazelversion ├── .bazeliskrc ├── .bazelversion ├── BUILD ├── README.md └── WORKSPACE ├── cascaded_workspaces ├── BUILD ├── WORKSPACE ├── module │ ├── BUILD │ └── hello-world.cc ├── other_lib │ ├── BUILD │ ├── src.cpp │ └── src.h ├── other_module │ ├── BUILD │ └── src.cpp └── sub_workspace │ ├── BUILD │ ├── WORKSPACE │ ├── include │ └── hello-greet.h │ ├── src │ └── hello-greet.cc │ └── sub_sub │ └── module │ ├── BUILD │ └── hello-world.cc ├── cc_proto ├── BUILD ├── README.md ├── WORKSPACE ├── a_binary │ ├── BUILD │ └── main.cpp ├── a_library │ ├── BUILD │ ├── lib.cpp │ └── lib.h ├── action_graph_0_24_1 ├── action_graph_0_25_0s └── some │ └── sub │ └── package │ └── path │ └── proto_pkg │ ├── BUILD │ └── proto_msg.proto ├── cc_sandwich_playground ├── BUILD ├── README.md ├── WORKSPACE ├── cc_api_rules.bzl ├── generator_and_builder.bzl ├── lib.cpp └── main.cpp ├── config_test ├── .bazelrc ├── BUILD ├── README.md ├── WORKSPACE └── sources │ ├── BUILD │ ├── include │ └── main.h │ ├── src │ ├── main_0.c │ ├── main_1.c │ └── main_2.c │ └── test │ └── main_test.cpp ├── configuration ├── BUILD ├── WORKSPACE └── myapp │ ├── BUILD │ ├── calcite.sh │ ├── feldspar.sh │ └── pyroxene.sh ├── crosstool ├── BUILD ├── WORKSPACE ├── main │ ├── BUILD │ └── helloworld.cc ├── third-party │ ├── emscripten-clang.BUILD │ └── emscripten-toolchain.BUILD └── toolchain │ ├── .gitattributes │ ├── BUILD │ ├── CROSSTOOL │ ├── emcc.sh │ └── emscripten_cache │ ├── binaryen_tag_version_38.txt │ ├── dlmalloc.bc │ ├── gl.bc │ ├── libc.bc │ ├── libcxxabi.bc │ └── wasm-libc.bc ├── dynamic_static_linking ├── BUILD ├── WORKSPACE ├── library.cpp ├── library.h └── main.cpp ├── environments ├── .bazelrc ├── BUILD ├── README.md ├── WORKSPACE ├── action_environment.bzl └── environment_spy.sh ├── error_masking_with_includes ├── README.md ├── WORKSPACE ├── includes_and_strip_prefix │ ├── BUILD │ ├── include │ │ └── lib │ │ │ └── library_includes.h │ └── src │ │ └── library_includes.cpp ├── only_includes │ ├── BUILD │ ├── include │ │ └── lib │ │ │ └── library_includes.h │ └── src │ │ └── library_includes.cpp └── only_strip_prefix │ ├── BUILD │ ├── include │ └── lib │ │ └── library_includes.h │ └── src │ └── library_includes.cpp ├── find_all_tests ├── BUILD ├── README.md ├── WORKSPACE ├── l1 │ ├── BUILD │ ├── library1.cpp │ ├── library1.h │ └── test.cpp ├── l2 │ ├── BUILD │ ├── library2.cpp │ ├── library2.h │ ├── test.cpp │ └── tests │ │ ├── BUILD │ │ └── test.cpp ├── l3 │ ├── BUILD │ ├── library3.cpp │ ├── library3.h │ └── test.cpp └── main.cpp ├── generate_arbitrary_number_of_files ├── BUILD ├── WORKSPACE ├── genccs.bzl ├── py_binary │ ├── BUILD │ └── py_gen.py └── src │ └── main.cc ├── generated_sources ├── BUILD ├── WORKSPACE ├── generated │ └── BUILD ├── rule.bzl └── source.c ├── genrule ├── BUILD ├── WORKSPACE ├── generator.py └── out.cpp ├── genrule_outs ├── .bazelrc ├── .bazelversion ├── BUILD ├── WORKSPACE ├── custom_rule.bzl └── foo.cpp ├── implicit_outputs ├── BUILD ├── WORKSPACE └── implicit_outputs.bzl ├── include_handling ├── WORKSPACE ├── library_includer │ ├── BUILD │ ├── include │ │ └── lib │ │ │ └── library_includer.h │ └── src │ │ └── library_includer.cpp ├── no_public_headers │ ├── BUILD │ └── src │ │ ├── implementation.cpp │ │ └── implementation.h ├── private_headers │ ├── BUILD │ ├── include │ │ └── lib │ │ │ └── library_private.h │ └── src │ │ ├── library_private.cpp │ │ ├── private_header.cpp │ │ ├── private_header.h │ │ └── sub │ │ ├── sub.cpp │ │ └── sub.h ├── strip_prefix_library │ ├── BUILD │ ├── include │ │ └── lib │ │ │ └── library_prefix.h │ └── src │ │ └── library_prefix.cpp └── using_includes │ ├── BUILD │ ├── include │ └── lib │ │ └── library_includes.h │ └── src │ └── library_includes.cpp ├── packaging ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── generate_files.bzl └── my_library │ ├── BUILD │ ├── include │ └── my_library │ │ └── library.h │ └── src │ └── library.cpp ├── py_runtime ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── a_dependency_library.py └── show_python_version.py ├── python-tutorial ├── WORKSPACE ├── py_binary │ ├── BUILD │ └── py_binary_a.py └── py_library │ ├── BUILD │ └── lib_module.py ├── python_with_cxx ├── BUILD ├── WORKSPACE ├── a_python_library.py ├── a_python_main.py ├── cpp_code.cpp └── cpp_code.h ├── repository_rules ├── .bazelversion ├── BUILD ├── WORKSPACE ├── deb.bzl └── depend_on_tinyxml.cpp ├── run_action ├── .bazelversion ├── BUILD ├── WORKSPACE └── rule.bzl ├── run_with_files ├── .bazelrc ├── BUILD ├── BUILD.ext_file ├── WORKSPACE ├── binary.py ├── ext_file │ └── ext_file ├── generated │ └── BUILD ├── input │ ├── BUILD │ └── file └── workspace_name_var.bzl ├── runfiles ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── app.py └── runfile.bzl ├── runfiles_mapper ├── BUILD ├── WORKSPACE ├── runfile.txt └── runfiles_mapper.bzl ├── sh_binary_args ├── BUILD ├── WORKSPACE ├── other_script.bash └── shell_binary.bash ├── standalone_so ├── .bazelversion ├── .gitignore ├── BUILD ├── WORKSPACE ├── content.cpp ├── content.h └── so_headers.bzl ├── test_rules ├── BUILD ├── WORKSPACE ├── another_important_py_lib │ ├── BUILD │ └── py_lib.py ├── launchfile.test ├── py_runner.py ├── schema_a.scm ├── schema_b.scm ├── sh_runner.sh ├── some_important_py_lib │ ├── BUILD │ └── py_lib.py └── test_rule.bzl ├── toolchain_testing_playground ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── action_configs.bzl ├── cpp_tests │ ├── BUILD │ ├── define_test.cpp │ ├── include_test.cpp │ ├── lib.cpp │ ├── main.cpp │ ├── other.cpp │ └── sub_package │ │ ├── BUILD │ │ └── include │ │ └── header.h ├── gcc_config.bzl └── third_party │ ├── BUILD │ ├── BUILD.gcc │ ├── libc6dev_files.bzl │ ├── libgcc8_dev.bzl │ ├── libstdcpp8_files.bzl │ └── linuxlibcdev_files.bzl ├── toolchains_generic ├── .bazelrc ├── BUILD ├── README.md ├── WORKSPACE ├── local_tool │ ├── BUILD │ ├── WORKSPACE │ └── tool.cpp ├── tool_rule.bzl └── toolchain_config.bzl ├── transition_user_defined_build_settings ├── BUILD ├── WORKSPACE ├── ice_cream_machine.bzl ├── select_flavor.bzl ├── setting.bzl └── tools │ └── whitelists │ └── function_transition_whitelist │ └── BUILD ├── transitions ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE ├── binary.bzl ├── cc_api_rules.bzl ├── cc_transition │ ├── BUILD │ ├── code.c │ ├── code.h │ ├── main.c │ ├── test.cpp │ └── transition_rule.bzl ├── code.c ├── consumer.bzl ├── include │ └── header.h ├── main.c ├── output_dir_names │ ├── BUILD │ ├── cc_api_rules.bzl │ ├── code.c │ ├── code.h │ ├── main.c │ ├── main │ │ ├── BUILD │ │ └── main.c │ ├── run.bat │ ├── test.cpp │ └── transition_rule.bzl ├── tools │ └── whitelists │ │ └── function_transition_whitelist │ │ └── BUILD └── with_a_generator │ ├── BUILD │ ├── generator.bzl │ └── generator.sh ├── use_java_fragments ├── .bazelrc ├── .bazelversion ├── BUILD ├── README.md ├── WORKSPACE └── rule_with_java.bzl ├── variable_output_with_user_configs ├── .bazelversion ├── BUILD ├── WORKSPACE └── custom_rule.bzl └── workspace_status ├── .bazelrc ├── .bazelversion ├── BUILD ├── WORKSPACE ├── status └── workspace_status.sh └── version.bzl /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | bazel-* 35 | -------------------------------------------------------------------------------- /CcToolchainConfigInfo/BUILD: -------------------------------------------------------------------------------- 1 | load(":explore_cc_toolchain.bzl", "explore") 2 | 3 | cc_library( 4 | name = "lib", 5 | srcs = [ 6 | "library.cpp", 7 | "library.h", 8 | ], 9 | ) 10 | 11 | cc_binary( 12 | name = "main", 13 | srcs = ["main.cpp"], 14 | deps = [":lib"], 15 | ) 16 | 17 | explore( 18 | name = "explore_lib", 19 | lib = ":lib", 20 | ) 21 | 22 | explore( 23 | name = "explore_main", 24 | lib = ":main", 25 | ) 26 | -------------------------------------------------------------------------------- /CcToolchainConfigInfo/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/CcToolchainConfigInfo/WORKSPACE -------------------------------------------------------------------------------- /CcToolchainConfigInfo/explore_cc_toolchain.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") 2 | load( 3 | "@bazel_tools//tools/build_defs/cc:action_names.bzl", 4 | "CPP_COMPILE_ACTION_NAME", 5 | "CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME", 6 | "C_COMPILE_ACTION_NAME", 7 | ) 8 | 9 | def explore_object(obj): 10 | print("=" * 80) 11 | print(obj) 12 | print(dir(obj)) 13 | for attr in dir(obj): 14 | print(attr, "-", getattr(obj, attr, None)) 15 | print("=" * 80) 16 | 17 | def _explore_impl(ctx): 18 | lib = ctx.attr.lib 19 | tc = find_cpp_toolchain(ctx) 20 | print("Toolchain:") 21 | explore_object(tc) 22 | 23 | feature_configuration = cc_common.configure_features( 24 | cc_toolchain = tc, 25 | requested_features = ctx.features, 26 | unsupported_features = ctx.disabled_features, 27 | ) 28 | print("Feature configuration:") 29 | explore_object(feature_configuration) 30 | 31 | compile_variables = cc_common.create_compile_variables( 32 | feature_configuration = feature_configuration, 33 | cc_toolchain = tc, 34 | user_compile_flags = ctx.fragments.cpp.copts, 35 | ) 36 | print("Compile variables:") 37 | explore_object(compile_variables) 38 | 39 | compiler_options = cc_common.get_memory_inefficient_command_line( 40 | feature_configuration = feature_configuration, 41 | action_name = CPP_COMPILE_ACTION_NAME, 42 | variables = compile_variables, 43 | ) 44 | print("Compiler options:") 45 | explore_object(compiler_options) 46 | 47 | compiler = str( 48 | cc_common.get_tool_for_action( 49 | feature_configuration = feature_configuration, 50 | action_name = CPP_COMPILE_ACTION_NAME, 51 | ), 52 | ) 53 | print("Compiler:") 54 | explore_object(compiler) 55 | 56 | explore = rule( 57 | attrs = { 58 | "lib": attr.label(), 59 | "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), 60 | }, 61 | fragments = ["cpp"], 62 | implementation = _explore_impl, 63 | ) 64 | -------------------------------------------------------------------------------- /CcToolchainConfigInfo/library.cpp: -------------------------------------------------------------------------------- 1 | #include "library.h" 2 | #include 3 | 4 | Library::Library() = default; 5 | 6 | void Library::HelloWorld() const 7 | { 8 | std::cout << "HelloWorld!" << '\n'; 9 | } 10 | -------------------------------------------------------------------------------- /CcToolchainConfigInfo/library.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_H 2 | #define LIBRARY_H 3 | 4 | class Library 5 | { 6 | public: 7 | Library(); 8 | void HelloWorld() const; 9 | }; 10 | 11 | #endif /* LIBRARY_H */ 12 | -------------------------------------------------------------------------------- /CcToolchainConfigInfo/main.cpp: -------------------------------------------------------------------------------- 1 | #include "library.h" 2 | 3 | int main(int argc, char* argv[]) 4 | { 5 | Library foo{}; 6 | foo.HelloWorld(); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /PyInfoProvider/.bazelrc: -------------------------------------------------------------------------------- 1 | build --python_path=python3 2 | 3 | -------------------------------------------------------------------------------- /PyInfoProvider/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.25.2 2 | -------------------------------------------------------------------------------- /PyInfoProvider/BUILD: -------------------------------------------------------------------------------- 1 | load(":gen_py_lib.bzl", "gen_py_lib") 2 | load(":inspect_native_pyinfo.bzl", "inspect_py_info") 3 | 4 | gen_py_lib( 5 | name = "generated_lib", 6 | constant_value = 42, 7 | module = "MyLib", 8 | ) 9 | 10 | py_library( 11 | name = "library_in_root_package", 12 | srcs = ["app.py"], 13 | deps = [ 14 | ":generated_lib", 15 | ], 16 | ) 17 | 18 | py_binary( 19 | name = "use_generated_py_lib", 20 | srcs = ["app.py"], 21 | main = "app.py", 22 | deps = [ 23 | ":generated_lib", 24 | ], 25 | ) 26 | 27 | py_test( 28 | name = "test_generated_py_lib", 29 | srcs = ["app_test.py"], 30 | main = "app_test.py", 31 | deps = [ 32 | ":generated_lib", 33 | "//a/sub/package:generated_sub_lib", 34 | "//a/sub/package:py_library_with_imports_same_package", 35 | ], 36 | ) 37 | 38 | inspect_py_info( 39 | name = "inspect_a_sub_package_module", 40 | inspect = "//a/sub/package:py_library_with_imports_same_package", 41 | ) 42 | 43 | inspect_py_info( 44 | name = "inspect_library_in_root_package", 45 | inspect = "library_in_root_package", 46 | ) 47 | -------------------------------------------------------------------------------- /PyInfoProvider/README.md: -------------------------------------------------------------------------------- 1 | ### Using PyInfo to generate python libs 2 | 3 | Change the `constant_value` attribute to vary what should be used when running the py binary that 4 | uses the generated rule to access the defined constant value. 5 | ```python 6 | gen_py_lib( 7 | name = "generated_lib", 8 | constant_value = 42, 9 | module = "MyLib", 10 | ) 11 | ``` 12 | 13 | Use this to run the binary that use the generated python lib 14 | ```bash 15 | bazel run //:use_generated_py_lib 16 | ``` 17 | 18 | ##### Learnings 19 | Using PyInfo itself is not sufficient. 20 | The same files need to be provided through runfiles. 21 | This enables the inheriting rules to actually be able to "see" the files. 22 | 23 | e.g. Output structure when not providing runfiles: 24 | ```bash 25 | . 26 | ├── k8-fastbuild 27 | │   ├── bin 28 | │   │   ├── use_generated_py_lib 29 | │   │   ├── use_generated_py_lib.runfiles 30 | │   │   │   ├── __main__ 31 | │   │   │   │   ├── app.py 32 | │   │   │   │   └── use_generated_py_lib 33 | │   │   │   └── MANIFEST 34 | │   │   └── use_generated_py_lib.runfiles_manifest 35 | │   ├── genfiles 36 | │   └── testlogs 37 | ├── stable-status.txt 38 | ├── _tmp 39 | │   └── action_outs 40 | └── volatile-status.txt 41 | ``` 42 | 43 | And with runfiles being set: 44 | ```bash 45 | . 46 | ├── k8-fastbuild 47 | │   ├── bin 48 | │   │   ├── MyLib 49 | │   │   │   └── __init__.py 50 | │   │   ├── use_generated_py_lib 51 | │   │   ├── use_generated_py_lib.runfiles 52 | │   │   │   ├── __main__ 53 | │   │   │   │   ├── app.py 54 | │   │   │   │   ├── MyLib 55 | │   │   │   │   │   └── __init__.py 56 | │   │   │   │   └── use_generated_py_lib 57 | │   │   │   └── MANIFEST 58 | │   │   └── use_generated_py_lib.runfiles_manifest 59 | │   ├── genfiles 60 | │   └── testlogs 61 | ├── stable-status.txt 62 | ├── _tmp 63 | │   └── action_outs 64 | └── volatile-status.txt 65 | ``` 66 | 67 | Transitive Sources seem not to impact which files get linked to rules using the generated files. 68 | -------------------------------------------------------------------------------- /PyInfoProvider/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/PyInfoProvider/WORKSPACE -------------------------------------------------------------------------------- /PyInfoProvider/a/sub/package/BUILD: -------------------------------------------------------------------------------- 1 | load("//:gen_py_lib.bzl", "gen_py_lib") 2 | load("//:inspect_native_pyinfo.bzl", "inspect_py_info") 3 | 4 | gen_py_lib( 5 | name = "generated_sub_lib", 6 | constant_value = 43, 7 | module = "SubLib", 8 | visibility = ["//visibility:public"], 9 | ) 10 | 11 | py_library( 12 | name = "py_library_with_imports_same_package", 13 | srcs = ["example_module/__init__.py"], 14 | imports = ["."], 15 | visibility = ["//visibility:public"], 16 | ) 17 | 18 | py_library( 19 | name = "py_library_with_dependency_on_generated_lib", 20 | srcs = ["example_module/__init__.py"], 21 | imports = ["."], 22 | visibility = ["//visibility:public"], 23 | deps = [":generated_sub_lib"], 24 | ) 25 | 26 | inspect_py_info( 27 | name = "inspect_generated_sub_lib", 28 | inspect = ":generated_sub_lib", 29 | ) 30 | 31 | inspect_py_info( 32 | name = "inspect_py_library_with_imports_same_package", 33 | inspect = ":py_library_with_imports_same_package", 34 | ) 35 | 36 | inspect_py_info( 37 | name = "inspect_py_library_with_dependency_on_generated_lib", 38 | inspect = ":py_library_with_dependency_on_generated_lib", 39 | ) 40 | -------------------------------------------------------------------------------- /PyInfoProvider/a/sub/package/example_module/__init__.py: -------------------------------------------------------------------------------- 1 | CONSTANT_IN_LIB = 84 2 | -------------------------------------------------------------------------------- /PyInfoProvider/app.py: -------------------------------------------------------------------------------- 1 | #This is the generated module 2 | import MyLib 3 | 4 | if __name__ == "__main__": 5 | print("Constant value defined in build rule:", MyLib.CONSTANT_IN_LIB) 6 | -------------------------------------------------------------------------------- /PyInfoProvider/app_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unittest 3 | 4 | 5 | class TestStringMethods(unittest.TestCase): 6 | 7 | def test_import_generated(self): 8 | import MyLib 9 | self.assertEqual(MyLib.CONSTANT_IN_LIB, 42) 10 | 11 | def test_import_sub_generated_module_absolute(self): 12 | from a.sub.package.SubLib import CONSTANT_IN_LIB 13 | self.assertEqual(CONSTANT_IN_LIB, 43) 14 | 15 | def test_import_sub_generated_module_relative(self): 16 | import SubLib 17 | self.assertEqual(SubLib.CONSTANT_IN_LIB, 43) 18 | 19 | def test_import_example_sub_module_absolute(self): 20 | from a.sub.package.example_module import CONSTANT_IN_LIB 21 | self.assertEqual(CONSTANT_IN_LIB, 84) 22 | 23 | def test_import_example_sub_module_relative(self): 24 | import example_module 25 | self.assertEqual(example_module.CONSTANT_IN_LIB, 84) 26 | 27 | 28 | if __name__ == "__main__": 29 | __import__('pprint').pprint(sys.path) 30 | unittest.main() 31 | -------------------------------------------------------------------------------- /PyInfoProvider/gen_py_lib.bzl: -------------------------------------------------------------------------------- 1 | module_template = """ 2 | CONSTANT_IN_LIB = {value} 3 | """ 4 | 5 | def _gen_py_lib_impl(ctx): 6 | packagefile_content = module_template.format(value = ctx.attr.constant_value) 7 | 8 | generated_package_file = ctx.actions.declare_file("/".join([ctx.attr.module, "__init__.py"])) 9 | ctx.actions.write(output = generated_package_file, content = packagefile_content) 10 | 11 | return [ 12 | DefaultInfo( 13 | default_runfiles = ctx.runfiles(files = [generated_package_file]), 14 | ), 15 | PyInfo( 16 | imports = depset(direct = [ctx.attr.module]), 17 | transitive_sources = depset(direct = [generated_package_file]), 18 | ), 19 | ] 20 | 21 | gen_py_lib = rule( 22 | attrs = { 23 | "module": attr.string( 24 | doc = """The name of the module that shall be generated.""", 25 | mandatory = True, 26 | ), 27 | "constant_value": attr.int( 28 | doc = """A value that will be generated into the lib, and accessible by the inheriting rules""", 29 | mandatory = True, 30 | ), 31 | }, 32 | implementation = _gen_py_lib_impl, 33 | ) 34 | -------------------------------------------------------------------------------- /PyInfoProvider/inspect_native_pyinfo.bzl: -------------------------------------------------------------------------------- 1 | def inspect(label, x): 2 | print("=" * 50) 3 | print(label) 4 | print(x) 5 | print(dir(x)) 6 | for element in dir(x): 7 | if element not in ["union", "aspect_ids", "rule", "to_list", "to_json"]: 8 | val = getattr(x, element, None) 9 | if val != None: 10 | print(element, val) 11 | else: 12 | print("Not readable", element) 13 | print("=" * 50) 14 | 15 | def _inspect_py_info_impl(ctx): 16 | inspectee = ctx.attr.inspect 17 | inspect("label", ctx.label) 18 | inspect("inspectee", inspectee) 19 | inspect("inspectee.label", inspectee.label) 20 | inspect("inspectee.files", inspectee.files) 21 | inspect("inspectee.data_runfiles", inspectee.data_runfiles) 22 | inspect("inspectee.default_runfiles", inspectee.default_runfiles) 23 | 24 | inspect("PyInfo", inspectee[PyInfo]) 25 | 26 | inspect_py_info = rule( 27 | attrs = { 28 | "inspect": attr.label( 29 | mandatory = True, 30 | providers = [PyInfo], 31 | ), 32 | }, 33 | implementation = _inspect_py_info_impl, 34 | ) 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bazel-learning -------------------------------------------------------------------------------- /alot_of_files/.gitignore: -------------------------------------------------------------------------------- 1 | target_* 2 | -------------------------------------------------------------------------------- /alot_of_files/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/alot_of_files/BUILD -------------------------------------------------------------------------------- /alot_of_files/BUILD.template: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "a_lib", 3 | srcs = glob([ 4 | "*.cpp", 5 | "*.h", 6 | ]), 7 | hdrs = glob([ 8 | "*.cpp", 9 | "*.h", 10 | ]), 11 | visibility = ["//visibility:public"], 12 | deps = [ 13 | "", 14 | ], 15 | ) 16 | -------------------------------------------------------------------------------- /alot_of_files/README.md: -------------------------------------------------------------------------------- 1 | # Create and build alot of very small files 2 | 3 | ```bash 4 | ./create_files.zsh 5 | ``` 6 | -------------------------------------------------------------------------------- /alot_of_files/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/alot_of_files/WORKSPACE -------------------------------------------------------------------------------- /alot_of_files/create_files.zsh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | git clean -xfd 3 | n=1000 4 | mkdir target_{1..$n} 5 | touch target_{1..$n}/BUILD 6 | touch target_{1..$n}/source_file.cpp 7 | touch target_{1..$n}/source_file.h 8 | 9 | cat ./BUILD.template > target_{1..$n}/BUILD 10 | cat ./source_file.cpp.template > target_{1..$n}/source_file.cpp 11 | cat ./source_file.h.template > target_{1..$n}/source_file.h 12 | 13 | sed -i "//d" target_1/BUILD 14 | 15 | for n in {2..$n}; do 16 | (( x=$n - 1 )) 17 | sed -i "s##//target_${x}:a_lib#g" target_${n}/BUILD 18 | done 19 | 20 | mkdir /tmp/profile 2>&1 > /dev/null 21 | 22 | bazel build --nobuild --profile=/tmp/profile/no-build-profile //... 23 | bazel analyze-profile /tmp/profile/no-build-profile 24 | 25 | bazel build --profile=/tmp/profile/build-profile //... 26 | bazel analyze-profile /tmp/profile/build-profile 27 | -------------------------------------------------------------------------------- /alot_of_files/source_file.cpp.template: -------------------------------------------------------------------------------- 1 | #include "source_file.h" 2 | 3 | SourceFile::SourceFile() = default; 4 | void SourceFile::FooBar() const {}; 5 | -------------------------------------------------------------------------------- /alot_of_files/source_file.h.template: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE_FILE_H 2 | #define SOURCE_FILE_H 3 | 4 | class SourceFile 5 | { 6 | public: 7 | SourceFile(); 8 | void FooBar() const; 9 | }; 10 | 11 | #endif /* SOURCE_FILE_H */ 12 | -------------------------------------------------------------------------------- /aspects/.bazelrc: -------------------------------------------------------------------------------- 1 | build:clang-tidy --aspects static_analysis/clang_tidy.bzl%clang_tidy_aspect 2 | build --strategy ClangTidy=local 3 | -------------------------------------------------------------------------------- /aspects/.bazelversion: -------------------------------------------------------------------------------- 1 | 1.0.0 2 | -------------------------------------------------------------------------------- /aspects/BUILD: -------------------------------------------------------------------------------- 1 | load("//static_analysis:clang_tidy.bzl", "clang_tidy") 2 | load("@bazel_compilation_database//:aspects.bzl", "compilation_database") 3 | 4 | exports_files([".clang-tidy"]) 5 | 6 | clang_tidy( 7 | name = "clang_tidy_main", 8 | targets = ["//module_with_strip_includes:lib"], 9 | visibility = ["//visibility:public"], 10 | ) 11 | 12 | compilation_database( 13 | name = "comp_db", 14 | targets = ["//module_with_strip_includes:lib"], 15 | visibility = ["//visibility:public"], 16 | ) 17 | -------------------------------------------------------------------------------- /aspects/README.md: -------------------------------------------------------------------------------- 1 | # Clang tidy with bazel 2 | 3 | Inspired by (grailbio/bazel-compilation-database)[https://github.com/grailbio/bazel-compilation-database] 4 | 5 | To run the analysis on selected targets build 6 | ```bash 7 | bazel build //:clang_tidy_main 8 | ``` 9 | 10 | To run the analysis from the command line, use: 11 | ```bash 12 | bazel build ... --aspects static_analysis/clang_tidy.bzl%clang_tidy_aspect 13 | ``` 14 | or 15 | ```bash 16 | bazel build ... --config clang-tidy 17 | ``` 18 | 19 | 20 | ### Configurability 21 | To use a static `.clang-tidy` file the problem is that the aspect does not see the file in its sandboxed environment. 22 | One approach could be to explicitely add it as an input to the aspect. 23 | However this is not really configurable since it allows only for one global file and this is implicitely coupled to the aspect 24 | 25 | In this example a configuration is set in the .clang-tidy file that causes a warning with the code: 26 | ``` 27 | <...>/execroot/__main__/module1/source1.hpp:11:10: warning: invalid case style for private method 'HelloWorld2' [readability-identifier-naming] 28 | void HelloWorld2() const; 29 | ^~~~~~~~~~~ 30 | Private_PrefixHelloWorld2 31 | ``` 32 | 33 | 34 | 35 | ##### Running without sandboxing 36 | If a .clang-tidy file is checked in, `--spawn_strategy=local` can be used. 37 | To enable this automatically, `--strategy ClangTidy=local` would be a good choice. 38 | Keep in mind that sandboxing is disabled by this! 39 | -------------------------------------------------------------------------------- /aspects/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("//third_party:dependencies.bzl", "load_dependencies") 2 | 3 | load_dependencies() 4 | -------------------------------------------------------------------------------- /aspects/legacy_cc_provider.bzl: -------------------------------------------------------------------------------- 1 | """ 2 | Utility functions that replace old C++ Starlark API using the new API. 3 | See migration instructions in https://github.com/bazelbuild/bazel/issues/7036 4 | Replacements: 5 | dep.cc.transitive_headers -> dep[CcInfo].compilation_context.headers 6 | dep.cc.defines -> dep[CcInfo].compilation_context.defines.to_list() 7 | dep.cc.system_include_directories -> dep[CcInfo].compilation_context.system_includes.to_list() 8 | dep.cc.include_directories -> dep[CcInfo].compilation_context.includes.to_list() 9 | dep.cc.quote_include_directories -> dep[CcInfo].compilation_context.quote_includes.to_list() 10 | dep.cc.link_flags = dep[CcInfo].linking_context.user_link_flags 11 | dep.cc.libs = get_libs_for_static_executable(dep) 12 | dep.cc.compile_flags = get_compile_flags(dep) 13 | """ 14 | 15 | def get_libs_for_static_executable(dep): 16 | """ 17 | Finds the libraries used for linking an executable statically. 18 | This replaces the old API dep.cc.libs 19 | Args: 20 | dep: Target 21 | Returns: 22 | A list of File instances, these are the libraries used for linking. 23 | """ 24 | libraries_to_link = dep[CcInfo].linking_context.libraries_to_link 25 | libs = [] 26 | for library_to_link in libraries_to_link: 27 | if library_to_link.static_library != None: 28 | libs.append(library_to_link.static_library) 29 | elif library_to_link.pic_static_library != None: 30 | libs.append(library_to_link.pic_static_library) 31 | elif library_to_link.interface_library != None: 32 | libs.append(library_to_link.interface_library) 33 | elif library_to_link.dynamic_library != None: 34 | libs.append(library_to_link.dynamic_library) 35 | return depset(libs) 36 | 37 | def get_compile_flags(dep): 38 | """ 39 | Builds compilation flags. This replaces the old API dep.cc.compile_flags 40 | This is not the command line that C++ rules will use. For that the toolchain API should be 41 | used (feature configuration and variables). 42 | Args: 43 | dep: Target 44 | Returns: 45 | A list of strings 46 | """ 47 | options = [] 48 | compilation_context = dep[CcInfo].compilation_context 49 | for define in compilation_context.defines.to_list(): 50 | options.append("-D{}".format(define)) 51 | 52 | for system_include in compilation_context.system_includes.to_list(): 53 | if len(system_include) == 0: 54 | system_include = "." 55 | options.append("-isystem {}".format(system_include)) 56 | 57 | for include in compilation_context.includes.to_list(): 58 | if len(include) == 0: 59 | include = "." 60 | options.append("-I {}".format(include)) 61 | 62 | for quote_include in compilation_context.quote_includes.to_list(): 63 | if len(quote_include) == 0: 64 | quote_include = "." 65 | options.append("-iquote {}".format(quote_include)) 66 | 67 | return options 68 | -------------------------------------------------------------------------------- /aspects/main/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "main", 3 | srcs = ["main.cpp"], 4 | visibility = ["//visibility:public"], 5 | deps = [ 6 | "//module1:lib", 7 | "//module2:lib", 8 | "//module3:lib", 9 | "//module4:lib", 10 | "//module5:lib", 11 | "//module_with_strip_includes:lib", 12 | ], 13 | ) 14 | -------------------------------------------------------------------------------- /aspects/main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "module1/source1.hpp" 2 | #include "module2/source2.hpp" 3 | #include "module3/source3.hpp" 4 | #include "module4/source4.hpp" 5 | #include "module5/source5.hpp" 6 | 7 | int main() 8 | { 9 | Source1 a{}; 10 | Source2 b{}; 11 | Source3 c{}; 12 | Source4 d{}; 13 | Source5 e{}; 14 | a.HelloWorld(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /aspects/module1/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = ["source1.cpp"], 4 | hdrs = ["source1.hpp"], 5 | defines = ["DEFINE=42"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /aspects/module1/source1.cpp: -------------------------------------------------------------------------------- 1 | #include "source1.hpp" 2 | // #include 3 | 4 | Source1::Source1() 5 | { 6 | // std::cout << "Hello"; 7 | } 8 | 9 | void Source1::HelloWorld() const 10 | { 11 | // std::cout << "World" << '\n'; 12 | int a{}; 13 | long b{}; 14 | a = b; 15 | a++; 16 | } 17 | void Source1::HelloWorld2() const {} 18 | -------------------------------------------------------------------------------- /aspects/module1/source1.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE1_H 2 | #define SOURCE1_H 3 | 4 | class Source1 5 | { 6 | public: 7 | Source1(); 8 | void HelloWorld() const; 9 | 10 | private: 11 | void HelloWorld2() const; 12 | }; 13 | 14 | #endif /* SOURCE1_H */ 15 | -------------------------------------------------------------------------------- /aspects/module2/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = ["source2.cpp"], 4 | hdrs = ["source2.hpp"], 5 | visibility = ["//visibility:public"], 6 | ) 7 | -------------------------------------------------------------------------------- /aspects/module2/source2.cpp: -------------------------------------------------------------------------------- 1 | #include "source2.hpp" 2 | 3 | Source2::Source2() = default; 4 | -------------------------------------------------------------------------------- /aspects/module2/source2.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE2_H 2 | #define SOURCE2_H 3 | 4 | class Source2 5 | { 6 | public: 7 | Source2(); 8 | }; 9 | 10 | #endif /* SOURCE2_H */ 11 | -------------------------------------------------------------------------------- /aspects/module3/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_library( 3 | name = "lib", 4 | srcs = ["source3.cpp"], 5 | hdrs = ["source3.hpp"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /aspects/module3/source3.cpp: -------------------------------------------------------------------------------- 1 | #include "source3.hpp" 2 | 3 | Source3::Source3() = default; 4 | -------------------------------------------------------------------------------- /aspects/module3/source3.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE3_H 2 | #define SOURCE3_H 3 | 4 | class Source3 5 | { 6 | public: 7 | Source3(); 8 | }; 9 | 10 | #endif /* SOURCE3_H */ 11 | -------------------------------------------------------------------------------- /aspects/module4/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_library( 3 | name = "lib", 4 | srcs = ["source4.cpp"], 5 | hdrs = ["source4.hpp"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /aspects/module4/source4.cpp: -------------------------------------------------------------------------------- 1 | #include "source4.hpp" 2 | 3 | Source4::Source4() = default; 4 | -------------------------------------------------------------------------------- /aspects/module4/source4.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE4_H 2 | #define SOURCE4_H 3 | 4 | class Source4 5 | { 6 | public: 7 | Source4(); 8 | }; 9 | 10 | #endif /* SOURCE4_H */ 11 | -------------------------------------------------------------------------------- /aspects/module5/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_library( 3 | name = "lib", 4 | srcs = ["source5.cpp"], 5 | hdrs = ["source5.hpp"], 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /aspects/module5/source5.cpp: -------------------------------------------------------------------------------- 1 | #include "source5.hpp" 2 | 3 | Source5::Source5() = default; 4 | -------------------------------------------------------------------------------- /aspects/module5/source5.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE5_H 2 | #define SOURCE5_H 3 | 4 | class Source5 5 | { 6 | public: 7 | Source5(); 8 | }; 9 | 10 | #endif /* SOURCE5_H */ 11 | -------------------------------------------------------------------------------- /aspects/module_with_strip_includes/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = ["source6.cpp"], 4 | hdrs = ["include_dir/source6.hpp"], 5 | strip_include_prefix = "include_dir", 6 | visibility = ["//visibility:public"], 7 | ) 8 | -------------------------------------------------------------------------------- /aspects/module_with_strip_includes/include_dir/source6.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE5_H 2 | #define SOURCE5_H 3 | 4 | class Source6 5 | { 6 | public: 7 | Source6(); 8 | void method() 9 | { 10 | long c{}; 11 | }; 12 | }; 13 | 14 | #endif /* SOURCE5_H */ 15 | -------------------------------------------------------------------------------- /aspects/module_with_strip_includes/source6.cpp: -------------------------------------------------------------------------------- 1 | #include "source6.hpp" 2 | 3 | Source6::Source6() = default; 4 | -------------------------------------------------------------------------------- /aspects/static_analysis/BUILD: -------------------------------------------------------------------------------- 1 | sh_binary( 2 | name = "command_wrapper", 3 | srcs = ["command_wrapper.sh"], 4 | visibility = ["//visibility:public"], 5 | ) 6 | -------------------------------------------------------------------------------- /aspects/static_analysis/command_wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # A small shell wrapper script to pipe the output of an arbitrary command 4 | # to a file. 5 | # Usage: 6 | # 7 | 8 | set -euo pipefail 9 | executable=$1 10 | output=$2 11 | arguments=${@:3} 12 | $executable $arguments 2>&1 | tee $output 13 | -------------------------------------------------------------------------------- /aspects/third_party/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/aspects/third_party/BUILD -------------------------------------------------------------------------------- /aspects/third_party/BUILD.clang: -------------------------------------------------------------------------------- 1 | sh_binary( 2 | name = "clang_tidy", 3 | srcs = ["clang-tidy"], 4 | visibility = ["//visibility:public"], 5 | ) 6 | -------------------------------------------------------------------------------- /aspects/third_party/dependencies.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3 | 4 | def load_dependencies(): 5 | if "clang" not in native.existing_rules(): 6 | http_archive( 7 | name = "clang", 8 | build_file = "//third_party:BUILD.clang", 9 | sha256 = "a23b082b30c128c9831dbdd96edad26b43f56624d0ad0ea9edec506f5385038d", 10 | strip_prefix = "clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04/bin", 11 | url = "http://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz", 12 | ) 13 | 14 | if "bazel_compilation_database" not in native.existing_rules(): 15 | git_repository( 16 | name = "bazel_compilation_database", 17 | remote = "https://github.com/grailbio/bazel-compilation-database.git", 18 | tag = "0.4.1", 19 | ) 20 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/.gitignore: -------------------------------------------------------------------------------- 1 | .bazelrc 2 | .bazelversion 3 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/bazel_cquery_tag_filter/BUILD -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/README.md: -------------------------------------------------------------------------------- 1 | # Possible cquery bug 2 | 3 | ### Abstract 4 | Bazel cquery seems to ignore changes in --build_tags_filter starting with bazel 2.1.0. 5 | 6 | It can be reproduced on windows and linux (ubuntu window-subsystem-linux) using the provided scripts 7 | 8 | `run_tests.bat` or `run_tests.bat` 9 | 10 | #### Description 11 | 12 | I'm using bazelisk for version handling. 13 | Starting with a clean version of this workspace. 14 | 15 | ####### 1 16 | The scripts run bazel cquery 3 times to show the deps of `//package_b/...` 17 | Without any filters set this should resolve to `//package_a` and `//package_b` 18 | 19 | ####### 2 20 | As a next step a `--build_tags_filter` is introduced which removes `//package_b:package_b` from 21 | the wildcard selection. 22 | 23 | Expected behaviour now is that no targets are found. 24 | 25 | ####### 3 26 | In the third step this filter is removed again, and the same results from the first step should be found. 27 | 28 | 29 | #### Error case 30 | Starting from bazel 2.1.0, Step 2 still returns the same result as step 1 even tough it should not. 31 | This is the case up to and including version 3.1.0 32 | 33 | 34 | ### Bisect result 35 | 36 | I did a git bisect between the tags 2.1.0 and 2.0.0 37 | This lead to this commit: 38 | ``` 39 | 9f9b919ecc00cb36787ac0d0936394d983df51f9 is the first bad commit 40 | commit 9f9b919ecc00cb36787ac0d0936394d983df51f9 41 | Author: gregce 42 | Date: Tue Jan 7 13:31:04 2020 -0800 43 | 44 | Make cquery 'somepath' more accurate. 45 | 46 | Specifically, make somepath(//foo, //bar) report results 47 | when //bar isn't built in the top-level configuration (because 48 | of a transition). 49 | 50 | To really work properly, this requires --universe_scope: 51 | 52 | $ blaze cquery 'somepath(//foo, //bar)' -- universe_scope=//foo 53 | 54 | Otherwise, //bar also gets built in the top-level configuration and 55 | somepath looks for *that* version, which is not the one in //foo's 56 | deps. 57 | 58 | RELNOTES: cquery 'somepath' returns more reliable results when the 59 | dep has a different configuration than the parent. To get a result for 60 | `somepath(//foo, //bar`) where //bar isn't in the top-level configuration, 61 | run your query with `--universe_scope=//foo`. See cquery docs for details. 62 | PiperOrigin-RevId: 288560710 63 | ``` 64 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/bazel_cquery_tag_filter/WORKSPACE -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/bisect.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | pushd C:\dev\bazel-learning\bazel_cquery_tag_filter 4 | set bazel=C:\dev\home\bazel\bazel-bin\src\bazel.exe 5 | 6 | break>.bazelrc 7 | 8 | %bazel% shutdown 9 | 10 | REM Expect to see //package_b:package_b as a dependency 11 | CALL :call_bazel 12 | set result=%errorlevel% 13 | IF /I "%result%" NEQ "0" ( 14 | popd 15 | EXIT /B 1 16 | ) 17 | 18 | REM Expect to see no dependency: 19 | echo build --build_tag_filters=-foo> .bazelrc 20 | CALL :call_bazel 21 | set result=%errorlevel% 22 | IF /I "%result%" NEQ "1" ( 23 | popd 24 | EXIT /B 1 25 | ) 26 | 27 | 28 | break>.bazelrc 29 | REM Expect to see //package_b:package_b as a dependency 30 | CALL :call_bazel 31 | set result=%errorlevel% 32 | IF /I "%result%" NEQ "0" ( 33 | popd 34 | EXIT /B 1 35 | ) 36 | EXIT /B 0 37 | 38 | 39 | :call_bazel 40 | %bazel% cquery deps(//package_a/...) --noimplicit_deps --nohost_deps --notool_deps 2>&1 | findstr /R /C:"//package_b:package_b" 41 | EXIT /B %errorlevel% 42 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/output.txt: -------------------------------------------------------------------------------- 1 | INFO: Reading 'startup' options from c:\dev\home\user.bazelrc: --output_base=C:\b, --output_user_root=C:\bazelUserRoot 2 | INFO: Options provided by the client: 3 | Inherited 'common' options: --isatty=0 --terminal_columns=80 4 | INFO: Options provided by the client: 5 | Inherited 'build' options: --python_path=C:/Program Files/Python37/python.exe 6 | INFO: Reading rc options for 'cquery' from c:\dev\home\user.bazelrc: 7 | Inherited 'build' options: --explain=C:\dev\bazel_explain.txt --verbose_explanations --experimental_execution_log_file=C:\dev\local_bazel_execution.log --announce_rc --repository_cache=C:\bazel_repository_cache 8 | Loading: 9 | Loading: 0 packages loaded 10 | Analyzing: target //package_a:package_a (0 packages loaded, 0 targets configured) 11 | INFO: Analyzed target //package_a:package_a (0 packages loaded, 0 targets configured). 12 | INFO: Found 1 target... 13 | //package_a:package_a (8e1baeccb049cf233a6df89aa3418c90e5a6780a625b49a75b8333191506e665) 14 | @bazel_tools//tools/cpp:toolchain_type (8e1baeccb049cf233a6df89aa3418c90e5a6780a625b49a75b8333191506e665) 15 | //package_b:package_b (8e1baeccb049cf233a6df89aa3418c90e5a6780a625b49a75b8333191506e665) 16 | INFO: Elapsed time: 0.140s 17 | INFO: 0 processes. 18 | INFO: Build completed successfully, 0 total actions 19 | INFO: Build completed successfully, 0 total actions 20 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/package_a/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "package_a", 3 | tags = ["foo"], 4 | visibility = ["//visibility:public"], 5 | deps = ["//package_b"], 6 | ) 7 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/package_b/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "package_b", 3 | tags = ["bar"], 4 | visibility = ["//visibility:public"], 5 | ) 6 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/reproduce: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function call_bazel { 3 | echo Content of .bazelrc: 4 | echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 | cat .bazelrc 6 | echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 | 8 | echo Query Output: 9 | echo '************************************************************' 10 | bazel cquery 'deps(//package_a/...)' --noimplicit_deps --nohost_deps --notool_deps 2>&1 | grep '//package_b:package_b' 11 | echo $? 12 | echo '************************************************************' 13 | } 14 | 15 | 16 | function run_test { 17 | version="${1}" 18 | echo "Runnning with version: ${version}" 19 | echo "${version}"> .bazelversion 20 | echo "" > .bazelrc 21 | 22 | bazel shutdown 23 | bazel version 24 | 25 | echo '############################################################' 26 | echo Expect to see //package_b:package_b as a dependency 27 | sleep 5s 28 | call_bazel 29 | echo '############################################################' 30 | sleep 5s 31 | 32 | echo '############################################################' 33 | echo Expect to see no dependency: 34 | sleep 5s 35 | echo "build --build_tag_filters=-foo"> .bazelrc 36 | call_bazel 37 | echo '############################################################' 38 | sleep 5s 39 | 40 | 41 | echo "" > .bazelrc 42 | 43 | echo '############################################################' 44 | echo "Expect to see //package_b:package_b as a dependency" 45 | sleep 5s 46 | call_bazel 47 | echo '############################################################' 48 | sleep 5s 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source "reproduce" 4 | 5 | run_test 2.0.0 6 | run_test 2.1.0 7 | # run_test 3.1.0 8 | # run_test latest 9 | -------------------------------------------------------------------------------- /bazel_cquery_tag_filter/run_tests.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | CALL :run_test 2.0.0 4 | CALL :run_test 2.1.0 5 | 6 | EXIT /B 0 7 | 8 | :run_test 9 | SETLOCAL 10 | set version=%1 11 | echo Runnning with version: %version% 12 | echo %version%> .bazelversion 13 | break>.bazelrc 14 | 15 | bazel shutdown 16 | bazel version 17 | 18 | echo ############################################################ 19 | echo Expect to see //package_b:package_b as a dependency 20 | pause 21 | echo 22 | CALL :call_bazel 0 23 | echo ############################################################ 24 | pause 25 | 26 | echo ############################################################ 27 | echo Expect to see no dependency: 28 | pause 29 | echo 30 | echo build --build_tag_filters=-foo> .bazelrc 31 | CALL :call_bazel 1 32 | echo ############################################################ 33 | pause 34 | 35 | 36 | break>.bazelrc 37 | 38 | echo ############################################################ 39 | echo Expect to see //package_b:package_b as a dependency 40 | pause 41 | echo 42 | CALL :call_bazel 0 43 | echo ############################################################ 44 | pause 45 | ENDLOCAL 46 | EXIT /B 0 47 | 48 | 49 | 50 | :call_bazel 51 | echo Content of .bazelrc: 52 | echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 53 | type .bazelrc 54 | echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 55 | 56 | bazel cquery deps(//package_a/...) --noimplicit_deps --nohost_deps --notool_deps >output.txt 2>&1 57 | EXIT /B 0 58 | -------------------------------------------------------------------------------- /bazelversion/.bazeliskrc: -------------------------------------------------------------------------------- 1 | github_url: "github.com" 2 | github_api_url: "api.github.com" 3 | owner: "bazelbuild" 4 | -------------------------------------------------------------------------------- /bazelversion/.bazelversion: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/bazelversion/.bazelversion -------------------------------------------------------------------------------- /bazelversion/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/bazelversion/BUILD -------------------------------------------------------------------------------- /bazelversion/README.md: -------------------------------------------------------------------------------- 1 | Playground for https://github.com/bazelbuild/bazelisk/pull/91 / https://github.com/bazelbuild/bazelisk/issues/72 2 | -------------------------------------------------------------------------------- /bazelversion/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/bazelversion/WORKSPACE -------------------------------------------------------------------------------- /cascaded_workspaces/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/cascaded_workspaces/BUILD -------------------------------------------------------------------------------- /cascaded_workspaces/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "main_workspace") 2 | 3 | local_repository( 4 | name = "sub", 5 | path = "sub_workspace", 6 | ) 7 | -------------------------------------------------------------------------------- /cascaded_workspaces/module/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "hello-world", 3 | srcs = ["hello-world.cc"], 4 | deps = [ 5 | "@sub//:hello-greet", 6 | ], 7 | visibility = ["//visibility:public"], 8 | ) 9 | 10 | -------------------------------------------------------------------------------- /cascaded_workspaces/module/hello-world.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "hello-greet.h" 5 | 6 | void print_localtime() 7 | { 8 | std::time_t result = std::time(nullptr); 9 | std::cout << std::asctime(std::localtime(&result)); 10 | } 11 | 12 | int main(int argc, char** argv) 13 | { 14 | std::string who = "world"; 15 | if (argc > 1) 16 | { 17 | who = argv[1]; 18 | } 19 | std::cout << get_greet(who) << std::endl; 20 | print_localtime(); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /cascaded_workspaces/other_lib/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "other_lib", 3 | srcs = ["src.cpp", "src.h"], 4 | hdrs = ["src.h"], 5 | ) 6 | -------------------------------------------------------------------------------- /cascaded_workspaces/other_lib/src.cpp: -------------------------------------------------------------------------------- 1 | #include "src.h" 2 | Src::Src() {} 3 | -------------------------------------------------------------------------------- /cascaded_workspaces/other_lib/src.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_H 2 | #define SRC_H 3 | 4 | class Src 5 | { 6 | public: 7 | Src(); 8 | }; 9 | 10 | #endif /* SRC_H */ 11 | -------------------------------------------------------------------------------- /cascaded_workspaces/other_module/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_binary( 3 | name = "other_lib", 4 | srcs = ["src.cpp"], 5 | deps = [ 6 | "@sub//:hello-greet", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /cascaded_workspaces/other_module/src.cpp: -------------------------------------------------------------------------------- 1 | int main(int argc, char* argv[]) 2 | { 3 | 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "hello-greet", 3 | srcs = ["src/hello-greet.cc", "include/hello-greet.h"], 4 | hdrs = ["include/hello-greet.h"], 5 | strip_include_prefix = "include", 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "sub_workspace") 2 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/include/hello-greet.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_HELLO_GREET_H_ 2 | #define LIB_HELLO_GREET_H_ 3 | 4 | #include 5 | 6 | std::string get_greet(const std::string &thing); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/src/hello-greet.cc: -------------------------------------------------------------------------------- 1 | #include "hello-greet.h" 2 | #include 3 | 4 | std::string get_greet(const std::string& who) 5 | { 6 | return "Hello " + who; 7 | } 8 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/sub_sub/module/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "hello-world", 3 | srcs = ["hello-world.cc"], 4 | deps = [ 5 | "//:hello-greet", 6 | ], 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /cascaded_workspaces/sub_workspace/sub_sub/module/hello-world.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "hello-greet.h" 5 | 6 | void print_localtime() 7 | { 8 | std::time_t result = std::time(nullptr); 9 | std::cout << std::asctime(std::localtime(&result)); 10 | } 11 | 12 | int main(int argc, char** argv) 13 | { 14 | std::string who = "world"; 15 | if (argc > 1) 16 | { 17 | who = argv[1]; 18 | } 19 | std::cout << get_greet(who) << std::endl; 20 | print_localtime(); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /cc_proto/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/cc_proto/BUILD -------------------------------------------------------------------------------- /cc_proto/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "com_google_protobuf", 5 | sha256 = "d6618d117698132dadf0f830b762315807dc424ba36ab9183f1f436008a2fdb6", 6 | strip_prefix = "protobuf-3.6.1.2", 7 | urls = ["https://github.com/google/protobuf/archive/v3.6.1.2.zip"], 8 | ) 9 | -------------------------------------------------------------------------------- /cc_proto/a_binary/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "main", 3 | srcs = ["main.cpp"], 4 | tags = ["no-cache"], 5 | deps = ["//a_library:lib"], 6 | ) 7 | -------------------------------------------------------------------------------- /cc_proto/a_binary/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char* argv[]) 3 | { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /cc_proto/a_library/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = ["lib.cpp"], 4 | hdrs = ["lib.h"], 5 | strip_include_prefix = "", 6 | visibility = ["//visibility:public"], 7 | deps = [ 8 | # "//some/sub/package/path:cc_proto_lib", 9 | "//some/sub/package/path/proto_pkg:cc_proto_pkg", 10 | ], 11 | ) 12 | -------------------------------------------------------------------------------- /cc_proto/a_library/lib.cpp: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | 3 | Lib::Lib() = default; 4 | -------------------------------------------------------------------------------- /cc_proto/a_library/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | 6 | class Lib 7 | { 8 | public: 9 | Lib(); 10 | }; 11 | 12 | #endif /* LIB_H */ 13 | -------------------------------------------------------------------------------- /cc_proto/action_graph_0_24_1: -------------------------------------------------------------------------------- 1 | action 'Compiling a_library/lib.cpp' 2 | Mnemonic: CppCompile 3 | Target: //a_library:lib 4 | Configuration: k8-fastbuild 5 | ActionKey: 74510dc7fd37a5aabf43fe7fa5320f63 6 | Inputs: [a_library/lib.cpp, bazel-out/k8-fastbuild/internal/_middlemen/_S_Sa_Ulibrary_Clib-null, external/bazel_tools/tools/cpp/grep-includes.sh] 7 | Outputs: [bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.d, bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o] 8 | Command Line: (exec /usr/bin/gcc \ 9 | -U_FORTIFY_SOURCE \ 10 | -fstack-protector \ 11 | -Wall \ 12 | -Wunused-but-set-parameter \ 13 | -Wno-free-nonheap-object \ 14 | -fno-omit-frame-pointer \ 15 | '-std=c++0x' \ 16 | -MD \ 17 | -MF \ 18 | bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.d \ 19 | '-frandom-seed=bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o' \ 20 | -fPIC \ 21 | -iquote \ 22 | . \ 23 | -iquote \ 24 | bazel-out/k8-fastbuild/genfiles \ 25 | -iquote \ 26 | bazel-out/k8-fastbuild/bin \ 27 | -iquote \ 28 | external/com_google_protobuf \ 29 | -iquote \ 30 | bazel-out/k8-fastbuild/genfiles/external/com_google_protobuf \ 31 | -iquote \ 32 | bazel-out/k8-fastbuild/bin/external/com_google_protobuf \ 33 | -Ibazel-out/k8-fastbuild/bin/a_library/_virtual_includes/lib \ 34 | -isystem \ 35 | some/sub/package/path \ 36 | -isystem \ 37 | bazel-out/k8-fastbuild/genfiles/some/sub/package/path \ 38 | -isystem \ 39 | bazel-out/k8-fastbuild/bin/some/sub/package/path \ 40 | -isystem \ 41 | external/com_google_protobuf/src \ 42 | -isystem \ 43 | bazel-out/k8-fastbuild/genfiles/external/com_google_protobuf/src \ 44 | -isystem \ 45 | bazel-out/k8-fastbuild/bin/external/com_google_protobuf/src \ 46 | -fno-canonical-system-headers \ 47 | -Wno-builtin-macro-redefined \ 48 | '-D__DATE__="redacted"' \ 49 | '-D__TIMESTAMP__="redacted"' \ 50 | '-D__TIME__="redacted"' \ 51 | -c \ 52 | a_library/lib.cpp \ 53 | -o \ 54 | bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o) 55 | 56 | -------------------------------------------------------------------------------- /cc_proto/action_graph_0_25_0s: -------------------------------------------------------------------------------- 1 | action 'Compiling a_library/lib.cpp' 2 | Mnemonic: CppCompile 3 | Target: //a_library:lib 4 | Configuration: k8-fastbuild 5 | ActionKey: 4b5b6a5460c1b363a031ec3c5513a093 6 | Inputs: [a_library/lib.cpp, bazel-out/k8-fastbuild/internal/_middlemen/_S_Sa_Ulibrary_Clib-null, external/bazel_tools/tools/cpp/grep-includes.sh] 7 | Outputs: [bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.d, bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o] 8 | Command Line: (exec /usr/bin/gcc \ 9 | -U_FORTIFY_SOURCE \ 10 | -fstack-protector \ 11 | -Wall \ 12 | -Wunused-but-set-parameter \ 13 | -Wno-free-nonheap-object \ 14 | -fno-omit-frame-pointer \ 15 | '-std=c++0x' \ 16 | -MD \ 17 | -MF \ 18 | bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.d \ 19 | '-frandom-seed=bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o' \ 20 | -fPIC \ 21 | -iquote \ 22 | . \ 23 | -iquote \ 24 | bazel-out/k8-fastbuild/bin \ 25 | -iquote \ 26 | external/com_google_protobuf \ 27 | -iquote \ 28 | bazel-out/k8-fastbuild/bin/external/com_google_protobuf \ 29 | -Ibazel-out/k8-fastbuild/bin/a_library/_virtual_includes/lib \ 30 | -Ibazel-out/k8-fastbuild/bin/some/sub/package/path/proto_pkg/_virtual_includes/proto_pkg \ 31 | -isystem \ 32 | some/sub/package/path \ 33 | -isystem \ 34 | bazel-out/k8-fastbuild/bin/some/sub/package/path \ 35 | -isystem \ 36 | external/com_google_protobuf/src \ 37 | -isystem \ 38 | bazel-out/k8-fastbuild/bin/external/com_google_protobuf/src \ 39 | -fno-canonical-system-headers \ 40 | -Wno-builtin-macro-redefined \ 41 | '-D__DATE__="redacted"' \ 42 | '-D__TIMESTAMP__="redacted"' \ 43 | '-D__TIME__="redacted"' \ 44 | -c \ 45 | a_library/lib.cpp \ 46 | -o \ 47 | bazel-out/k8-fastbuild/bin/a_library/_objs/lib/lib.pic.o) 48 | 49 | -------------------------------------------------------------------------------- /cc_proto/some/sub/package/path/proto_pkg/BUILD: -------------------------------------------------------------------------------- 1 | cc_proto_library( 2 | name = "cc_proto_pkg", 3 | visibility = ["//visibility:public"], 4 | deps = [":proto_pkg"], 5 | ) 6 | 7 | proto_library( 8 | name = "proto_pkg", 9 | srcs = ["proto_msg.proto"], 10 | import_prefix = "proto_pkg", 11 | strip_import_prefix = "", 12 | ) 13 | -------------------------------------------------------------------------------- /cc_proto/some/sub/package/path/proto_pkg/proto_msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option optimize_for = SPEED; 4 | 5 | package proto_pkg; 6 | 7 | message Timestamp 8 | { 9 | optional uint32 sec = 2; 10 | } 11 | 12 | message Entity 13 | { 14 | optional uint32 id = 1; 15 | } 16 | 17 | message Entities 18 | { 19 | optional Timestamp timestamp = 1; 20 | repeated Entity entities = 3; 21 | } 22 | -------------------------------------------------------------------------------- /cc_sandwich_playground/BUILD: -------------------------------------------------------------------------------- 1 | load("//:cc_api_rules.bzl", "cc_bin", "cc_lib") 2 | load("//:generator_and_builder.bzl", "gen_code", "pipe") 3 | 4 | gen_code( 5 | name = "gen", 6 | deps = [], 7 | ) 8 | 9 | pipe( 10 | name = "pip", 11 | src = ":gen", 12 | ) 13 | 14 | cc_lib( 15 | name = "lib", 16 | srcs = ["lib.cpp"], 17 | deps = [":pip"], 18 | ) 19 | 20 | cc_bin( 21 | name = "main", 22 | srcs = ["main.cpp"], 23 | deps = [":lib", ":gen"], 24 | ) 25 | -------------------------------------------------------------------------------- /cc_sandwich_playground/README.md: -------------------------------------------------------------------------------- 1 | # cc_api_rules.bzl copied from: 2 | 3 | ```bash 4 | https://github.com/bazelbuild/bazel/blob/master/src/test/shell/bazel/cc_api_rules.bzl 5 | ``` 6 | -------------------------------------------------------------------------------- /cc_sandwich_playground/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/cc_sandwich_playground/WORKSPACE -------------------------------------------------------------------------------- /cc_sandwich_playground/generator_and_builder.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") 2 | 3 | PipeInfo = provider(fields = ["cc_info"]) 4 | 5 | def _filter_none(input_list): 6 | filtered_list = [] 7 | for element in input_list: 8 | if element != None: 9 | filtered_list.append(element) 10 | return filtered_list 11 | 12 | def _gen_comp_unit(ctx): 13 | src = ctx.actions.declare_file(ctx.label.name + ".cpp") 14 | hdr = ctx.actions.declare_file(ctx.label.name + ".h") 15 | ctx.actions.write(output = src, content = '#include "{}"'.format(hdr.basename)) 16 | ctx.actions.write(output = hdr, content = "") 17 | return src, hdr 18 | 19 | def _gen_code_impl(ctx): 20 | src, hdr = _gen_comp_unit(ctx) 21 | 22 | cc_toolchain = find_cpp_toolchain(ctx) 23 | feature_configuration = cc_common.configure_features( 24 | ctx = ctx, 25 | cc_toolchain = cc_toolchain, 26 | requested_features = ctx.features, 27 | unsupported_features = ctx.disabled_features, 28 | ) 29 | compilation_contexts = [] 30 | linking_contexts = [] 31 | for dep in ctx.attr.deps: 32 | if CcInfo in dep: 33 | compilation_contexts.append(dep[CcInfo].compilation_context) 34 | linking_contexts.append(dep[CcInfo].linking_context) 35 | 36 | (compilation_context, compilation_outputs) = cc_common.compile( 37 | name = ctx.label.name, 38 | actions = ctx.actions, 39 | feature_configuration = feature_configuration, 40 | cc_toolchain = cc_toolchain, 41 | public_hdrs = ctx.files.public_hdrs + [hdr], 42 | private_hdrs = ctx.files.private_hdrs, 43 | srcs = ctx.files.srcs + [src], 44 | includes = ctx.attr.includes + [src.dirname], 45 | quote_includes = ctx.attr.quote_includes, 46 | system_includes = ctx.attr.system_includes, 47 | defines = ctx.attr.defines, 48 | user_compile_flags = ctx.attr.user_compile_flags, 49 | compilation_contexts = compilation_contexts, 50 | ) 51 | (linking_context, linking_outputs) = cc_common.create_linking_context_from_compilation_outputs( 52 | name = ctx.label.name, 53 | actions = ctx.actions, 54 | feature_configuration = feature_configuration, 55 | cc_toolchain = cc_toolchain, 56 | language = "c++", 57 | compilation_outputs = compilation_outputs, 58 | linking_contexts = linking_contexts, 59 | ) 60 | 61 | files = [] 62 | files.extend(compilation_outputs.objects) 63 | files.extend(compilation_outputs.pic_objects) 64 | 65 | library = linking_outputs.library_to_link 66 | 67 | if library: 68 | files.append(library.pic_static_library) 69 | files.append(library.static_library) 70 | files.append(library.dynamic_library) 71 | 72 | cc_info = CcInfo( 73 | compilation_context = compilation_context, 74 | linking_context = linking_context, 75 | ) 76 | return [ 77 | DefaultInfo( 78 | files = depset(_filter_none(files)), 79 | ), 80 | cc_info, 81 | PipeInfo(cc_info = cc_info), 82 | ] 83 | 84 | gen_code = rule( 85 | implementation = _gen_code_impl, 86 | attrs = { 87 | "public_hdrs": attr.label_list(allow_files = [".h"]), 88 | "private_hdrs": attr.label_list(allow_files = [".h"]), 89 | "srcs": attr.label_list(allow_files = [".cc", ".cpp"]), 90 | "deps": attr.label_list( 91 | allow_empty = True, 92 | providers = [[CcInfo]], 93 | ), 94 | "user_compile_flags": attr.string_list(), 95 | "user_link_flags": attr.string_list(), 96 | "includes": attr.string_list(), 97 | "quote_includes": attr.string_list(), 98 | "system_includes": attr.string_list(), 99 | "defines": attr.string_list(), 100 | "alwayslink": attr.bool(default = False), 101 | "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"), 102 | }, 103 | fragments = ["cpp"], 104 | ) 105 | 106 | def _pipe_impl(ctx): 107 | return ctx.attr.src[PipeInfo].cc_info 108 | 109 | pipe = rule( 110 | implementation = _pipe_impl, 111 | attrs = { 112 | "src": attr.label(providers = [PipeInfo]), 113 | }, 114 | ) 115 | -------------------------------------------------------------------------------- /cc_sandwich_playground/lib.cpp: -------------------------------------------------------------------------------- 1 | #include "gen.h" 2 | 3 | -------------------------------------------------------------------------------- /cc_sandwich_playground/main.cpp: -------------------------------------------------------------------------------- 1 | int main(int argc, char* argv[]) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /config_test/.bazelrc: -------------------------------------------------------------------------------- 1 | test --test_output=all 2 | -------------------------------------------------------------------------------- /config_test/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/config_test/BUILD -------------------------------------------------------------------------------- /config_test/README.md: -------------------------------------------------------------------------------- 1 | # Scenario 2 | A test is linked against different libraries based on config settings. 3 | The test asserts that the only function in those libraries `int Foo()` returns a 0. 4 | 5 | By switching to the other libraries, the test fails, as the functions don't return 0. 6 | 7 | # Learning: 8 | This Config is not triggered by the --config=fail passed via the command line 9 | it triggers once the defines match the values. 10 | The --config option only selects the appropriate calls which are stored in the .bazelrc 11 | 12 | 13 | With this the test fails 14 | ``` 15 | bazel test //... --define test_outcome=fail 16 | ``` 17 | 18 | With this the test succeeds 19 | ``` 20 | e.g. bazel test //... --define test_outcome=succeed 21 | ``` 22 | 23 | With this the test fails again, but for a different reason. 24 | ``` 25 | bazel test //... --define test_outcome=succeed --define override= 26 | ``` 27 | -------------------------------------------------------------------------------- /config_test/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "config_test") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 4 | 5 | git_repository( 6 | name = "gtest", 7 | remote = "https://github.com/google/googletest.git", 8 | commit = "de5be0eb28b74ecd6335e3bd61d9dc8914ce0e57", 9 | ) 10 | -------------------------------------------------------------------------------- /config_test/sources/BUILD: -------------------------------------------------------------------------------- 1 | config_setting( 2 | name = "succeed", 3 | define_values = { 4 | "test_outcome": "succeed", 5 | }, 6 | ) 7 | 8 | config_setting( 9 | name = "fail", 10 | define_values = { 11 | "test_outcome": "fail", 12 | }, 13 | ) 14 | 15 | config_setting( 16 | name = "override", 17 | define_values = { 18 | "override": "", 19 | }, 20 | ) 21 | 22 | cc_library( 23 | name = "succeding_test", 24 | srcs = glob(["src/main_0.c", "include/*.h"]), 25 | hdrs = glob(["include/*.h"]), 26 | strip_include_prefix = "include", 27 | ) 28 | 29 | cc_library( 30 | name = "failing_test", 31 | srcs = glob(["src/main_1.c", "include/*.h"]), 32 | hdrs = glob(["include/*.h"]), 33 | strip_include_prefix = "include", 34 | ) 35 | 36 | cc_library( 37 | name = "other_failing_test", 38 | srcs = glob(["src/main_2.c", "include/*.h"]), 39 | hdrs = glob(["include/*.h"]), 40 | strip_include_prefix = "include", 41 | ) 42 | 43 | cc_library( 44 | name = "default_proxy", 45 | deps = select({ 46 | ":succeed": [":succeding_test"], 47 | ":fail": [":failing_test"], 48 | }), 49 | ) 50 | cc_library( 51 | name = "override_proxy", 52 | deps = select({ 53 | ":succeed": [":other_failing_test"], 54 | ":fail": [":other_failing_test"], 55 | }), 56 | ) 57 | 58 | cc_test( 59 | name = "foo_test", 60 | srcs = glob(["test/*.cpp", "test/*.h"]), 61 | deps = [ 62 | "@gtest//:gtest", 63 | "@gtest//:gtest_main", 64 | ] + select({ 65 | ":override": [":override_proxy"], 66 | "//conditions:default": [":default_proxy"], 67 | }), 68 | ) 69 | -------------------------------------------------------------------------------- /config_test/sources/include/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | int Foo(); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #endif /* MAIN_H */ 15 | -------------------------------------------------------------------------------- /config_test/sources/src/main_0.c: -------------------------------------------------------------------------------- 1 | int Foo() 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /config_test/sources/src/main_1.c: -------------------------------------------------------------------------------- 1 | int Foo() 2 | { 3 | return 1; 4 | } 5 | -------------------------------------------------------------------------------- /config_test/sources/src/main_2.c: -------------------------------------------------------------------------------- 1 | int Foo() 2 | { 3 | return 2; 4 | } 5 | -------------------------------------------------------------------------------- /config_test/sources/test/main_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "main.h" 4 | 5 | TEST(Foo, Bar) 6 | { 7 | EXPECT_EQ(Foo(), 0); 8 | } 9 | -------------------------------------------------------------------------------- /configuration/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/configuration/BUILD -------------------------------------------------------------------------------- /configuration/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/configuration/WORKSPACE -------------------------------------------------------------------------------- /configuration/myapp/BUILD: -------------------------------------------------------------------------------- 1 | # constraint_setting acts as an enum type, and constraint_value as an enum value. 2 | constraint_setting(name = "color") 3 | constraint_value(name = "black", constraint_setting = "color") 4 | constraint_value(name = "white", constraint_setting = "color") 5 | 6 | constraint_setting(name = "texture") 7 | constraint_value(name = "smooth", constraint_setting = "texture") 8 | 9 | constraint_setting(name = "type") 10 | constraint_value(name = "igneous", constraint_setting = "type") 11 | constraint_value(name = "metamorphic", constraint_setting = "type") 12 | 13 | platform( 14 | name = "basalt_platform", 15 | constraint_values = [ 16 | ":black", 17 | ":igneous", 18 | ], 19 | ) 20 | 21 | platform( 22 | name = "marble_platform", 23 | constraint_values = [ 24 | ":white", 25 | ":smooth", 26 | ":metamorphic", 27 | ], 28 | ) 29 | 30 | # Config settings that fire if all constraints are met 31 | config_setting( 32 | name = "basalt", 33 | constraint_values = [ 34 | ":black", 35 | ":igneous", 36 | ], 37 | ) 38 | 39 | config_setting( 40 | name = "marble", 41 | constraint_values = [ 42 | ":white", 43 | ":metamorphic", 44 | ], 45 | ) 46 | 47 | # Binary selecting the resulting binary on the matching config_setting 48 | sh_binary( 49 | name = "my_rocks", 50 | srcs = select({ 51 | ":basalt": ["pyroxene.sh"], 52 | ":marble": ["calcite.sh"], 53 | "//conditions:default": ["feldspar.sh"], 54 | }), 55 | ) 56 | -------------------------------------------------------------------------------- /configuration/myapp/calcite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "calcite!" 4 | 5 | -------------------------------------------------------------------------------- /configuration/myapp/feldspar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "feldspar!" 4 | -------------------------------------------------------------------------------- /configuration/myapp/pyroxene.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "pyroxene!" 4 | -------------------------------------------------------------------------------- /crosstool/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/BUILD -------------------------------------------------------------------------------- /crosstool/WORKSPACE: -------------------------------------------------------------------------------- 1 | 2 | new_http_archive( 3 | name = 'emscripten_toolchain', 4 | url = 'https://github.com/kripken/emscripten/archive/1.37.22.tar.gz', 5 | build_file = 'third-party/emscripten-toolchain.BUILD', 6 | strip_prefix = "emscripten-1.37.22", 7 | ) 8 | 9 | new_http_archive( 10 | name = 'emscripten_clang', 11 | url = 'https://s3.amazonaws.com/mozilla-games/emscripten/packages/llvm/tag/linux_64bit/emscripten-llvm-e1.37.22.tar.gz', 12 | build_file = 'third-party/emscripten-clang.BUILD', 13 | strip_prefix = "emscripten-llvm-e1.37.22", 14 | ) 15 | -------------------------------------------------------------------------------- /crosstool/main/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "helloworld.js", 3 | srcs = ["helloworld.cc"], 4 | ) 5 | -------------------------------------------------------------------------------- /crosstool/main/helloworld.cc: -------------------------------------------------------------------------------- 1 | // helloworld.cc 2 | #include 3 | 4 | int main() { 5 | printf("Hello, World!\n"); 6 | return 0; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /crosstool/third-party/emscripten-clang.BUILD: -------------------------------------------------------------------------------- 1 | 2 | # emscripten-clang.BUILD 3 | package(default_visibility = ['//visibility:public']) 4 | 5 | filegroup( 6 | name = "all", 7 | srcs = glob(["**/*"]), 8 | ) 9 | -------------------------------------------------------------------------------- /crosstool/third-party/emscripten-toolchain.BUILD: -------------------------------------------------------------------------------- 1 | # emscripten-toolchain.BUILD 2 | package(default_visibility = ['//visibility:public']) 3 | 4 | filegroup( 5 | name = "all", 6 | srcs = glob(["**/*"]), 7 | ) 8 | -------------------------------------------------------------------------------- /crosstool/toolchain/.gitattributes: -------------------------------------------------------------------------------- 1 | emscripten_cache/* binary 2 | -------------------------------------------------------------------------------- /crosstool/toolchain/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ['//visibility:public']) 2 | 3 | filegroup( name="empty" ) 4 | filegroup( 5 | name="all", 6 | srcs = [ 7 | "emcc.sh", 8 | "@emscripten_toolchain//:all", 9 | "@emscripten_clang//:all", 10 | ":emscripten_cache_content", 11 | ], 12 | 13 | ) 14 | 15 | filegroup( 16 | name = "emscripten_cache_content", 17 | srcs = glob(["emscripten_cache/**/*"]), 18 | ) 19 | 20 | cc_toolchain( 21 | name = "asmjs_toolchain", 22 | cpu = "asmjs", 23 | all_files = ":all", 24 | compiler_files = ":all", 25 | strip_files = ":empty", 26 | objcopy_files = ":empty", 27 | linker_files = ":all", 28 | dwp_files = ":empty", 29 | static_runtime_libs = [":empty"], 30 | dynamic_runtime_libs = [":empty"], 31 | supports_param_files = 0, 32 | ) 33 | 34 | cc_toolchain_suite( 35 | name="emscripten", 36 | toolchains = { 37 | "asmjs": "asmjs_toolchain" 38 | } 39 | ) 40 | -------------------------------------------------------------------------------- /crosstool/toolchain/CROSSTOOL: -------------------------------------------------------------------------------- 1 | major_version: "1" 2 | minor_version: "0" 3 | default_target_cpu: "asmjs" 4 | 5 | toolchain { 6 | toolchain_identifier: "asmjs-toolchain" 7 | host_system_name: "x86_linux" 8 | target_system_name: "asmjs-unknown-emscripten" 9 | target_cpu: "asmjs" 10 | target_libc: "unknown" 11 | compiler: "emscripten" 12 | abi_version: "unknown" 13 | abi_libc_version: "unknown" 14 | tool_path { 15 | name: "gcc" 16 | path: "emcc.sh" 17 | } 18 | 19 | tool_path { 20 | name: "ld" 21 | path: "emcc.sh" 22 | } 23 | 24 | tool_path { 25 | name: "ar" 26 | path: "/bin/false" 27 | } 28 | 29 | tool_path { 30 | name: "cpp" 31 | path: "/bin/false" 32 | } 33 | 34 | tool_path { 35 | name: "gcov" 36 | path: "/bin/false" 37 | } 38 | 39 | tool_path { 40 | name: "nm" 41 | path: "/bin/false" 42 | } 43 | 44 | tool_path { 45 | name: "objdump" 46 | path: "/bin/false" 47 | } 48 | 49 | tool_path { 50 | name: "strip" 51 | path: "/bin/false" 52 | } 53 | 54 | compiler_flag: "-isystem" 55 | compiler_flag: "external/emscripten_toolchain/system/include/libcxx" 56 | compiler_flag: "-isystem" 57 | compiler_flag: "external/emscripten_toolchain/system/include/libc" 58 | 59 | } 60 | 61 | 62 | default_toolchain { 63 | cpu: "asmjs", 64 | toolchain_identifier: "asmjs-toolchain" 65 | } 66 | 67 | -------------------------------------------------------------------------------- /crosstool/toolchain/emcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # toolchain/emcc.sh 3 | set -euo pipefail 4 | 5 | export LLVM_ROOT='external/emscripten_clang' 6 | export EMSCRIPTEN_NATIVE_OPTIMIZER='external/emscripten_clang/optimizer' 7 | export BINARYEN_ROOT='external/emscripten_clang/' 8 | export NODE_JS='' 9 | export EMSCRIPTEN_ROOT='external/emscripten_toolchain' 10 | export SPIDERMONKEY_ENGINE='' 11 | export EM_EXCLUSIVE_CACHE_ACCESS=1 12 | export EMCC_SKIP_SANITY_CHECK=1 13 | export EMCC_WASM_BACKEND=0 14 | 15 | mkdir -p "tmp/emscripten_cache" 16 | export EM_CACHE="tmp/emscripten_cache" 17 | export TEMP_DIR="tmp" 18 | 19 | # Prepare the cache content so emscripten doesn't try to rebuild it all the time 20 | cp -r toolchain/emscripten_cache/* tmp/emscripten_cache 21 | # Run emscripten to compile and link 22 | python external/emscripten_toolchain/emcc.py "$@" 23 | # Remove the first line of .d file (emscripten resisted all my attempts to make 24 | # it realize it's just the absolute location of the source) 25 | find . -name "*.d" -exec sed -i '2d' {} \; 26 | -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/binaryen_tag_version_38.txt: -------------------------------------------------------------------------------- 1 | version_38 -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/dlmalloc.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/toolchain/emscripten_cache/dlmalloc.bc -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/gl.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/toolchain/emscripten_cache/gl.bc -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/libc.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/toolchain/emscripten_cache/libc.bc -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/libcxxabi.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/toolchain/emscripten_cache/libcxxabi.bc -------------------------------------------------------------------------------- /crosstool/toolchain/emscripten_cache/wasm-libc.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/crosstool/toolchain/emscripten_cache/wasm-libc.bc -------------------------------------------------------------------------------- /dynamic_static_linking/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar") 2 | 3 | cc_library( 4 | name = "mylib", 5 | srcs = [ 6 | "library.cpp", 7 | "library.h", 8 | ], 9 | hdrs = ["library.h"], 10 | ) 11 | 12 | # This is runnable 13 | cc_binary( 14 | name = "bin_with_shared_dependencies", 15 | srcs = ["main.cpp"], 16 | linkstatic = False, 17 | deps = [":mylib"], 18 | ) 19 | 20 | # This fails to run 21 | # ./bin_with_invalid_shared_dependencies: error while loading shared libraries: liblibmylib.so: cannot open shared object file: No such file or directory 22 | cc_binary( 23 | name = "bin_with_invalid_shared_dependencies", 24 | srcs = ["main.cpp"], 25 | linkstatic = False, 26 | deps = [":mylib"], 27 | ) 28 | 29 | # This links completely static 30 | cc_binary( 31 | name = "bin_with_static_dependencies", 32 | srcs = ["main.cpp"], 33 | linkstatic = True, 34 | deps = [":mylib"], 35 | ) 36 | 37 | # This is basically an alias for mylib 38 | cc_binary( 39 | name = "libalias.so", 40 | linkshared = True, 41 | deps = [":mylib"], 42 | ) 43 | 44 | # Put it in a zip 45 | pkg_tar( 46 | name = "debian-data", 47 | srcs = [ 48 | ":bin_with_invalid_shared_dependencies", 49 | ":bin_with_shared_dependencies", 50 | ":bin_with_static_dependencies", 51 | ":mylib", 52 | ], 53 | extension = "tar.gz", 54 | ) 55 | -------------------------------------------------------------------------------- /dynamic_static_linking/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/dynamic_static_linking/WORKSPACE -------------------------------------------------------------------------------- /dynamic_static_linking/library.cpp: -------------------------------------------------------------------------------- 1 | #include "library.h" 2 | #include 3 | 4 | Library::Library() = default; 5 | void Library::HelloWorld() const noexcept 6 | { 7 | std::cout << "Hello World!" << std::endl; 8 | }; 9 | -------------------------------------------------------------------------------- /dynamic_static_linking/library.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_H 2 | #define LIBRARY_H 3 | 4 | class Library 5 | { 6 | public: 7 | Library(); 8 | 9 | void HelloWorld() const noexcept; 10 | }; 11 | 12 | #endif /* LIBRARY_H */ 13 | -------------------------------------------------------------------------------- /dynamic_static_linking/main.cpp: -------------------------------------------------------------------------------- 1 | #include "library.h" 2 | 3 | int main() 4 | { 5 | Library foo{}; 6 | foo.HelloWorld(); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /environments/.bazelrc: -------------------------------------------------------------------------------- 1 | test --test_output=all 2 | 3 | # Try out a few different variable definitions 4 | test --test_env=TEST_ENV_VARIABLE_WITH_VALUE=FOOBAR 5 | test --test_env=TEST_ENV_VARIABLE_WITHOUT_VALUE= 6 | test --test_env=TEST_ENV_VARIABLE_ONLY_DEFINED 7 | 8 | test --test_env=TEST_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FOOBAR 9 | test --test_env=TEST_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE= 10 | test --test_env=TEST_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED 11 | 12 | test:with_action --action_env=ACTION_ENV_VARIABLE_WITH_VALUE=FOOBAR 13 | test:with_action --action_env=ACTION_ENV_VARIABLE_WITHOUT_VALUE= 14 | test:with_action --action_env=ACTION_ENV_VARIABLE_ONLY_DEFINED 15 | 16 | test:with_action --action_env=ACTION_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FOOBAR 17 | test:with_action --action_env=ACTION_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE= 18 | test:with_action --action_env=ACTION_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED 19 | 20 | common --action_env=ACTION_ENV_VARIABLE_WITH_VALUE=FOOBAR 21 | common --action_env=ACTION_ENV_VARIABLE_WITHOUT_VALUE= 22 | common --action_env=ACTION_ENV_VARIABLE_ONLY_DEFINED 23 | -------------------------------------------------------------------------------- /environments/BUILD: -------------------------------------------------------------------------------- 1 | load("//:action_environment.bzl", "rule_env") 2 | 3 | sh_test( 4 | name = "environment_spy", 5 | size = "small", 6 | srcs = ["environment_spy.sh"], 7 | ) 8 | 9 | rule_env( 10 | name = "rule_env_spy", 11 | ) 12 | -------------------------------------------------------------------------------- /environments/README.md: -------------------------------------------------------------------------------- 1 | # What Test enviroments variable can be set by the user? 2 | 3 | Bazel does set some environment variables according to [this article](https://docs.bazel.build/versions/master/test-encyclopedia.html#initial-conditions) 4 | 5 | However some additional variables may need to be set. 6 | 7 | I created this small helper to check which environment variables get passed to the test in which way and to memorize it more easily. 8 | 9 | # 'Test' setup 10 | 11 | I defined 6 env-vars in the [.bazelrc](./.bazelrc) that should be passed to the test. 12 | Use this small snippet to run the test binary. 13 | 14 | ```bash 15 | export TEST_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FIZZBUZZ 16 | export TEST_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE=FIZZBUZZ 17 | export TEST_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED=FIZZBUZZ 18 | export ACTION_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FIZZBUZZ 19 | export ACTION_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE=FIZZBUZZ 20 | export ACTION_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED=FIZZBUZZ 21 | 22 | # This will show you which environment variables the test executable sees 23 | bazel test ... 2>&1 | grep ENV_VARIABLE 24 | ``` 25 | 26 | # Output with bazel 0.23.2 27 | 28 | With only `--test_env`'s being set. [ref](https://docs.bazel.build/versions/master/command-line-reference.html#flag--test_env) 29 | ```bash 30 | $ bazel test ... 2>&1 | grep ENV_VARIABLE 31 | TEST_ENV_VARIABLE_WITH_VALUE=FOOBAR 32 | TEST_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE= 33 | TEST_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FOOBAR 34 | TEST_ENV_VARIABLE_WITHOUT_VALUE= 35 | TEST_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED=FIZZBUZZ 36 | ``` 37 | 38 | With `--action_env`'s being set. [ref](https://docs.bazel.build/versions/master/command-line-reference.html#flag--action_env) 39 | ```bash 40 | $ bazel test ... --config with_action 2>&1 | grep ENV_VARIABLE 41 | TEST_ENV_VARIABLE_WITH_VALUE=FOOBAR 42 | TEST_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE= 43 | ACTION_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FOOBAR 44 | ACTION_ENV_VARIABLE_WITH_VALUE=FOOBAR 45 | TEST_ENV_VARIABLE_FROM_ENV_WITH_VALUE=FOOBAR 46 | ACTION_ENV_VARIABLE_FROM_ENV_WITHOUT_VALUE= 47 | TEST_ENV_VARIABLE_WITHOUT_VALUE= 48 | TEST_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED=FIZZBUZZ 49 | ACTION_ENV_VARIABLE_WITHOUT_VALUE= 50 | ACTION_ENV_VARIABLE_FROM_ENV_ONLY_DEFINED=FIZZBUZZ 51 | ``` 52 | -------------------------------------------------------------------------------- /environments/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/environments/WORKSPACE -------------------------------------------------------------------------------- /environments/action_environment.bzl: -------------------------------------------------------------------------------- 1 | def _rule_env_impl(ctx): 2 | exe = ctx.actions.declare_file(ctx.attr.name) 3 | args = ctx.actions.args() 4 | args.add(exe) 5 | ctx.actions.run_shell( 6 | inputs = [], 7 | outputs = [exe], 8 | command = """ 9 | set -x 10 | printenv 11 | echo "single variables" 12 | printenv action_env_variable_with_value 13 | printenv action_env_variable_without_value 14 | printenv action_env_variable_only_defined 15 | echo "/bin/true" > $1 16 | """, 17 | env = { 18 | "ACTION_ENV_VARIABLE_WITH_VALUE": "", 19 | "ACTION_ENV_VARIABLE_WITHOUT_VALUE": "", 20 | "ACTION_ENV_VARIABLE_ONLY_DEFINED": "", 21 | }, 22 | arguments = [args], 23 | ) 24 | return DefaultInfo(executable = exe) 25 | 26 | rule_env = rule( 27 | executable = True, 28 | implementation = _rule_env_impl, 29 | ) 30 | -------------------------------------------------------------------------------- /environments/environment_spy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "printing Environment:" 4 | printenv 5 | echo "done" 6 | 7 | exit 0 8 | -------------------------------------------------------------------------------- /error_masking_with_includes/README.md: -------------------------------------------------------------------------------- 1 | # Possible error masking when only using includes 2 | 3 | The code has a intentional warning. 4 | ```bash 5 | [...]library_includes.h:10:13: error: unused variable 'a' [-Werror=unused-variable] 6 | int a{}; 7 | ``` 8 | 9 | Compiled with `-Werror` the build should fail when building. 10 | Since the warning is in the header, the build should fail. 11 | 12 | ```bash 13 | bazel build //includes_and_strip_prefix 14 | ``` 15 | Building only with strip prefix and includes fails as expected 16 | 17 | ```bash 18 | bazel build //only_strip_prefix 19 | ``` 20 | Building only with strip prefix fails as expected 21 | 22 | 23 | 24 | ```bash 25 | bazel build //only_includes 26 | ``` 27 | Building only with includes does compile! which it shouldn't 28 | -------------------------------------------------------------------------------- /error_masking_with_includes/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/error_masking_with_includes/WORKSPACE -------------------------------------------------------------------------------- /error_masking_with_includes/includes_and_strip_prefix/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "includes_and_strip_prefix", 3 | srcs = glob(["src/*.cpp"]), 4 | hdrs = glob(["include/**/*.h"]), 5 | copts = [ 6 | "-Wextra", 7 | "-Wall", 8 | "-Wpedantic", 9 | "-Werror", 10 | ], 11 | includes = ["include"], 12 | strip_include_prefix = "include", 13 | visibility = ["//visibility:public"], 14 | ) 15 | -------------------------------------------------------------------------------- /error_masking_with_includes/includes_and_strip_prefix/include/lib/library_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_INCLUDES_H 2 | #define LIBRARY_INCLUDES_H 3 | 4 | class LibraryIncludes 5 | { 6 | public: 7 | LibraryIncludes(); 8 | void ThisShouldTriggerAWarning() 9 | { 10 | int a{}; 11 | }; 12 | }; 13 | 14 | #endif /* LIBRARY_INCLUDES_H */ 15 | -------------------------------------------------------------------------------- /error_masking_with_includes/includes_and_strip_prefix/src/library_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_includes.h" 2 | 3 | LibraryIncludes::LibraryIncludes() = default; 4 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_includes/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "only_includes", 3 | srcs = glob(["src/*.cpp"]), 4 | hdrs = glob(["include/**/*.h"]), 5 | copts = [ 6 | "-Wextra", 7 | "-Wall", 8 | "-Wpedantic", 9 | "-Werror", 10 | ], 11 | includes = ["include"], 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_includes/include/lib/library_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_INCLUDES_H 2 | #define LIBRARY_INCLUDES_H 3 | 4 | class LibraryIncludes 5 | { 6 | public: 7 | LibraryIncludes(); 8 | void ThisShouldTriggerAWarning() 9 | { 10 | int a{}; 11 | }; 12 | }; 13 | 14 | #endif /* LIBRARY_INCLUDES_H */ 15 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_includes/src/library_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_includes.h" 2 | 3 | LibraryIncludes::LibraryIncludes() = default; 4 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_strip_prefix/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "only_strip_prefix", 3 | srcs = glob(["src/*.cpp"]), 4 | hdrs = glob(["include/**/*.h"]), 5 | copts = [ 6 | "-Wextra", 7 | "-Wall", 8 | "-Wpedantic", 9 | "-Werror", 10 | ], 11 | strip_include_prefix = "include", 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_strip_prefix/include/lib/library_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_INCLUDES_H 2 | #define LIBRARY_INCLUDES_H 3 | 4 | class LibraryIncludes 5 | { 6 | public: 7 | LibraryIncludes(); 8 | void ThisShouldTriggerAWarning() 9 | { 10 | int a{}; 11 | }; 12 | }; 13 | 14 | #endif /* LIBRARY_INCLUDES_H */ 15 | -------------------------------------------------------------------------------- /error_masking_with_includes/only_strip_prefix/src/library_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_includes.h" 2 | 3 | LibraryIncludes::LibraryIncludes() = default; 4 | -------------------------------------------------------------------------------- /find_all_tests/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "b", 3 | srcs = ["main.cpp"], 4 | deps = [ 5 | "//l1", 6 | "//l2", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /find_all_tests/README.md: -------------------------------------------------------------------------------- 1 | # Find & run all dependend tests of a target 2 | 3 | Assume you have a binary `b` which aggregates multible libraries `l1, l2`. 4 | If you want to run all all tests that test depend on the libraries which were used when building `b`, 5 | 6 | Of course you could run all tests using `bazel test ...` but this is not considered an option for this case. 7 | 8 | You can use some bazel queries to achieve that. 9 | This is the final call: 10 | ```bash 11 | bazel test $(bazel query --noimplicit_deps 'tests(rdeps(set(//...), deps(//:b)))') 12 | ``` 13 | 14 | Let's disect it: 15 | `$ assumes bazel query for simplicity` 16 | 17 | 1. We need to get the targets on which `b` depends using [deps](https://docs.bazel.build/versions/master/query.html#deps) 18 | 19 | ```bash 20 | $ 'deps(//:b)' 21 | ``` 22 | 23 | Yields all dependencies including the toolchain dependencies, lets circumvent this: 24 | 25 | ```bash 26 | $ --noimplicit_deps 'deps(//:b)' 27 | ``` 28 | 29 | 2. Now we have all libraries of which we want to execute the tests. 30 | We can find them using the simple case of [rdeps](https://docs.bazel.build/versions/master/query.html#rdeps) 31 | 32 | For our universe set we use all targets `set(//...)` 33 | 34 | ```bash 35 | $ --noimplicit_deps 'rdeps(set(//...), deps(//:b))' 36 | ``` 37 | This yields also our test targets. 38 | 39 | 3. In the last step, the targets are filtered for test labels. query has a function for that: [tests](https://docs.bazel.build/versions/master/query.html#tests) 40 | ```bash 41 | $ --noimplicit_deps 'tests(rdeps(set(//...), deps(//:b)))' 42 | ``` 43 | 44 | 4. Pipe the results to a `bazel test` call using a subshell 45 | ```bash 46 | $ bazel test $(bazel query --noimplicit_deps 'tests(rdeps(set(//...), deps(//:b)))') 47 | //l1:l1_test PASSED in 0.1s 48 | //l2:l2_test PASSED in 0.1s 49 | //l2/tests:l2_test PASSED in 0.1s 50 | ``` 51 | 52 | ## Conclusion 53 | 54 | As `bazel test ...` would execute all tests. More than required in this case. 55 | ```diff 56 | # diff <(bazel test ... --nocache_test_results) <(bazel query --noimplicit_deps 'let target=//:b in let closure=//... in tests(rdeps(set($closure), deps($target)))') -y 2 ↵ 57 | //l1:l1_test | //l1:l1_test 58 | //l2:l2_test | //l2:l2_test 59 | //l2/tests:l2_test | //l2/tests:l2_test 60 | //l3:l3_test < 61 | ``` 62 | 63 | Using rdeps allows to run the tests that directly go into the selected closure. 64 | 65 | You could even name the variables: 66 | ``` 67 | $ --noimplicit_deps 'let target=//:b in let closure=//... in tests(rdeps(set($closure), deps($target)))' 68 | ``` 69 | 70 | ## References 71 | 72 | 1) [bazel query doc](https://docs.bazel.build/versions/master/query.html) 73 | 2) [bazel query how-to](https://docs.bazel.build/versions/master/query-how-to.html) 74 | -------------------------------------------------------------------------------- /find_all_tests/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3 | 4 | # Abseil 5 | http_archive( 6 | name = "com_google_absl", 7 | sha256 = "d5dcbef22d30d89e2ce61fffa3e4308b760aa2197c875ddcec014d11841b1ef2", 8 | strip_prefix = "abseil-cpp-master", 9 | urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], 10 | ) 11 | 12 | git_repository( 13 | name = "googletest", 14 | remote = "https://github.com/google/googletest", 15 | tag = "release-1.8.1", 16 | ) 17 | -------------------------------------------------------------------------------- /find_all_tests/l1/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "l1", 3 | srcs = ["library1.cpp"], 4 | hdrs = ["library1.h"], 5 | strip_include_prefix = ".", 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_test( 10 | name = "l1_test", 11 | srcs = ["test.cpp"], 12 | deps = [ 13 | "l1", 14 | "@googletest//:gtest_main", 15 | ], 16 | ) 17 | -------------------------------------------------------------------------------- /find_all_tests/l1/library1.cpp: -------------------------------------------------------------------------------- 1 | #include "library1.h" 2 | 3 | Library1::Library1() = default; 4 | -------------------------------------------------------------------------------- /find_all_tests/l1/library1.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY1_H 2 | #define LIBRARY1_H 3 | 4 | class Library1 5 | { 6 | public: 7 | Library1(); 8 | }; 9 | 10 | #endif /* LIBRARY1_H */ 11 | -------------------------------------------------------------------------------- /find_all_tests/l1/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "library1.h" 3 | 4 | TEST(Foo, Bar) 5 | { 6 | Library1 a{}; 7 | } 8 | -------------------------------------------------------------------------------- /find_all_tests/l2/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "l2", 3 | srcs = ["library2.cpp"], 4 | hdrs = ["library2.h"], 5 | strip_include_prefix = ".", 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_test( 10 | name = "l2_test", 11 | srcs = ["test.cpp"], 12 | deps = [ 13 | "l2", 14 | "@googletest//:gtest_main", 15 | ], 16 | ) 17 | -------------------------------------------------------------------------------- /find_all_tests/l2/library2.cpp: -------------------------------------------------------------------------------- 1 | #include "library2.h" 2 | 3 | Library2::Library2() = default; 4 | -------------------------------------------------------------------------------- /find_all_tests/l2/library2.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY2_H 2 | #define LIBRARY2_H 3 | 4 | class Library2 5 | { 6 | public: 7 | Library2(); 8 | }; 9 | 10 | #endif /* LIBRARY2_H */ 11 | -------------------------------------------------------------------------------- /find_all_tests/l2/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "library2.h" 3 | 4 | TEST(Foo, Bar) 5 | { 6 | Library2 a{}; 7 | } 8 | -------------------------------------------------------------------------------- /find_all_tests/l2/tests/BUILD: -------------------------------------------------------------------------------- 1 | cc_test( 2 | name = "l2_test", 3 | srcs = ["test.cpp"], 4 | deps = [ 5 | "//l2", 6 | "@googletest//:gtest_main", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /find_all_tests/l2/tests/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "library2.h" 3 | 4 | TEST(Foo, Bar) 5 | { 6 | Library2 a{}; 7 | } 8 | -------------------------------------------------------------------------------- /find_all_tests/l3/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "l3", 3 | srcs = ["library3.cpp"], 4 | hdrs = ["library3.h"], 5 | strip_include_prefix = ".", 6 | visibility = ["//visibility:public"], 7 | ) 8 | 9 | cc_test( 10 | name = "l3_test", 11 | srcs = ["test.cpp"], 12 | deps = [ 13 | "l3", 14 | "@googletest//:gtest_main", 15 | ], 16 | ) 17 | -------------------------------------------------------------------------------- /find_all_tests/l3/library3.cpp: -------------------------------------------------------------------------------- 1 | #include "library3.h" 2 | 3 | Library3::Library3() = default; 4 | -------------------------------------------------------------------------------- /find_all_tests/l3/library3.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY3_H 2 | #define LIBRARY3_H 3 | 4 | class Library3 5 | { 6 | public: 7 | Library3(); 8 | }; 9 | 10 | #endif /* LIBRARY3_H */ 11 | -------------------------------------------------------------------------------- /find_all_tests/l3/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "library3.h" 3 | 4 | TEST(Foo, Bar) 5 | { 6 | Library3 a{}; 7 | } 8 | -------------------------------------------------------------------------------- /find_all_tests/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | Library1 a{}; 7 | Library2 b{}; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/BUILD: -------------------------------------------------------------------------------- 1 | package( 2 | default_visibility = ['//visibility:public'] 3 | ) 4 | 5 | load(":genccs.bzl", "genccs", "genlib") 6 | 7 | 8 | genccs( 9 | name = "foo_gen", 10 | n = 5, 11 | ) 12 | 13 | genlib( 14 | name = "foo_lib", 15 | n = 5, 16 | ) 17 | 18 | cc_binary( 19 | name = "bar", 20 | srcs = ["src/main.cc", "foo_gen"], 21 | ) 22 | 23 | cc_binary( 24 | name = "bar2", 25 | srcs = ["src/main.cc"], 26 | deps = [":foo_lib"] 27 | ) 28 | -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/generate_arbitrary_number_of_files/WORKSPACE -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/genccs.bzl: -------------------------------------------------------------------------------- 1 | def _impl(ctx): 2 | tree = ctx.actions.declare_directory(ctx.attr.name) 3 | ctx.actions.run( 4 | inputs = [], 5 | outputs = [ tree ], 6 | arguments = ['-o', tree.path, '-n', str(ctx.attr.n) ], 7 | progress_message = "Generating cc files into '%s'" % tree.path, 8 | executable = ctx.executable._tool, 9 | ) 10 | 11 | return [ DefaultInfo(files = depset([ tree ])) ] 12 | 13 | genccs = rule( 14 | implementation = _impl, 15 | attrs = { 16 | "n": attr.int(mandatory=True), 17 | "_tool": attr.label( 18 | executable = True, 19 | cfg = "host", 20 | allow_files = True, 21 | default = Label("//py_binary:py_gen"), 22 | ) 23 | }, 24 | output_to_genfiles = True, 25 | ) 26 | 27 | def genlib(name, n, **kwargs): 28 | genccs(name='gen_'+name, n=n) 29 | native.cc_library( 30 | name = name, 31 | srcs = [":gen_{}".format(name)], 32 | **kwargs 33 | ) 34 | -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/py_binary/BUILD: -------------------------------------------------------------------------------- 1 | py_binary( 2 | name = "py_gen", 3 | srcs = ["py_gen.py"], 4 | deps = [], 5 | main = "py_gen.py", 6 | visibility = ['//visibility:public'] 7 | ) 8 | 9 | 10 | -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/py_binary/py_gen.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import argparse 4 | import sys 5 | import os 6 | import random 7 | 8 | 9 | def main(out_directory, number): 10 | possible_artifacts = ['Main_%s'%c for c in 'abcdefghijklmnobqrstuvwxyz'] 11 | os.makedirs(out_directory) 12 | for i, artifact in enumerate(random.sample(possible_artifacts, k=number)): 13 | print('Generating', i, artifact) 14 | with open(os.path.join(out_directory, '{}.cc'.format(artifact)), 'w') as f: 15 | f.write(""" 16 | // Sample content: {i} - {art} 17 | """.format(i=i, art=artifact)) 18 | 19 | 20 | 21 | 22 | def get_arguments(): 23 | parser = argparse.ArgumentParser() 24 | parser.add_argument("-o", "--output_directory", default=None) 25 | parser.add_argument("-n", "--number_of_outs", default=1, type=int) 26 | return parser.parse_args() 27 | 28 | if __name__ == "__main__": 29 | args = get_arguments() 30 | print(args) 31 | main(args.output_directory, args.number_of_outs) 32 | -------------------------------------------------------------------------------- /generate_arbitrary_number_of_files/src/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char* argv[]) 3 | { 4 | std::cerr << "Hello world" << '\n'; 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /generated_sources/BUILD: -------------------------------------------------------------------------------- 1 | load("//:rule.bzl", "generator") 2 | 3 | generator( 4 | name = "gen", 5 | ) 6 | 7 | cc_library( 8 | name = "lib", 9 | srcs = ["source.c"], 10 | deps = [ 11 | ":gen", 12 | "//generated", 13 | ], 14 | ) 15 | -------------------------------------------------------------------------------- /generated_sources/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | 3 | git_repository( 4 | name = "bazel_skylib", 5 | remote = "https://github.com/bazelbuild/bazel-skylib.git", 6 | tag = "1.0.2", 7 | ) 8 | -------------------------------------------------------------------------------- /generated_sources/generated/BUILD: -------------------------------------------------------------------------------- 1 | load("//:rule.bzl", "generator") 2 | 3 | generator( 4 | name = "generated", 5 | visibility = ["//:__pkg__"], 6 | ) 7 | -------------------------------------------------------------------------------- /generated_sources/rule.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//lib:paths.bzl", "paths") 2 | 3 | _CONTENT = """#ifndef HEADER_GUARD_H 4 | #define HEADER_GUARD_H 5 | 6 | extern int foo; 7 | 8 | #endif 9 | """ 10 | 11 | def _generator_impl(ctx): 12 | out = ctx.actions.declare_file(paths.join(ctx.label.name, ctx.label.name + ".h")) 13 | ctx.actions.write( 14 | output = out, 15 | content = _CONTENT, 16 | ) 17 | 18 | return [ 19 | DefaultInfo(files = depset([out])), 20 | CcInfo(compilation_context = cc_common.create_compilation_context( 21 | headers = depset([out]), 22 | includes = depset([out.dirname]), 23 | )), 24 | ] 25 | 26 | generator = rule( 27 | implementation = _generator_impl, 28 | attrs = {}, 29 | ) 30 | -------------------------------------------------------------------------------- /generated_sources/source.c: -------------------------------------------------------------------------------- 1 | #include "gen.h" 2 | #include "generated.h" 3 | 4 | -------------------------------------------------------------------------------- /genrule/BUILD: -------------------------------------------------------------------------------- 1 | py_binary( 2 | name = "generator", 3 | srcs = ["generator.py"], 4 | ) 5 | 6 | genrule( 7 | name = "foo", 8 | srcs = [], 9 | outs = ["hello_world.cpp"], 10 | cmd = "$(location :generator) \"$@\" foo", 11 | tools = [":generator"], 12 | ) 13 | 14 | genrule( 15 | name = "concat_all_files", 16 | srcs = [ 17 | ":foo", # a genrule with a single output ==> $(location) 18 | ], 19 | outs = ["concatenated.txt"], 20 | cmd = "cat $(location :foo) > $@", 21 | ) 22 | 23 | cc_binary( 24 | name = "generated", 25 | srcs = [ 26 | ":foo", 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /genrule/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/genrule/WORKSPACE -------------------------------------------------------------------------------- /genrule/generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | from string import Template 4 | 5 | s = Template('''#include 6 | 7 | int main(int, char**) { 8 | std::cout << "$what" << '\\n'; 9 | return 0; 10 | } 11 | ''') 12 | 13 | if __name__ == "__main__": 14 | where = sys.argv[1] 15 | what = sys.argv[2] 16 | 17 | with open(where, 'w') as f: 18 | f.write(s.substitute(what=what)) 19 | -------------------------------------------------------------------------------- /genrule/out.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main() { 5 | std::cout << "Hello World" << '\n'; 6 | } 7 | -------------------------------------------------------------------------------- /genrule_outs/.bazelrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/genrule_outs/.bazelrc -------------------------------------------------------------------------------- /genrule_outs/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.29.1 2 | -------------------------------------------------------------------------------- /genrule_outs/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:write_file.bzl", "write_file") 2 | 3 | write_file( 4 | name = "generator", 5 | out = "gen.cpp", 6 | content = [], 7 | ) 8 | 9 | write_file( 10 | name = "generator2", 11 | out = "gen.cpp", 12 | content = [], 13 | ) 14 | 15 | genrule( 16 | name = "receiver_cpp", 17 | outs = ["generated_communication_mappingreceiver.cpp"], 18 | cmd = "echo '' > $@", 19 | ) 20 | 21 | cc_library( 22 | name = "foo", 23 | srcs = ["gen.cpp"], 24 | ) 25 | 26 | cc_library( 27 | name = "bar", 28 | srcs = ["generator"], 29 | ) 30 | -------------------------------------------------------------------------------- /genrule_outs/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | 3 | git_repository( 4 | name = "bazel_skylib", 5 | remote = "https://github.com/bazelbuild/bazel-skylib.git", 6 | tag = "1.0.2", 7 | ) 8 | -------------------------------------------------------------------------------- /genrule_outs/custom_rule.bzl: -------------------------------------------------------------------------------- 1 | def _custom_rule_impl(ctx): 2 | pass 3 | 4 | custom_rule = rule( 5 | implementation = _custom_rule_impl, 6 | attrs = { 7 | }, 8 | ) 9 | -------------------------------------------------------------------------------- /genrule_outs/foo.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/genrule_outs/foo.cpp -------------------------------------------------------------------------------- /implicit_outputs/BUILD: -------------------------------------------------------------------------------- 1 | load(":implicit_outputs.bzl", "implicit_outputs") 2 | 3 | implicit_outputs( 4 | name = "bar", 5 | out = "foobar.txt", 6 | ) 7 | 8 | filegroup( 9 | name = "outs", 10 | srcs = [ 11 | "foobar.txt", 12 | ], 13 | ) 14 | -------------------------------------------------------------------------------- /implicit_outputs/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/implicit_outputs/WORKSPACE -------------------------------------------------------------------------------- /implicit_outputs/implicit_outputs.bzl: -------------------------------------------------------------------------------- 1 | def _implicit_outputs_impl(ctx): 2 | ctx.actions.write(output = ctx.outputs.out, content = "foobar") 3 | 4 | implicit_outputs = rule( 5 | implementation = _implicit_outputs_impl, 6 | attrs = { 7 | "out": attr.output(), 8 | }, 9 | ) 10 | -------------------------------------------------------------------------------- /include_handling/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/include_handling/WORKSPACE -------------------------------------------------------------------------------- /include_handling/library_includer/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_library( 3 | name = "lib", 4 | srcs = glob(["src/*.cpp", "include/**/*.h"]), 5 | hdrs = glob(["include/**/*.h"]), 6 | strip_include_prefix = "include", 7 | deps = [ 8 | "//private_headers:lib", 9 | "//strip_prefix_library:lib", 10 | "//using_includes:lib", 11 | ], 12 | visibility = ["//visibility:public"], 13 | ) 14 | -------------------------------------------------------------------------------- /include_handling/library_includer/include/lib/library_includer.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_INCLUDER_H 2 | #define LIBRARY_INCLUDER_H 3 | 4 | class LibraryIncluder 5 | { 6 | public: 7 | LibraryIncluder(); 8 | }; 9 | 10 | #endif /* LIBRARY_INCLUDER_H */ 11 | -------------------------------------------------------------------------------- /include_handling/library_includer/src/library_includer.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_includer.h" 2 | 3 | // other includes 4 | 5 | #include "lib/library_includes.h" 6 | #include "lib/library_prefix.h" 7 | #include "lib/library_private.h" 8 | 9 | // These two headers should not be found since they are supposedly private headers of library_private 10 | #include "private_header.h" 11 | #include "sub/sub.h" 12 | 13 | LibraryIncluder::LibraryIncluder() = default; 14 | -------------------------------------------------------------------------------- /include_handling/no_public_headers/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = glob(["src/**/*", "include/**/*"]), 4 | visibility = ["//visibility:public"], 5 | ) 6 | -------------------------------------------------------------------------------- /include_handling/no_public_headers/src/implementation.cpp: -------------------------------------------------------------------------------- 1 | #include "implementation.h" 2 | 3 | Implementation::Implementation() {} 4 | -------------------------------------------------------------------------------- /include_handling/no_public_headers/src/implementation.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPLEMENTATION_H 2 | #define IMPLEMENTATION_H 3 | 4 | class Implementation 5 | { 6 | public: 7 | Implementation(); 8 | }; 9 | 10 | #endif /* IMPLEMENTATION_H */ 11 | -------------------------------------------------------------------------------- /include_handling/private_headers/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib_private", 3 | srcs = glob(["src/**/*.h"]), 4 | hdrs = glob(["src/**/*.h"]), 5 | strip_include_prefix = "src", 6 | visibility = ["//visibility:__pkg__"], 7 | ) 8 | 9 | cc_library( 10 | name = "lib", 11 | # The srcs that exclude the src/sub directory would not compile on its own because 12 | # src/sub/sub.h is included via #include 13 | # This requires that a include path to src is set. 14 | # This can only be done via a seperate cc_library 15 | # --> Only one strip_include_prefix is possible 16 | # --> However this makes the supposedly private library public to all dependening on lib 17 | # 18 | # sub.cpp does not compile because of not being found. 19 | # One solution would be to add a helper library (lib_private) 20 | # However this leaks the includes to other libraries depending on lib 21 | srcs = glob(["src/**/*", "include/**/*"]), 22 | # !!! Leaks private dependencies transitively !!! 23 | deps = [":lib_private"], 24 | 25 | # Uncomment this to ignore the sub module for compilation 26 | # srcs = glob(["src/**/*", "include/**/*"], exclude=["src/sub/*"]), 27 | 28 | hdrs = glob(["include/**/*.h"]), 29 | strip_include_prefix = "include", 30 | visibility = ["//visibility:public"], 31 | ) 32 | -------------------------------------------------------------------------------- /include_handling/private_headers/include/lib/library_private.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_PRIVATE_H 2 | #define LIBRARY_PRIVATE_H 3 | 4 | class LibraryPrivate 5 | { 6 | public: 7 | LibraryPrivate(); 8 | }; 9 | 10 | #endif /* LIBRARY_PRIVATE_H */ 11 | -------------------------------------------------------------------------------- /include_handling/private_headers/src/library_private.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_private.h" 2 | 3 | LibraryPrivate::LibraryPrivate() {} 4 | -------------------------------------------------------------------------------- /include_handling/private_headers/src/private_header.cpp: -------------------------------------------------------------------------------- 1 | #include "private_header.h" 2 | 3 | PrivateHeader::PrivateHeader() {} 4 | -------------------------------------------------------------------------------- /include_handling/private_headers/src/private_header.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_HEADER_H 2 | #define PRIVATE_HEADER_H 3 | 4 | class PrivateHeader 5 | { 6 | public: 7 | PrivateHeader(); 8 | }; 9 | 10 | #endif /* PRIVATE_HEADER_H */ 11 | -------------------------------------------------------------------------------- /include_handling/private_headers/src/sub/sub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /include_handling/private_headers/src/sub/sub.h: -------------------------------------------------------------------------------- 1 | #ifndef SUB_H 2 | #define SUB_H 3 | 4 | class Sub 5 | { 6 | public: 7 | Sub(); 8 | }; 9 | 10 | #endif /* SUB_H */ 11 | -------------------------------------------------------------------------------- /include_handling/strip_prefix_library/BUILD: -------------------------------------------------------------------------------- 1 | 2 | cc_library( 3 | name = "lib", 4 | srcs = glob(["src/*.cpp", "include/**/*.h"]), 5 | hdrs = glob(["include/**/*.h"]), 6 | strip_include_prefix = "include", 7 | visibility = ["//visibility:public"], 8 | ) 9 | -------------------------------------------------------------------------------- /include_handling/strip_prefix_library/include/lib/library_prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_PREFIX_H 2 | #define LIBRARY_PREFIX_H 3 | 4 | class LibraryPrefix 5 | { 6 | public: 7 | LibraryPrefix(); 8 | }; 9 | 10 | #endif /* LIBRARY_PREFIX_H */ 11 | -------------------------------------------------------------------------------- /include_handling/strip_prefix_library/src/library_prefix.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_prefix.h" 2 | 3 | LibraryPrefix::LibraryPrefix() {} 4 | -------------------------------------------------------------------------------- /include_handling/using_includes/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "lib", 3 | srcs = glob(["src/*.cpp"]), 4 | hdrs = glob(["include/**/*.h"]), 5 | copts = [ 6 | "-Wextra", 7 | "-Wall", 8 | "-Wpedantic", 9 | "-Werror", 10 | ], 11 | includes = ["include"], 12 | strip_include_prefix = "include", 13 | visibility = ["//visibility:public"], 14 | ) 15 | -------------------------------------------------------------------------------- /include_handling/using_includes/include/lib/library_includes.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_INCLUDES_H 2 | #define LIBRARY_INCLUDES_H 3 | 4 | class LibraryIncludes 5 | { 6 | public: 7 | LibraryIncludes(); 8 | void ThisShouldTriggerAWarning() 9 | { 10 | int a{}; 11 | }; 12 | }; 13 | 14 | #endif /* LIBRARY_INCLUDES_H */ 15 | -------------------------------------------------------------------------------- /include_handling/using_includes/src/library_includes.cpp: -------------------------------------------------------------------------------- 1 | #include "lib/library_includes.h" 2 | 3 | LibraryIncludes::LibraryIncludes() = default; 4 | -------------------------------------------------------------------------------- /packaging/.bazelversion: -------------------------------------------------------------------------------- 1 | 3.4.0 2 | -------------------------------------------------------------------------------- /packaging/BUILD: -------------------------------------------------------------------------------- 1 | load("//:generate_files.bzl", "generate_files") 2 | load("@rules_pkg//:pkg.bzl", "pkg_deb", "pkg_tar") 3 | 4 | pkg_tar( 5 | name = "lib", 6 | srcs = ["//my_library"], 7 | mode = "0755", 8 | package_dir = "/usr/lib", 9 | ) 10 | 11 | pkg_deb( 12 | name = "my_library-dev", 13 | architecture = "amd64", 14 | built_using = "bazel (0.26.1)", 15 | data = ":lib", 16 | description_file = "README.md", 17 | homepage = "https://foo.bar.de", 18 | maintainer = "John Doe ", 19 | package = "my_library-dev", 20 | version = "0.0.4", 21 | ) 22 | 23 | prefix = "out_dir" 24 | 25 | generate_files( 26 | name = "bar", 27 | prefix = prefix, 28 | ) 29 | 30 | pkg_tar( 31 | name = "pkg_subdir", 32 | srcs = [":bar"], 33 | package_dir = "/usr", 34 | strip_prefix = prefix, 35 | ) 36 | 37 | pkg_deb( 38 | name = "sub_packages-dev", 39 | architecture = "amd64", 40 | built_using = "bazel (0.26.1)", 41 | data = ":pkg_subdir", 42 | description_file = "README.md", 43 | homepage = "https://foo.bar.de", 44 | maintainer = "John Doe ", 45 | package = "sub_packages-dev", 46 | version = "0.0.1", 47 | ) 48 | 49 | genrule( 50 | name = "gen_version_file", 51 | outs = ["version"], 52 | cmd = "echo 'version 0.0.42' > $@", 53 | ) 54 | 55 | pkg_deb( 56 | name = "generated_version_file", 57 | architecture = "amd64", 58 | built_using = "bazel (0.26.1)", 59 | data = ":pkg_subdir", 60 | description_file = "README.md", 61 | homepage = "https://foo.bar.de", 62 | maintainer = "John Doe ", 63 | package = "generated_version_file", 64 | # This only works partly 65 | # The Version is written into the debian metadata 66 | # But is not included in the name of the generated debian file 67 | # This makes sense, considering that bazel doesn't know what the generated 68 | # file will be named when it is declared 69 | version_file = ":gen_version_file", 70 | ) 71 | -------------------------------------------------------------------------------- /packaging/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/packaging/README.md -------------------------------------------------------------------------------- /packaging/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "rules_pkg", 5 | sha256 = "352c090cc3d3f9a6b4e676cf42a6047c16824959b438895a76c2989c6d7c246a", 6 | url = "https://github.com/bazelbuild/rules_pkg/releases/download/0.2.5/rules_pkg-0.2.5.tar.gz", 7 | ) 8 | 9 | load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") 10 | 11 | rules_pkg_dependencies() 12 | -------------------------------------------------------------------------------- /packaging/generate_files.bzl: -------------------------------------------------------------------------------- 1 | def _generate_files_impl(ctx): 2 | files = [ 3 | "share/lib/foo", 4 | "share/bar", 5 | "lib/libfoo", 6 | ] 7 | 8 | out_files = [ 9 | ctx.actions.declare_file("/".join([ctx.attr.prefix, f])) 10 | for f in files 11 | ] 12 | 13 | [ 14 | ctx.actions.run_shell( 15 | inputs = [], 16 | outputs = [f], 17 | command = """ 18 | out=$@; 19 | mkdir -p $(basename $out) 20 | touch $out 21 | """, 22 | arguments = [f.path], 23 | ) 24 | for f in out_files 25 | ] 26 | 27 | return [DefaultInfo(files = depset(out_files))] 28 | 29 | generate_files = rule( 30 | attrs = { 31 | "prefix": attr.string(), 32 | }, 33 | implementation = _generate_files_impl, 34 | ) 35 | -------------------------------------------------------------------------------- /packaging/my_library/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "my_library", 3 | srcs = glob(["src/*.cpp", "src/*.h", "include/**/*.h"]), 4 | hdrs = glob(["include/**/*.h"]), 5 | strip_include_prefix = "include", 6 | linkstatic = True, 7 | visibility = ["//visibility:public"], 8 | ) 9 | -------------------------------------------------------------------------------- /packaging/my_library/include/my_library/library.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_H 2 | #define LIBRARY_H 3 | 4 | class Library 5 | { 6 | public: 7 | Library(); 8 | }; 9 | 10 | #endif /* LIBRARY_H */ 11 | -------------------------------------------------------------------------------- /packaging/my_library/src/library.cpp: -------------------------------------------------------------------------------- 1 | #include "my_library/library.h" 2 | 3 | Library::Library() {} 4 | -------------------------------------------------------------------------------- /py_runtime/.bazelrc: -------------------------------------------------------------------------------- 1 | common --incompatible_use_python_toolchains 2 | common --verbose_failures 3 | -------------------------------------------------------------------------------- /py_runtime/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.25.2 2 | -------------------------------------------------------------------------------- /py_runtime/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") 2 | 3 | py_runtime( 4 | name = "python-3.6.0", 5 | interpreter_path = "/usr/bin/python3.6", 6 | python_version = "PY3", 7 | ) 8 | 9 | py_runtime( 10 | name = "python-2.7.0", 11 | interpreter_path = "/usr/bin/python2.7", 12 | python_version = "PY2", 13 | ) 14 | 15 | py_runtime_pair( 16 | name = "py_runtime_pair", 17 | py2_runtime = ":python-2.7.0", 18 | py3_runtime = ":python-3.6.0", 19 | ) 20 | 21 | toolchain( 22 | name = "python_toolchain", 23 | toolchain = ":py_runtime_pair", 24 | toolchain_type = "@bazel_tools//tools/python:toolchain_type", 25 | ) 26 | ###################################################################### 27 | # A library that may be available as python2 or python3 compatible # 28 | ###################################################################### 29 | 30 | py_library( 31 | name = "python2_dependency", 32 | srcs = ["a_dependency_library.py"], 33 | srcs_version = "PY2", 34 | deps = [ 35 | # Uncomment to see the error for transitive python dependencies 36 | # ":python3_dependency", 37 | # ":python3only_dependency", 38 | ], 39 | ) 40 | 41 | py_library( 42 | name = "python2only_dependency", 43 | srcs = ["a_dependency_library.py"], 44 | srcs_version = "PY2ONLY", 45 | ) 46 | 47 | py_library( 48 | name = "python3_dependency", 49 | srcs = ["a_dependency_library.py"], 50 | srcs_version = "PY3", 51 | ) 52 | 53 | py_library( 54 | name = "python3only_dependency", 55 | srcs = ["a_dependency_library.py"], 56 | srcs_version = "PY3ONLY", 57 | ) 58 | 59 | py_library( 60 | name = "python2and3_dependency", 61 | srcs = ["a_dependency_library.py"], 62 | srcs_version = "PY2AND3", 63 | ) 64 | 65 | ########################################################### 66 | # Run these binaries to print the actual python version # 67 | ########################################################### 68 | 69 | py_binary( 70 | name = "default", 71 | srcs = ["show_python_version.py"], 72 | main = "show_python_version.py", 73 | deps = [ 74 | ":python2and3_dependency", 75 | ":python3_dependency", 76 | ":python3only_dependency", 77 | ], 78 | ) 79 | 80 | py_binary( 81 | name = "python2", 82 | srcs = ["show_python_version.py"], 83 | main = "show_python_version.py", 84 | python_version = "PY2", 85 | deps = [ 86 | ":python2_dependency", 87 | ":python2and3_dependency", 88 | ":python2only_dependency", 89 | # Uncomment to show the hard dependency error 90 | # ":python3only_dependency", 91 | # Uncomment to show the hard dependency error 92 | # ":python3_dependency", 93 | ], 94 | ) 95 | 96 | py_binary( 97 | name = "python3", 98 | srcs = ["show_python_version.py"], 99 | main = "show_python_version.py", 100 | python_version = "PY3", 101 | deps = [ 102 | ":python2and3_dependency", 103 | ":python3_dependency", 104 | ":python3only_dependency", 105 | # Uncomment to show the hard dependency error 106 | # ":python2only_dependency", 107 | # Uncomment to show the 2to3 build error 108 | # ":python2_dependency", 109 | ], 110 | ) 111 | -------------------------------------------------------------------------------- /py_runtime/README.md: -------------------------------------------------------------------------------- 1 | # Python runtime toolchains 2 | 3 | The best description i could find about how to use this: 4 | [#7899](https://github.com/bazelbuild/bazel/issues/7899) 5 | 6 | ``` 7 | Flag: --incompatible_use_python_toolchains 8 | Available since: 0.25 9 | Will be flipped in: 0.27 10 | Feature tracking issue: #7375 11 | ``` 12 | 13 | ### Using python2 dependencies in python3 targets 14 | 15 | As of [issues/1393#issuecomment-431110617](https://github.com/bazelbuild/bazel/issues/1393#issuecomment-431110617) 16 | `2to3` is just stubbed for bazel. Therefore dependencies must be version consistent. 17 | 18 | ### Debugging python2/3 dependency errors 19 | 20 | There is an aspect to show dependencies of python libraries in [bazel_tools](https://github.com/bazelbuild/bazel/blob/master/tools/python/srcs_version.bzl) 21 | This is what the output would look like for the two defined python binaries 22 | ```bash 23 | $ bazel build //:python3 \ 24 | --aspects=@bazel_tools//tools/python:srcs_version.bzl%find_requirements \ 25 | --output_groups=pyversioninfo 26 | 27 | $ cat bazel-bin/python3-pyversioninfo.txt 28 | Python 2-only deps: 29 | 30 | 31 | Python 3-only deps: 32 | //:python3_dependency 33 | //:python3only_dependency 34 | 35 | Paths to these deps: 36 | //:python3 -> //:python3_dependency 37 | //:python3 -> //:python3only_dependency 38 | ``` 39 | 40 | The python2 versions get put into their own bazel-bin directory 41 | ```bash 42 | $ bazel build //:python2 \ 43 | --aspects=@bazel_tools//tools/python:srcs_version.bzl%find_requirements \ 44 | --output_groups=pyversioninfo 45 | 46 | $ cat bazel-out/k8-py2-fastbuild/bin/python2-pyversioninfo.txt 47 | Python 2-only deps: 48 | //:python2only_dependency 49 | 50 | Python 3-only deps: 51 | 52 | 53 | Paths to these deps: 54 | //:python2 -> //:python2only_dependency 55 | ``` 56 | -------------------------------------------------------------------------------- /py_runtime/WORKSPACE: -------------------------------------------------------------------------------- 1 | register_toolchains("//:python_toolchain") 2 | -------------------------------------------------------------------------------- /py_runtime/a_dependency_library.py: -------------------------------------------------------------------------------- 1 | CONSTANT_VALUE = 42 2 | -------------------------------------------------------------------------------- /py_runtime/show_python_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | 4 | if __name__ == "__main__": 5 | print(sys.version) 6 | -------------------------------------------------------------------------------- /python-tutorial/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/python-tutorial/WORKSPACE -------------------------------------------------------------------------------- /python-tutorial/py_binary/BUILD: -------------------------------------------------------------------------------- 1 | py_binary( 2 | name = "py_bin", 3 | srcs = ["py_binary_a.py"], 4 | deps = ["//py_library:py_lib"], 5 | main = "py_binary_a.py", 6 | ) 7 | 8 | 9 | -------------------------------------------------------------------------------- /python-tutorial/py_binary/py_binary_a.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import sys 4 | import os 5 | 6 | __import__('pprint').pprint(os.environ['PYTHONPATH'].split(':')) 7 | __import__('pprint').pprint(sys.path) 8 | 9 | from py_library import lib_module 10 | 11 | lib_module.doo_stuff() 12 | -------------------------------------------------------------------------------- /python-tutorial/py_library/BUILD: -------------------------------------------------------------------------------- 1 | py_library( 2 | name = "py_lib", 3 | srcs = glob(["*.py"]), 4 | visibility = ["//visibility:public"], 5 | ) 6 | 7 | 8 | -------------------------------------------------------------------------------- /python-tutorial/py_library/lib_module.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | def doo_stuff(): 5 | print("Did Stuff") 6 | -------------------------------------------------------------------------------- /python_with_cxx/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "a_shared_library", 3 | srcs = ["cpp_code.cpp"], 4 | hdrs = ["cpp_code.h"], 5 | ) 6 | 7 | py_library( 8 | name = "a_python_library", 9 | srcs = ["a_python_library.py"], 10 | data = [":a_shared_library"], 11 | ) 12 | 13 | py_binary( 14 | name = "a_python_main", 15 | srcs = ["a_python_main.py"], 16 | data = [":a_shared_library"], 17 | main = "a_python_main.py", 18 | deps = [":a_python_library"], 19 | ) 20 | -------------------------------------------------------------------------------- /python_with_cxx/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/python_with_cxx/WORKSPACE -------------------------------------------------------------------------------- /python_with_cxx/a_python_library.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/python_with_cxx/a_python_library.py -------------------------------------------------------------------------------- /python_with_cxx/a_python_main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/python_with_cxx/a_python_main.py -------------------------------------------------------------------------------- /python_with_cxx/cpp_code.cpp: -------------------------------------------------------------------------------- 1 | #include "cpp_code.h" 2 | 3 | CppCode::CppCode() = default; 4 | -------------------------------------------------------------------------------- /python_with_cxx/cpp_code.h: -------------------------------------------------------------------------------- 1 | #ifndef CPP_CODE_H 2 | #define CPP_CODE_H 3 | 4 | class CppCode 5 | { 6 | public: 7 | CppCode(); 8 | }; 9 | 10 | #endif /* CPP_CODE_H */ 11 | -------------------------------------------------------------------------------- /repository_rules/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.25.2 2 | -------------------------------------------------------------------------------- /repository_rules/BUILD: -------------------------------------------------------------------------------- 1 | cc_binary( 2 | name = "depends_on_tinyxml", 3 | srcs = ["depend_on_tinyxml.cpp"], 4 | visibility = ["//visibility:public"], 5 | deps = ["@tinyxml"], 6 | ) 7 | -------------------------------------------------------------------------------- /repository_rules/WORKSPACE: -------------------------------------------------------------------------------- 1 | load(":deb.bzl", "new_debian_archive") 2 | 3 | new_debian_archive( 4 | name = "tinyxml", 5 | sha256 = "8d2793098b1ec2f35153c14a780acd48c42970e8e491d22a2b61dc81f727ee71", 6 | url = "http://de.archive.ubuntu.com/ubuntu/pool/main/t/tinyxml/libtinyxml-dev_2.6.2-2_amd64.deb", 7 | ) 8 | -------------------------------------------------------------------------------- /repository_rules/deb.bzl: -------------------------------------------------------------------------------- 1 | _DEFAULT_BUILD_FILE_TEMPLATE = """ 2 | cc_library( 3 | name = "{name}", 4 | srcs = glob(["usr/lib/**/*.a", "usr/lib/**/*.so"]), 5 | hdrs = glob(["usr/include/**/*"]), 6 | includes = ["usr/include"], 7 | visibility = ["//visibility:public"], 8 | linkstatic = True, 9 | ) 10 | """ 11 | 12 | def _debian_archive_impl(ctx): 13 | loaded = ctx.download( 14 | url = ctx.attr.url, 15 | output = ctx.name, 16 | sha256 = ctx.attr.sha256, 17 | ) 18 | 19 | if not loaded: 20 | fail("Download of {} failed".format(ctx.attr.url)) 21 | 22 | # Extract debian 23 | tool = ctx.which("dpkg-deb") 24 | if not tool: 25 | fail("dpkg-deb not found") 26 | 27 | extraction_succeeded = ctx.execute([tool, "-X", ctx.name, "./"]) 28 | if not extraction_succeeded: 29 | fail("Extraction failed") 30 | 31 | # Not yet in bazel 0.25.2 32 | # ctx.delete("extracted/usr/share/") 33 | cleanup = ctx.execute(["rm", "-rf", "usr/share"]) 34 | cleanup = cleanup and ctx.execute(["rm", "-f", ctx.name]) 35 | if not cleanup: 36 | fail("Cleanup failed") 37 | 38 | if ctx.attr.build_file: 39 | ctx.symlink(ctx.attr.build_file, "BUILD.bazel") 40 | else: 41 | build_file_content = _DEFAULT_BUILD_FILE_TEMPLATE.format(name = ctx.name) 42 | ctx.file("BUILD.bazel", build_file_content) 43 | 44 | if ctx.attr.workspace_file: 45 | ctx.symlink(ctx.path(ctx.attr.workspace_file), "WORKSPACE") 46 | else: 47 | ctx.file("WORKSPACE", "") 48 | 49 | new_debian_archive = repository_rule( 50 | attrs = { 51 | "sha256": attr.string(default = ""), 52 | "url": attr.string(default = ""), 53 | "build_file": attr.label(allow_single_file = True), 54 | "workspace_file": attr.label(allow_single_file = True), 55 | }, 56 | local = False, 57 | implementation = _debian_archive_impl, 58 | ) 59 | -------------------------------------------------------------------------------- /repository_rules/depend_on_tinyxml.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char* argv[]) 4 | { 5 | 6 | return 0; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /run_action/.bazelversion: -------------------------------------------------------------------------------- 1 | 5.1.1 2 | -------------------------------------------------------------------------------- /run_action/BUILD: -------------------------------------------------------------------------------- 1 | load(":rule.bzl", "runner") 2 | 3 | runner( 4 | name = "foo", 5 | ) 6 | -------------------------------------------------------------------------------- /run_action/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/run_action/WORKSPACE -------------------------------------------------------------------------------- /run_action/rule.bzl: -------------------------------------------------------------------------------- 1 | _WINDOWS_RUNNER = """ 2 | echo "Hello Windows" 3 | echo 1 > {output} 4 | """ 5 | _LINUX_RUNNER = """ 6 | echo "Hello Linux" 7 | echo 1 > {output} 8 | """ 9 | 10 | def _runner_impl(ctx): 11 | is_windows = select({ 12 | "@platforms//os:windows": True, 13 | "//conditions:default": False, 14 | }) 15 | runner = ctx.actions.declare_file(ctx.label.name + (".bat" if is_windows else ".sh")) 16 | generated_file = ctx.actions.declare_file(ctx.label.name + ".output") 17 | 18 | runner_content = _WINDOWS_RUNNER if is_windows else _LINUX_RUNNER 19 | 20 | ctx.actions.write( 21 | output = runner, 22 | content = runner_content.format(output = generated_file.path), 23 | ) 24 | 25 | ctx.actions.run( 26 | executable = runner, 27 | outputs = [generated_file], 28 | ) 29 | 30 | return DefaultInfo(files = depset([generated_file])) 31 | 32 | _runner = rule( 33 | implementation = _runner_impl, 34 | attrs = { 35 | }, 36 | ) 37 | 38 | def runner(name, **kwargs): 39 | _runner( 40 | name = name, 41 | **kwargs 42 | ) 43 | -------------------------------------------------------------------------------- /run_with_files/.bazelrc: -------------------------------------------------------------------------------- 1 | run --experimental_strict_action_env 2 | build --experimental_strict_action_env 3 | -------------------------------------------------------------------------------- /run_with_files/BUILD: -------------------------------------------------------------------------------- 1 | load(":workspace_name_var.bzl", "workspace_name_var") 2 | 3 | py_binary( 4 | name = "binary", 5 | srcs = ["binary.py"], 6 | ) 7 | 8 | workspace_name_var( 9 | name = "workspace_name", 10 | ) 11 | 12 | py_binary( 13 | name = "foo", 14 | srcs = ["//:binary"], 15 | args = [ 16 | "$(WORKSPACE_NAME)", 17 | "$(location //input:file)", 18 | "$(location @ext//:file)", 19 | "$(location @ext//:generated_ext_file)", 20 | "$(location //generated)", 21 | ], 22 | data = [ 23 | "//generated", 24 | "//input:file", 25 | "@ext//:file", 26 | "@ext//:generated_ext_file", 27 | ], 28 | main = "binary.py", 29 | toolchains = [":workspace_name"], 30 | deps = [ 31 | "@rules_python//python/runfiles", 32 | ], 33 | ) 34 | -------------------------------------------------------------------------------- /run_with_files/BUILD.ext_file: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | load("@bazel_skylib//rules:write_file.bzl", "write_file") 3 | 4 | filegroup( 5 | name = "file", 6 | srcs = ["ext_file"], 7 | ) 8 | 9 | write_file( 10 | name = "generated_ext_file", 11 | out = "generated_file", 12 | content = ["generated file"], 13 | visibility = ["//visibility:public"], 14 | ) 15 | -------------------------------------------------------------------------------- /run_with_files/WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "windows_runfiles") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 4 | 5 | http_archive( 6 | name = "bazel_skylib", 7 | sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", 8 | urls = [ 9 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 10 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 11 | ], 12 | ) 13 | 14 | load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") 15 | 16 | bazel_skylib_workspace() 17 | 18 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 19 | 20 | http_archive( 21 | name = "rules_python", 22 | sha256 = "e46612e9bb0dae8745de6a0643be69e8665a03f63163ac6610c210e80d14c3e4", 23 | url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.3/rules_python-0.0.3.tar.gz", 24 | ) 25 | 26 | load("@rules_python//python:repositories.bzl", "py_repositories") 27 | 28 | py_repositories() 29 | 30 | new_local_repository( 31 | name = "ext", 32 | build_file = "BUILD.ext_file", 33 | path = "ext_file", 34 | ) 35 | -------------------------------------------------------------------------------- /run_with_files/binary.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from pathlib import Path 4 | 5 | 6 | from rules_python.python.runfiles import runfiles 7 | 8 | if __name__ == "__main__": 9 | r = runfiles.Create() 10 | for arg in sys.argv[2:]: 11 | print("arg", arg) 12 | print("argv1", sys.argv[1]) 13 | print("Rlocation", r.Rlocation(sys.argv[1]+'/'+arg)) 14 | p_arg = Path(r.Rlocation(sys.argv[1]+'/'+arg)) 15 | print(p_arg, p_arg.exists()) 16 | -------------------------------------------------------------------------------- /run_with_files/ext_file/ext_file: -------------------------------------------------------------------------------- 1 | content of file 2 | -------------------------------------------------------------------------------- /run_with_files/generated/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:write_file.bzl", "write_file") 2 | 3 | write_file( 4 | name = "generated", 5 | out = "generatet_file", 6 | content = ["generated file"], 7 | visibility = ["//visibility:public"], 8 | ) 9 | -------------------------------------------------------------------------------- /run_with_files/input/BUILD: -------------------------------------------------------------------------------- 1 | exports_files(["file"]) 2 | -------------------------------------------------------------------------------- /run_with_files/input/file: -------------------------------------------------------------------------------- 1 | content of file 2 | -------------------------------------------------------------------------------- /run_with_files/workspace_name_var.bzl: -------------------------------------------------------------------------------- 1 | def _workspace_name_var_impl(ctx): 2 | return [ 3 | platform_common.TemplateVariableInfo({ 4 | "WORKSPACE_NAME": ctx.workspace_name, 5 | }), 6 | ] 7 | 8 | workspace_name_var = rule( 9 | implementation = _workspace_name_var_impl, 10 | attrs = {}, 11 | ) 12 | -------------------------------------------------------------------------------- /runfiles/.bazelrc: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /runfiles/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.26.0 2 | -------------------------------------------------------------------------------- /runfiles/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar") 2 | load(":runfile.bzl", "data_runfile", "default_runfile", "runfile", "runfile_root_symlinks", "runfile_symlinks") 3 | 4 | runfile( 5 | name = "runfile", 6 | ) 7 | 8 | default_runfile( 9 | name = "default_runfile", 10 | ) 11 | 12 | data_runfile( 13 | name = "data_runfile", 14 | ) 15 | 16 | runfile_symlinks( 17 | name = "runfile_symlinks", 18 | ) 19 | 20 | runfile_root_symlinks( 21 | name = "runfile_root_symlinks", 22 | ) 23 | 24 | py_binary( 25 | name = "app", 26 | srcs = ["app.py"], 27 | data = [ 28 | ":data_runfile", 29 | ":default_runfile", 30 | ":runfile", 31 | ":runfile_root_symlinks", 32 | ":runfile_symlinks", 33 | ], 34 | ) 35 | 36 | py_binary( 37 | name = "dependent_app", 38 | srcs = ["app.py"], 39 | main = "app.py", 40 | deps = [":app"], 41 | ) 42 | 43 | py_binary( 44 | name = "data_dependent_app", 45 | srcs = ["app.py"], 46 | data = [":app"], 47 | main = "app.py", 48 | ) 49 | 50 | pkg_tar( 51 | name = "app_pkg", 52 | srcs = [":app"], 53 | package_dir = "/usr/share/test_app", 54 | strip_prefix = ".", 55 | ) 56 | 57 | pkg_tar( 58 | name = "dependent_app_pkg", 59 | srcs = [":dependent_app"], 60 | package_dir = "/usr/share/test_app", 61 | strip_prefix = ".", 62 | ) 63 | 64 | pkg_tar( 65 | name = "data_dependent_app_pkg", 66 | srcs = [":data_dependent_app"], 67 | package_dir = "/usr/share/test_app", 68 | strip_prefix = ".", 69 | ) 70 | 71 | pkg_deb( 72 | name = "debian_packaging", 73 | architecture = "amd64", 74 | data = ":data_dependent_app_pkg", 75 | depends = [ 76 | "zlib1g-dev", 77 | "unzip", 78 | ], 79 | description = "Some description", 80 | maintainer = "John Doe ", 81 | package = "data_dependent_app_pkg", 82 | version = "0.0.1", 83 | ) 84 | -------------------------------------------------------------------------------- /runfiles/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/runfiles/WORKSPACE -------------------------------------------------------------------------------- /runfiles/app.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import os 4 | import json 5 | from pprint import pprint 6 | 7 | 8 | def load_json(json_file): 9 | try: 10 | with open(json_file) as jsn: 11 | data = json.load(jsn) 12 | print('Loaded json file:', json_file) 13 | except FileNotFoundError: 14 | print('File could not be found:', json_file) 15 | 16 | 17 | def print_env_info(): 18 | print('pwd', os.getcwd()) 19 | print('dir contents', os.listdir(os.getcwd())) 20 | print('python-version', sys.version) 21 | 22 | 23 | if __name__ == "__main__": 24 | print_env_info() 25 | load_json('runfile.json') 26 | load_json('default_runfile.json') 27 | load_json('data_runfile.json') 28 | load_json('runfile_symlinks_link') 29 | load_json('runfile_root_symlinks_link') 30 | load_json('runfile_root_symlinks.json') 31 | -------------------------------------------------------------------------------- /runfiles/runfile.bzl: -------------------------------------------------------------------------------- 1 | runfile_template = """{{ 2 | "name": "{name}", 3 | "lastName": "Smith", 4 | "isAlive": true, 5 | "age": 27, 6 | "address": {{ 7 | "streetAddress": "21 2nd Street", 8 | "city": "New York", 9 | "state": "NY", 10 | "postalCode": "10021-3100" 11 | }}, 12 | "phoneNumbers": [ 13 | {{ 14 | "type": "home", 15 | "number": "212 555-1234" 16 | }}, 17 | {{ 18 | "type": "office", 19 | "number": "646 555-4567" 20 | }}, 21 | {{ 22 | "type": "mobile", 23 | "number": "123 456-7890" 24 | }} 25 | ], 26 | "children": [], 27 | "spouse": null 28 | }} 29 | """ 30 | 31 | common_runfiles_args = { 32 | "collect_data": True, 33 | "collect_default": True, 34 | } 35 | 36 | def _runfile_impl(ctx): 37 | out = ctx.actions.declare_file("{name}.json".format(name = ctx.attr.name)) 38 | content = runfile_template.format(name = ctx.attr.name) 39 | ctx.actions.write(output = out, content = content) 40 | 41 | runfiles = ctx.runfiles(files = [out], **common_runfiles_args) 42 | 43 | return DefaultInfo(runfiles = runfiles) 44 | 45 | runfile = rule( 46 | attrs = {}, 47 | implementation = _runfile_impl, 48 | ) 49 | 50 | def _default_runfile_impl(ctx): 51 | out = ctx.actions.declare_file("{name}.json".format(name = ctx.attr.name)) 52 | content = runfile_template.format(name = ctx.attr.name) 53 | ctx.actions.write(output = out, content = content) 54 | 55 | runfiles = ctx.runfiles(files = [out], **common_runfiles_args) 56 | 57 | return DefaultInfo(default_runfiles = runfiles) 58 | 59 | default_runfile = rule( 60 | attrs = {}, 61 | implementation = _default_runfile_impl, 62 | ) 63 | 64 | def _data_runfile_impl(ctx): 65 | out = ctx.actions.declare_file("{name}.json".format(name = ctx.attr.name)) 66 | content = runfile_template.format(name = ctx.attr.name) 67 | ctx.actions.write(output = out, content = content) 68 | 69 | runfiles = ctx.runfiles(files = [out], **common_runfiles_args) 70 | 71 | return DefaultInfo(data_runfiles = runfiles) 72 | 73 | data_runfile = rule( 74 | attrs = {}, 75 | implementation = _data_runfile_impl, 76 | ) 77 | 78 | def _runfile_symlinks_impl(ctx): 79 | out = ctx.actions.declare_file("{name}.json".format(name = ctx.attr.name)) 80 | content = runfile_template.format(name = ctx.attr.name) 81 | ctx.actions.write(output = out, content = content) 82 | 83 | linked_file = ctx.actions.declare_file("sub_folder/{name}.json".format(name = ctx.attr.name)) 84 | content = runfile_template.format(name = ctx.attr.name) 85 | ctx.actions.write(output = linked_file, content = content) 86 | 87 | runfiles = ctx.runfiles(symlinks = {"{name}_link".format(name = ctx.attr.name): linked_file}, **common_runfiles_args) 88 | 89 | return DefaultInfo(runfiles = runfiles) 90 | 91 | runfile_symlinks = rule( 92 | attrs = {}, 93 | implementation = _runfile_symlinks_impl, 94 | ) 95 | 96 | def _runfile_root_symlinks_impl(ctx): 97 | out = ctx.actions.declare_file("{name}.json".format(name = ctx.attr.name)) 98 | content = runfile_template.format(name = ctx.attr.name) 99 | ctx.actions.write(output = out, content = content) 100 | 101 | linked_file = ctx.actions.declare_file("sub_folder/{name}.json".format(name = ctx.attr.name)) 102 | content = runfile_template.format(name = ctx.attr.name) 103 | ctx.actions.write(output = linked_file, content = content) 104 | 105 | runfiles = ctx.runfiles(root_symlinks = {"{name}_root_link".format(name = ctx.attr.name): linked_file}, **common_runfiles_args) 106 | 107 | return DefaultInfo(runfiles = runfiles) 108 | 109 | runfile_root_symlinks = rule( 110 | attrs = {}, 111 | implementation = _runfile_root_symlinks_impl, 112 | ) 113 | -------------------------------------------------------------------------------- /runfiles_mapper/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:run_binary.bzl", "run_binary") 2 | load(":runfiles_mapper.bzl", "runfiles_mapper") 3 | 4 | runfiles_mapper( 5 | name = "mapped", 6 | files = {"runfile.txt": "etc/application/runfile.json"}, 7 | root_files = {"runfile.txt": "etc/application/runfile.json"}, 8 | ) 9 | 10 | py_test( 11 | name = "foo", 12 | srcs = ["foo.py"], 13 | data = [":mapped"], # a cc_binary which we invoke at run time 14 | ) 15 | 16 | py_binary( 17 | name = "bar", 18 | srcs = ["foo.py"], 19 | data = [":mapped"], # a cc_binary which we invoke at run time 20 | main = "foo.py", 21 | ) 22 | 23 | run_binary( 24 | name = "gen", 25 | outs = ["foobar"], 26 | args = ["$(locations foobar)"], 27 | tool = ":foo", 28 | ) 29 | -------------------------------------------------------------------------------- /runfiles_mapper/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "bazel_skylib", 5 | sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", 6 | urls = [ 7 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 8 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 9 | ], 10 | ) 11 | 12 | load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") 13 | 14 | bazel_skylib_workspace() 15 | 16 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 17 | 18 | http_archive( 19 | name = "rules_python", 20 | sha256 = "e46612e9bb0dae8745de6a0643be69e8665a03f63163ac6610c210e80d14c3e4", 21 | url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.3/rules_python-0.0.3.tar.gz", 22 | ) 23 | 24 | load("@rules_python//python:repositories.bzl", "py_repositories") 25 | 26 | py_repositories() 27 | -------------------------------------------------------------------------------- /runfiles_mapper/runfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/runfiles_mapper/runfile.txt -------------------------------------------------------------------------------- /runfiles_mapper/runfiles_mapper.bzl: -------------------------------------------------------------------------------- 1 | def _runfiles_mapper_impl(ctx): 2 | runfiles = ctx.runfiles( 3 | symlinks = {path: lbl.files.to_list()[0] for lbl, path in ctx.attr.files.items()}, 4 | root_symlinks = {path: lbl.files.to_list()[0] for lbl, path in ctx.attr.root_files.items()}, 5 | ) 6 | return DefaultInfo(runfiles = runfiles) 7 | 8 | runfiles_mapper = rule( 9 | implementation = _runfiles_mapper_impl, 10 | attrs = { 11 | "root_files": attr.label_keyed_string_dict(allow_files = True), 12 | "files": attr.label_keyed_string_dict(allow_files = True), 13 | }, 14 | ) 15 | -------------------------------------------------------------------------------- /sh_binary_args/BUILD: -------------------------------------------------------------------------------- 1 | genrule( 2 | name = "generated_script", 3 | srcs = [], 4 | outs = ["generated.bash"], 5 | cmd_bash = "echo 'echo \"running generated\"' > $@", 6 | ) 7 | 8 | sh_binary( 9 | name = "callable_shell", 10 | srcs = ["shell_binary.bash"], 11 | args = [ 12 | "$(location other_script.bash)", 13 | "$(location generated_script)", 14 | ], 15 | data = [ 16 | "other_script.bash", 17 | ":generated_script", 18 | ], 19 | ) 20 | -------------------------------------------------------------------------------- /sh_binary_args/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/sh_binary_args/WORKSPACE -------------------------------------------------------------------------------- /sh_binary_args/other_script.bash: -------------------------------------------------------------------------------- 1 | echo "Called other script" 2 | -------------------------------------------------------------------------------- /sh_binary_args/shell_binary.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 'Arguments:' 4 | echo "'${@}'" 5 | 6 | for script in "${@}"; do 7 | "${script}" 8 | done 9 | -------------------------------------------------------------------------------- /standalone_so/.bazelversion: -------------------------------------------------------------------------------- 1 | 5.1.1 2 | -------------------------------------------------------------------------------- /standalone_so/.gitignore: -------------------------------------------------------------------------------- 1 | bazel-* 2 | -------------------------------------------------------------------------------- /standalone_so/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") 2 | load("@rules_pkg//pkg:tar.bzl", "pkg_tar") 3 | load("@rules_pkg//pkg:zip.bzl", "pkg_zip") 4 | load("//:so_headers.bzl", "so_headers") 5 | 6 | cc_binary( 7 | name = "libcontent.so", 8 | srcs = [ 9 | "content.cpp", 10 | "content.h", 11 | ], 12 | linkshared = 1, 13 | linkstatic = True, 14 | ) 15 | 16 | so_headers( 17 | name = "so_headers", 18 | so_file = ":libcontent.so", 19 | ) 20 | 21 | pkg_files( 22 | name = "headers", 23 | srcs = [ 24 | ":so_headers", 25 | ], 26 | prefix = "/usr/include", 27 | ) 28 | 29 | pkg_files( 30 | name = "bin", 31 | srcs = [ 32 | ":libcontent.so", 33 | ], 34 | prefix = "usr/bin", 35 | # Required, but why?: see #354 36 | strip_prefix = strip_prefix.from_pkg(), 37 | ) 38 | 39 | pkg_tar( 40 | name = "foo_tar", 41 | srcs = [ 42 | ":bin", 43 | ":headers", 44 | ], 45 | ) 46 | 47 | pkg_zip( 48 | name = "foo_zip", 49 | srcs = [ 50 | ":bin", 51 | ":headers", 52 | ], 53 | ) 54 | -------------------------------------------------------------------------------- /standalone_so/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "rules_pkg", 5 | sha256 = "8a298e832762eda1830597d64fe7db58178aa84cd5926d76d5b744d6558941c2", 6 | urls = [ 7 | "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", 8 | "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", 9 | ], 10 | ) 11 | 12 | load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") 13 | 14 | rules_pkg_dependencies() 15 | -------------------------------------------------------------------------------- /standalone_so/content.cpp: -------------------------------------------------------------------------------- 1 | #include "content.h" 2 | int function(char const* const) 3 | { 4 | // do domething 5 | return 42; 6 | } 7 | -------------------------------------------------------------------------------- /standalone_so/content.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTENT_H 2 | #define CONTENT_H 3 | 4 | int function(char const* const); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /standalone_so/so_headers.bzl: -------------------------------------------------------------------------------- 1 | def _so_headers_impl(ctx): 2 | headers = ctx.attr.so_file[CcInfo].compilation_context.headers 3 | return DefaultInfo(files = headers) 4 | 5 | so_headers = rule( 6 | implementation = _so_headers_impl, 7 | attrs = { 8 | "so_file": attr.label(providers = [CcInfo]), 9 | }, 10 | ) 11 | -------------------------------------------------------------------------------- /test_rules/BUILD: -------------------------------------------------------------------------------- 1 | load(":test_rule.bzl", "basic_test", "with_context_test", "with_default_context_test") 2 | 3 | basic_test( 4 | name = "basic_test", 5 | ) 6 | 7 | py_binary( 8 | name = "py_runner", 9 | srcs = [":py_runner.py"], 10 | deps = [ 11 | "//another_important_py_lib", 12 | "//some_important_py_lib", 13 | ], 14 | ) 15 | 16 | with_context_test( 17 | name = "with_context_and_py_runner", 18 | data = [":py_runner"], 19 | launch = ":launchfile", 20 | runner = ":py_runner", 21 | ) 22 | 23 | with_default_context_test( 24 | name = "with_default_context_and_py_runner", 25 | launch = ":launchfile", 26 | ) 27 | 28 | filegroup( 29 | name = "launchfile", 30 | srcs = ["launchfile.test"], 31 | ) 32 | 33 | filegroup( 34 | name = "schemas", 35 | srcs = [ 36 | "schema_a.scm", 37 | "schema_b.scm", 38 | ], 39 | ) 40 | 41 | sh_test( 42 | name = "sh_runner", 43 | srcs = ["sh_runner.sh"], 44 | args = [ 45 | "$(location :py_runner)", 46 | "$(location :launchfile)", 47 | "$(locations :schemas)", 48 | ], 49 | data = [ 50 | ":launchfile", 51 | ":py_runner", 52 | ":schemas", 53 | ], 54 | ) 55 | -------------------------------------------------------------------------------- /test_rules/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/test_rules/WORKSPACE -------------------------------------------------------------------------------- /test_rules/another_important_py_lib/BUILD: -------------------------------------------------------------------------------- 1 | py_library( 2 | name = "another_important_py_lib", 3 | srcs = ["py_lib.py"], 4 | imports = ["."], 5 | visibility = ["//visibility:public"], 6 | deps = ["//some_important_py_lib"], 7 | ) 8 | -------------------------------------------------------------------------------- /test_rules/another_important_py_lib/py_lib.py: -------------------------------------------------------------------------------- 1 | from some_important_py_lib import py_lib 2 | ANOTHER_IMPORTANT_CONSTANT = py_lib.SOME_IMPORTANT_CONSTANT * 2 3 | -------------------------------------------------------------------------------- /test_rules/launchfile.test: -------------------------------------------------------------------------------- 1 | 2 | Foo 3 | 4 | -------------------------------------------------------------------------------- /test_rules/py_runner.py: -------------------------------------------------------------------------------- 1 | from some_important_py_lib import py_lib 2 | from another_important_py_lib import py_lib as another 3 | import argparse 4 | 5 | if __name__ == "__main__": 6 | parser = argparse.ArgumentParser() 7 | parser.add_argument('launch') 8 | args = parser.parse_args() 9 | print("Reading within python script:") 10 | with open(args.launch) as l: 11 | print(l.read()) 12 | 13 | print(py_lib.SOME_IMPORTANT_CONSTANT) 14 | print(another.ANOTHER_IMPORTANT_CONSTANT) 15 | -------------------------------------------------------------------------------- /test_rules/schema_a.scm: -------------------------------------------------------------------------------- 1 | schema_a 2 | -------------------------------------------------------------------------------- /test_rules/schema_b.scm: -------------------------------------------------------------------------------- 1 | schema_b 2 | -------------------------------------------------------------------------------- /test_rules/sh_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "run python" 3 | ${@: 1:1} ${@: 2:1} 4 | echo "Read second" 5 | cat ${@: 2:1} 6 | echo "Read third" 7 | cat ${@: 3} 8 | -------------------------------------------------------------------------------- /test_rules/some_important_py_lib/BUILD: -------------------------------------------------------------------------------- 1 | py_library( 2 | name = "some_important_py_lib", 3 | srcs = ["py_lib.py"], 4 | imports = ["."], 5 | visibility = ["//visibility:public"], 6 | ) 7 | -------------------------------------------------------------------------------- /test_rules/some_important_py_lib/py_lib.py: -------------------------------------------------------------------------------- 1 | SOME_IMPORTANT_CONSTANT = 42 2 | -------------------------------------------------------------------------------- /test_rules/test_rule.bzl: -------------------------------------------------------------------------------- 1 | def _basic_test_impl(ctx): 2 | ctx.actions.write(output = ctx.outputs.executable, content = "/bin/true", is_executable = True) 3 | 4 | basic_test = rule( 5 | attrs = {}, 6 | executable = True, 7 | test = True, 8 | implementation = _basic_test_impl, 9 | ) 10 | 11 | _with_context_content_template = """ 12 | {runner} {launch} 13 | """ 14 | 15 | def _with_context_test_impl(ctx): 16 | with_context_content = _with_context_content_template.format( 17 | runner = ctx.executable.runner.short_path, 18 | launch = ctx.file.launch.path, 19 | ) 20 | 21 | ctx.actions.write(output = ctx.outputs.executable, content = with_context_content, is_executable = True) 22 | 23 | runfiles = ctx.runfiles( 24 | collect_data = True, 25 | # This part is redundant if the files are provided via the data attribute 26 | # Even though it can be necessary to distinguish between the different files. 27 | # However, transitive runfiles seem to be collected only from data, etc 28 | files = [ctx.file.launch] + ctx.files.runner, 29 | ) 30 | 31 | return DefaultInfo(runfiles = runfiles) 32 | 33 | with_context_test = rule( 34 | attrs = { 35 | # This is the important bit. 36 | # It has to be a label_list and named one-of ['data', 'srcs', 'hdrs'] 37 | # In combination with collect_data = True, bazel collects the transitive runfiles 38 | # and sets them up at runtime 39 | "data": attr.label_list( 40 | allow_files = True, 41 | ), 42 | "runner": attr.label( 43 | executable = True, 44 | allow_files = True, 45 | cfg = "host", 46 | ), 47 | "launch": attr.label( 48 | allow_single_file = True, 49 | ), 50 | }, 51 | executable = True, 52 | test = True, 53 | implementation = _with_context_test_impl, 54 | ) 55 | 56 | with_default_context_test = rule( 57 | attrs = { 58 | # This can be defaulted, but overridden from the callside. So not very safe 59 | "data": attr.label_list( 60 | allow_files = True, 61 | default = ["//:py_runner"], 62 | ), 63 | # This could be scoped to private, but since i reuse the impl, i didn't do it 64 | "runner": attr.label( 65 | default = "//:py_runner", 66 | executable = True, 67 | allow_files = True, 68 | cfg = "host", 69 | ), 70 | "launch": attr.label( 71 | allow_single_file = True, 72 | ), 73 | }, 74 | executable = True, 75 | test = True, 76 | implementation = _with_context_test_impl, 77 | ) 78 | -------------------------------------------------------------------------------- /toolchain_testing_playground/.bazelrc: -------------------------------------------------------------------------------- 1 | build --toolchain_resolution_debug 2 | build --incompatible_enable_cc_toolchain_resolution 3 | build --experimental_strict_action_env 4 | -------------------------------------------------------------------------------- /toolchain_testing_playground/.bazelversion: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | -------------------------------------------------------------------------------- /toolchain_testing_playground/BUILD: -------------------------------------------------------------------------------- 1 | load(":gcc_config.bzl", "cc_toolchain_config") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | filegroup( 6 | name = "empty", 7 | srcs = [], 8 | ) 9 | 10 | cc_toolchain_config( 11 | name = "cc-toolchain-config", 12 | ) 13 | 14 | cc_toolchain( 15 | name = "cc-toolchain-x64_linux_gcc", 16 | all_files = "empty", 17 | ar_files = "@gcc//:ar_files", 18 | compiler_files = "@gcc//:compiler_files", 19 | dwp_files = ":empty", 20 | linker_files = "@gcc//:linker_files", 21 | objcopy_files = ":empty", 22 | strip_files = ":empty", 23 | supports_param_files = 1, 24 | toolchain_config = ":cc-toolchain-config", 25 | visibility = ["//visibility:public"], 26 | ) 27 | 28 | toolchain( 29 | name = "cc-x64_linux_gcc", 30 | exec_compatible_with = [ 31 | "@platforms//cpu:x86_64", 32 | "@platforms//os:linux", 33 | ], 34 | target_compatible_with = [ 35 | "@platforms//cpu:x86_64", 36 | "@platforms//os:linux", 37 | ], 38 | toolchain = ":cc-toolchain-x64_linux_gcc", 39 | toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", 40 | ) 41 | 42 | # vim: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab ft=bzl: 43 | -------------------------------------------------------------------------------- /toolchain_testing_playground/README.md: -------------------------------------------------------------------------------- 1 | Normal build 2 | ------------------------------------------------ 3 | ```bash 4 | bazel build //:main -s 5 | ``` 6 | 7 | With the feature being enabled 8 | ------------------------------------------------ 9 | ```bash 10 | bazel build :main --features=custom_include_paths -s 2>&1 | grep foobar 11 | ``` 12 | 13 | Here it can be see that the include path `-Ifoobar` is added to the command 14 | -------------------------------------------------------------------------------- /toolchain_testing_playground/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | 3 | git_repository( 4 | name = "debian_repository_rules", 5 | commit = "3f80031c3ccee36931400323f452f569b8046966", 6 | remote = "https://github.com/fabrand/debian_repository_rules", 7 | ) 8 | 9 | load("@debian_repository_rules//:debian.bzl", "debian_archive") 10 | 11 | debian_archive( 12 | name = "gcc", 13 | build_file = "//third_party:BUILD.gcc", 14 | urls = { 15 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/cpp-8_8.3.0-6_amd64.deb": "64f5f6fd7559a9f431132f24aa6ec9bfd062b0473f2e403c98dbd638be65f9c0", 16 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/g++-8_8.3.0-6_amd64.deb": "d333c8986adff11fb54aed83e1b29f99996c321f7fb5b75614d66e5aa611a5d8", 17 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/gcc-8-base_8.3.0-6_amd64.deb": "1b00f7cef567645a7e695caf6c1ad395577e7d2e903820097ebd3496ddcfcc84", 18 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/gcc-8_8.3.0-6_amd64.deb": "05e90f94363055cf27cd88b7968820645180d37a649a93cf5d7ea6f3c7fe973e", 19 | # "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/libcc1-0_8.3.0-6_amd64.deb": "579c11dd6004f06ac2639b338c320fde794ed3c36a1d2be559ec282ea3042dd7", 20 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/libgcc-8-dev_8.3.0-6_amd64.deb": "a52d5216858c7185bc245e52ad95a6ad515d087bc25e8556df06c5626b41a837", 21 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-defaults/g++_8.3.0-1_amd64.deb": "ae756853eff06749370f37f717339098d7ead8eb40d8eca9050c4dd8d64be33a", 22 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-defaults/gcc_8.3.0-1_amd64.deb": "c472cc849c02f03522b44e12191b6dfde496afa2a53b862f9b913dc2ae218f70", 23 | "http://security.debian.org/debian-security/pool/updates/main/l/linux/linux-libc-dev_4.19.67-2+deb10u2_amd64.deb": "71845ca23960692bae5e02abd56f0782010fc824b54b1dacb059a4a880b7e191", 24 | # c++ standard library 25 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/libstdc++6_8.3.0-6_amd64.deb": "5cc70625329655ff9382580971d4616db8aa39af958b7c995ee84598f142a4ee", 26 | "http://ftp.de.debian.org/debian/pool/main/g/gcc-8/libstdc++-8-dev_8.3.0-6_amd64.deb": "79965b74e6c839e7b90d24ac5b61840f57872ecb1e4ac1007937036c85364f82", 27 | "http://ftp.de.debian.org/debian/pool/main/g/glibc/libc6-dev_2.24-11+deb9u4_amd64.deb": "3e7655930adc6ed69ddb1c263ef6fa428590e19479863785adc723367f6bf21d", 28 | # binutils 29 | "http://ftp.de.debian.org/debian/pool/main/b/binutils/binutils_2.31.1-16_amd64.deb": "c2696ba3984dd2fc90bacb01c3bbb6c5f4477bcabbc90fa084cb9fe971b66d6d", 30 | "http://ftp.de.debian.org/debian/pool/main/b/binutils/binutils-x86-64-linux-gnu_2.31.1-16_amd64.deb": "c1da1cffff8a024b5eca0a6795558d9e0ec88fbd24fe059490dc665dc5cac92f", 31 | # "http://ftp.de.debian.org/debian/pool/main/b/binutils/binutils-common_2.31.1-16_amd64.deb": "95c39f813e7c99f93d7de3bab571f4c2f52c917a64d4dc33be8ef7c4dad14adb", 32 | "http://ftp.de.debian.org/debian/pool/main/b/binutils/libbinutils_2.31.1-16_amd64.deb": "bae88af666531b3b46a5c1b54f699e7354264e6fc1654b02bb537f2076694b05", 33 | # "http://ftp.de.debian.org/debian/pool/main/z/zlib/zlib1g_1.2.11.dfsg-1_amd64.deb": "61bc9085aadd3007433ce6f560a08446a3d3ceb0b5e061db3fc62c42fbfe3eff", 34 | }, 35 | ) 36 | 37 | register_toolchains( 38 | "//:cc-x64_linux_gcc", 39 | ) 40 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "other", 3 | srcs = ["other.cpp"], 4 | ) 5 | 6 | cc_library( 7 | name = "lib", 8 | srcs = ["lib.cpp"], 9 | ) 10 | 11 | cc_library( 12 | name = "lib_always", 13 | srcs = ["lib.cpp"], 14 | alwayslink = True, 15 | ) 16 | 17 | cc_binary( 18 | name = "libmain.so", 19 | srcs = ["main.cpp"], 20 | deps = [ 21 | ":lib", 22 | ":other", 23 | ], 24 | ) 25 | 26 | cc_binary( 27 | name = "main", 28 | srcs = ["main.cpp"], 29 | deps = [ 30 | ":lib", 31 | ":other", 32 | ], 33 | ) 34 | 35 | cc_binary( 36 | name = "main_shared_always", 37 | srcs = ["main.cpp"], 38 | linkstatic = False, 39 | deps = [ 40 | ":lib", 41 | ":other", 42 | ], 43 | ) 44 | 45 | cc_binary( 46 | name = "main_always", 47 | srcs = ["main.cpp"], 48 | deps = [ 49 | ":lib_always", 50 | ":other", 51 | ], 52 | ) 53 | 54 | cc_binary( 55 | name = "main_shared", 56 | srcs = ["main.cpp"], 57 | linkstatic = False, 58 | deps = [ 59 | ":lib_always", 60 | ":other", 61 | ], 62 | ) 63 | 64 | cc_test( 65 | name = "test_target", 66 | srcs = ["main.cpp"], 67 | deps = [ 68 | ":lib", 69 | ":other", 70 | ], 71 | ) 72 | 73 | cc_test( 74 | name = "test_target_shared", 75 | srcs = ["main.cpp"], 76 | linkstatic = False, 77 | deps = [ 78 | ":lib", 79 | ":other", 80 | ], 81 | ) 82 | 83 | cc_test( 84 | name = "test_target_always", 85 | srcs = ["main.cpp"], 86 | deps = [ 87 | ":lib_always", 88 | ":other", 89 | ], 90 | ) 91 | 92 | cc_binary( 93 | name = "define_test", 94 | srcs = ["define_test.cpp"], 95 | defines = ["THIS_IS_A_DEFINE"], 96 | ) 97 | 98 | cc_binary( 99 | name = "include_test", 100 | srcs = ["include_test.cpp"], 101 | deps = ["//cpp_tests/sub_package:header_library"], 102 | ) 103 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/define_test.cpp: -------------------------------------------------------------------------------- 1 | #ifndef THIS_IS_A_DEFINE 2 | #error "Defines is not passed" 3 | #endif /* ifndef THIS_IS_A_DEFINE */ 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/include_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "header.h" 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/lib.cpp: -------------------------------------------------------------------------------- 1 | 2 | extern const int constant_in_library{42}; 3 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int constant_in_library; 4 | int main(int argc, char* argv[]) 5 | { 6 | std::cout << "Hello World" << '\n'; 7 | return constant_in_library; 8 | } 9 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/other.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/toolchain_testing_playground/cpp_tests/other.cpp -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/sub_package/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "header_library", 3 | hdrs = ["include/header.h"], 4 | strip_include_prefix = "include", 5 | visibility = ["//visibility:public"], 6 | ) 7 | -------------------------------------------------------------------------------- /toolchain_testing_playground/cpp_tests/sub_package/include/header.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/toolchain_testing_playground/cpp_tests/sub_package/include/header.h -------------------------------------------------------------------------------- /toolchain_testing_playground/third_party/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/toolchain_testing_playground/third_party/BUILD -------------------------------------------------------------------------------- /toolchain_testing_playground/third_party/BUILD.gcc: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load("@//third_party:libstdcpp8_files.bzl", _LIBSTDCPP_HEADER = "HEADERS") 4 | load("@//third_party:libc6dev_files.bzl", _LIBC_HEADER = "HEADERS") 5 | load("@//third_party:libgcc8_dev.bzl", _LIBGCC_HEADER = "HEADERS") 6 | load("@//third_party:linuxlibcdev_files.bzl", _LINUXLIBC_HEADER = "HEADERS") 7 | 8 | filegroup( 9 | name = "all_files", 10 | srcs = glob( 11 | ["usr/**/*"], 12 | exclude = ["usr/share/**/*"], 13 | ), 14 | visibility = ["//visibility:public"], 15 | ) 16 | 17 | filegroup( 18 | name = "includes", 19 | srcs = _LIBC_HEADER + _LIBSTDCPP_HEADER + _LIBGCC_HEADER + _LINUXLIBC_HEADER, 20 | visibility = ["//visibility:public"], 21 | ) 22 | 23 | filegroup( 24 | name = "compiler_files", 25 | srcs = [ 26 | "usr/bin/as", 27 | "usr/bin/g++", 28 | "usr/bin/g++-8", 29 | "usr/bin/x86_64-linux-gnu-as", 30 | "usr/bin/x86_64-linux-gnu-g++-8", 31 | "usr/lib/gcc/x86_64-linux-gnu/8/cc1plus", 32 | "usr/lib/x86_64-linux-gnu/libbfd-2.31.1-system.so", 33 | "usr/lib/x86_64-linux-gnu/libopcodes-2.31.1-system.so", 34 | ":includes", 35 | ], 36 | ) 37 | 38 | filegroup( 39 | name = "ar_files", 40 | srcs = [ 41 | "usr/bin/ar", 42 | "usr/lib/x86_64-linux-gnu/libbfd-2.31.1-system.so", 43 | ], 44 | ) 45 | 46 | filegroup( 47 | name = "linker_files", 48 | srcs = [ 49 | #GCC 50 | "usr/bin/gcc", 51 | "usr/bin/gcc-8", 52 | "usr/bin/x86_64-linux-gnu-gcc-8", 53 | #GNULD 54 | "usr/bin/gold", 55 | "usr/bin/ld.gold", 56 | "usr/bin/x86_64-linux-gnu-gold", 57 | "usr/bin/x86_64-linux-gnu-ld.gold", 58 | "usr/lib/gold-ld/ld", 59 | "usr/lib/x86_64-linux-gnu/libbfd-2.31.1-system.so", 60 | #GOLD 61 | "usr/bin/ld", 62 | "usr/bin/ld.bfd", 63 | "usr/bin/x86_64-linux-gnu-ld", 64 | "usr/bin/x86_64-linux-gnu-ld.bfd", 65 | "usr/lib/compat-ld/ld", 66 | ], 67 | ) 68 | # vim: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab ft=bzl: 69 | -------------------------------------------------------------------------------- /toolchains_generic/.bazelrc: -------------------------------------------------------------------------------- 1 | build --toolchain_resolution_debug 2 | -------------------------------------------------------------------------------- /toolchains_generic/BUILD: -------------------------------------------------------------------------------- 1 | load(":tool_rule.bzl", "tool_user") 2 | load(":toolchain_config.bzl", "toolchain_config") 3 | 4 | ####################################################################### 5 | # Platform definition # 6 | ####################################################################### 7 | 8 | constraint_setting(name = "target_constraint") 9 | 10 | constraint_value( 11 | name = "value_a", 12 | constraint_setting = ":target_constraint", 13 | ) 14 | 15 | platform( 16 | name = "custom_platform", 17 | constraint_values = [ 18 | ":value_a", 19 | ], 20 | ) 21 | 22 | ####################################################################### 23 | # The toolchain itself # 24 | ####################################################################### 25 | 26 | toolchain_config( 27 | name = "tool_linux", 28 | tool = "@tool_linux//:tool", 29 | ) 30 | 31 | toolchain_config( 32 | name = "tool_linux_custom", 33 | tool = "@tool_linux_custom//:tool", 34 | ) 35 | 36 | toolchain_config( 37 | name = "tool_windows", 38 | tool = "@tool_windows//:tool", 39 | ) 40 | 41 | toolchain_type(name = "tool_toolchain") 42 | 43 | toolchain( 44 | name = "tool_toolchain_linux", 45 | exec_compatible_with = [ 46 | "@platforms//os:linux", 47 | "@platforms//cpu:x86_64", 48 | ], 49 | target_compatible_with = [ 50 | "@platforms//os:linux", 51 | "@platforms//cpu:x86_64", 52 | ], 53 | toolchain = ":tool_linux", 54 | toolchain_type = ":tool_toolchain", 55 | ) 56 | 57 | toolchain( 58 | name = "tool_toolchain_windows", 59 | exec_compatible_with = [ 60 | "@platforms//os:windows", 61 | "@platforms//cpu:x86_64", 62 | ], 63 | target_compatible_with = [ 64 | "@platforms//os:windows", 65 | "@platforms//cpu:x86_64", 66 | ], 67 | toolchain = ":tool_windows", 68 | toolchain_type = ":tool_toolchain", 69 | ) 70 | 71 | toolchain( 72 | name = "tool_toolchain_linux_custom", 73 | exec_compatible_with = [ 74 | "@platforms//os:linux", 75 | "@platforms//cpu:x86_64", 76 | ], 77 | target_compatible_with = [ 78 | "//:value_a", 79 | ], 80 | toolchain = ":tool_linux_custom", 81 | toolchain_type = ":tool_toolchain", 82 | ) 83 | 84 | ####################################################################### 85 | # The rule using the toolchain # 86 | ####################################################################### 87 | 88 | tool_user( 89 | name = "product", 90 | target_compatible_with = [ 91 | ":value_a", 92 | ], 93 | ) 94 | -------------------------------------------------------------------------------- /toolchains_generic/README.md: -------------------------------------------------------------------------------- 1 | # Objective 2 | 3 | To check if bazel actually fetches the tool dependent on the resolved toolchain 4 | 5 | # Observation 6 | 7 | Bazel does only fetch the toolchain that is resolved 8 | 9 | # Learnings 10 | 11 | Be as specific as possible with toolchain constraints. If atleast one constraint does match, that toolchain is selected. 12 | 13 | This seems strange 14 | From the [docs of constraint values](https://docs.bazel.build/versions/master/be/platform.html#platform.constraint_values): 15 | 16 | > In order for a platform to apply to a given environment, the environment must have at least the values in this list. 17 | 18 | The toolchain resolution log shows that for `bazel build product --platforms //:custom_platform` 19 | The less specific toolchain is selected: 20 | 21 | ``` 22 | INFO: ToolchainResolution: Type //:tool_toolchain: target platform //:custom_platform: Rejected toolchain //:tool_windows; mismatching values: windows 23 | INFO: ToolchainResolution: Type //:tool_toolchain: target platform //:custom_platform: execution @local_config_platform//:host: Selected toolchain //:tool_linux 24 | INFO: ToolchainResolution: Target platform //:custom_platform: Selected execution platform @local_config_platform//:host, type //:tool_toolchain -> toolchain //:tool_linux 25 | ``` 26 | 27 | Given this scenario: 28 | ```python 29 | platform( 30 | name = "custom_platform", 31 | constraint_values = [ 32 | "@platforms//os:linux", 33 | "@platforms//cpu:x86_64", 34 | ":value_a", 35 | ], 36 | ) 37 | 38 | toolchain( 39 | name = "tool_toolchain_linux", 40 | exec_compatible_with = [ 41 | "@platforms//os:linux", 42 | "@platforms//cpu:x86_64", 43 | ], 44 | target_compatible_with = [ 45 | "@platforms//os:linux", 46 | "@platforms//cpu:x86_64", 47 | ], 48 | toolchain = ":tool_linux", 49 | toolchain_type = ":tool_toolchain", 50 | ) 51 | 52 | toolchain( 53 | name = "tool_toolchain_linux_custom", 54 | exec_compatible_with = [ 55 | "@platforms//os:linux", 56 | "@platforms//cpu:x86_64", 57 | ], 58 | target_compatible_with = [ 59 | "@platforms//os:linux", 60 | "@platforms//cpu:x86_64", 61 | "//:value_a", 62 | ], 63 | toolchain = ":tool_linux_custom", 64 | toolchain_type = ":tool_toolchain", 65 | ) 66 | ``` 67 | 68 | If a build with `--platforms //:custom_platform` one would assume that the toolchain selected with the compatible target platform 69 | does have atleast all constraint values defined in the platform. 70 | 71 | The expectation is that bazel would select the toolchain `tool_linux_custom` 72 | 73 | However bazel selects a toolchain that matches only a subset of the constraint_values 74 | 75 | ``` 76 | INFO: ToolchainResolution: Type //:tool_toolchain: target platform //:custom_platform: Rejected toolchain //:tool_windows; mismatching values: windows 77 | INFO: ToolchainResolution: Type //:tool_toolchain: target platform //:custom_platform: execution @local_config_platform//:host: Selected toolchain //:tool_linux 78 | INFO: ToolchainResolution: Target platform //:custom_platform: Selected execution platform @local_config_platform//:host, type //:tool_toolchain -> toolchain //:tool_linux 79 | ``` 80 | 81 | 82 | Only in this scenario the custom toolchain is selected. It is therefore not possible to combine the target platforms. 83 | ```python 84 | platform( 85 | name = "custom_platform", 86 | constraint_values = [ 87 | ":value_a", 88 | ], 89 | ) 90 | 91 | toolchain( 92 | name = "tool_toolchain_linux", 93 | exec_compatible_with = [ 94 | "@platforms//os:linux", 95 | "@platforms//cpu:x86_64", 96 | ], 97 | target_compatible_with = [ 98 | "@platforms//os:linux", 99 | "@platforms//cpu:x86_64", 100 | ], 101 | toolchain = ":tool_linux", 102 | toolchain_type = ":tool_toolchain", 103 | ) 104 | 105 | toolchain( 106 | name = "tool_toolchain_linux_custom", 107 | exec_compatible_with = [ 108 | "@platforms//os:linux", 109 | "@platforms//cpu:x86_64", 110 | ], 111 | target_compatible_with = [ 112 | "//:value_a", 113 | ], 114 | toolchain = ":tool_linux_custom", 115 | toolchain_type = ":tool_toolchain", 116 | ) 117 | ``` 118 | 119 | 120 | Seperating the os:linux and cpu constraint into a parent platform does yield the same seemingly wrong behaviour (`tool_linux` is selected instead of `tool_linux_custom`) 121 | ```python 122 | platform( 123 | name = "linux_platform", 124 | constraint_values = [ 125 | "@platforms//os:linux", 126 | "@platforms//cpu:x86_64", 127 | ], 128 | ) 129 | 130 | platform( 131 | name = "custom_platform", 132 | constraint_values = [ 133 | ":value_a", 134 | ], 135 | parents = [":linux_platform"], 136 | ) 137 | ``` 138 | -------------------------------------------------------------------------------- /toolchains_generic/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "tool_windows", 5 | build_file_content = """load("@rules_cc//cc:defs.bzl", "cc_binary") 6 | package(default_visibility = ["//visibility:public"]) 7 | cc_binary( 8 | name = "tool" 9 | ) 10 | """, 11 | sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 12 | urls = ["http://this.does.not.exist/tool.zip"], 13 | ) 14 | 15 | local_repository( 16 | name = "tool_linux", 17 | path = "local_tool", 18 | ) 19 | 20 | local_repository( 21 | name = "tool_linux_custom", 22 | path = "local_tool", 23 | ) 24 | 25 | register_toolchains( 26 | "//:tool_toolchain_windows", 27 | "//:tool_toolchain_linux", 28 | "//:tool_toolchain_linux_custom", 29 | ) 30 | -------------------------------------------------------------------------------- /toolchains_generic/local_tool/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:defs.bzl", "cc_binary") 2 | 3 | package(default_visibility = ["//visibility:public"]) 4 | 5 | cc_binary( 6 | name = "tool", 7 | srcs = ["tool.cpp"], 8 | ) 9 | -------------------------------------------------------------------------------- /toolchains_generic/local_tool/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/toolchains_generic/local_tool/WORKSPACE -------------------------------------------------------------------------------- /toolchains_generic/local_tool/tool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main(int argc, char *argv[]) { 6 | ofstream myfile; 7 | myfile.open(argv[argc - 1]); 8 | myfile << "Writing this to a file.\n"; 9 | myfile.close(); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /toolchains_generic/tool_rule.bzl: -------------------------------------------------------------------------------- 1 | def _tool_user_impl(ctx): 2 | toolchain = ctx.toolchains["//:tool_toolchain"] 3 | out = ctx.actions.declare_file(ctx.label.name) 4 | args = ctx.actions.args() 5 | args.add(out) 6 | ctx.actions.run( 7 | inputs = [], 8 | executable = toolchain.tool_info.tool, 9 | arguments = [args], 10 | outputs = [out], 11 | mnemonic = "Tool", 12 | progress_message = "Running tool for {}".format(out.basename), 13 | ) 14 | return DefaultInfo(files = depset([out])) 15 | 16 | tool_user = rule( 17 | implementation = _tool_user_impl, 18 | attrs = {}, 19 | toolchains = ["//:tool_toolchain"], 20 | ) 21 | -------------------------------------------------------------------------------- /toolchains_generic/toolchain_config.bzl: -------------------------------------------------------------------------------- 1 | ToolchainInfo = provider() 2 | 3 | def _toolchain_config_impl(ctx): 4 | return platform_common.ToolchainInfo( 5 | tool_info = ToolchainInfo( 6 | tool = ctx.executable.tool, 7 | ), 8 | ) 9 | 10 | toolchain_config = rule( 11 | implementation = _toolchain_config_impl, 12 | attrs = { 13 | "tool": attr.label( 14 | mandatory = True, 15 | cfg = "exec", 16 | executable = True, 17 | ), 18 | }, 19 | ) 20 | -------------------------------------------------------------------------------- /transition_user_defined_build_settings/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar") 2 | load("//:setting.bzl", "flavor") 3 | load("//:select_flavor.bzl", "select_flavor") 4 | load("//:ice_cream_machine.bzl", "ice_cream_machine") 5 | 6 | flavor( 7 | name = "flavor", 8 | build_setting_default = "Apple", 9 | ) 10 | 11 | ice_cream_machine( 12 | name = "maker", 13 | flavor = "//:flavor", 14 | ) 15 | 16 | select_flavor( 17 | name = "cranberry_ice_cream", 18 | flavor = "Cranberry", 19 | inputs = ["maker"], 20 | ) 21 | 22 | select_flavor( 23 | name = "cherry_ice_cream", 24 | flavor = "Cherry", 25 | inputs = ["maker"], 26 | ) 27 | 28 | pkg_tar( 29 | name = "cranberry_order", 30 | srcs = [ 31 | "cranberry_ice_cream", 32 | ], 33 | ) 34 | 35 | pkg_tar( 36 | name = "cherry_order", 37 | srcs = [ 38 | "cherry_ice_cream", 39 | "cranberry_ice_cream", 40 | "maker", 41 | ], 42 | ) 43 | 44 | pkg_tar( 45 | name = "apple_order", 46 | srcs = [ 47 | "maker", 48 | ], 49 | ) 50 | 51 | pkg_tar( 52 | name = "delivery", 53 | srcs = [ 54 | ":apple_order", 55 | ":cherry_order", 56 | ":cranberry_order", 57 | ], 58 | ) 59 | -------------------------------------------------------------------------------- /transition_user_defined_build_settings/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/transition_user_defined_build_settings/WORKSPACE -------------------------------------------------------------------------------- /transition_user_defined_build_settings/ice_cream_machine.bzl: -------------------------------------------------------------------------------- 1 | load("//:setting.bzl", "FlavorProvider") 2 | 3 | def _ice_cream_machine_impl(ctx): 4 | flavor = ctx.attr.flavor[FlavorProvider].type 5 | 6 | out = ctx.actions.declare_file(flavor + ".icecream") 7 | 8 | ctx.actions.write( 9 | output = out, 10 | content = "\n".join(["I am a", flavor, "ice cream cone"]), 11 | ) 12 | 13 | return DefaultInfo(files = depset(direct = [out])) 14 | 15 | ice_cream_machine = rule( 16 | implementation = _ice_cream_machine_impl, 17 | attrs = { 18 | "flavor": attr.label(), 19 | }, 20 | ) 21 | -------------------------------------------------------------------------------- /transition_user_defined_build_settings/select_flavor.bzl: -------------------------------------------------------------------------------- 1 | def _flavor_transition_impl(settings, attr): 2 | return { 3 | "//:flavor": attr.flavor, 4 | } 5 | 6 | _flavor_transition = transition( 7 | implementation = _flavor_transition_impl, 8 | inputs = [ 9 | "//:flavor", 10 | ], 11 | outputs = [ 12 | "//:flavor", 13 | ], 14 | ) 15 | 16 | def _select_flavor_impl(ctx): 17 | return DefaultInfo(files = depset(ctx.files.inputs)) 18 | 19 | select_flavor = rule( 20 | implementation = _select_flavor_impl, 21 | attrs = { 22 | "flavor": attr.string(), 23 | "_whitelist_function_transition": attr.label(default = Label("//tools/whitelists/function_transition_whitelist:function_transition_whitelist")), #this path is hard coded by bazel 24 | "inputs": attr.label_list( 25 | cfg = _flavor_transition, 26 | allow_files = True, 27 | ), 28 | }, 29 | ) 30 | -------------------------------------------------------------------------------- /transition_user_defined_build_settings/setting.bzl: -------------------------------------------------------------------------------- 1 | FlavorProvider = provider(fields = ["type"]) 2 | 3 | def _impl(ctx): 4 | return FlavorProvider(type = ctx.build_setting_value) 5 | 6 | flavor = rule( 7 | implementation = _impl, 8 | build_setting = config.string(flag = True), 9 | ) 10 | -------------------------------------------------------------------------------- /transition_user_defined_build_settings/tools/whitelists/function_transition_whitelist/BUILD: -------------------------------------------------------------------------------- 1 | package_group( 2 | name = "function_transition_whitelist", 3 | packages = [ 4 | "//", 5 | ], 6 | ) 7 | -------------------------------------------------------------------------------- /transitions/.bazelrc: -------------------------------------------------------------------------------- 1 | build --experimental_strict_action_env 2 | -------------------------------------------------------------------------------- /transitions/.bazelversion: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | 3 | -------------------------------------------------------------------------------- /transitions/BUILD: -------------------------------------------------------------------------------- 1 | load(":cc_api_rules.bzl", "cc_bin") 2 | load(":consumer.bzl", "consumer") 3 | 4 | cc_library( 5 | name = "header", 6 | hdrs = ["include/header.h"], 7 | ) 8 | 9 | cc_library( 10 | name = "library_a", 11 | srcs = ["code.c"], 12 | deps = [":header"], 13 | ) 14 | 15 | cc_library( 16 | name = "library_b", 17 | srcs = ["code.c"], 18 | ) 19 | 20 | cc_bin( 21 | name = "variant_a", 22 | srcs = ["main.c"], 23 | # Sets transition with copts 24 | copt = ["-DVARIANTA"], 25 | deps = [":library_a"], 26 | ) 27 | 28 | cc_bin( 29 | name = "variant_b", 30 | srcs = ["main.c"], 31 | # Sets transition with copts 32 | copt = ["-DVARIANTB"], 33 | deps = [":library_b"], 34 | ) 35 | 36 | consumer( 37 | name = "consumer", 38 | srcs = [ 39 | ":variant_a", 40 | ":variant_b", 41 | ], 42 | ) 43 | -------------------------------------------------------------------------------- /transitions/README.md: -------------------------------------------------------------------------------- 1 | # Scenario 2 | 3 | A source file is compiled with different flags. 4 | 5 | The flags are set via transitions. 6 | 7 | One configuration is buildable and the other is not aka, 8 | 9 | For one configuration (variant_a) the included header can be found. 10 | For one configuration (variant_b) the included header can not be found. 11 | 12 | The header is included only if a define `-DVARIANTA/B` is set. 13 | 14 | # Error 15 | If a rule adds two binaries with different transitions, one is built with the wrong set of flags. 16 | This is expressed by the compilation failing because of the missing header. 17 | -------------------------------------------------------------------------------- /transitions/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3 | 4 | git_repository( 5 | name = "bazel_skylib", 6 | remote = "https://github.com/bazelbuild/bazel-skylib.git", 7 | tag = "1.0.2", 8 | ) 9 | 10 | # Abseil 11 | http_archive( 12 | name = "com_google_absl", 13 | sha256 = "d5dcbef22d30d89e2ce61fffa3e4308b760aa2197c875ddcec014d11841b1ef2", 14 | strip_prefix = "abseil-cpp-master", 15 | urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"], 16 | ) 17 | 18 | git_repository( 19 | name = "googletest", 20 | remote = "https://github.com/google/googletest", 21 | tag = "release-1.8.1", 22 | ) 23 | -------------------------------------------------------------------------------- /transitions/binary.bzl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/transitions/binary.bzl -------------------------------------------------------------------------------- /transitions/cc_transition/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") 2 | load(":transition_rule.bzl", "cc_transition") 3 | 4 | cc_library( 5 | name = "foo", 6 | srcs = ["code.c"], 7 | hdrs = ["code.h"], 8 | ) 9 | 10 | cc_transition( 11 | name = "baz", 12 | copt = ["-DOUTPUT=3"], 13 | deps = [":foo"], 14 | ) 15 | 16 | # This test fails with a NullPointerException 17 | cc_test( 18 | name = "bar", 19 | srcs = ["test.cpp"], 20 | defines = ["EXPECTED=3"], 21 | linkstatic = 1, 22 | deps = [ 23 | ":baz", 24 | "@googletest//:gtest_main", 25 | ], 26 | ) 27 | 28 | cc_test( 29 | name = "foobar", 30 | srcs = ["test.cpp"], 31 | defines = ["EXPECTED=0"], 32 | deps = [ 33 | ":foo", 34 | "@googletest//:gtest_main", 35 | ], 36 | ) 37 | -------------------------------------------------------------------------------- /transitions/cc_transition/code.c: -------------------------------------------------------------------------------- 1 | #include "code.h" 2 | 3 | int out = OUTPUT; 4 | -------------------------------------------------------------------------------- /transitions/cc_transition/code.h: -------------------------------------------------------------------------------- 1 | #ifndef OUTPUT 2 | #define OUTPUT 0 3 | #endif /* ifndef OUTPUT */ 4 | 5 | extern int out; 6 | -------------------------------------------------------------------------------- /transitions/cc_transition/main.c: -------------------------------------------------------------------------------- 1 | #include "cc_transition/code.h" 2 | int main(int argc, char* argv[]) 3 | { 4 | return out; 5 | } 6 | -------------------------------------------------------------------------------- /transitions/cc_transition/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cc_transition/code.h" 3 | 4 | TEST(foo, bar) 5 | { 6 | EXPECT_EQ(out, EXPECTED); 7 | } 8 | -------------------------------------------------------------------------------- /transitions/cc_transition/transition_rule.bzl: -------------------------------------------------------------------------------- 1 | def _cc_transition_impl(settings, attr): 2 | return {"//command_line_option:copt": settings["//command_line_option:copt"] + attr.copt} 3 | 4 | _cc_transition = transition( 5 | implementation = _cc_transition_impl, 6 | inputs = ["//command_line_option:copt"], 7 | outputs = ["//command_line_option:copt"], 8 | ) 9 | 10 | def _cc_transition_rule_impl(ctx): 11 | return cc_common.merge_cc_infos( 12 | cc_infos = [dep[CcInfo] for dep in ctx.attr.deps], 13 | ) 14 | 15 | cc_transition = rule( 16 | implementation = _cc_transition_rule_impl, 17 | attrs = { 18 | "deps": attr.label_list(allow_empty = True, providers = [CcInfo]), 19 | "copt": attr.string_list(), 20 | "_whitelist_function_transition": attr.label(default = Label("//tools/whitelists/function_transition_whitelist:function_transition_whitelist")), #this path is hard coded by bazel 21 | }, 22 | cfg = _cc_transition, 23 | ) 24 | -------------------------------------------------------------------------------- /transitions/code.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef VARIANTA 3 | #include "include/header.h" 4 | #endif 5 | 6 | #ifdef VARIANTB 7 | #endif 8 | -------------------------------------------------------------------------------- /transitions/consumer.bzl: -------------------------------------------------------------------------------- 1 | def _consumer_impl(ctx): 2 | content = "\n".join(["REM " + f.path for f in ctx.files.srcs]) 3 | 4 | out = ctx.actions.declare_file(ctx.label.name + ".bat") 5 | ctx.actions.write(output = out, content = content) 6 | 7 | runfiles = ctx.runfiles(files = ctx.files.srcs) 8 | 9 | return DefaultInfo( 10 | executable = out, 11 | runfiles = runfiles, 12 | files = depset(direct = [out]), 13 | ) 14 | 15 | consumer = rule( 16 | implementation = _consumer_impl, 17 | attrs = { 18 | "srcs": attr.label_list(allow_files = True), 19 | }, 20 | executable = True, 21 | ) 22 | -------------------------------------------------------------------------------- /transitions/include/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_INCLUDED 2 | #define HEADER_INCLUDED 3 | 4 | #endif /* ifndef HEADER_INCLUDED */ 5 | -------------------------------------------------------------------------------- /transitions/main.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char* argv[]) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /transitions/output_dir_names/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") 2 | load(":transition_rule.bzl", "cc_transition") 3 | load(":cc_api_rules.bzl", "cc_bin") 4 | 5 | cc_library( 6 | name = "foo", 7 | srcs = ["code.c"], 8 | hdrs = ["code.h"], 9 | ) 10 | 11 | cc_transition( 12 | name = "baz", 13 | copt = ["-DOUTPUT=3"], 14 | deps = [":foo"], 15 | ) 16 | 17 | cc_transition( 18 | name = "foobaz", 19 | copt = ["-DOUTPUT=4"], 20 | deps = [":foo"], 21 | ) 22 | 23 | cc_test( 24 | name = "bar", 25 | srcs = ["test.cpp"], 26 | defines = ["EXPECTED=3"], 27 | linkstatic = 1, 28 | deps = [ 29 | ":baz", 30 | "@googletest//:gtest_main", 31 | ], 32 | ) 33 | 34 | cc_test( 35 | name = "foobar", 36 | srcs = ["test.cpp"], 37 | defines = ["EXPECTED=0"], 38 | deps = [ 39 | ":foo", 40 | "@googletest//:gtest_main", 41 | ], 42 | ) 43 | 44 | cc_test( 45 | name = "foobaz_test", 46 | srcs = ["test.cpp"], 47 | defines = ["EXPECTED=4"], 48 | linkstatic = 1, 49 | deps = [ 50 | ":foobaz", 51 | "@googletest//:gtest_main", 52 | ], 53 | ) 54 | 55 | cc_bin( 56 | name = "main", 57 | srcs = ["main.c"], 58 | ) 59 | -------------------------------------------------------------------------------- /transitions/output_dir_names/code.c: -------------------------------------------------------------------------------- 1 | #include "code.h" 2 | 3 | int out = OUTPUT; 4 | -------------------------------------------------------------------------------- /transitions/output_dir_names/code.h: -------------------------------------------------------------------------------- 1 | #ifndef OUTPUT 2 | #define OUTPUT 0 3 | #endif /* ifndef OUTPUT */ 4 | 5 | extern int out; 6 | -------------------------------------------------------------------------------- /transitions/output_dir_names/main.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char* argv[]) { 2 | #ifdef NDEBUG 3 | return 1; 4 | #else 5 | return 2; 6 | #endif 7 | } 8 | -------------------------------------------------------------------------------- /transitions/output_dir_names/main/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") 2 | load("//output_dir_names:transition_rule.bzl", "cc_transition") 3 | load("//output_dir_names:cc_api_rules.bzl", "cc_bin") 4 | 5 | cc_library( 6 | name = "foo", 7 | srcs = ["code.c"], 8 | hdrs = ["code.h"], 9 | ) 10 | 11 | cc_transition( 12 | name = "baz", 13 | copt = ["-DOUTPUT=3"], 14 | deps = [":foo"], 15 | ) 16 | 17 | cc_transition( 18 | name = "foobaz", 19 | copt = ["-DOUTPUT=4"], 20 | deps = [":foo"], 21 | ) 22 | 23 | cc_test( 24 | name = "bar", 25 | srcs = ["test.cpp"], 26 | defines = ["EXPECTED=3"], 27 | linkstatic = 1, 28 | deps = [ 29 | ":baz", 30 | "@googletest//:gtest_main", 31 | ], 32 | ) 33 | 34 | cc_test( 35 | name = "foobar", 36 | srcs = ["test.cpp"], 37 | defines = ["EXPECTED=0"], 38 | deps = [ 39 | ":foo", 40 | "@googletest//:gtest_main", 41 | ], 42 | ) 43 | 44 | cc_test( 45 | name = "foobaz_test", 46 | srcs = ["test.cpp"], 47 | defines = ["EXPECTED=4"], 48 | linkstatic = 1, 49 | deps = [ 50 | ":foobaz", 51 | "@googletest//:gtest_main", 52 | ], 53 | ) 54 | 55 | cc_bin( 56 | name = "main", 57 | srcs = ["main.c"], 58 | ) 59 | -------------------------------------------------------------------------------- /transitions/output_dir_names/main/main.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char* argv[]) { 2 | #ifdef NDEBUG 3 | return 1; 4 | #else 5 | return 2; 6 | #endif 7 | } 8 | -------------------------------------------------------------------------------- /transitions/output_dir_names/run.bat: -------------------------------------------------------------------------------- 1 | bazel run :main -s %* 2 | echo %errorlevel% 3 | -------------------------------------------------------------------------------- /transitions/output_dir_names/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "output_dir_names/code.h" 3 | 4 | TEST(foo, bar) 5 | { 6 | EXPECT_EQ(out, EXPECTED); 7 | } 8 | -------------------------------------------------------------------------------- /transitions/output_dir_names/transition_rule.bzl: -------------------------------------------------------------------------------- 1 | def _cc_transition_impl(settings, attr): 2 | dir_name = "-".join([ 3 | settings["//command_line_option:cpu"], 4 | attr.name, 5 | ]) 6 | return { 7 | "//command_line_option:copt": settings["//command_line_option:copt"] + attr.copt, 8 | "//command_line_option:output directory name": dir_name, 9 | } 10 | 11 | _cc_transition = transition( 12 | implementation = _cc_transition_impl, 13 | inputs = ["//command_line_option:copt", "//command_line_option:cpu"], 14 | outputs = ["//command_line_option:copt", "//command_line_option:output directory name"], 15 | ) 16 | 17 | def _cc_transition_rule_impl(ctx): 18 | return cc_common.merge_cc_infos( 19 | cc_infos = [dep[CcInfo] for dep in ctx.attr.deps], 20 | ) 21 | 22 | cc_transition = rule( 23 | implementation = _cc_transition_rule_impl, 24 | attrs = { 25 | "deps": attr.label_list(allow_empty = True, providers = [CcInfo]), 26 | "copt": attr.string_list(), 27 | "_whitelist_function_transition": attr.label(default = Label("//tools/whitelists/function_transition_whitelist:function_transition_whitelist")), #this path is hard coded by bazel 28 | }, 29 | cfg = _cc_transition, 30 | ) 31 | -------------------------------------------------------------------------------- /transitions/tools/whitelists/function_transition_whitelist/BUILD: -------------------------------------------------------------------------------- 1 | # This is unfortunately a hardcoded path in bazel: 2 | # See https://github.com/bazelbuild/bazel/issues/7056 for the tracking issue 3 | package_group( 4 | name = "function_transition_whitelist", 5 | packages = [ 6 | "//...", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /transitions/with_a_generator/BUILD: -------------------------------------------------------------------------------- 1 | load("//:cc_api_rules.bzl", "cc_bin") 2 | load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar") 3 | load("@bazel_skylib//rules:write_file.bzl", "write_file") 4 | load(":generator.bzl", "generator") 5 | 6 | generator( 7 | name = "generated_file", 8 | content = """ 9 | int main(int argc, char* argv[]) 10 | { 11 | #ifdef VARIANTA 12 | return 0; 13 | #else 14 | return 1; 15 | #endif 16 | } 17 | """, 18 | ) 19 | 20 | cc_bin( 21 | name = "variant_a", 22 | srcs = [":generated_file"], 23 | # Sets transition with copts 24 | copt = ["-DVARIANTA"], 25 | ) 26 | 27 | cc_bin( 28 | name = "variant_b", 29 | srcs = [":generated_file"], 30 | # Sets transition with copts 31 | copt = ["-DVARIANTB"], 32 | ) 33 | 34 | pkg_tar( 35 | name = "pkg", 36 | srcs = [ 37 | "generated_file", 38 | "variant_a", 39 | "variant_b", 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /transitions/with_a_generator/generator.bzl: -------------------------------------------------------------------------------- 1 | def _cc_bin_transition_impl(settings, attr): 2 | return {} 3 | 4 | _cc_bin_transition = transition( 5 | implementation = _cc_bin_transition_impl, 6 | inputs = ["//command_line_option:copt"], 7 | outputs = [], 8 | ) 9 | 10 | def _generator_impl(ctx): 11 | out = ctx.actions.declare_file(ctx.label.name + ".cpp") 12 | 13 | ctx.actions.run( 14 | inputs = [], 15 | executable = ctx.executable._tool, 16 | arguments = [ctx.attr.content, out.path], 17 | outputs = [out], 18 | mnemonic = "RunTool", 19 | progress_message = "generating {}".format(out.basename), 20 | ) 21 | 22 | return DefaultInfo(files = depset([out])) 23 | 24 | _generator = rule( 25 | implementation = _generator_impl, 26 | attrs = { 27 | "content": attr.string(), 28 | "_tool": attr.label( 29 | cfg = "host", 30 | executable = True, 31 | allow_single_file = True, 32 | default = "//with_a_generator:generator.sh", 33 | ), 34 | "_whitelist_function_transition": attr.label(default = Label("//tools/whitelists/function_transition_whitelist:function_transition_whitelist")), #this path is hard coded by bazel 35 | }, 36 | cfg = _cc_bin_transition, 37 | ) 38 | 39 | def _as_host_impl(ctx): 40 | providers = [ 41 | DefaultInfo, 42 | OutputGroupInfo, 43 | ] 44 | return [ 45 | ctx.attr.src[prov] 46 | for prov in providers 47 | if prov in ctx.attr.src 48 | ] 49 | 50 | as_host = rule( 51 | implementation = _as_host_impl, 52 | attrs = { 53 | "src": attr.label( 54 | allow_files = True, 55 | cfg = "host", 56 | ), 57 | }, 58 | ) 59 | 60 | def generator(name, **kwargs): 61 | _generator( 62 | name = name + "_gen", 63 | **kwargs 64 | ) 65 | 66 | as_host( 67 | name = name, 68 | src = name + "_gen", 69 | ) 70 | -------------------------------------------------------------------------------- /transitions/with_a_generator/generator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | echo "${1}" > "${2}" 4 | sleep 5s 5 | -------------------------------------------------------------------------------- /use_java_fragments/.bazelrc: -------------------------------------------------------------------------------- 1 | common --subcommands 2 | common --keep_going 3 | -------------------------------------------------------------------------------- /use_java_fragments/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.27.0 2 | -------------------------------------------------------------------------------- /use_java_fragments/BUILD: -------------------------------------------------------------------------------- 1 | load("//:rule_with_java.bzl", "rule_with_java") 2 | 3 | # Using a custom rule 4 | rule_with_java( 5 | name = "show_java_version", 6 | ) 7 | 8 | # Using a genrule 9 | gen_cmds = [ 10 | "$(JAVABASE)/bin/java --version", 11 | "touch $@", 12 | "exit 1", 13 | ] 14 | 15 | genrule( 16 | name = "show_java_version_with_genrule", 17 | srcs = [], 18 | outs = ["foo"], 19 | cmd = " && ".join(gen_cmds), 20 | toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], 21 | ) 22 | -------------------------------------------------------------------------------- /use_java_fragments/README.md: -------------------------------------------------------------------------------- 1 | # Usage of the java runtimes 2 | 3 | It can be necessary for tools to use the builtin java runtime. 4 | This is one way of doing so. 5 | Unfortunately i could not it to work using the `toolchains` argument of the `rule` constructor. 6 | Apparently the default `java_toolchain` aka `@bazel_tools//tools/jdk:current_host_java_runtime` does not expose 7 | the necessary providers. 8 | 9 | Using it fails with: 10 | ```bash 11 | ERROR: While resolving toolchains for target //:use_java: Target @bazel_tools//tools/jdk:current_host_java_runtime was referenced as a toolchain type, but does not provide ToolchainTypeInfo 12 | ``` 13 | 14 | Another approach with using the [JavaRuntimeInfo](https://docs.bazel.build/versions/0.27.0/skylark/lib/JavaRuntimeInfo.html) with its [java_home_runfiles_path](https://docs.bazel.build/versions/0.27.0/skylark/lib/JavaRuntimeInfo.html#java_executable_runfiles_path) argument did not work out 15 | since the `PathFragment` Class apparently is not usable in Starlark. 16 | 17 | I then used the solution applied [here](https://github.com/tensorflow/tensorflow/pull/27206/files) 18 | 19 | #### References 20 | [1] https://github.com/bazelbuild/bazel/issues/5594 21 | 22 | [2] https://github.com/tensorflow/tensorflow/pull/27206/files 23 | 24 | [3] https://docs.bazel.build/versions/master/skylark/lib/java_common.html#JavaRuntimeInfo 25 | 26 | [4] https://docs.bazel.build/versions/0.27.0/skylark/lib/JavaRuntimeInfo.html 27 | -------------------------------------------------------------------------------- /use_java_fragments/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/use_java_fragments/WORKSPACE -------------------------------------------------------------------------------- /use_java_fragments/rule_with_java.bzl: -------------------------------------------------------------------------------- 1 | def _rule_with_java_impl(ctx): 2 | out = ctx.actions.declare_file(ctx.attr.name) 3 | java_runtime = ctx.attr._jdk[java_common.JavaRuntimeInfo] 4 | jar_path = "%s/bin/java" % java_runtime.java_home 5 | 6 | args = ctx.actions.args() 7 | args.add(out) 8 | 9 | ctx.actions.run_shell( 10 | inputs = ctx.files._jdk, 11 | outputs = [out], 12 | command = "%s -version; touch $@; exit 1" % (jar_path), 13 | arguments = [args], 14 | progress_message = "Show current java version", 15 | mnemonic = "JavaVersion", 16 | ) 17 | 18 | return [ 19 | DefaultInfo(files = depset([out])), 20 | OutputGroupInfo(foo = [out]), 21 | ] 22 | 23 | rule_with_java = rule( 24 | attrs = { 25 | "_jdk": attr.label( 26 | default = Label("@bazel_tools//tools/jdk:current_host_java_runtime"), 27 | providers = [java_common.JavaRuntimeInfo], 28 | doc = "Provide the current java runtime files to this rule", 29 | ), 30 | }, 31 | toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], 32 | implementation = _rule_with_java_impl, 33 | ) 34 | -------------------------------------------------------------------------------- /variable_output_with_user_configs/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.29.1 2 | -------------------------------------------------------------------------------- /variable_output_with_user_configs/BUILD: -------------------------------------------------------------------------------- 1 | load(":custom_rule.bzl", "custom_rule", "version_config") 2 | 3 | version_config( 4 | name = "version", 5 | build_setting_default = "123", 6 | ) 7 | 8 | custom_rule( 9 | name = "foo", 10 | version = ":version", 11 | ) 12 | -------------------------------------------------------------------------------- /variable_output_with_user_configs/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") 2 | 3 | git_repository( 4 | name = "bazel_skylib", 5 | remote = "https://github.com/bazelbuild/bazel-skylib.git", 6 | tag = "1.0.2", 7 | ) 8 | -------------------------------------------------------------------------------- /variable_output_with_user_configs/custom_rule.bzl: -------------------------------------------------------------------------------- 1 | VersionInfo = provider(fields = ["version"]) 2 | 3 | def _version_config_impl(ctx): 4 | return VersionInfo(version = ctx.build_setting_value) 5 | 6 | version_config = rule( 7 | implementation = _version_config_impl, 8 | build_setting = config.string(flag = True), 9 | ) 10 | 11 | def _custom_rule_impl(ctx): 12 | print(ctx.attr.version[VersionInfo].version) 13 | 14 | custom_rule = rule( 15 | implementation = _custom_rule_impl, 16 | attrs = { 17 | "version": attr.label( 18 | providers = [VersionInfo], 19 | mandatory = True, 20 | ), 21 | }, 22 | ) 23 | -------------------------------------------------------------------------------- /workspace_status/.bazelrc: -------------------------------------------------------------------------------- 1 | build --workspace_status_command=./status/workspace_status.sh 2 | -------------------------------------------------------------------------------- /workspace_status/.bazelversion: -------------------------------------------------------------------------------- 1 | 0.26.0 2 | -------------------------------------------------------------------------------- /workspace_status/BUILD: -------------------------------------------------------------------------------- 1 | load(":version.bzl", "gen_version_file") 2 | 3 | gen_version_file( 4 | name = "gen_version_file_rule", 5 | ) 6 | -------------------------------------------------------------------------------- /workspace_status/WORKSPACE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaBrand/bazel-learning/6f2122028e21d6e6f56d7581419d76466c64c494/workspace_status/WORKSPACE -------------------------------------------------------------------------------- /workspace_status/status/workspace_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "CURRENT_TIME $(date +%s)" 3 | echo "RANDOM_HASH $(cat /dev/urandom | head -c16 | md5sum 2>/dev/null | cut -f1 -d' ')" 4 | echo "STABLE_GIT_COMMIT $(git rev-parse HEAD)" 5 | echo "STABLE_USER_NAME $USER" 6 | -------------------------------------------------------------------------------- /workspace_status/version.bzl: -------------------------------------------------------------------------------- 1 | def _gen_version_file_impl(ctx): 2 | out = ctx.actions.declare_file(ctx.attr.name) 3 | 4 | args = ctx.actions.args() 5 | 6 | args.add(ctx.info_file) 7 | args.add(ctx.version_file) 8 | args.add(out) 9 | 10 | ctx.actions.run_shell( 11 | outputs = [out], 12 | inputs = [ctx.info_file, ctx.version_file], 13 | arguments = [args], 14 | command = "cat $1 $2 > $3", 15 | ) 16 | 17 | return [DefaultInfo(files = depset([out])), OutputGroupInfo(version = [out])] 18 | 19 | gen_version_file = rule( 20 | attrs = {}, 21 | implementation = _gen_version_file_impl, 22 | ) 23 | --------------------------------------------------------------------------------