From 2870725464b6920bbdf7204301b33b7f6e3bb365 Mon Sep 17 00:00:00 2001 From: Bryan Kersting Date: Thu, 10 Sep 2026 01:32:52 -0700 Subject: [PATCH] deflate: prepare deflate-cpp-bindings for crates.io release Move Cargo.toml to the package root so that `cargo publish` includes the C++ headers, source files, and CMakeLists.txt alongside the Rust bindings. Also copy the license file into the crate directory. PiperOrigin-RevId: 979030123 --- deflate/CMakeLists.txt | 29 +++++- deflate/Cargo.toml | 33 +++++++ deflate/LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++ deflate/flate2.cc | 46 ++++----- deflate/flate2.h | 34 +++---- deflate/gzip_wrapper.cc | 14 +-- deflate/rust/Cargo.toml | 13 --- 7 files changed, 305 insertions(+), 65 deletions(-) create mode 100644 deflate/Cargo.toml create mode 100644 deflate/LICENSE delete mode 100644 deflate/rust/Cargo.toml diff --git a/deflate/CMakeLists.txt b/deflate/CMakeLists.txt index 1915ec3..e818f08 100644 --- a/deflate/CMakeLists.txt +++ b/deflate/CMakeLists.txt @@ -21,8 +21,27 @@ FetchContent_Declare( FetchContent_MakeAvailable(Corrosion) -corrosion_experimental_crubit(rust) -corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) +corrosion_experimental_crubit(deflate_cpp_bindings) +corrosion_import_crate(MANIFEST_PATH Cargo.toml) + +# Crubit names the static library after the package (libdeflate-cpp-bindings.a), +# while Corrosion expects Cargo library target naming (libdeflate_cpp_bindings.a). +# Copy the byproduct before Corrosion attempts to copy it. +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/copy_crubit_lib.cmake" +"file(GLOB_RECURSE libs + \"${CMAKE_CURRENT_BINARY_DIR}/cargo/*deflate-cpp-bindings.a\" + \"${CMAKE_CURRENT_BINARY_DIR}/cargo/*deflate-cpp-bindings.lib\" +) +foreach(lib IN LISTS libs) + string(REPLACE \"deflate-cpp-bindings\" \"deflate_cpp_bindings\" target_lib \"\${lib}\") + file(COPY_FILE \"\${lib}\" \"\${target_lib}\") +endforeach() +") +add_custom_command( + TARGET _cargo-build_deflate_cpp_bindings + POST_BUILD + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/copy_crubit_lib.cmake" +) FetchContent_Declare( absl @@ -33,10 +52,10 @@ FetchContent_MakeAvailable(absl) add_library(flate2 flate2.cc flate2.h) target_include_directories(flate2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") -target_link_libraries(flate2 PRIVATE rust absl::status absl::statusor absl::cord absl::strings absl::span) +target_link_libraries(flate2 PRIVATE deflate_cpp_bindings absl::status absl::statusor absl::cord absl::strings absl::span) add_library(gzip_wrapper gzip_wrapper.cc gzip_wrapper.h) -target_link_libraries(gzip_wrapper PRIVATE flate2 rust absl::status absl::statusor absl::strings absl::span) +target_link_libraries(gzip_wrapper PRIVATE flate2 deflate_cpp_bindings absl::status absl::statusor absl::strings absl::span) add_executable(deflate_example main.cc) -target_link_libraries(deflate_example PRIVATE rust flate2 gzip_wrapper absl::statusor absl::strings) +target_link_libraries(deflate_example PRIVATE deflate_cpp_bindings flate2 gzip_wrapper absl::statusor absl::strings) diff --git a/deflate/Cargo.toml b/deflate/Cargo.toml new file mode 100644 index 0000000..206d6c4 --- /dev/null +++ b/deflate/Cargo.toml @@ -0,0 +1,33 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 . +# This file may not be copied, modified, or distributed +# except according to those terms. + +[package] +name = "deflate-cpp-bindings" +description = "C++ bindings for the flate2 crate using crubit" +version = "0.1.0-prerelease" +license-file = "LICENSE" +license = "Apache-2.0" +edition = "2024" +repository = "https://github.com/google/safe-bindings" + +include = [ + "Cargo.toml", + "README.md", + "LICENSE", + "rust/*.rs", + "*.h", + "*.cc", + "CMakeLists.txt", +] + +[lib] +path = "rust/lib.rs" +doctest = false + +[dependencies] +bytes = "1" +flate2 = { version = "1", features = ["rust_backend", "zlib-rs"] } diff --git a/deflate/LICENSE b/deflate/LICENSE new file mode 100644 index 0000000..56ee3c8 --- /dev/null +++ b/deflate/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. \ No newline at end of file diff --git a/deflate/flate2.cc b/deflate/flate2.cc index 0b147a8..02110c8 100644 --- a/deflate/flate2.cc +++ b/deflate/flate2.cc @@ -4,7 +4,7 @@ #include #include -#include "crubit/rust.h" +#include "crubit/deflate_cpp_bindings.h" #include "crubit_helpers/string_conversions.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -16,7 +16,7 @@ namespace security::deflate { using ::security::crubit_helpers::StringViewFromVecU8; -VecU8Wrapper::VecU8Wrapper(rust::vec_u8::VecU8 vec_u8) +VecU8Wrapper::VecU8Wrapper(deflate_cpp_bindings::vec_u8::VecU8 vec_u8) : vec_u8_(std::move(vec_u8)) {} absl::string_view VecU8Wrapper::as_string_view() const { @@ -36,21 +36,21 @@ absl::Cord VecU8Wrapper::as_cord() && { return absl::MakeCordFromExternal(view, [b = std::move(vec_u8_)] {}); } -Compression::Compression(rust::Compression compression) +Compression::Compression(deflate_cpp_bindings::Compression compression) : compression_(compression) {} Compression::Compression(int level) - : compression_(rust::Compression::new_(level)) {} + : compression_(deflate_cpp_bindings::Compression::new_(level)) {} -rust::Compression Compression::get() const { return compression_; } +deflate_cpp_bindings::Compression Compression::get() const { return compression_; } Compression Compression::best() { - return Compression(rust::Compression::best()); + return Compression(deflate_cpp_bindings::Compression::best()); } Compression Compression::none() { - return Compression(rust::Compression::none()); + return Compression(deflate_cpp_bindings::Compression::none()); } -GzHeader::GzHeader(rust::GzHeader gz_header) : gz_header_(gz_header) {} +GzHeader::GzHeader(deflate_cpp_bindings::GzHeader gz_header) : gz_header_(gz_header) {} uint8_t GzHeader::operating_system() const { return gz_header_.operating_system(); @@ -58,7 +58,7 @@ uint8_t GzHeader::operating_system() const { uint32_t GzHeader::mtime() const { return gz_header_.mtime(); } std::optional GzHeader::FromRustOptionGzHeader( - std::optional header) { + std::optional header) { if (!header.has_value()) { return std::nullopt; } @@ -85,7 +85,7 @@ std::optional GzDecoderImpl::header() const { template absl::StatusOr GzDecoderImpl::read_to_end() { - rs_std::Result + rs_std::Result result_vec_u8 = decoder_.read_to_end(); if (!result_vec_u8.has_value()) { // Potential errors from flate2 crate @@ -100,18 +100,18 @@ absl::StatusOr GzDecoderImpl::read_to_end() { return VecU8Wrapper(std::move(result_vec_u8).value()); } -GzEncoder::GzEncoder(rust::read::GzEncoder encoder) +GzEncoder::GzEncoder(deflate_cpp_bindings::read::GzEncoder encoder) : encoder_(std::move(encoder)) {} GzEncoder GzEncoder::create(absl::string_view data, Compression level) { - return GzEncoder(rust::read::GzEncoder::create( + return GzEncoder(deflate_cpp_bindings::read::GzEncoder::create( absl::Span(reinterpret_cast(data.data()), data.size()), level.get())); } absl::StatusOr GzEncoder::read_to_end() { - rs_std::Result + rs_std::Result result_vec_u8 = encoder_.read_to_end(); if (!result_vec_u8.has_value()) { // Potential errors only include system errors when reading from the @@ -123,8 +123,8 @@ absl::StatusOr GzEncoder::read_to_end() { return VecU8Wrapper(std::move(result_vec_u8).value()); } -template class GzDecoderImpl; -template class GzDecoderImpl; +template class GzDecoderImpl; +template class GzDecoderImpl; } // namespace read @@ -146,7 +146,7 @@ std::optional GzDecoderImpl::header() const { template absl::Status GzDecoderImpl::write_all(absl::string_view data) { - rs_std::Result result_unit = + rs_std::Result result_unit = decoder_.write_all(absl::Span( reinterpret_cast(data.data()), data.size())); if (!result_unit.has_value()) { @@ -164,7 +164,7 @@ absl::Status GzDecoderImpl::write_all(absl::string_view data) { template absl::StatusOr GzDecoderImpl::finish() && { - rs_std::Result + rs_std::Result result_vec_u8 = std::move(decoder_).finish(); if (!result_vec_u8.has_value()) { // Potential errors from flate2 crate @@ -176,15 +176,15 @@ absl::StatusOr GzDecoderImpl::finish() && { return VecU8Wrapper(std::move(result_vec_u8).value()); } -GzEncoder::GzEncoder(rust::write::GzEncoder encoder) +GzEncoder::GzEncoder(deflate_cpp_bindings::write::GzEncoder encoder) : encoder_(std::move(encoder)) {} GzEncoder GzEncoder::create(Compression level) { - return GzEncoder(rust::write::GzEncoder::create(level.get())); + return GzEncoder(deflate_cpp_bindings::write::GzEncoder::create(level.get())); } absl::Status GzEncoder::write_all(absl::string_view data) { - rs_std::Result result_unit = + rs_std::Result result_unit = encoder_.write_all(absl::Span( reinterpret_cast(data.data()), data.size())); if (!result_unit.has_value()) { @@ -199,7 +199,7 @@ absl::Status GzEncoder::write_all(absl::string_view data) { } absl::StatusOr GzEncoder::finish() && { - rs_std::Result + rs_std::Result result_vec_u8 = std::move(encoder_).finish(); if (!result_vec_u8.has_value()) { // Potential errors only include system errors when using the @@ -211,8 +211,8 @@ absl::StatusOr GzEncoder::finish() && { return VecU8Wrapper(std::move(result_vec_u8).value()); } -template class GzDecoderImpl; -template class GzDecoderImpl; +template class GzDecoderImpl; +template class GzDecoderImpl; } // namespace write diff --git a/deflate/flate2.h b/deflate/flate2.h index 1113591..a4c2f3c 100644 --- a/deflate/flate2.h +++ b/deflate/flate2.h @@ -4,7 +4,7 @@ #include #include -#include "crubit/rust.h" +#include "crubit/deflate_cpp_bindings.h" #include "absl/base/attributes.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -31,8 +31,8 @@ class GzDecoderImpl final { RustDecoder decoder_; }; -using GzDecoder = GzDecoderImpl; -using MultiGzDecoder = GzDecoderImpl; +using GzDecoder = GzDecoderImpl; +using MultiGzDecoder = GzDecoderImpl; class GzEncoder final { public: @@ -40,8 +40,8 @@ class GzEncoder final { absl::StatusOr read_to_end(); private: - explicit GzEncoder(rust::read::GzEncoder encoder); - rust::read::GzEncoder encoder_; + explicit GzEncoder(deflate_cpp_bindings::read::GzEncoder encoder); + deflate_cpp_bindings::read::GzEncoder encoder_; }; } // namespace read @@ -62,8 +62,8 @@ class GzDecoderImpl final { RustDecoder decoder_; }; -using GzDecoder = GzDecoderImpl; -using MultiGzDecoder = GzDecoderImpl; +using GzDecoder = GzDecoderImpl; +using MultiGzDecoder = GzDecoderImpl; class GzEncoder final { public: @@ -72,8 +72,8 @@ class GzEncoder final { absl::StatusOr finish() &&; private: - explicit GzEncoder(rust::write::GzEncoder encoder); - rust::write::GzEncoder encoder_; + explicit GzEncoder(deflate_cpp_bindings::write::GzEncoder encoder); + deflate_cpp_bindings::write::GzEncoder encoder_; }; } // namespace write @@ -87,10 +87,10 @@ class Compression final { private: friend class read::GzEncoder; friend class write::GzEncoder; - explicit Compression(rust::Compression compression); - rust::Compression get() const; + explicit Compression(deflate_cpp_bindings::Compression compression); + deflate_cpp_bindings::Compression get() const; - rust::Compression compression_; + deflate_cpp_bindings::Compression compression_; }; class GzHeader final { @@ -99,22 +99,22 @@ class GzHeader final { uint32_t mtime() const; static std::optional FromRustOptionGzHeader( - std::optional header); + std::optional header); private: - explicit GzHeader(rust::GzHeader gz_header); + explicit GzHeader(deflate_cpp_bindings::GzHeader gz_header); - rust::GzHeader gz_header_; + deflate_cpp_bindings::GzHeader gz_header_; }; class VecU8Wrapper { public: - explicit VecU8Wrapper(rust::vec_u8::VecU8 vec_u8); + explicit VecU8Wrapper(deflate_cpp_bindings::vec_u8::VecU8 vec_u8); absl::string_view as_string_view() const ABSL_ATTRIBUTE_LIFETIME_BOUND; absl::Cord as_cord() &&; private: - rust::vec_u8::VecU8 vec_u8_; + deflate_cpp_bindings::vec_u8::VecU8 vec_u8_; }; } // namespace security::deflate diff --git a/deflate/gzip_wrapper.cc b/deflate/gzip_wrapper.cc index 924bc8a..97a1a0e 100644 --- a/deflate/gzip_wrapper.cc +++ b/deflate/gzip_wrapper.cc @@ -4,7 +4,7 @@ #include #include "flate2.h" -#include "crubit/rust.h" +#include "crubit/deflate_cpp_bindings.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/string_view.h" @@ -14,7 +14,7 @@ namespace security::deflate { namespace { -absl::string_view StringViewFromVecU8(const rust::vec_u8::VecU8& vec) { +absl::string_view StringViewFromVecU8(const deflate_cpp_bindings::vec_u8::VecU8& vec) { static_assert(sizeof(const char) == sizeof(const uint8_t), "Alignment check failed"); static_assert(alignof(const char) <= alignof(const uint8_t), @@ -32,12 +32,12 @@ absl::StatusOr CompressGzip(absl::string_view contents, return absl::InvalidArgumentError("invalid compression level, must be 0-9"); } - auto encoder = rust::read::GzEncoder::create( + auto encoder = deflate_cpp_bindings::read::GzEncoder::create( absl::Span( reinterpret_cast(contents.data()), contents.size()), - rust::Compression::new_(compression_level)); + deflate_cpp_bindings::Compression::new_(compression_level)); - rs_std::Result result = + rs_std::Result result = encoder.read_to_end(); if (!result.has_value()) { // Potential errors only include system errors when reading from the @@ -49,9 +49,9 @@ absl::StatusOr CompressGzip(absl::string_view contents, } absl::StatusOr UncompressGzip(absl::string_view compressed) { - auto decoder = rust::read::GzDecoder::create(absl::Span( + auto decoder = deflate_cpp_bindings::read::GzDecoder::create(absl::Span( reinterpret_cast(compressed.data()), compressed.size())); - rs_std::Result result = + rs_std::Result result = decoder.read_to_end(); if (!result.has_value()) { // Potential errors from flate2 crate diff --git a/deflate/rust/Cargo.toml b/deflate/rust/Cargo.toml deleted file mode 100644 index 1df4b45..0000000 --- a/deflate/rust/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "rust" -version = "0.1.0" -edition = "2024" -license-file = "../../LICENSE" - -[lib] -path = "lib.rs" -doctest = false - -[dependencies] -bytes = "1" -flate2 = { version = "1", features = ["rust_backend", "zlib-rs"] }