Skip to content

Commit

Permalink
Add CORROSION_TOOLS_RUST_TOOLCHAIN option
Browse files Browse the repository at this point in the history
This allows users to choose a different rust toolchain
to compile build-tools use by corrosion
(currently cbindgen and cxxbridge)
  • Loading branch information
jschwe committed Dec 29, 2024
1 parent 4b954fa commit e0bad7c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
3 changes: 3 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
the crate-types of Rust libraries (e.g. force building as a staticlib instead of an rlib).
- Support *-windows-gnullvm targets.
- experimental support in corrosion_install for installing libraries and header files
- Add `CORROSION_TOOLS_RUST_TOOLCHAIN` cache variable which allows users to select a different
rust toolchain for compiling build-tools used by corrosion (currently cbindgen and cxxbridge).
This mainly allows using a newer toolchain for such build-tools then for the actual project.

[doc-cmake-rt-output-dir]: https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html
[#459]: https://github.com/corrosion-rs/corrosion/pull/459
Expand Down
66 changes: 57 additions & 9 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,26 @@ get_property(
TARGET Rust::Cargo PROPERTY IMPORTED_LOCATION
)

set(corrosion_tools_rust_toolchain_docstring "Rust toolchain to use for building helper tools such as cbindgen or cxx-bridge")
if(DEFINED CORROSION_TOOLS_RUST_TOOLCHAIN)
set(cor_default_tools_toolchain "${CORROSION_TOOLS_RUST_TOOLCHAIN}")
else()
set(cor_default_tools_toolchain "${Rust_TOOLCHAIN}")
endif()
set(CORROSION_TOOLS_RUST_TOOLCHAIN "${cor_default_tools_toolchain}" CACHE STRING "${corrosion_tools_rust_toolchain_docstring}" FORCE)
set_property(CACHE CORROSION_TOOLS_RUST_TOOLCHAIN PROPERTY STRINGS "${Rust_RUSTUP_TOOLCHAINS}")

if(NOT "$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}" IN_LIST Rust_RUSTUP_TOOLCHAINS)
if("$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}-${Rust_CARGO_HOST_TARGET}" IN_LIST Rust_RUSTUP_TOOLCHAINS)
set(CORROSION_TOOLS_RUST_TOOLCHAIN "$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}-${Rust_CARGO_HOST_TARGET}"
CACHE PATH "${corrosion_tools_rust_toolchain_docstring}" FORCE)
else()
message(FATAL_ERROR "CORROSION_TOOLS_RUST_TOOLCHAIN must be set to a valid rustup managed toolchain path."
"You can select a valid toolchain "
)
endif()
endif()

function(_corrosion_bin_target_suffix target_name out_var_suffix)
get_target_property(hostbuild "${target_name}" ${_CORR_PROP_HOST_BUILD})
if((hostbuild AND CMAKE_HOST_WIN32)
Expand Down Expand Up @@ -1535,6 +1555,26 @@ set_target_properties(${INSTALL_TARGET}-shared
endif()
endfunction()

# Helper function which places the cargo and rustc exectuble paths into the variable names specified by
# `out_cargo` and `out_rustc` based on the value of the CORROSION_TOOLS_RUST_TOOLCHAIN cache variable.
function(_corrosion_get_tools_rust_toolchain out_cargo out_rustc)
foreach(toolchain tc_rustc tc_cargo IN ZIP_LISTS Rust_RUSTUP_TOOLCHAINS Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH Rust_RUSTUP_TOOLCHAINS_CARGO_PATH)
if("${toolchain}" STREQUAL $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN})
# Minimum CMake version 3.29 for `IS_EXECUTABLE`.
if(NOT (EXISTS "${tc_cargo}" AND EXISTS "${tc_rustc}" ))
message(FATAL_ERROR "Failed to find executable rustc or cargo for toolchain `$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}`")
endif()
set("${out_cargo}" "${tc_cargo}" PARENT_SCOPE)
set( "${out_rustc}" "${tc_rustc}" PARENT_SCOPE)
return()
endif()
endforeach()

message(FATAL_ERROR "Internal error: Failed to find toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN} in "
"list of rustup managed toolchains: ${Rust_RUSTUP_TOOLCHAINS}"
)
endfunction()

#[=======================================================================[.md:
** EXPERIMENTAL **: This function is currently still considered experimental
and is not officially released yet. Feedback and Suggestions are welcome.
Expand Down Expand Up @@ -1661,20 +1701,21 @@ function(corrosion_add_cxxbridge cxx_target)
if(Rust_CARGO_HOST_OS STREQUAL "windows")
set(executable_postfix ".exe")
endif()
_corrosion_get_tools_rust_toolchain(builder_cargo builder_rustc)
add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}/bin/cxxbridge${executable_postfix}"
COMMAND
${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}"
COMMAND
${CMAKE_COMMAND} -E env
"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}"
${_CORROSION_CARGO} install
"CARGO_BUILD_RUSTC=${builder_rustc}"
${builder_cargo} install
cxxbridge-cmd
--version "${cxx_required_version}"
--locked
--root "${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}"
--quiet
# todo: use --target-dir to potentially reuse artifacts
COMMENT "Building cxxbridge (version ${cxx_required_version})"
COMMENT "Building cxxbridge (version ${cxx_required_version}) with Rust toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}"
)
add_custom_target("cxxbridge_v${cxx_required_version}"
DEPENDS "${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}/bin/cxxbridge${executable_postfix}"
Expand Down Expand Up @@ -1818,7 +1859,7 @@ between multiple invocations of this function.
* **CBINDGEN_VERSION**: Version requirement for cbindgen. Exact semantics to be specified. Currently not implemented.
* **FLAGS**: Arbitrary other flags for `cbindgen`. Run `cbindgen --help` to see the possible flags.
[cbindgen]: https://github.com/eqrion/cbindgen
[cbindgen]: https://github.com/mozilla/cbindgen
### Current limitations
Expand All @@ -1832,12 +1873,13 @@ between multiple invocations of this function.
ANCHOR_END: corrosion_cbindgen
#]=======================================================================]
function(corrosion_experimental_cbindgen)
set(OPTIONS "")
set(OPTIONS "USE_DEFAULT_RUST_TOOLCHAIN")
set(ONE_VALUE_KEYWORDS
TARGET
MANIFEST_DIRECTORY
HEADER_NAME
CBINDGEN_VERSION)
CBINDGEN_VERSION
)
set(MULTI_VALUE_KEYWORDS "FLAGS")
cmake_parse_arguments(PARSE_ARGV 0 CCN "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")

