diff --git a/bazel/BUILD.bazel b/bazel/BUILD.bazel index eb8da77..495584f 100644 --- a/bazel/BUILD.bazel +++ b/bazel/BUILD.bazel @@ -11,3 +11,9 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. + +cc_binary( + name = "generate_resource_lib", + srcs = ["resource_library_main.cc"], + visibility = ["//visibility:public"], +) diff --git a/bazel/resource_library.bzl b/bazel/resource_library.bzl new file mode 100644 index 0000000..ff009ec --- /dev/null +++ b/bazel/resource_library.bzl @@ -0,0 +1,28 @@ +def resource_library( + name, + srcs, + visibility = None, + **kargs): + gen_src = name + ".c" + gen_hdr = name + ".h" + gen_srcs = [s + ".c" for s in srcs] + + native.genrule( + name = "resource_gen_" + name, + srcs = srcs, + outs = [gen_hdr, gen_src] + gen_srcs, + cmd = """ + $(location //bazel:generate_resource_lib) $(OUTS) $(SRCS) + """, + tools = [ + "//bazel:generate_resource_lib", + ], + ) + + native.cc_library( + name = name, + srcs = [gen_src] + gen_srcs, + hdrs = [gen_hdr], + visibility = visibility, + **kargs + ) diff --git a/bazel/resource_library_main.cc b/bazel/resource_library_main.cc new file mode 100644 index 0000000..bd8f3d9 --- /dev/null +++ b/bazel/resource_library_main.cc @@ -0,0 +1,158 @@ +// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this +// file except in compliance with the License. You may obtain a copy of the +// License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#include +#include +#include + +void GenerateComments(std::ostream &f) { + f << "// This file was automatically generated by resource_library\n"; +} + +void GenerateExternCOpen(std::ofstream &f) { + f << "#if __cplusplus\n"; + f << "extern \"C\" {\n"; + f << "#endif // __cplusplus\n\n"; +} + +void GenerateExternCClose(std::ofstream &f) { + f << "#if __cplusplus\n"; + f << "}\n"; + f << "#endif // __cplusplus\n\n"; +} + +std::string MakeVariable(const std::string &s) { + std::string variable = "RESOURCE_" + s; + for (char &c : variable) { + if (c == '-' || c == '.' || c == '/') { + c = '_'; + } + } + return variable; +} + +void GenerateResourceEntry(std::ostream &f) { + f << "struct ResourceEntry {\n"; + f << " const char* name; // the file's original name\n"; + f << " const char* data; // beginning of the file\n"; + f << " unsigned int size; // length of the file\n"; + f << "};\n\n"; +} + +bool GenerateHeader(const std::string &output_hdr, + const std::vector &input_files) { + std::ofstream hdr(output_hdr); + GenerateComments(hdr); + + hdr << "#pragma once\n\n"; + GenerateExternCOpen(hdr); + + GenerateResourceEntry(hdr); + // TODO(kangjinci): generate resource entry table + + for (const auto &file : input_files) { + auto variable = MakeVariable(file); + std::ifstream f(file, std::ios::binary | std::ios::ate); + if (!f.is_open()) { + printf("open file %s failed\n", file.c_str()); + return false; + } + hdr << "// " << file << "\n"; + hdr << "extern const char " << variable << "[" << f.tellg() << "];\n"; + hdr << "extern const unsigned " << variable << "_len;\n\n"; + f.close(); + } + + GenerateExternCClose(hdr); + + return true; +} + +bool GenerateSource(const std::string &output_src, + const std::vector &input_files, + const std::vector &output_files) { + std::ofstream src(output_src); + GenerateComments(src); + // TODO(kangjinci): generate resource entry table + + size_t size = input_files.size(); + for (size_t i = 0; i < size; ++i) { + std::ifstream input(input_files[i], std::ios::binary | std::ios::ate); + std::ofstream output(output_files[i]); + + if (!input.is_open()) { + printf("open file %s failed\n", input_files[i].c_str()); + return false; + } + + auto file_size = input.tellg(); + input.seekg(0); + + GenerateComments(output); + + auto variable = MakeVariable(input_files[i]); + output << "const char " << variable << "[] = {\n"; + + char buf[13] = {0}; + do { + output << " "; + input.read(buf, 12); + for (short c : buf) { + if (c == '\0') { + break; + } + output << c << ", "; + } + output << "\n"; + } while (!input.eof()); + + output << "};\n"; + output << "const unsigned int " << variable << "_len = " << file_size + << ";\n\n"; + + input.close(); + output.close(); + } + + return true; +} + +int main(int argc, char **argv) { + if (argc == 1) { + printf("Please specify the output header and source files\n"); + return -1; + } + + if (argc < 4) { + printf("Please specify the input source files\n"); + return -1; + } + + if ((argc - 3) % 2 == 1) { + printf("Invalid arguments\n"); + return -1; + } + int size = (argc - 3) / 2; + + std::vector output_files(argv + 3, argv + 3 + size); + std::vector input_files(argv + 3 + size, argv + argc); + + if (!GenerateHeader(argv[1], input_files)) { + return -1; + } + + if (!GenerateSource(argv[2], input_files, output_files)) { + return -1; + } +} diff --git a/flare/rpc/protocol/http/builtin/BUILD.bazel b/flare/rpc/protocol/http/builtin/BUILD.bazel index 84f2085..8af2647 100644 --- a/flare/rpc/protocol/http/builtin/BUILD.bazel +++ b/flare/rpc/protocol/http/builtin/BUILD.bazel @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations under # the License. +load("//bazel:resource_library.bzl", "resource_library") + cc_library( name = "builtin", hdrs = [], @@ -22,10 +24,10 @@ cc_library( ":misc_handler", ":options_handler", ":prof_cpu_handler", - # ":rpc_form_handler", + ":rpc_form_handler", ":rpc_reflect_handler", ":rpc_statistics_handler", - # ":static_resource_http_handler", + ":static_resource_http_handler", ], ) @@ -139,22 +141,22 @@ cc_library( alwayslink = True, ) -# cc_test( -# name = "rpc_statistics_handler_test", -# srcs = ["rpc_statistics_handler_test.cc"], -# deps = [ -# ":rpc_statistics_handler", -# "//flare/base:down_cast", -# "//flare/net/http:http_client", -# "//flare/rpc", -# "//flare/rpc/load_balancer:round_robin", -# "//flare/rpc/name_resolver:list", -# "//flare/testing:echo_service_proto_flare", -# "//flare/testing:endpoint", -# "//flare/testing:main", -# "@com_github_jsoncpp//:jsoncpp", -# ], -# ) +cc_test( + name = "rpc_statistics_handler_test", + srcs = ["rpc_statistics_handler_test.cc"], + deps = [ + ":rpc_statistics_handler", + "//flare/base:down_cast", + "//flare/net/http:http_client", + "//flare/rpc", + "//flare/rpc/load_balancer:round_robin", + "//flare/rpc/name_resolver:list", + "//flare/testing:echo_service_proto_flare", + "//flare/testing:endpoint", + "//flare/testing:main", + "@com_github_jsoncpp//:jsoncpp", + ], +) cc_library( name = "prof_cpu_handler", @@ -179,18 +181,18 @@ cc_test( ], ) -# cc_library( -# name = "static_resource_http_handler", -# srcs = ["static_resource_http_handler.cc"], -# hdrs = ["static_resource_http_handler.h"], -# deps = [ -# ":static_resources", -# "//flare/rpc:http", -# ], -# alwayslink = True, -# ) +cc_library( + name = "static_resource_http_handler", + srcs = ["static_resource_http_handler.cc"], + hdrs = ["static_resource_http_handler.h"], + deps = [ + ":static_resources", + "//flare/rpc:http", + ], + alwayslink = True, +) -filegroup( +resource_library( name = "static_resources", srcs = [ "resources/static/antd-4.8.2.css", @@ -205,18 +207,18 @@ filegroup( ], ) -# cc_library( -# name = "rpc_form_handler", -# srcs = ["rpc_form_handler.cc"], -# hdrs = ["rpc_form_handler.h"], -# deps = [ -# ":static_resources", -# "//flare/base:string", -# "//flare/rpc:http", -# "@com_github_olafvdspek_ctemplate//:ctemplate", -# ], -# alwayslink = True, -# ) +cc_library( + name = "rpc_form_handler", + srcs = ["rpc_form_handler.cc"], + hdrs = ["rpc_form_handler.h"], + deps = [ + ":static_resources", + "//flare/base:string", + "//flare/rpc:http", + "@com_github_olafvdspek_ctemplate//:ctemplate", + ], + alwayslink = True, +) cc_library( name = "rpc_reflect_handler", @@ -232,19 +234,19 @@ cc_library( alwayslink = True, ) -# cc_test( -# name = "rpc_reflect_handler_test", -# srcs = ["rpc_reflect_handler_test.cc"], -# deps = [ -# ":rpc_reflect_handler", -# "//flare/base/net:endpoint", -# "//flare/net/http:http_client", -# "//flare/rpc", -# "//flare/rpc/protocol/protobuf:service_method_locator", -# "//flare/testing:echo_service_proto_flare", -# "//flare/testing:endpoint", -# "//flare/testing:main", -# "@com_github_jsoncpp//:jsoncpp", -# "@com_google_protobuf//:protobuf", -# ], -# ) +cc_test( + name = "rpc_reflect_handler_test", + srcs = ["rpc_reflect_handler_test.cc"], + deps = [ + ":rpc_reflect_handler", + "//flare/base/net:endpoint", + "//flare/net/http:http_client", + "//flare/rpc", + "//flare/rpc/protocol/protobuf:service_method_locator", + "//flare/testing:echo_service_proto_flare", + "//flare/testing:endpoint", + "//flare/testing:main", + "@com_github_jsoncpp//:jsoncpp", + "@com_google_protobuf//:protobuf", + ], +)