Skip to content

Commit 61b1a2d

Browse files
committed
Use single Rust staticlib for FFI
Currently, each Rust FFI library is built and linked into the HHVM binaries as separate static libraries. This is [explicitly unsupported](https://cxx.rs/build/other.html#linking-the-c-and-rust-together) by the `cxx` crate, which recommends either using rustc as the final linker or using a single Rust staticlib for the Rust components, and has been the cause of linking errors for the last couple of years (see T146965521). The former does not seem to be feasible for HHVM OSS, so go with the latter approach and combine Rust FFI libraries into a single staticlib, then link that into HHVM. This will likely need corresponding changes in the internal buck2 build.
1 parent e661382 commit 61b1a2d

24 files changed

Lines changed: 123 additions & 123 deletions

CMake/HPHPFindLibs.cmake

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,7 @@ macro(hphp_link target)
408408
target_link_libraries(${target} ${VISIBILITY} fizz)
409409
target_link_libraries(${target} ${VISIBILITY} brotli)
410410
target_link_libraries(${target} ${VISIBILITY} hhbc_ast_header)
411-
target_link_libraries(${target} ${VISIBILITY} compiler_ffi)
412-
target_link_libraries(${target} ${VISIBILITY} package_ffi)
413-
target_link_libraries(${target} ${VISIBILITY} parser_ffi)
414-
target_link_libraries(${target} ${VISIBILITY} hhvm_types_ffi)
415-
target_link_libraries(${target} ${VISIBILITY} hhvm_hhbc_defs_ffi)
411+
target_link_libraries(${target} ${VISIBILITY} hack_rust_ffi_bridge)
416412

417413
target_link_libraries(${target} ${VISIBILITY} tbb)
418414

hphp/compiler/compiler-systemlib.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "hphp/compiler/compiler-systemlib.h"
1818

1919
#include "hphp/hack/src/hackc/ffi_bridge/decl_provider.h"
20-
#include "hphp/hack/src/hackc/ffi_bridge/compiler_ffi.rs.h"
20+
#include "hphp/hack/src/hhvm_ffi/compiler_ffi.rs.h"
2121

2222
#include "hphp/hhvm/process-init.h"
2323

hphp/compiler/compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "hphp/compiler/option.h"
2020
#include "hphp/compiler/package.h"
2121

22-
#include "hphp/hack/src/hackc/ffi_bridge/compiler_ffi.rs.h"
22+
#include "hphp/hack/src/hhvm_ffi/compiler_ffi.rs.h"
2323

2424
#include "hphp/hhbbc/hhbbc.h"
2525
#include "hphp/hhbbc/misc.h"

hphp/compiler/package.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
#include "hphp/compiler/decl-provider.h"
3535
#include "hphp/compiler/option.h"
36-
#include "hphp/hack/src/hackc/ffi_bridge/compiler_ffi.rs.h"
36+
#include "hphp/hack/src/hhvm_ffi/compiler_ffi.rs.h"
3737
#include "hphp/hhvm/process-init.h"
3838
#include "hphp/runtime/base/execution-context.h"
3939
#include "hphp/runtime/base/file-util-defs.h"

hphp/hack/CMakeLists.txt

Lines changed: 66 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -225,115 +225,82 @@ HHVM_RENDER_CONFIG_SPECIFICATION(
225225
OUTPUT_PATH "${CMAKE_BINARY_DIR}/hphp/hack/src/hackc/compile"
226226
)
227227

228-
# Compiling cxx entrypoints for hhvm
229-
#
230-
# Usage:
231-
# build_cxx_bridge(
232-
# name
233-
# DIR directory
234-
# [EXTRA_SRCS src [src ...]]
235-
# [LINK_LIBS lib [lib ...]]
236-
# )
237-
#
238-
# Where:
239-
# `name` is the target name of the cxx_bridge.
240-
# `directory` is the required directory of the cxx_bridge sources.
241-
# `src` are extra source files to include in the bridge.
242-
# `lib` are extra link libraries to include in the bridge.
243-
#
244-
function(build_cxx_bridge NAME)
245-
cmake_parse_arguments(CXX_BRIDGE "" "DIR" "EXTRA_SRCS;LINK_LIBS" ${ARGN})
228+
set(
229+
FFI_CRATES
230+
"package_ffi"
231+
"parser_ffi"
232+
"compiler_ffi"
233+
"hdf"
234+
"hhvm_types_ffi"
235+
"hhvm_hhbc_defs_ffi"
236+
)
246237

247-
if ("${CXX_BRIDGE_DIR}" STREQUAL "")
248-
message(FATAL_ERROR "Missing DIR parameter")
249-
endif()
250-
if (NOT "${CXX_BRIDGE_UNPARSED_ARGUMENTS}" STREQUAL "")
251-
message(FATAL_ERROR "Unexpected parameters: ${CXX_BRIDGE_UNPARSED_ARGUMENTS}")
252-
endif()
238+
set(FFI_BRIDGE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/hhvm_ffi")
239+
set(FFI_BRIDGE_BIN "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/hhvm_ffi")
240+
set(RUST_PART_LIB "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/hhvm_ffi/${PROFILE}/${CMAKE_STATIC_LIBRARY_PREFIX}hhvm_ffi${CMAKE_STATIC_LIBRARY_SUFFIX}")
253241

254-
set(FFI_BRIDGE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${CXX_BRIDGE_DIR}")
255-
set(FFI_BRIDGE_BIN "${RUST_FFI_BUILD_ROOT}/hphp/hack/${CXX_BRIDGE_DIR}")
256-
257-
set(RUST_PART_LIB "${FFI_BRIDGE_BIN}/${PROFILE}/${CMAKE_STATIC_LIBRARY_PREFIX}${NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
258-
set(RUST_PART_CXX "${FFI_BRIDGE_BIN}/${NAME}.cpp")
259-
set(RUST_PART_HEADER "${FFI_BRIDGE_BIN}/${NAME}.rs.h")
260-
set(GENERATED "${FFI_BRIDGE_BIN}/cxxbridge/${NAME}/${NAME}")
261-
set(GENERATED_CXXBRIDGE "${FFI_BRIDGE_BIN}/cxxbridge")
262-
263-
add_custom_command(
264-
OUTPUT
265-
${RUST_PART_CXX}
266-
${RUST_PART_HEADER}
267-
${RUST_PART_LIB}
268-
${GENERATED_CXXBRIDGE}
269-
COMMAND
270-
${CMAKE_COMMAND} -E make_directory "${FFI_BRIDGE_BIN}" &&
271-
. "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
272-
${INVOKE_CARGO} "${NAME}" "${NAME}" --target-dir "${FFI_BRIDGE_BIN}" &&
273-
${CMAKE_COMMAND} -E copy "${GENERATED}.rs.cc" "${RUST_PART_CXX}" &&
274-
${CMAKE_COMMAND} -E copy "${GENERATED}.rs.h" "${RUST_PART_HEADER}"
275-
WORKING_DIRECTORY ${FFI_BRIDGE_SRC}
276-
DEPENDS rustc cargo "${OPCODE_DATA}"
277-
)
278-
add_custom_target(
279-
"${NAME}_cxx"
280-
DEPENDS ${RUST_PART_LIB}
281-
)
282-
add_library("${NAME}" STATIC ${RUST_PART_CXX} ${CXX_BRIDGE_EXTRA_SRCS} )
283-
add_dependencies(hack_rust_ffi_bridge_targets "${NAME}")
284-
add_library("${NAME}_rust_part" STATIC IMPORTED)
285-
add_dependencies("${NAME}_rust_part" "${NAME}_cxx")
286-
287-
# Intentionally create link-time cyclic dependency between ${NAME}_rust_part
288-
# and ${NAME} so that CMake will automatically construct the link line so
289-
# that the linker will scan through involved static libraries multiple times.
290-
set_target_properties(
291-
"${NAME}_rust_part"
292-
PROPERTIES
293-
IMPORTED_LOCATION ${RUST_PART_LIB}
294-
IMPORTED_LINK_DEPENDENT_LIBRARIES "${NAME}"
295-
)
296-
target_link_libraries(
297-
"${NAME}"
298-
PUBLIC
299-
"${NAME}_rust_part"
300-
${CXX_BRIDGE_LINK_LIBS}
301-
)
302-
target_include_directories("${NAME}" INTERFACE "${RUST_FFI_BUILD_ROOT}")
303-
target_include_directories("${NAME}" PRIVATE "${GENERATED_CXXBRIDGE}")
304-
endfunction()
242+
foreach(NAME ${FFI_CRATES})
243+
list(APPEND FFI_CXXBRIDGE_ORIG_SRCS "${FFI_BRIDGE_BIN}/cxxbridge/${NAME}/${NAME}.rs.cc")
244+
list(APPEND FFI_CXXBRIDGE_SRCS "${FFI_BRIDGE_BIN}/${NAME}.rs.cc")
245+
246+
list(APPEND FFI_CXXBRIDGE_ORIG_HEADERS "${FFI_BRIDGE_BIN}/cxxbridge/${NAME}/${NAME}.rs.h")
247+
list(APPEND FFI_CXXBRIDGE_HEADERS "${FFI_BRIDGE_BIN}/${NAME}.rs.h")
248+
endforeach()
305249

306-
build_cxx_bridge(
307-
package_ffi
308-
DIR "src/package/ffi_bridge"
250+
add_custom_command(
251+
OUTPUT
252+
${RUST_PART_LIB} ${FFI_CXXBRIDGE_ORIG_SRCS} ${FFI_CXXBRIDGE_ORIG_HEADERS}
253+
COMMAND
254+
${CMAKE_COMMAND} -E make_directory "${FFI_BRIDGE_BIN}" &&
255+
. "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
256+
${CMAKE_COMMAND} -E env CXX=${CMAKE_CXX_COMPILER} CXXFLAGS=${CMAKE_CXX_FLAGS} ${INVOKE_CARGO} hhvm_ffi hhvm_ffi --target-dir "${FFI_BRIDGE_BIN}"
257+
WORKING_DIRECTORY ${FFI_BRIDGE_SRC}
258+
DEPENDS rustc cargo hackc_options "${OPCODE_DATA}"
309259
)
310-
build_cxx_bridge(
311-
parser_ffi
312-
DIR "src/parser/ffi_bridge"
260+
261+
add_custom_target(
262+
hack_rust_ffi_bridge_rust_build
263+
DEPENDS ${RUST_PART_LIB}
313264
)
314-
build_cxx_bridge(
315-
compiler_ffi
316-
DIR "src/hackc/ffi_bridge"
317-
EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/ffi_bridge/external_decl_provider.cpp"
318-
LINK_LIBS hdf
265+
266+
add_custom_command(
267+
OUTPUT ${FFI_CXXBRIDGE_HEADERS} ${FFI_CXXBRIDGE_SRCS}
268+
COMMAND
269+
${CMAKE_COMMAND} -E make_directory "${FFI_BRIDGE_BIN}" &&
270+
${CMAKE_COMMAND} -E copy_if_different ${FFI_CXXBRIDGE_ORIG_HEADERS} ${FFI_BRIDGE_BIN} &&
271+
${CMAKE_COMMAND} -E copy_if_different ${FFI_CXXBRIDGE_ORIG_SRCS} ${FFI_BRIDGE_BIN}
272+
DEPENDS ${FFI_CXXBRIDGE_ORIG_HEADERS} ${FFI_CXXBRIDGE_ORIG_SRCS}
319273
)
320-
build_cxx_bridge(
321-
hdf
322-
DIR "src/utils/hdf"
323-
EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/utils/hdf/hdf-wrap.cpp"
324-
LINK_LIBS folly
274+
275+
add_custom_target(
276+
hack_rust_ffi_bridge_copy_cxxbridge
277+
DEPENDS ${FFI_CXXBRIDGE_HEADERS} ${FFI_CXXBRIDGE_SRCS}
325278
)
326-
build_cxx_bridge(
327-
hhvm_types_ffi
328-
DIR "src/hackc/hhvm_cxx/hhvm_types"
329-
EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_types/as-base-ffi.cpp"
279+
280+
add_library(hack_rust_ffi_bridge_rust_part STATIC IMPORTED)
281+
add_dependencies(hack_rust_ffi_bridge_rust_part hack_rust_ffi_bridge_rust_build hack_rust_ffi_bridge_copy_cxxbridge)
282+
set_target_properties(
283+
hack_rust_ffi_bridge_rust_part
284+
PROPERTIES
285+
IMPORTED_LOCATION ${RUST_PART_LIB}
286+
# Intentionally create a link-time cyclic dependency between the Rust library
287+
# and the dependent C++ library so that CMake will automatically construct the link line,
288+
# causing the linker to scan through involved static libraries multiple times.
289+
IMPORTED_LINK_DEPENDENT_LIBRARIES hack_rust_ffi_bridge
330290
)
331-
build_cxx_bridge(
332-
hhvm_hhbc_defs_ffi
333-
DIR "src/hackc/hhvm_cxx/hhvm_hhbc_defs"
334-
EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_hhbc_defs/as-hhbc-ffi.cpp"
291+
292+
add_library(
293+
hack_rust_ffi_bridge
294+
${FFI_CXXBRIDGE_SRCS}
295+
"${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/ffi_bridge/external_decl_provider.cpp"
296+
"${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_types/as-base-ffi.cpp"
297+
"${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_hhbc_defs/as-hhbc-ffi.cpp"
335298
)
336299

300+
target_link_libraries(hack_rust_ffi_bridge PRIVATE folly hack_rust_ffi_bridge_rust_part)
301+
target_include_directories(hack_rust_ffi_bridge INTERFACE "${RUST_FFI_BUILD_ROOT}")
302+
target_include_directories(hack_rust_ffi_bridge PRIVATE "${FFI_BRIDGE_BIN}/cxxbridge")
303+
337304
if (NOT LZ4_FOUND)
338305
add_dependencies(hack_dune lz4)
339306
add_dependencies(hack_dune_debug lz4)

hphp/hack/src/Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hphp/hack/src/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ members = [
4242
"hh_fanout/cargo/hh_fanout_dep_graph_is_subgraph_rust",
4343
"hh_fanout/cargo/hh_fanout_dep_graph_stats_rust",
4444
"hh_naming_table_builder/cargo/naming_table_builder_ffi",
45+
"hhvm_ffi",
4546
"naming",
4647
"naming/cargo/elaborate_namespaces",
4748
"naming/cargo/naming_attributes",

hphp/hack/src/hackc/ffi_bridge/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "MIT"
99

1010
[lib]
1111
path = "compiler_ffi.rs"
12-
crate-type = ["lib", "staticlib"]
12+
crate-type = ["rlib"]
1313

1414
[dependencies]
1515
anyhow = "1.0.95"

hphp/hack/src/hackc/ffi_bridge/decl_provider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#pragma once
88
#include <string>
9-
#include "hphp/hack/src/hackc/ffi_bridge/compiler_ffi.rs.h"
9+
#include "hphp/hack/src/hhvm_ffi/compiler_ffi.rs.h"
1010

1111
namespace HPHP {
1212
namespace hackc {

hphp/hack/src/hackc/hhvm_cxx/hhvm_hhbc_defs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "MIT"
99

1010
[lib]
1111
path = "hhvm_hhbc_defs_ffi.rs"
12-
crate-type = ["lib", "staticlib"]
12+
crate-type = ["rlib"]
1313

1414
[dependencies]
1515
cxx = "1.0.119"

0 commit comments

Comments
 (0)