I am about to use external libraries but they does not work, when i look at them i found this
// This class file was compiled with different version of Kotlin compiler and can't be decompiled.
//
// Current compiler ABI version is 1.1.16
// File ABI version is 1.5.1
so i was wondering how to update my compiler Abi version
and also, should i be worried about, may some other external libraries conflict with this? It is posible to manage different compiler ABI version?
The Kotlin compiler should provide for specifying source and target version compatibility.
Source version means what features of the Kotlin language are supported. Should be https://kotlinlang.org/docs/compiler-reference.html#language-version-version
Target version defines what version the resulting JVM bytecode is going to be. I think this is the right switch: https://kotlinlang.org/docs/compiler-reference.html#jvm-target-version. When talking about ABI version this is what matters. Note that still you may want to change the source version if an older target version does not support new language features.
Related
SDL2 is often described as breaking backwards compatibility with SDL 1.2.
This implies that within different versions of SDL2, the API and ABI remain backwards-compatible.
However, I have not been able to find any authoritative source confirming that this is the case.
For example, for GLIBC, Red Hat maintains a webpage which states:
One of the GNU C Library's (glibc's) unwritten rules is that a program built against an old version of glibc will continue to work against newer versions of glibc.
This guarantee is very useful for portability, as it means that a program can be compiled against an older version of GLIBC and run on any platform that ships at least that version or any newer version of GLIBC.
The closest to such a guarantee that I have been able to find for SDL2 are the release notes for PySDL2, a separate project, which make passing references to "backwards compatibility":
Improved compatibility with older SDL2 releases […]
[…] properly wrapped now to retain backwards compatibility with previous SDL2 releases
[…] provide backwards compatibility for previous SDL2 releases […]
There are also two issues on Github which make passing mentions to "backwards compatibility" in the context of using SDL2, but also aren't actually directly tied to the SDL library at all.
Is there any official or authoritative source documenting or guaranteeing backwards compatibility across different versions of SDL2?
I.E., If I compile a program to dynamically link against an older version of SDL2, is it safe to assume that it will work on platforms that provide a newer version of SDL2?
Official Statements
It appears that one of the first goals reached in the development of SDL2 was to stabilize the ABI, explicitly so that no breaking changes would happen to it until SDL 3, according to the original author and main developer of SDL:
slouken
Regular
Mar '13
As of tonight, SDL 2.0 is ABI locked!
This means that no breaking changes will happen to the API until SDL
3.
Cheers!
From the SDL wiki:
We are obsessive about SDL2 having a backwards-compatible ABI. Whether you build your game using the Steam Runtime SDK or just about any old copy of SDL2, it should work with the one that ships with Steam.
A similar process is planned for the development of SDL 3:
slouken commented 22 days ago (4 Oct 2022, 18:45 GMT)
Our current plan is to make all the ABI breaking changes immediately before the very first SDL3 release, so we have a stable ABI from the very beginning.
Empirically
If we go on abi-laboratory.pro, we may see that SDL2 has more or less kept its promise of perfect ABI compatibility throughout every release:
Source
Specific changes between each version can furthermore be reported by clicking on the percentages.
I am new to Rust and is trying to understand the Cargo thing. I read in their FAQ about "why do binaries have Cargo.lock in version control, but not libraries?" but do not understand what this means.
"Users dependent on the library will not inspect the library’s Cargo.lock (even if it exists). This is precisely because a library should not be deterministically recompiled for all users of the library.
If a library ends up being used transitively by several dependencies, it’s likely that just a single copy of the library is desired (based on semver compatibility). If Cargo used all of the dependencies' Cargo.lock files, then multiple copies of the library could be used, and perhaps even a version conflict."
Appreciate if anyone can explain this. Thanks.
Say we have the following crates:
string-tools: this is some kind of commonly used library exporting a FastString struct that has faster implementations of some commonly needed functions. This library has two versions: 1.0.1 and 1.0.2. Version 1.0.2 was recently released.
database: a library to interface with your favorite database. It needs to do some string processing, and so it uses the string-tools library. One of the public methods in database has a signature like this:
fn get_username(id: u64) -> string_tools::FastString
The library has not had a chance or need to update to version 1.0.2 of string-tools - maybe it's unaffected by any of the bugs that were fixed in the patch. Consequently, it's Cargo.lock pins the version of string-tools to 1.0.1.
client: this library is for interacting with the client. It also depends on string-tools, and has a method like this:
fn show_name(name: string_tools::FastString)
This library is using the most recent version of string-tools, version 1.0.2. That is also the version in its Cargo.lock.
You would like to write a website that makes use of the database and client libraries. When you build your project, Cargo compiles each library's dependencies with the versions that are specified in the Cargo.lock. This means that database uses version 1.0.1 of string-tools and client uses version 1.0.2. But now imagine that you've written some code like this:
client::show_name(database::get_username(id));
This should compile. After all, the get_username function returns a string_tools::FastString, which is accepted by the show_name function. But it doesn't! That's because the FastString returned by get_username comes from version 1.0.1 of string_tools, while show_name wants a FastString from version 1.0.2! This can't work; after all, when the patch to string-tools for version 1.0.2 was written, it's possible that the author added an additional field to the type. There's nothing reasonable for the compiler to do.
This kind of issue is avoided by having Cargo ignore the Cargo.lock file on libraries. Instead what it does is compile both database and client against the 1.0.2 version of string_tools. This is correct because 1.0.1 and 1.0.2 are "semver compatible versions." That means it is ok to change out one for the other, things must still compile. Now you no longer get a compiler error, because the types that the one function returns and the other function accepts are no longer different.
I've built a rust toolchain using someone else's repo, and it contains
a configure line I'm not familiar with: --release-channel=nightly
After I build and install the toolchain it reports its version as:
rustc 1.57.0-nightly (f1edd0429 2021-11-29)
while the standard off the shelf install of 1.57 reports its version as:
rustc 1.57.0 (f1edd0429 2021-11-29)
What does the nightly suffix mean in this version string?
Nightly is an unstable, unfinished, experimental version of Rust.
The name comes from the fact that literally every night a new "nightly" version is automatically released from whatever happens to be in the rust-lang repository at the time.
The nightly version allows use of Rust features that are still work in progress, special unstable features that are private to the compiler or the standard library, or even features that were failed experiments and will never be available in the stable releases of the Rust language.
Nightly versions may crash, may miscompile code, may stop working at any time. There is absolutely no warranty about them. Do not use them unless you specifically want to test the latest, unfinished Rust language features.
There's one case where users may hear about "nightly" features: when they use an outdated version of the compiler.
When an old Rust version sees language features "from the future", it may ask you to enable nightly features to use the code. This is misleading. You should upgrade Rust to the latest stable version instead of using nightly.
To repeat: I'm looking for ABI compatibility between libraries of the same Visual-C++ version!
We want to mix and match some internal C++ DLLs from different teams - built at different times with different project files. Because of long build times, we exactly want to avoid large monolithic builds where each team re-compiles the source code of another team's library.
When consuming C++ DLLs with C++ interfaces it is rather clear that you only can do this if all DLLs are compiled with the same compiler / Visual Studio version.
What is not readily apparent to me is what, exactly needs to be the same to get ABI compatibility.
Obviously debug (_DEBUG) and release (NDEBUG) cannot be mixed -- but that's also apparent from the fact that these link to different versions of the shared runtime.
Do you need the exact same compiler version, or is it sufficient that the resulting DLL links to the same shared C++ runtime -- that is, basically to the same redistributable? (I think static doesn't fly when passing full C++ objects around)
Is there a documented list of compiler (and linker) options that need to be the same for two C++ DLLs of the same vc++ version to be compatible?
For example, is the same /O switch necessary - does the optimization level affect ABI compatibility´? (I'm pretty sure not.)
Or do both version have to use the same /EH switch?
Or /volatile:ms|iso ... ?
Essentially, I'd like to come up with a set of (meta-)data to associate with a Visual-C++ DLL that describes it's ABI compatibility.
If differences exist, my focus is on VS2015 only at the moment.
Have been thinking this through the last days, and what I did do was to try to see if some use-cases exists where devs have already needed to categorize their C++ build to make sure binaries are compatible.
One such place is the Native Packages from nuget. So I looked at one package there, specifically the cpprestsdk:
The binaries in the downloadable package as split like this:
native\v120\windesktop\msvcstl\dyn\rt-dyn\x64\Release\
^ ^ ^ ^ ^
VS version | not sure | uses cpp-runtime dynamically
| lib itself dynamic (as opposed to static)
or WinXP or WinApp(WinRT?)
I pulled this out from this example, because I couldn't find any other docs. I also know that the boost binaries build directory is separated in a similar way.
So, to get to a list of meta data to identify the ABI compatibility, I can preliminarily list the following:
VC version (that is, the version of the C and CPP runtime libraries used)
one point here is that e.g. vc140 should be enough nowadays - given how the CRT is linked in, all possible bugfixes to the versioned CRT components must be ABI compatible anyway, so it shouldn't matter which version a given precompiled library was built with.
pure native | managed (/CLI) | WinRT
how the CRT is consumed (statically / dynamically)
bitness / platform (Win32, x64, ARM, etc.)
Release or Debug version (i.e. which version of the CRT we link to)
plus: _ITERATOR_DEBUG_LEVEL ... if everyone goes with the defaults, fine, if a project does not, it must declare so
Additionally my best guess as to the following items:
/O must not matter - we constantly mix&match binaries with different optimization settings - specifically, this is even working for object files within the same binary
/volatile - since this is a code-gen thing, I have a hard time imagining how this could break an ABI
/EH - except for the option to disable all exception, in which case you obviously can't call anything that throws, I'm pretty confident this is save from an ABI perspective: There are possible pitfalls here, but I think they can't really be categorized into ABI compat. (Maybe some complex callback chains could be said to be ABI incompatible, not sure)
Others:
Default calling convention (/G..) : I think this would break at link time, when mangled export symbols and header declarations don't match up.
/Zc:wchar_t - will break at link time (It's actually ABI compatible, but the symbols won't macth.)
Enable RTTI (/GR) - not too sure 'bout this one - I never have worked with this disabled.
I follow a version scheme for a library with a version number of three parts and a so version of two parts. example-1.0.0 and libexample.so.1.0.
The last number in the version string is updated when I make changes without breaking the ABI. The second number is updated when I add new symbols and the major version number is used for incompatible changes.
The so version is updated when symbols are added even if it does not break compatibility with other programs. This means that programs need to be recompiled because the so version has changed even if the library still is ABI compatible with older versions.
Should I avoid updating the so version when I add new symbols?
This means that programs need to be recompiled because the so version has changed even if the library still is ABI compatible with older versions.
That means you are not doing it correctly. You should only change SONAME when doing ABI-incompatible change. It is customary to use example.1 as the SONAME. Documentation.
P.S. If you only care about Linux, you likely should stop doing external versioning altogether, and instead use symbol versioning to provide a single libexample.so.1 that provides multiple ABI-incompatible symbols to both old and new client binaries.