From f4965657782293ae02a96cbf286040cd84b5aa6a Mon Sep 17 00:00:00 2001 From: John Elliott Date: Fri, 10 Nov 2023 15:25:25 -0800 Subject: [PATCH 1/2] Add rust_cxx_bridge CMake function (#9411) Summary: X-link: https://github.com/facebook/fboss/pull/166 X-link: https://github.com/facebookincubator/zstrong/pull/617 X-link: https://github.com/facebookincubator/katran/pull/208 X-link: https://github.com/facebookincubator/fizz/pull/102 X-link: https://github.com/facebookexternal/traffixr/pull/4 X-link: https://github.com/facebook/watchman/pull/1173 X-link: https://github.com/facebook/proxygen/pull/473 X-link: https://github.com/facebook/fbthrift/pull/587 X-link: https://github.com/facebookincubator/velox/pull/7518 We need a better way to create cxxbridges - something that uses the recommended method of cxxbridge-cmd. This function creates C++ bindings using the [cxx] crate. Original function found here: https://github.com/corrosion-rs/corrosion/blob/master/cmake/Corrosion.cmake#L1390 Differential Revision: D51160627 --- .../CMake/RustStaticLibrary.cmake | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/build/fbcode_builder/CMake/RustStaticLibrary.cmake b/build/fbcode_builder/CMake/RustStaticLibrary.cmake index bd1b5f96ac8ac..7a5fc9f23d95a 100644 --- a/build/fbcode_builder/CMake/RustStaticLibrary.cmake +++ b/build/fbcode_builder/CMake/RustStaticLibrary.cmake @@ -324,3 +324,191 @@ function(install_rust_static_library TARGET) DESTINATION ${ARG_INSTALL_DIR} ) endfunction() + +# This function creates C++ bindings using the [cxx] crate. +# +# Original function found here: https://github.com/corrosion-rs/corrosion/blob/master/cmake/Corrosion.cmake#L1390 +# Simplified for use as part of RustStaticLibrary module. License below. +# +# MIT License +# +# Copyright (c) 2018 Andrew Gaspar +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# The rules approximately do the following: +# - Check which version of `cxx` the Rust crate depends on. +# - Check if the exact same version of `cxxbridge-cmd` is installed +# - If not, create a rule to build the exact same version of `cxxbridge-cmd`. +# - Create rules to run `cxxbridge` and generate +# - The `rust/cxx.h` header +# - A header and source file for the specified CXX_BRIDGE_FILE. +# - The generated sources (and header include directories) are added to the +# `${TARGET}` CMake library target. +# +# ```cmake +# rust_cxx_bridge( [CRATE ]) +# ``` +# +# Parameters: +# - TARGET: +# Name of the target name. The target that the bridge will be included with. +# - CXX_BRIDGE_FILE: +# Name of the file that include the cxxbridge (e.g., "src/ffi.rs"). +# - CRATE_NAME: +# Name of the crate. This parameter is optional. If unspecified, it will +# fallback to `${TARGET}`. +# +function(rust_cxx_bridge TARGET CXX_BRIDGE_FILE) + fb_cmake_parse_args(ARG "" "CRATE" "" "${ARGN}") + + if(DEFINED ARG_CRATE) + set(crate_name "${ARG_CRATE}") + else() + set(crate_name "${TARGET}") + endif() + + execute_process(COMMAND + ${CARGO_COMMAND} tree -i cxx --depth=0 + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE cxx_version_result + OUTPUT_VARIABLE cxx_version_output + ) + + if(NOT "${cxx_version_result}" EQUAL "0") + message(FATAL_ERROR "Crate ${crate_name} does not depend on cxx.") + endif() + if(cxx_version_output MATCHES "cxx v([0-9]+.[0-9]+.[0-9]+)") + set(cxx_required_version "${CMAKE_MATCH_1}") + else() + message( + FATAL_ERROR + "Failed to parse cxx version from cargo tree output: `cxx_version_output`") + endif() + + # First check if a suitable version of cxxbridge is installed + find_program(INSTALLED_CXXBRIDGE cxxbridge PATHS "$ENV{HOME}/.cargo/bin/") + mark_as_advanced(INSTALLED_CXXBRIDGE) + if(INSTALLED_CXXBRIDGE) + execute_process( + COMMAND ${INSTALLED_CXXBRIDGE} + --version OUTPUT_VARIABLE cxxbridge_version_output) + if(cxxbridge_version_output MATCHES "cxxbridge ([0-9]+.[0-9]+.[0-9]+)") + set(cxxbridge_version "${CMAKE_MATCH_1}") + else() + set(cxxbridge_version "") + endif() + endif() + + set(cxxbridge "") + if(cxxbridge_version) + if(cxxbridge_version VERSION_EQUAL cxx_required_version) + set(cxxbridge "${INSTALLED_CXXBRIDGE}") + if(NOT TARGET "cxxbridge_v${cxx_required_version}") + # Add an empty target. + add_custom_target("cxxbridge_v${cxx_required_version}") + endif() + endif() + endif() + + # No suitable version of cxxbridge was installed, + # so use custom target to install correct version. + if(NOT cxxbridge) + if(NOT TARGET "cxxbridge_v${cxx_required_version}") + add_custom_command( + OUTPUT + "${CMAKE_BINARY_DIR}/cxxbridge_v${cxx_required_version}/bin/cxxbridge" + COMMAND + ${CMAKE_COMMAND} -E make_directory + "${CMAKE_BINARY_DIR}/cxxbridge_v${cxx_required_version}" + COMMAND + ${CARGO_COMMAND} install cxxbridge-cmd + --version "${cxx_required_version}" + --root "${CMAKE_BINARY_DIR}/cxxbridge_v${cxx_required_version}" + --quiet + # todo: use --target-dir to potentially reuse artifacts + COMMENT "Installing cxxbridge (version ${cxx_required_version})" + ) + add_custom_target( + "cxxbridge_v${cxx_required_version}" + DEPENDS + "${CMAKE_BINARY_DIR}/cxxbridge_v${cxx_required_version}/bin/cxxbridge" + ) + endif() + set( + cxxbridge + "${CMAKE_BINARY_DIR}/cxxbridge_v${cxx_required_version}/bin/cxxbridge") + endif() + + add_library(${crate_name} STATIC) + target_include_directories( + ${crate_name} + PUBLIC + $ + $ + ) + + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rust") + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rust/cxx.h" + COMMAND + ${cxxbridge} + --header --output "${CMAKE_CURRENT_BINARY_DIR}/rust/cxx.h" + DEPENDS "cxxbridge_v${cxx_required_version}" + COMMENT "Generating rust/cxx.h header" + ) + + get_filename_component(filename_component ${CXX_BRIDGE_FILE} NAME) + get_filename_component(directory_component ${CXX_BRIDGE_FILE} DIRECTORY) + set(directory "") + if(directory_component) + set(directory "${directory_component}") + endif() + + set(cxx_header ${directory}/${filename_component}.h) + set(cxx_source ${directory}/${filename_component}.cc) + set(rust_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${CXX_BRIDGE_FILE}") + + file( + MAKE_DIRECTORY + "${CMAKE_CURRENT_BINARY_DIR}/${directory_component}" + ) + + add_custom_command( + OUTPUT + "${CMAKE_CURRENT_BINARY_DIR}/${cxx_header}" + "${CMAKE_CURRENT_BINARY_DIR}/${cxx_source}" + COMMAND + ${cxxbridge} ${rust_source_path} + --header --output "${CMAKE_CURRENT_BINARY_DIR}/${cxx_header}" + COMMAND + ${cxxbridge} ${rust_source_path} + --output "${CMAKE_CURRENT_BINARY_DIR}/${cxx_source}" + --include "${cxx_header}" + DEPENDS "cxxbridge_v${cxx_required_version}" "${rust_source_path}" + COMMENT "Generating cxx bindings for crate ${crate_name}" + ) + + target_sources(${crate_name} + PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}/${cxx_header}" + "${CMAKE_CURRENT_BINARY_DIR}/rust/cxx.h" + "${CMAKE_CURRENT_BINARY_DIR}/${cxx_source}" + ) +endfunction() From 0fe57675962c88e363992a3101594e00ded21ffd Mon Sep 17 00:00:00 2001 From: John Elliott Date: Fri, 10 Nov 2023 15:25:25 -0800 Subject: [PATCH 2/2] Update root Config.toml version of libc to 0.2.149 Differential Revision: D51220868 --- hphp/hack/src/hackc/ffi_bridge/Cargo.toml | 2 +- hphp/hack/src/hackc/utils/cargo/hhbc_string_utils/Cargo.toml | 2 +- hphp/hack/src/hh_fanout/cargo/hh_fanout_build/Cargo.toml | 2 +- hphp/hack/src/naming/cargo/naming_table_rust/Cargo.toml | 2 +- hphp/hack/src/shmffi/cargo/ocaml_blob/Cargo.toml | 2 +- hphp/hack/src/shmffi/cargo/shmffi/Cargo.toml | 2 +- hphp/hack/src/shmrs/Cargo.toml | 2 +- hphp/hack/src/utils/perf/cargo/profile/Cargo.toml | 2 +- hphp/hack/src/utils/rust/file_rwlock/Cargo.toml | 2 +- hphp/hack/src/utils/unwrap_ocaml/Cargo.toml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hphp/hack/src/hackc/ffi_bridge/Cargo.toml b/hphp/hack/src/hackc/ffi_bridge/Cargo.toml index 945972f88520b..137dad5d2f16e 100644 --- a/hphp/hack/src/hackc/ffi_bridge/Cargo.toml +++ b/hphp/hack/src/hackc/ffi_bridge/Cargo.toml @@ -21,7 +21,7 @@ facts = { version = "0.0.0", path = "../facts/cargo/facts_rust" } hash = { version = "0.0.0", path = "../../utils/hash" } hhbc = { version = "0.0.0", path = "../hhbc/cargo/hhbc" } hhbc_string_utils = { version = "0.0.0", path = "../utils/cargo/hhbc_string_utils" } -libc = "0.2.139" +libc = "0.2.149" options = { version = "0.0.0", path = "../compile/cargo/options" } oxidized = { version = "0.0.0", path = "../../oxidized" } oxidized_by_ref = { version = "0.0.0", path = "../../oxidized_by_ref" } diff --git a/hphp/hack/src/hackc/utils/cargo/hhbc_string_utils/Cargo.toml b/hphp/hack/src/hackc/utils/cargo/hhbc_string_utils/Cargo.toml index 3ed319fda90a6..a1bfc5a8f32e9 100644 --- a/hphp/hack/src/hackc/utils/cargo/hhbc_string_utils/Cargo.toml +++ b/hphp/hack/src/hackc/utils/cargo/hhbc_string_utils/Cargo.toml @@ -12,7 +12,7 @@ path = "../../string_utils.rs" bstr = { version = "1.4.0", features = ["serde", "std", "unicode"] } escaper = { version = "0.0.0", path = "../../../../utils/escaper" } lazy_static = "1.4" -libc = "0.2.139" +libc = "0.2.149" naming_special_names_rust = { version = "0.0.0", path = "../../../../naming" } ocaml_helper = { version = "0.0.0", path = "../../../../utils/ocaml_helper" } regex = "1.9.2" diff --git a/hphp/hack/src/hh_fanout/cargo/hh_fanout_build/Cargo.toml b/hphp/hack/src/hh_fanout/cargo/hh_fanout_build/Cargo.toml index 945a8015b62fc..35869ffacaa2d 100644 --- a/hphp/hack/src/hh_fanout/cargo/hh_fanout_build/Cargo.toml +++ b/hphp/hack/src/hh_fanout/cargo/hh_fanout_build/Cargo.toml @@ -18,7 +18,7 @@ depgraph_compress = { version = "0.0.0", path = "../../../depgraph/depgraph_comp depgraph_reader = { version = "0.0.0", path = "../../../depgraph/cargo/depgraph_reader" } depgraph_writer = { version = "0.0.0", path = "../../../depgraph/cargo/depgraph_writer" } hash = { version = "0.0.0", path = "../../../utils/hash" } -libc = "0.2.139" +libc = "0.2.149" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_std"] } memmap2 = "0.5.10" newtype = { version = "0.0.0", path = "../../../utils/newtype" } diff --git a/hphp/hack/src/naming/cargo/naming_table_rust/Cargo.toml b/hphp/hack/src/naming/cargo/naming_table_rust/Cargo.toml index 4c5286acf3c34..c69e5044accf5 100644 --- a/hphp/hack/src/naming/cargo/naming_table_rust/Cargo.toml +++ b/hphp/hack/src/naming/cargo/naming_table_rust/Cargo.toml @@ -25,7 +25,7 @@ shm_store = { version = "0.0.0", path = "../../../shmffi/cargo/shm_store" } [dev-dependencies] hh24_test = { version = "0.0.0", path = "../../../utils/cargo/hh24_test" } -libc = "0.2.139" +libc = "0.2.149" maplit = "1.0" rpds = "0.11.0" shmffi = { version = "0.0.0", path = "../../../shmffi/cargo/shmffi" } diff --git a/hphp/hack/src/shmffi/cargo/ocaml_blob/Cargo.toml b/hphp/hack/src/shmffi/cargo/ocaml_blob/Cargo.toml index 22b9bff60cf26..12e8de8efc673 100644 --- a/hphp/hack/src/shmffi/cargo/ocaml_blob/Cargo.toml +++ b/hphp/hack/src/shmffi/cargo/ocaml_blob/Cargo.toml @@ -10,7 +10,7 @@ path = "../../ocaml_blob.rs" crate-type = ["lib", "staticlib"] [dependencies] -libc = "0.2.139" +libc = "0.2.149" lz4 = "1.24.0" ocamlrep = { version = "0.1.0", git = "https://github.com/facebook/ocamlrep/", branch = "main" } shmrs = { version = "0.0.0", path = "../../../shmrs" } diff --git a/hphp/hack/src/shmffi/cargo/shmffi/Cargo.toml b/hphp/hack/src/shmffi/cargo/shmffi/Cargo.toml index 0a65f200bb3b2..4b810d8ffe1f6 100644 --- a/hphp/hack/src/shmffi/cargo/shmffi/Cargo.toml +++ b/hphp/hack/src/shmffi/cargo/shmffi/Cargo.toml @@ -12,7 +12,7 @@ doctest = false crate-type = ["lib", "staticlib"] [dependencies] -libc = "0.2.139" +libc = "0.2.149" ocaml_blob = { version = "0.0.0", path = "../ocaml_blob" } ocamlrep = { version = "0.1.0", git = "https://github.com/facebook/ocamlrep/", branch = "main" } ocamlrep_ocamlpool = { version = "0.1.0", git = "https://github.com/facebook/ocamlrep/", branch = "main" } diff --git a/hphp/hack/src/shmrs/Cargo.toml b/hphp/hack/src/shmrs/Cargo.toml index 6de146a97de01..7215baa835157 100644 --- a/hphp/hack/src/shmrs/Cargo.toml +++ b/hphp/hack/src/shmrs/Cargo.toml @@ -10,7 +10,7 @@ path = "shmrs.rs" [dependencies] hashbrown = { version = "0.12.3", features = ["nightly", "raw", "serde"] } -libc = "0.2.139" +libc = "0.2.149" nohash-hasher = "0.2" static_assertions = "1.1.0" diff --git a/hphp/hack/src/utils/perf/cargo/profile/Cargo.toml b/hphp/hack/src/utils/perf/cargo/profile/Cargo.toml index 5e18ef9c86ef5..b4ff4f7b6fdbd 100644 --- a/hphp/hack/src/utils/perf/cargo/profile/Cargo.toml +++ b/hphp/hack/src/utils/perf/cargo/profile/Cargo.toml @@ -9,4 +9,4 @@ edition = "2021" path = "../../profile.rs" [dependencies] -libc = "0.2.139" +libc = "0.2.149" diff --git a/hphp/hack/src/utils/rust/file_rwlock/Cargo.toml b/hphp/hack/src/utils/rust/file_rwlock/Cargo.toml index 957edc19b6dc3..3ae83c266cd74 100644 --- a/hphp/hack/src/utils/rust/file_rwlock/Cargo.toml +++ b/hphp/hack/src/utils/rust/file_rwlock/Cargo.toml @@ -11,7 +11,7 @@ path = "../file_rwlock.rs" [dependencies] anyhow = "=1.0.72" fs2 = "0.4" -libc = "0.2.139" +libc = "0.2.149" serde = { version = "1.0.185", features = ["derive", "rc"] } serde_json = { version = "1.0.100", features = ["float_roundtrip", "unbounded_depth"] } tempfile = "3.8" diff --git a/hphp/hack/src/utils/unwrap_ocaml/Cargo.toml b/hphp/hack/src/utils/unwrap_ocaml/Cargo.toml index eb4a6df1b3345..6ed9373e2aa96 100644 --- a/hphp/hack/src/utils/unwrap_ocaml/Cargo.toml +++ b/hphp/hack/src/utils/unwrap_ocaml/Cargo.toml @@ -11,4 +11,4 @@ test = false doctest = false [dependencies] -libc = "0.2.139" +libc = "0.2.149"