Can you use a different compiler when the first one fails to build a crate? - rust

I am trying to compile a project and I need to use the reqwest crate, which is dependent on the ring and mime_guess crates. When using the MinGW compiler, ring fails, but with tdm-gcc, mime_guess won't build.
Is it possible to use a fallback compiler? If yes, how?

Keep the tdm-gcc directory renamed, but first in the PATH, so that when you need to build something with it, just name it properly and any programs looking for gcc.exe can find it.

Related

How to compile include_external_msproject() dependencies?

I am moving our project repo from MSVC project files to CMake. But one special module I want to leave in .vcxproj. This seem to be possible thanks to include_external_msproject(). There are a number of issues with this command. But the most stopping is that I need to somehow define dependences.
Well, I use add_dependencies(). But it seems to be that CMake doesn't enforce dependent module to bi compiled :(
Is there any way to force dependency compilation?

Is there any way to compile AssemblyScript without node.js nor npm? Preferrably a standalone compiler that I could call from another program?

I have been searching some way to compile AssemblyScript without node.js. I have not found it and it is a tragedy because I really could use it to dynamically generate some special web assembly from other programs, for example, from a PHP program, in environments where node is not supported (like many shared hostings). I have the intuition that the compiler does not actually require node at all, that it must be written in some other language, but I have not found any way to install the compiler at all.
Do you have any idea of how to use it without node?
There is a way to do what you want, but it does not get rid of node completely.
The AssemblyScript README.md about the asc compiler lists two ways of building the compiler: the usual compilation to JavaScript, and a bootstrapping process, where you compile asc to WebAssembly by compiling it to JavaScript and then using that compiler to compile it to WebAssembly.
The caveat is that, at least initially, you still node to obtain the compiler from sources.
A second caveat is that the frontend for asc is JavaScript only, for now. You can use the WebAssembly binary only as a library, which may be actually what you want, given your use-case.

What is the exact difference between a Crate and a Package?

I come from a Java background and have recently started with Rust.
The official Rust doc is pretty self-explanatory except the chapter that explains Crates and Packages.
The official doc complicates it with so many ORs and ANDs while explaining the two.
This reddit post explains it a little better, but is not thorough.
What is the exact difference between a Crate and Package in Rust? Where/When do we use them?
Much thanks!
Crates
From the perspective of the Rust compiler, "crate" is the name of the compilation unit. A crate consists of an hierarchy of modules in one or multiple files. This is in contrast to most "traditional" compiled languages like Java, C or C++, where the compilation unit is a single file.
From the perspective of an user, this definition isn't really helpful. Indeed, in most cases, you will need to distinguish between two types of crates:
binary crates can be compiled to executables by the Rust compiler. For example, Cargo, the Rust package manager, is a binary crate translated by the Rust compiler to the executable that you use to manage your project.
library crates are what you'd simply call libraries in other languages. A binary crate can depend on library crates to use functionality supplied by the libraries.
Packages
The concept of packages does not originate in the Rust compiler, but in Cargo, the Rust package manager. At least for simple projects, a package is also what you will check into version control.
A package consists of one or multiple crates, but no more than one library crate.
Creating packages
to create a new package consisting of one binary crate, you can run cargo new
to create a new package consisting of one library crate, you can run cargo new --lib
to create a package consisting of a library as well as one or multiple binaries, you can run either cargo new or cargo new --lib and then modify the package directory structure to add the other crate
When should you use crates, and when should you use packages?
As you can see now, this question doesn't really make sense – you should and must always use both. A package can't exist without at least one crate, and a crate is (at least if you are using Cargo) always part of a package.
Therefore, a better question is this:
When should you put multiple crates into one package?
There are multiple reasons to have more than one crate in a package. For example:
If you have a binary crate, it is idiomatic to have the "business logic" in a library in the same package. This has multiple advantages:
Libraries can be integration tested while binaries can't
If you later decide that the business logic needs to also be used in another binary, it is trivial to add this second binary to the package and also use the library
If you have a library crate that generates some files (a database engine or something like that), you may want to have a helper binary to inspect those files
Note that if you have a very big project, you may instead want to use the workspace feature of Cargo in these cases.

Why does `cargo new` create a binary instead of a library?

I am creating a library with Rust. On library creation I type
cargo new name
According to the docs this should create a lib, because --bin is omitted.
However, the file is auto set to a binary.
Is there a setting I have to adjust to disable auto setting all projects to binary?
Cargo features
Cargo’s CLI has one really important change this release: cargo new will now default to generating a binary, rather than a library. We try to keep Cargo’s CLI quite stable, but this change is important, and is unlikely to cause breakage.
For some background, cargo new accepts two flags: --lib, for creating libraries, and --bin, for creating binaries, or executables. If you don’t pass one of these flags, in previous versions of Cargo, it would default to --lib. We made this decision because each binary (often) depends on many libraries, and so the library case is more common. However, this is incorrect; each library is depended upon by many binaries. Furthermore, when getting started, what you often want is a program you can run and play around with. It’s not just new Rustaceans though; even very long-time community members have said that they find this default surprising. As such, we’re changing it.
Source
Since Cargo 1.25 cargo new defaults to creating a binary crate, instead of a library crate.
cargo new accepts two flags: --lib, for creating libraries, and --bin, for creating binaries, or executables.
See the Changelog for 1.25.

How to make a fix in one of the shared libraries (.so) in the project on linux?

I want to make a quick fix to one of the project's .so libraries. Is it safe to just recompile the .so and replace the original? Or I have to rebuild and reinstall the whole project? Or it depends?
It depends. Shared library needs to be binary-compatible with your executable.
For example,
if you changed the behaviour of one of library's internal functions, you probably don't need to recompile.
If you changed the size of a struct (e.g. by adding a member) that's known by the application, you will need to recompile, otherwise the library and the application will think the struct is smaller than it is, and will crash when the library tries to read an extra uninitialized member that the application didn't write to.
If you change the type or the position of arguments of any functions visible from the applications, you do need to recompile, because the library will try to read more arguments off the stack than the application has put on it (this is the case with C, in C++ argument types are the part of function signature, so the app will refuse run, rather than crashing).
The rule of thumb (for production releases) is that, if you are not consciously aware that you are maintaining binary compatibility, or not sure what binary compatibility is, you should recompile.
That's certainly the intent of using dynamic libraries: if something in the library needs updating, then you just update the library, and programs that use it don't need to be changed. If the signature of the function you're changing doesn't change, and it accomplishes the same thing, then this will in general be fine.
There are of course always edge cases where a program depends on some undocumented side-effect of a function, and then changing that function's implementation might change the side-effect and break the program; but c'est la vie.
If you have not changed the ABI of the shared library, you can just rebuild and replace the library.
It depends yes.
However, I assume you have the exact same source and compiler that built the other stuff and now if you only change in a .cpp file something, it is fine.
Other things e.g. changing an interface (between the shared lib and the rest of the system) in a header file is not fine.
If you don't change your library binary interface, it's ok to recompile and redeploy only the shared library.
Good references:
How To Write Shared Libraries
The Little Manual of API Design

Resources