Meta: Replace corrosion with custom function that tracks dependencies
It is a known issue that corrosion_import_crate() does not track deps and will issue a cargo command on every ninja invocation. Now that we use Rust in LibUnicode, we initially see 3k+ targets queued as dirty. This quickly drops to zero, but ideally, when no Rust-related files have changed, ninja would simply report "no work to do". This introduces an import_rust_crate() function. This is much like corrosion, but it tracks dependencies. So when nothing changes, then nothing is queued for rebuilds. It uses rustc's depfile to track Rust dependencies automatically.
This commit is contained in:
parent
b894278295
commit
ba8d63556f
4 changed files with 115 additions and 19 deletions
|
|
@ -307,18 +307,16 @@ endif()
|
|||
target_link_libraries(LibJS PUBLIC JSClangPlugin)
|
||||
|
||||
if (ENABLE_RUST)
|
||||
corrosion_import_crate(MANIFEST_PATH Rust/Cargo.toml CRATES libjs_rust)
|
||||
import_rust_crate(MANIFEST_PATH Rust/Cargo.toml CRATE_NAME libjs_rust)
|
||||
target_link_libraries(LibJS PRIVATE libjs_rust)
|
||||
target_compile_definitions(LibJS PRIVATE ENABLE_RUST)
|
||||
install(TARGETS libjs_rust EXPORT LagomTargets
|
||||
ARCHIVE COMPONENT Lagom_Development
|
||||
)
|
||||
|
||||
# The Rust library and LibJS have a circular dependency (C++ calls Rust
|
||||
# entry points, Rust calls C++ callbacks). For static builds, merge the
|
||||
# Rust archive into the LibJS archive so all symbols are in one place.
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
add_custom_command(TARGET LibJS POST_BUILD
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:libjs_rust-static>
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:libjs_rust>
|
||||
COMMAND ${CMAKE_AR} -qS $<TARGET_FILE:LibJS> *.o
|
||||
COMMAND ${CMAKE_RANLIB} $<TARGET_FILE:LibJS>
|
||||
COMMAND ${CMAKE_COMMAND} -E remove -f *.o
|
||||
|
|
|
|||
|
|
@ -28,11 +28,8 @@ ladybird_lib(LibUnicode unicode)
|
|||
find_package(ICU 78.2 EXACT REQUIRED COMPONENTS data i18n uc)
|
||||
target_link_libraries(LibUnicode PRIVATE ICU::i18n ICU::uc ICU::data)
|
||||
|
||||
corrosion_import_crate(MANIFEST_PATH Rust/Cargo.toml CRATES libunicode_rust)
|
||||
import_rust_crate(MANIFEST_PATH Rust/Cargo.toml CRATE_NAME libunicode_rust)
|
||||
target_link_libraries(LibUnicode PRIVATE libunicode_rust)
|
||||
install(TARGETS libunicode_rust EXPORT LagomTargets
|
||||
ARCHIVE COMPONENT Lagom_Development
|
||||
)
|
||||
|
||||
# FIXME: Add support for building LibGfx in sanitize
|
||||
# lld-link: error: /failifmismatch: mismatch detected for 'annotate_string':
|
||||
|
|
|
|||
110
Meta/CMake/rust_crate.cmake
Normal file
110
Meta/CMake/rust_crate.cmake
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# import_rust_crate(MANIFEST_PATH path/to/Cargo.toml CRATE_NAME name)
|
||||
#
|
||||
# Builds a Rust static library crate using cargo and creates an IMPORTED target.
|
||||
# MANIFEST_PATH is relative to CMAKE_CURRENT_SOURCE_DIR.
|
||||
#
|
||||
# When corrosion supports dependency tracking, we can use corrosion_import_crate() instead of this function. See:
|
||||
# https://github.com/corrosion-rs/corrosion/issues/206
|
||||
# https://github.com/corrosion-rs/corrosion/issues/624
|
||||
function(import_rust_crate)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "MANIFEST_PATH;CRATE_NAME" "")
|
||||
|
||||
set(ARG_MANIFEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${ARG_MANIFEST_PATH}")
|
||||
|
||||
# Find the workspace Cargo.lock to track as a dependency.
|
||||
get_filename_component(workspace_dir "${ARG_MANIFEST_PATH}" DIRECTORY)
|
||||
while(NOT EXISTS "${workspace_dir}/Cargo.lock")
|
||||
get_filename_component(workspace_dir "${workspace_dir}" DIRECTORY)
|
||||
endwhile()
|
||||
|
||||
# Detect the Rust toolchain.
|
||||
find_program(RUST_CARGO cargo REQUIRED)
|
||||
find_program(RUST_RUSTC rustc REQUIRED)
|
||||
if (NOT DEFINED CACHE{RUST_TARGET_TRIPLE})
|
||||
execute_process(COMMAND "${RUST_RUSTC}" -vV OUTPUT_VARIABLE rustc_verbose)
|
||||
string(REGEX MATCH "host: ([^\n]+)" _ "${rustc_verbose}")
|
||||
string(STRIP "${CMAKE_MATCH_1}" host_triple)
|
||||
set(RUST_TARGET_TRIPLE "${host_triple}" CACHE INTERNAL "Rust target triple")
|
||||
endif()
|
||||
|
||||
# Build the uppercased and underscored variants of the target triple.
|
||||
string(REPLACE "-" "_" target_underscore "${RUST_TARGET_TRIPLE}")
|
||||
string(TOUPPER "${target_underscore}" target_upper)
|
||||
|
||||
# Determine the cargo profile and output directory name.
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type_upper)
|
||||
if (build_type_upper STREQUAL "DEBUG")
|
||||
set(cargo_profile_flag "")
|
||||
set(cargo_profile_dir "debug")
|
||||
else()
|
||||
set(cargo_profile_flag "--release")
|
||||
set(cargo_profile_dir "release")
|
||||
endif()
|
||||
|
||||
set(cargo_target_dir "${CMAKE_BINARY_DIR}/cargo/build")
|
||||
set(cargo_output_dir "${cargo_target_dir}/${RUST_TARGET_TRIPLE}/${cargo_profile_dir}")
|
||||
|
||||
if (WIN32)
|
||||
set(output_lib "${cargo_output_dir}/${ARG_CRATE_NAME}.lib")
|
||||
set(depfile "${cargo_output_dir}/${ARG_CRATE_NAME}.d")
|
||||
else()
|
||||
set(output_lib "${cargo_output_dir}/lib${ARG_CRATE_NAME}.a")
|
||||
set(depfile "${cargo_output_dir}/lib${ARG_CRATE_NAME}.d")
|
||||
endif()
|
||||
|
||||
# Build environment variables for cargo.
|
||||
set(cargo_env
|
||||
"CC_${target_underscore}=${CMAKE_C_COMPILER}"
|
||||
"CXX_${target_underscore}=${CMAKE_CXX_COMPILER}"
|
||||
"CARGO_BUILD_RUSTC=${RUST_RUSTC}"
|
||||
)
|
||||
|
||||
# On Windows, rustc invokes the linker directly with MSVC-style flags, so we must not override it with a
|
||||
# compiler driver like clang-cl.
|
||||
if (NOT WIN32)
|
||||
list(APPEND cargo_env
|
||||
"CARGO_TARGET_${target_upper}_LINKER=${CMAKE_C_COMPILER}"
|
||||
"AR_${target_underscore}=${CMAKE_AR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (APPLE AND CMAKE_OSX_SYSROOT)
|
||||
list(APPEND cargo_env "SDKROOT=${CMAKE_OSX_SYSROOT}")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${output_lib}"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env ${cargo_env}
|
||||
"${RUST_CARGO}"
|
||||
rustc
|
||||
--lib
|
||||
"--target=${RUST_TARGET_TRIPLE}"
|
||||
--package ${ARG_CRATE_NAME}
|
||||
--manifest-path "${ARG_MANIFEST_PATH}"
|
||||
--target-dir "${cargo_target_dir}"
|
||||
${cargo_profile_flag}
|
||||
--
|
||||
-Cdefault-linker-libraries=yes
|
||||
--emit=dep-info
|
||||
DEPENDS "${ARG_MANIFEST_PATH}"
|
||||
"${workspace_dir}/Cargo.lock" "${workspace_dir}/Cargo.toml"
|
||||
DEPFILE "${depfile}"
|
||||
COMMENT "Building Rust crate ${ARG_CRATE_NAME}"
|
||||
USES_TERMINAL
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
|
||||
add_custom_target(${ARG_CRATE_NAME}-build DEPENDS "${output_lib}")
|
||||
|
||||
add_library(${ARG_CRATE_NAME} STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(${ARG_CRATE_NAME} PROPERTIES IMPORTED_LOCATION "${output_lib}")
|
||||
add_dependencies(${ARG_CRATE_NAME} ${ARG_CRATE_NAME}-build)
|
||||
|
||||
# Rust staticlibs bundle the standard library, which on Windows depends on system libraries.
|
||||
if (WIN32)
|
||||
set_target_properties(${ARG_CRATE_NAME} PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "kernel32;ntdll;Ws2_32;userenv"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
@ -171,16 +171,7 @@ if (WIN32)
|
|||
find_package(mman REQUIRED)
|
||||
endif()
|
||||
|
||||
if (ENABLE_RUST)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
Corrosion
|
||||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||
GIT_TAG v0.5.1
|
||||
)
|
||||
FetchContent_MakeAvailable(Corrosion)
|
||||
endif()
|
||||
|
||||
include(rust_crate)
|
||||
include(targets)
|
||||
|
||||
# Plugins need to be installed in order to be used by non-lagom builds
|
||||
|
|
|
|||
Loading…
Reference in a new issue