Providing compiler flags to Rust build for the MSVC toolchain - visual-c++

I am looking to enable compiler options for Rust applications built on Windows using the MSVC toolchain. I see that rustc provides the option "-C llvm-args" to provide flags to the LLVM toolchain but I don't see such an option for MSVC. Does this support currently exist for rustc or cargo?

Rustc is the Rust compiler and it relies on the LLVM backends for actual code generation on all platforms. So if you need to pass arguments to the backend, you can use -C llvm-args on Windows like in other platforms.
The distinction between the MSVC toolchain or the MINGW toolchain mostly concerns the linker. Options can be passed to the linker with -C link-arg or -C link-args on all platforms, although of course in this case the available options will depend on the targeted toolchain.

Related

How to enable Rust debugging when using WSL toolchain in CLion?

I am new to Rust and I am using CLion and the Rust plugin from JetBrains on Windows now. It works well when I just compile and run. But when I start debugging, it shows a dialog like this even though I switch my toolchain to WSL.
I wonder whether WSL is a kind of GNU toolchain. And if it is, what should I do to enable Rust debugging?
Rust provides two kinds of Tier 1 toolchains for the Windows operating system: pc-windows-msvc and pc-windows-gnu (for i686 and x864_64 architectures, making 4 toolchains in total). Their differences are highlighted here: What are the differences between the GNU and MSVC Rust toolchain?
WSL requires you to use the GNU toolchain. With Rustup, you can install it and make it the default (or configure it in your IDE of choice):
rustup toolchain add stable-x86_64-pc-windows-gnu
rustup default stable-x86_64-pc-windows-gnu

How to build the Rust compiler to use a custom fork of LLVM?

AMD released an optimized version of the LLVM toolchain named AOCC. Rust uses LLVM as the native code generator. Is it possible to use this LLVM instead of the fork from the Rust team?
As of Rust 1ad094, when configuring Rust, you can pass various LLVM-related options:
./configure --help | grep -i llvm
--enable-llvm-static-stdcpp statically link to libstdc++ for LLVM
--enable-llvm-link-shared prefer shared linking to LLVM (llvm-config --link-shared)
--enable-llvm-version-check check if the LLVM version is supported, build anyway
--enable-ninja build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)
--enable-emscripten compile the emscripten backend as well as LLVM
--enable-optimize-llvm build optimized LLVM
--enable-llvm-assertions build LLVM with assertions
--enable-llvm-release-debuginfo build LLVM with debugger metadata
--llvm-root=VAL set LLVM root
--experimental-targets=VAL experimental LLVM targets to build
--build=VAL GNUs ./configure syntax LLVM build triple
--host=VAL GNUs ./configure syntax LLVM host triples
--target=VAL GNUs ./configure syntax LLVM target triples
If the version of LLVM in the fork you want to use is compatible with the version of LLVM that Rust needs, then you should just be able to use --llvm-root=

Can gcc produce binary for Arm without cross compilation

Can we configure gcc running on intel x64 architecture to produce binary for ARM chip by just passing some flags to gcc and not using a cross compiler.
Short: Nope
Compiler:
gcc is not a native crosscompiler, the target architecture has to be specified at the time you compile gcc. (Some exceptions apply, as for example x86 and x86_64 can be supported at the same time)
clang would be a native crosscompiler, and you can generate code for arm by passing -target=arm-linux-gnu, but you still cant produce binaries, as you need a linker and a C-library too. Means you can run clang -target=arm-linux-gnu -c <your file> and compile C/C++ Code (will likely need to point it to your C/C++ include paths) - but you cant build binaries.
Rest of the toolchain:
You need a fitting linker and toolchain too, both are specific to the architecture and OS you want to run at.
Possible solutions:
Get a fitting toolchain, or compile your own. For arm linux you have for ex. CrossToolchains if you are on debian, for barebones you can get a crosscompiler from codesourcery.
Since you were very vague, its not possible to give you a clearer answer

Generating Rust executable from LLVM bitcode

How can I generate an executable of an application written in Rust that was compiled into LLVM-IR bitcode?
If I try to compile the .bc file with rustc it tells me stream did not contain valid UTF-8 and I can't seem to figure out if there is a specific option in rustc for this.
Basically I want to achieve this:
program.rs -> program.bc -> program.
Where program is the final executable. What steps should I make to achieve this?
Starting with this source code:
fn main() {
println!("Hello, world!");
}
You can create LLVM intermediate representation (IR) or bitcode (BC):
# IR in hello.ll
rustc hello.rs --emit=llvm-ir
# BC in hello.bc
rustc hello.rs --emit=llvm-bc
These files can then be further processed by LLVM to produce assembly or an object file:
# Assembly in hello.s
llc hello.bc
# Object in hello.o
llc hello.bc --filetype=obj
Then you need to link the files to produce an executable. This requires linking to the Rust standard libraries. The path is platform- and version-dependent:
cc -L/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ -lstd-f4a73f2c70e583e1 -o hello2 hello.o
You can then run the program:
DYLD_LIBRARY_PATH=/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ ./hello2
This answer has macOS specific solutions, but the general concepts should be extendable to Linux and Windows. The implementation will differ slightly for Linux and probably greatly for Windows. Notably, I'm using DYLD_LIBRARY_PATH as I've dynamically linked to the Rust standard library which isn't in my usual library search path.
Note that LLVM IR and BC files don't have the strongest forward / backward compatibility guarantees. This means that you need to use a version of llc that is compatible with the version of rustc you are using. For this answer, I used an llc that was produced by my local Rust development build:
% rustc --version --verbose
rustc 1.53.0 (53cb7b09b 2021-06-17)
binary: rustc
commit-hash: 53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b
commit-date: 2021-06-17
host: x86_64-apple-darwin
release: 1.53.0
LLVM version: 12.0.1
% llc --version
LLVM (http://llvm.org/):
LLVM version 12.0.1-rust-dev
Optimized build.
Default target: x86_64-apple-darwin20.5.0
Host CPU: skylake
See also:
How stable is the LLVM assembly language?
It isn't obvious since the LLVM documentation is very obscure, but clang will compile both LLVM IR files (".ll") and bitcode files (".bc"), and link with your system libraries.
On Linux with Rust 1.9:
clang -dynamic-linker /usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d16b8f0e.so hello.ll -o hello

Using libraries compiled with GCC in a VisualC++ project (and vice versa)

It's possible to use code (and libraries) compiled with VisualC++ (so with .lib extension) in a project that will use GCC as compiler (and vice versa)? Or I have to rebuild them?
I'm trying to use SOCI 3.1 libraries that I have compiled with VisualC++ in a project that has GCC as compiler, but I'm getting some errors, and I don't know why..
You have to produce binaries for GCC using MinGW tools: reimp and dlltool. Here is MinGW wiki with complete explanation of the procedures: MSVC and MinGW DLLs
Short example:
reimp -d libmysql.lib
dlltool -k --input-def libmysql.def --dllname libmysql.dll --output-lib libmysql.a
reimp libmysql.lib
By the way, here is related thread on SOCI users mailing list which: MySQL Build fails. Look for useful links given in the thread.

Resources