Clone the repo using this command:
git clone [email protected]:FractalFir/rustc_codegen_clr.git
rustup install nightly
cargo check
If the project does not compile due to error messages, try updating your rust version.
rustup update
If this does not solve the problem, open an issue. The project is only compatible with a narrow set of rustc
versions, and tries to always use the newest nigthly build.
Note: This is only relevant if you want to use this project in its .NET mode This project requires the .NET runtime to be used. You can find instalation instructions here.
After installing .NET, run dotnet --info
to confoirm it is installed propely.
Note: This is only relevant if you want to use this project in its .NET mode
ilasm
comes installed with Visual Studio. So, you propably already have it. If not, install visual stuido.
This tool supports both the "Core" and "Mono" flavours of ILASM. While you can install / build ilasm
separeately, installing the mono runtime is the easiest option.
After you installed dotnet
and ilasm
(, run ./bin/rustflags.rs
to check if you installed ilasm
and dotnet
correctly.
If you want to use the project to generate C code, set C_MODE
to 1
.
export C_MODE=1
This script uses the experimental cargo-script
feaure to will check your enviroment, build the project, and print the flags you need to use it.
As one last step, you can run cargo test ::stable
to check if the codegen runs as expected. This can take a minute or two, but it should ensure the project is working as expected.
The project is relatively simple to use. You will still have to do some setup to get core
and std
working, but it is a straigtforward process.
At the root of your crate, create a directory named .cargo
. In this directory, create a file named config.toml
, with the following contents.
[build]
target = "x86_64-unknown-linux-gnu" # Change to the host target.
[unstable]
build-std = ["core","alloc","std","panic_abort"]
Then, run the codegen utility rustflags
again, by running ./bin/rustflags.rs
in the directory rustc_codegen_clr
.
It should provide you with the commands necesarry for enabling the codegen. They should look something like this:
On Linux:
export RUSTFLAGS="-Z codegen-backend=/home/USER/rustc_codegen_clr/target/release/librustc_codegen_clr.so -C linker=/home/USER/rustc_codegen_clr/target/release/linker -C link-args=--cargo-support "
On Windows:
$Env:RUSTFLAGS = '-Z codegen-backend=C:\Users\USER\rustc_codegen_clr\target\release\librustc_codegen_clr.dll -C linker=\Users\USER\rustc_codegen_clr\target\release\linker.exe -C link-args=--cargo-support '
You can then run this command in your shell session (aka. command prompt window). This command will enable the codegen for that session(command prompt window) only! The project makes no pernament changes to your instaltation, and simply closing the shell session(command prompt window) will disable it.
After this, simply run cargo run
to compile & run your app inside the .NET runtime. Other cargo commands should work to. There may be quite a few error / warning messages dispalyed, but they will not stop compilation.
NOTE: the project currently does not properly support proc-macros
, due to technical liminations. Fully supporting them is possible, but it is currently more effort than it is worth.
Currently, the generated code will, by default, depend on some features of C that may not always be present.
Those features are:
- malloc and aligned allocators - certain static/constant variables require alignments higher than the ones guaranteed by the C standard. As a workaround,
cg_clr
will use malloc & aligned allocators to ensure sufficient alignment of static variables. This is something I am actively working on resolving, and this should not be an issue in the near future. - POSIX threading APIs. The header files generated by
cg_clr
will override certain POSIX APIs in order to track new threads. This is needed to ensure proper initialization of thread-local data.
Additionally, you might notice that the generated code sometimes calls "wierd" functions, like System_Numerics_BitOperations_LeadingZeroCountu64i32
.
This is a limitation of the current abstractions over .NET and C. Most of the time, those functions simply call / emulate a C builtin. This is also something that will not be an issue in the future:
I am actively working on better abstractions.
By default, cg_clr
will keep symbol(function) names more-or-less intact. However, those names may contain characters accepted by most, but not all compilers.
_ZN54_$LT$$LP$A$C$B$RP$$u20$as$u20$fuzz100__PrintFDebug$GT$12printf_debug17h769fc7ecbdc54ca9E
In those cases, simply set ASCI_IDENT
enviroment variable to ensure correct symbol names.