From 5c1b0a6b7eedf0eb295e93dd1e355f524f65ff76 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 2 Nov 2025 14:04:34 +0530 Subject: [PATCH] Rust: Add experimental support with Ninja The TU for Rust is a crate, not per-source. `rustc` expects entry file to TU as input, and cannot work with object files. So we need to have one-step build/link in most cases, similar to what old Swift was doing. Issue: #25492 Signed-off-by: Ayush Singh --- .gitlab/ci/configure_fedora43_ninja.cmake | 1 + .../ci/configure_fedora43_ninja_multi.cmake | 1 + Help/dev/experimental.rst | 12 +++++ Modules/CMakeDetermineRustCompiler.cmake | 49 +++++++++++++++++++ Modules/CMakeRustCompiler.cmake.in | 5 ++ Modules/CMakeRustInformation.cmake | 41 ++++++++++++++++ Modules/CMakeTestRustCompiler.cmake | 9 ++++ Source/cmExperimental.cxx | 8 +++ Source/cmExperimental.h | 1 + Source/cmGlobalGenerator.cxx | 10 ++++ Source/cmNinjaNormalTargetGenerator.cxx | 39 +++++++++++++++ Source/cmRulePlaceholderExpander.cxx | 10 ++++ Source/cmRulePlaceholderExpander.h | 2 + Tests/CMakeLists.txt | 4 ++ Tests/RunCMake/CMakeLists.txt | 3 ++ Tests/RunCMake/Rust/CMakeLists.txt | 3 ++ Tests/RunCMake/Rust/Enable-stderr.txt | 6 +++ Tests/RunCMake/Rust/Enable-stdout.txt | 1 + Tests/RunCMake/Rust/Enable.cmake | 3 ++ .../Rust/EnableExperimental-result.txt | 1 + .../Rust/EnableExperimental-stderr.txt | 4 ++ Tests/RunCMake/Rust/EnableExperimental.cmake | 1 + Tests/RunCMake/Rust/RunCMakeTest.cmake | 4 ++ Tests/RustMix/CMakeLists.txt | 14 ++++++ Tests/RustMix/liba.rs | 4 ++ Tests/RustMix/libb.rs | 4 ++ Tests/RustMix/libc.rs | 4 ++ Tests/RustMix/main.c | 15 ++++++ Tests/RustOnly/CMakeLists.txt | 14 ++++++ Tests/RustOnly/liba.rs | 4 ++ Tests/RustOnly/libb.rs | 4 ++ Tests/RustOnly/libc.rs | 4 ++ Tests/RustOnly/main.rs | 15 ++++++ Tests/RustOnly/moda.rs | 3 ++ 34 files changed, 303 insertions(+) create mode 100644 Modules/CMakeDetermineRustCompiler.cmake create mode 100644 Modules/CMakeRustCompiler.cmake.in create mode 100644 Modules/CMakeRustInformation.cmake create mode 100644 Modules/CMakeTestRustCompiler.cmake create mode 100644 Tests/RunCMake/Rust/CMakeLists.txt create mode 100644 Tests/RunCMake/Rust/Enable-stderr.txt create mode 100644 Tests/RunCMake/Rust/Enable-stdout.txt create mode 100644 Tests/RunCMake/Rust/Enable.cmake create mode 100644 Tests/RunCMake/Rust/EnableExperimental-result.txt create mode 100644 Tests/RunCMake/Rust/EnableExperimental-stderr.txt create mode 100644 Tests/RunCMake/Rust/EnableExperimental.cmake create mode 100644 Tests/RunCMake/Rust/RunCMakeTest.cmake create mode 100644 Tests/RustMix/CMakeLists.txt create mode 100644 Tests/RustMix/liba.rs create mode 100644 Tests/RustMix/libb.rs create mode 100644 Tests/RustMix/libc.rs create mode 100644 Tests/RustMix/main.c create mode 100644 Tests/RustOnly/CMakeLists.txt create mode 100644 Tests/RustOnly/liba.rs create mode 100644 Tests/RustOnly/libb.rs create mode 100644 Tests/RustOnly/libc.rs create mode 100644 Tests/RustOnly/main.rs create mode 100644 Tests/RustOnly/moda.rs diff --git a/.gitlab/ci/configure_fedora43_ninja.cmake b/.gitlab/ci/configure_fedora43_ninja.cmake index 43cfbbaf1b..5c75c1e120 100644 --- a/.gitlab/ci/configure_fedora43_ninja.cmake +++ b/.gitlab/ci/configure_fedora43_ninja.cmake @@ -5,6 +5,7 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "") set(CMake_TEST_ISPC "ON" CACHE STRING "") endif() set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "") +set(CMake_TEST_Rust "ON" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "") diff --git a/.gitlab/ci/configure_fedora43_ninja_multi.cmake b/.gitlab/ci/configure_fedora43_ninja_multi.cmake index b4d9a70ddf..1708a7b8b5 100644 --- a/.gitlab/ci/configure_fedora43_ninja_multi.cmake +++ b/.gitlab/ci/configure_fedora43_ninja_multi.cmake @@ -2,5 +2,6 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "") set(CMake_TEST_ISPC "ON" CACHE STRING "") endif() set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "") +set(CMake_TEST_Rust "ON" CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 933e927d29..3dc7007c34 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -158,3 +158,15 @@ When activated, this experimental feature provides the following: * The experimental ``export(SBOM)`` and ``install(SBOM)`` commands are available to generate a Software Bill of Materials or "SBOM" for the current project. See :command:`install(SBOM)` for a complete overview of the command. + +Rust Support +============ + +In order to activate support for Rust, set + +* variable ``CMAKE_EXPERIMENTAL_RUST`` to +* value ``3cc9b32c-47d3-4056-8953-d74e69fc0d6c``. + +This UUID may change in future versions of CMake. Be sure to use the value +documented here by the source tree of the version of CMake with which you are +experimenting. diff --git a/Modules/CMakeDetermineRustCompiler.cmake b/Modules/CMakeDetermineRustCompiler.cmake new file mode 100644 index 0000000000..43441b0402 --- /dev/null +++ b/Modules/CMakeDetermineRustCompiler.cmake @@ -0,0 +1,49 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENSE.rst or https://cmake.org/licensing for details. + +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) + +if(NOT "${CMAKE_GENERATOR}" MATCHES "^Ninja") + message(FATAL_ERROR "Rust language not supported by \"${CMAKE_GENERATOR}\" generator") +endif() + +set(CMAKE_Rust_COMPILER_INIT "rustc") +set(CMAKE_Rust_COMPILER_HINTS "$ENV{HOME}/.cargo/bin") + +_cmake_find_compiler(Rust) + +get_filename_component(RUSTC_REAL "${CMAKE_Rust_COMPILER}" REALPATH) +get_filename_component(RUSTC_FILENAME "${RUSTC_REAL}" NAME) + +# When rustup is used for installing rust, rustc will just be a symlink to rustup. In such cases, +# we need to query rustup for underlying rustc path. +if(RUSTC_FILENAME STREQUAL "rustup") + get_filename_component(RUSTC_DIR "${CMAKE_Rust_COMPILER}" DIRECTORY) + set(RUSTUP_PATH "${RUSTC_DIR}/rustup") + + # Fix RUSTUP_HOME in ctest. + if(RUSTC_FILENAME STREQUAL "rustup" AND NOT "$ENV{CTEST_REAL_HOME}" STREQUAL "" AND "$ENV{RUSTUP_HOME}" STREQUAL "") + set(ENV{RUSTUP_HOME} "$ENV{CTEST_REAL_HOME}/.rustup") + endif() + + execute_process( + COMMAND ${RUSTUP_PATH} which rustc + OUTPUT_VARIABLE REAL_RUSTC + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if("${REAL_RUSTC}" STREQUAL "") + message(FATAL_ERROR "Failed to find path to real rustc") + endif() + + set_property(CACHE CMAKE_Rust_COMPILER PROPERTY VALUE "${REAL_RUSTC}") +endif() + +if(CMAKE_Rust_COMPILER) + set(CMAKE_Rust_COMPILER_WORKS TRUE) +endif() + +configure_file( + "${CMAKE_ROOT}/Modules/CMakeRustCompiler.cmake.in" + "${CMAKE_PLATFORM_INFO_DIR}/CMakeRustCompiler.cmake" + @ONLY) diff --git a/Modules/CMakeRustCompiler.cmake.in b/Modules/CMakeRustCompiler.cmake.in new file mode 100644 index 0000000000..deb19ba825 --- /dev/null +++ b/Modules/CMakeRustCompiler.cmake.in @@ -0,0 +1,5 @@ +set(CMAKE_Rust_COMPILER "@CMAKE_Rust_COMPILER@") +set(CMAKE_Rust_COMPILER_ENV_VAR "RUSTC") +set(CMAKE_Rust_SOURCE_FILE_EXTENSIONS rs) +set(CMAKE_Rust_COMPILER_LOADED 1) +set(CMAKE_Rust_COMPILER_WORKS @CMAKE_Rust_COMPILER_WORKS@) diff --git a/Modules/CMakeRustInformation.cmake b/Modules/CMakeRustInformation.cmake new file mode 100644 index 0000000000..2224d012e9 --- /dev/null +++ b/Modules/CMakeRustInformation.cmake @@ -0,0 +1,41 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENSE.rst or https://cmake.org/licensing for details. + +include(CMakeLanguageInformation) + +if(UNIX) + set(CMAKE_Rust_OUTPUT_EXTENSION .o) +else() + set(CMAKE_Rust_OUTPUT_EXTENSION .obj) +endif() + +set(CMAKE_Rust_LIBRARY_PATH_FLAG "-L ") +set(CMAKE_Rust_LINK_LIBRARY_FILE_FLAG "-C link-arg=") +set(CMAKE_EXECUTABLE_RUNTIME_Rust_FLAG "-C link-arg=-Wl,-rpath,") +set(CMAKE_EXECUTABLE_RUNTIME_Rust_FLAG_SEP ",") + +set(CMAKE_Rust_FLAGS_DEBUG_INIT "-C opt-level=0 -g") +set(CMAKE_Rust_FLAGS_RELEASE_INIT "-O") +set(CMAKE_Rust_FLAGS_RELWITHDEBINFO_INIT "-O -g") +set(CMAKE_Rust_FLAGS_MINSIZEREL_INIT "-C opt-level=z") + +cmake_initialize_per_config_variable(CMAKE_Rust_FLAGS "Flags used by the Rust compiler") + +if(NOT CMAKE_Rust_CREATE_STATIC_LIBRARY) + set(CMAKE_Rust_CREATE_STATIC_LIBRARY "${CMAKE_Rust_COMPILER} --crate-type=staticlib -o -C link-args=\"\"") +endif() + +if(NOT CMAKE_Rust_CREATE_SHARED_LIBRARY) + set(CMAKE_Rust_CREATE_SHARED_LIBRARY "${CMAKE_Rust_COMPILER} --crate-type=cdylib -o -C link-args=\"\"") +endif() + +# Deadcode warnings are not useful when generating object files. +if(NOT CMAKE_Rust_COMPILE_OBJECT) + set(CMAKE_Rust_COMPILE_OBJECT "${CMAKE_Rust_COMPILER} -A dead_code --crate-type=lib --emit=obj=,dep-info= ") +endif() + +if(NOT CMAKE_Rust_LINK_EXECUTABLE) + set(CMAKE_Rust_LINK_EXECUTABLE "${CMAKE_Rust_COMPILER} --crate-type=bin -o -C link-args=\"\"") +endif() + +set(CMAKE_Rust_INFORMATION_LOADED 1) diff --git a/Modules/CMakeTestRustCompiler.cmake b/Modules/CMakeTestRustCompiler.cmake new file mode 100644 index 0000000000..8e3e819f55 --- /dev/null +++ b/Modules/CMakeTestRustCompiler.cmake @@ -0,0 +1,9 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENSE.rst or https://cmake.org/licensing for details. + +configure_file( + "${CMAKE_ROOT}/Modules/CMakeRustCompiler.cmake.in" + "${CMAKE_PLATFORM_INFO_DIR}/CMakeRustCompiler.cmake" + @ONLY) + +include(${CMAKE_PLATFORM_INFO_DIR}/CMakeRustCompiler.cmake) diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx index 2ad4f151d5..c467a7c34e 100644 --- a/Source/cmExperimental.cxx +++ b/Source/cmExperimental.cxx @@ -80,6 +80,14 @@ cmExperimental::FeatureData const LookupTable[] = { "experimentation and feedback to CMake developers.", {}, cmExperimental::TryCompileCondition::Never }, + // Rust support + { "Rust", + "3cc9b32c-47d3-4056-8953-d74e69fc0d6c", + "CMAKE_EXPERIMENTAL_RUST", + "CMake's support for the Rust programming language is experimental. " + "It is meant only for experimentation and feedback to CMake developers.", + {}, + cmExperimental::TryCompileCondition::Never }, }; static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) == static_cast(cmExperimental::Feature::Sentinel), diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h index cac8e438c1..c10e0209e6 100644 --- a/Source/cmExperimental.h +++ b/Source/cmExperimental.h @@ -24,6 +24,7 @@ public: MappedPackageInfo, ExportBuildDatabase, GenerateSbom, + Rust, Sentinel, }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 1decc42f77..2172a96d81 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -733,6 +733,16 @@ void cmGlobalGenerator::EnableLanguage( for (std::string const& lang : languages) { needSetLanguageEnabledMaps[lang] = false; + + if (lang == "Rust" && + !cmExperimental::HasSupportEnabled(*this->Makefiles[0].get(), + cmExperimental::Feature::Rust)) { + mf->IssueMessage(MessageType::FATAL_ERROR, + "Experimental Rust support is not enabled."); + cmSystemTools::SetFatalErrorOccurred(); + return; + } + if (lang == "NONE") { this->SetLanguageEnabled("NONE", mf); continue; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 3b5681ac80..e5cb1c0926 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -478,6 +478,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule( vars.Includes = "$INCLUDES"; } + if (this->TargetLinkLanguage(config) == "Rust") { + vars.RustSources = "$RUST_SOURCES"; + vars.RustObjectDeps = "$RUST_OBJECT_DEPS"; + } + std::string responseFlag; std::string cmakeVarLang = @@ -1276,6 +1281,40 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( gt->IsExecutableWithExports()) { linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]); } + } else if (this->TargetLinkLanguage(config) == "Rust") { + // Use one-step build/link for Rust. + // Compute specific libraries to link with. + std::vector sources; + gt->GetObjectSources(sources, config); + cmLocalGenerator const* lg = this->GetLocalGenerator(); + std::string entry_obj; + + for (auto const& source : sources) { + if (source->GetLanguage() == "Rust") { + if (vars.count("RUST_SOURCES") == 0) { + std::string const sourcePath = + this->GetCompiledSourceNinjaPath(source); + vars["RUST_SOURCES"] = + lg->ConvertToOutputFormat(sourcePath, cmOutputConverter::SHELL); + entry_obj = this->GetObjectFilePath(source, config); + } else { + assert(false && "Rust crate can only have 1 entry"); + } + } + } + + linkBuild.ExplicitDeps = this->GetObjects(config); + std::stringstream obj_deps; + + // Do not try linking to object file created from the crate entry. + for (auto const& obj : linkBuild.ExplicitDeps) { + if (obj != entry_obj) { + obj_deps << " " + << lg->ConvertToOutputFormat(obj, cmOutputConverter::SHELL); + } + } + + vars["RUST_OBJECT_DEPS"] = obj_deps.str(); } else { linkBuild.ExplicitDeps = this->GetObjects(config); } diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 9261007d50..83eef7770b 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -143,6 +143,16 @@ std::string cmRulePlaceholderExpander::ExpandVariable( return this->ReplaceValues->SwiftSources; } } + if (this->ReplaceValues->RustSources) { + if (variable == "RUST_SOURCES") { + return this->ReplaceValues->RustSources; + } + } + if (this->ReplaceValues->RustObjectDeps) { + if (variable == "RUST_OBJECT_DEPS") { + return this->ReplaceValues->RustObjectDeps; + } + } if (this->ReplaceValues->TargetPDB) { if (variable == "TARGET_PDB") { return this->ReplaceValues->TargetPDB; diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index bb6250f321..4b44c642e5 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -69,6 +69,8 @@ public: char const* SwiftModuleName = nullptr; char const* SwiftOutputFileMapOption = nullptr; char const* SwiftSources = nullptr; + char const* RustSources = nullptr; + char const* RustObjectDeps = nullptr; char const* ISPCHeader = nullptr; char const* CudaCompileMode = nullptr; char const* Fatbinary = nullptr; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 9cd8243537..5c2a6e6750 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -461,6 +461,10 @@ if(BUILD_TESTING) ADD_TEST_MACRO(SwiftMixLib Swifty) endif() endif() + if(CMake_TEST_Rust) + ADD_TEST_MACRO(RustOnly RustOnly) + ADD_TEST_MACRO(RustMix RustMix) + endif() if(CMAKE_Fortran_COMPILER) ADD_TEST_MACRO(FortranOnly FortranOnly) set_property(TEST FortranOnly APPEND PROPERTY LABELS "Fortran") diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 48b873484a..2fc19c7721 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -600,6 +600,9 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG) -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT} ) endif() +if(CMake_TEST_Rust) + add_RunCMake_test(Rust) +endif() add_RunCMake_test(ScriptMode) add_RunCMake_test(StandardLinkDirectories) add_RunCMake_test(Swift -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} diff --git a/Tests/RunCMake/Rust/CMakeLists.txt b/Tests/RunCMake/Rust/CMakeLists.txt new file mode 100644 index 0000000000..abd58e2f9a --- /dev/null +++ b/Tests/RunCMake/Rust/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 4.2) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/Rust/Enable-stderr.txt b/Tests/RunCMake/Rust/Enable-stderr.txt new file mode 100644 index 0000000000..5f0fc64c80 --- /dev/null +++ b/Tests/RunCMake/Rust/Enable-stderr.txt @@ -0,0 +1,6 @@ +^CMake Warning \(dev\) at Enable\.cmake:[0-9]+ \(enable_language\): + CMake's support for the Rust programming language is experimental\. It is + meant only for experimentation and feedback to CMake developers\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/Rust/Enable-stdout.txt b/Tests/RunCMake/Rust/Enable-stdout.txt new file mode 100644 index 0000000000..821b6f0cb1 --- /dev/null +++ b/Tests/RunCMake/Rust/Enable-stdout.txt @@ -0,0 +1 @@ +-- CMAKE_Rust_COMPILER='[^']*/rustc' diff --git a/Tests/RunCMake/Rust/Enable.cmake b/Tests/RunCMake/Rust/Enable.cmake new file mode 100644 index 0000000000..89d9c54871 --- /dev/null +++ b/Tests/RunCMake/Rust/Enable.cmake @@ -0,0 +1,3 @@ +set(CMAKE_EXPERIMENTAL_RUST "3cc9b32c-47d3-4056-8953-d74e69fc0d6c") +enable_language(Rust) +message(STATUS "CMAKE_Rust_COMPILER='${CMAKE_Rust_COMPILER}'") diff --git a/Tests/RunCMake/Rust/EnableExperimental-result.txt b/Tests/RunCMake/Rust/EnableExperimental-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/Rust/EnableExperimental-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Rust/EnableExperimental-stderr.txt b/Tests/RunCMake/Rust/EnableExperimental-stderr.txt new file mode 100644 index 0000000000..79307c1250 --- /dev/null +++ b/Tests/RunCMake/Rust/EnableExperimental-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at EnableExperimental\.cmake:[0-9]+ \(enable_language\): + Experimental Rust support is not enabled\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/Rust/EnableExperimental.cmake b/Tests/RunCMake/Rust/EnableExperimental.cmake new file mode 100644 index 0000000000..e85697f710 --- /dev/null +++ b/Tests/RunCMake/Rust/EnableExperimental.cmake @@ -0,0 +1 @@ +enable_language(Rust) diff --git a/Tests/RunCMake/Rust/RunCMakeTest.cmake b/Tests/RunCMake/Rust/RunCMakeTest.cmake new file mode 100644 index 0000000000..5178b4f538 --- /dev/null +++ b/Tests/RunCMake/Rust/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(Enable) +run_cmake(EnableExperimental) diff --git a/Tests/RustMix/CMakeLists.txt b/Tests/RustMix/CMakeLists.txt new file mode 100644 index 0000000000..8551afdd96 --- /dev/null +++ b/Tests/RustMix/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 4.2) + +set(CMAKE_EXPERIMENTAL_RUST "3cc9b32c-47d3-4056-8953-d74e69fc0d6c") + +project(RustMix LANGUAGES C Rust) + +add_library(liba STATIC liba.rs) +add_library(libb SHARED libb.rs) +add_library(libc OBJECT libc.rs) + +add_executable(RustMix main.c) +target_link_libraries(RustMix liba) +target_link_libraries(RustMix libb) +target_link_libraries(RustMix libc) diff --git a/Tests/RustMix/liba.rs b/Tests/RustMix/liba.rs new file mode 100644 index 0000000000..2958db3758 --- /dev/null +++ b/Tests/RustMix/liba.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn liba_greet() { + println!("Hello from Rust liba"); +} diff --git a/Tests/RustMix/libb.rs b/Tests/RustMix/libb.rs new file mode 100644 index 0000000000..e94f46fb88 --- /dev/null +++ b/Tests/RustMix/libb.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn libb_greet() { + println!("Hello from Rust libb"); +} diff --git a/Tests/RustMix/libc.rs b/Tests/RustMix/libc.rs new file mode 100644 index 0000000000..52bd67d5a2 --- /dev/null +++ b/Tests/RustMix/libc.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn libc_greet() { + println!("Hello from Rust libc"); +} diff --git a/Tests/RustMix/main.c b/Tests/RustMix/main.c new file mode 100644 index 0000000000..39ceba10e0 --- /dev/null +++ b/Tests/RustMix/main.c @@ -0,0 +1,15 @@ +#include + +extern void liba_greet(); +extern void libb_greet(); +extern void libc_greet(); + +int main() +{ + printf("Hello from C main\n"); + liba_greet(); + libb_greet(); + libc_greet(); + + return 0; +} diff --git a/Tests/RustOnly/CMakeLists.txt b/Tests/RustOnly/CMakeLists.txt new file mode 100644 index 0000000000..8f889fbfb7 --- /dev/null +++ b/Tests/RustOnly/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 4.2) + +set(CMAKE_EXPERIMENTAL_RUST "3cc9b32c-47d3-4056-8953-d74e69fc0d6c") + +project(RustOnly LANGUAGES Rust) + +add_library(liba STATIC liba.rs) +add_library(libb SHARED libb.rs) +add_library(libc OBJECT libc.rs) + +add_executable(RustOnly main.rs) +target_link_libraries(RustOnly liba) +target_link_libraries(RustOnly libb) +target_link_libraries(RustOnly libc) diff --git a/Tests/RustOnly/liba.rs b/Tests/RustOnly/liba.rs new file mode 100644 index 0000000000..1cfd077c14 --- /dev/null +++ b/Tests/RustOnly/liba.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn liba_greet() { + println!("Hello from liba"); +} diff --git a/Tests/RustOnly/libb.rs b/Tests/RustOnly/libb.rs new file mode 100644 index 0000000000..2fb797c2dd --- /dev/null +++ b/Tests/RustOnly/libb.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn libb_greet() { + println!("Hello from libb"); +} diff --git a/Tests/RustOnly/libc.rs b/Tests/RustOnly/libc.rs new file mode 100644 index 0000000000..dd46cc51a3 --- /dev/null +++ b/Tests/RustOnly/libc.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn libc_greet() { + println!("Hello from libc"); +} diff --git a/Tests/RustOnly/main.rs b/Tests/RustOnly/main.rs new file mode 100644 index 0000000000..067fb247e4 --- /dev/null +++ b/Tests/RustOnly/main.rs @@ -0,0 +1,15 @@ +mod moda; + +extern "C" { + fn liba_greet(); + fn libb_greet(); + fn libc_greet(); +} + +fn main() { + println!("Hello from main.rs"); + moda::moda_greet(); + unsafe { liba_greet() }; + unsafe { libb_greet() }; + unsafe { libc_greet() }; +} diff --git a/Tests/RustOnly/moda.rs b/Tests/RustOnly/moda.rs new file mode 100644 index 0000000000..a70276634b --- /dev/null +++ b/Tests/RustOnly/moda.rs @@ -0,0 +1,3 @@ +pub fn moda_greet() { + println!("Hello from moda"); +}