Expand Down Expand Up @@ -1895,18 +1937,24 @@ function(corrosion_experimental_cbindgen)
set(executable_postfix ".exe")
endif()
set(cbindgen "${local_cbindgen_install_dir}/bin/cbindgen${executable_postfix}")

if(NOT TARGET "_corrosion_cbindgen")
file(MAKE_DIRECTORY "${local_cbindgen_install_dir}")
unset(cbindgen_cargo)
unset(cbindgen_rustc)
_corrosion_get_tools_rust_toolchain(cbindgen_cargo cbindgen_rustc)

add_custom_command(OUTPUT "${cbindgen}"
COMMAND ${CMAKE_COMMAND}
-E env
"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}"
${_CORROSION_CARGO} install
"CARGO_BUILD_RUSTC=${cbindgen_rustc}"
${cbindgen_cargo} install
cbindgen
--locked
--root "${local_cbindgen_install_dir}"
${_CORROSION_QUIET_OUTPUT_FLAG}
COMMENT "Building cbindgen"
COMMENT "Building cbindgen with Rust toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}"
VERBATIM
)
add_custom_target("_corrosion_cbindgen"
DEPENDS "${cbindgen}"
Expand Down
7 changes: 7 additions & 0 deletions doc/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ them **before** `find_package(Corrosion REQUIRED)`.
- `Rust_CARGO_TARGET:STRING` - The default target triple to build for. Alter for cross-compiling.
Default: On Visual Studio Generator, the matching triple for `CMAKE_VS_PLATFORM_NAME`. Otherwise,
the default target triple reported by `${Rust_COMPILER} --version --verbose`.
- `CORROSION_TOOLS_RUST_TOOLCHAIN:STRING`: Specify a different toolchain (e.g. `stable`) to use for compiling helper
tools such as `cbindgen` or `cxxbridge`. This can be useful when you want to compile your project with an
older rust version (e.g. for checking the MSRV), but you can build build-tools with a newer installed rust version.

#### Enable Convenience Options

Expand Down Expand Up @@ -208,6 +211,10 @@ versions individually.
- `Rust_LLVM_VERSION<_MAJOR|_MINOR|_PATCH>` - The LLVM version used by rustc.
- `Rust_IS_NIGHTLY` - 1 if a nightly toolchain is used, otherwise 0. Useful for selecting an unstable feature for a
crate, that is only available on nightly toolchains.
- `Rust_RUSTUP_TOOLCHAINS`, `Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH`, `Rust_RUSTUP_TOOLCHAINS_CARGO_PATH`
and `Rust_RUSTUP_TOOLCHAINS_VERSION`: These variables are lists, which should be iterated over with
CMakes `foreach(var IN ZIP_LISTS list1 list2 ...)` iterator. They provide a list of installed rustup managed toolchains and
the associated rustc and cargo paths as well as the corresponding rustc version.
- Cache variables containing information based on the target triple for the selected target
as well as the default host target:
- `Rust_CARGO_TARGET_ARCH`, `Rust_CARGO_HOST_ARCH`: e.g. `x86_64` or `aarch64`
Expand Down
3 changes: 2 additions & 1 deletion test/cbindgen/rust2cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.15)
project(test_project VERSION 0.1.0)
include(../../test_header.cmake)

set(CORROSION_TOOLS_RUST_TOOLCHAIN "stable")
include(../../test_header.cmake)
corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)
corrosion_experimental_cbindgen(TARGET rust_lib HEADER_NAME "rust-lib.h")

Expand Down

0 comments on commit e0bad7c

Please sign in to comment.