How do I compare the protobuf version used to compile the .proto files and the version of the Golang library to make sure they are compatible? - go

I have a Golang service which uses Protobuf. The library used by Go and the version of the compiler need to be similar enough as per the documentation:
Users should use generated code produced by a version of protoc-gen-go that is identical to the runtime version provided by the protobuf module. This project promises that the runtime remains compatible with code produced by a version of the generator that is no older than 1 year from the version of the runtime used, according to the release dates of the minor version. Generated code is expected to use a runtime version that is at least as new as the generator used to produce it. Generated code contains references to protoimpl.EnforceVersion to statically ensure that the generated code and runtime do not drift sufficiently far apart.
The last sentence seems to imply that there is already code to ensure compatibility.
Is that correct?
That being said, I would like to be able to display the version of the library and of the compiled protobuf files in my logs to at least be able to manually verify that the versions are indeed compatible. How do I get both of these versions?
Update: Here is the section I mention in the comments.
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

Related

Figuring out the target MacOS SDK version in CMake?

I have code that I want to conditionally compile depending on the target SDK version, so that I can use newer features if possible. This can be done by checking the __MAC_OS_X_VERSION_MIN_REQUIRED macro, which tells us the target SDK version, in the source code.
Typically, performing conditional compilation on that macro suffices, and everything is nice and good. However, when targeting a newer SDK version, I would like to use features from a new library (specifically the UniformTypeIdentifiers library) that is not available on an older SDK version. This means that the target_link_libraries() in CMake has to account for this, i.e. link the new library if targeting a newer SDK version, and skip the new library otherwise.
I can't seem to find any way to figure out the target SDK version in CMake. What is the proper way to do this?
Things I have tried:
Checking CMAKE_OSX_DEPLOYMENT_TARGET. This flag is what CMake uses to pass the -mmacosx-version-min flag to clang, that makes it use a particular deployment target. However, it turns out that this may not necessarily be defined. When not defined, clang doesn't get the flag, but since clang is given something like -isysroot /Applications/Xcode-13.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk, the framework sets __MAC_OS_X_VERSION_MIN_REQUIRED to something default (12.3), and so the source code is able to still perform conditional compilation.
Checking if the library exists by using find_library() (e.g. find_library(UNIFORMTYPEIDENTIFIERS_LIBRARY UniformTypeIdentifiers)). This does not work when users want to target a lower version (e.g. by setting CMAKE_OSX_DEPLOYMENT_TARGET), since the new library will still exist.
Essentially, I would like a way for CMake to figure out the deployment target that ultimately gets chosen (i.e. something equivalent to __MAC_OS_X_VERSION_MIN_REQUIRED), so that it can decide whether or not to link with the new library.
How should I do this?
Context:
I'm trying to resolve an issue in my library here.
I also have a testing branch set up to check CMAKE_OSX_DEPLOYMENT_TARGET and the compiler command in the CI builds: GitHub CI builds MacOS 10.15 (without the new library, with CMAKE_OSX_DEPLOYMENT_TARGET) and 11 (with the new library, with CMAKE_OSX_DEPLOYMENT_TARGET), and Circle CI builds MacOS 12 (with the new library, but without CMAKE_OSX_DEPLOYMENT_TARGET).
I couldn't find a way to determine this via some CMake variable, so I rolled by own compilation test for it:
include(CheckCXXSourceCompiles)
check_cxx_source_compiles(
"
#include <Availability.h>
#if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || !defined(__MAC_11_0) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_11_0
static_assert(false);
#endif
int main() { return 0; }
"
NFD_USE_ALLOWEDCONTENTTYPES
)
This ensures full consistency with the check in the source code, at the cost of a slightly longer time to configure the build.

unresolved reference to boost::program_options::options_description::options_description

First off I know there are several posts similar to this,but I am going to ask anyway. Is there a known problem with boost program_options::options_description in Debian "Buster" and Boost 1.67 packages?
I have code that was developed back in Debian 7, system upgraded to 8.3 then 8.11 now using Boost 1.55.
Code builds and runs. Now upgrade system to Debian Buster with Boost 1.67 and get the link errors for unresolved reference to options_description(const std::string& , unsigned int, unsigned int) along with several other program_options functions. All unresolved, expect the options_description, are from boost calling another boost function, so not even directly called from within my code. boost_program_options IS in the link line.
I AM not a novice and understand link order and this has nothing to do with link order.
I am going to try getting the source code for boost and building to see if that works, if not I will be building a system from scratch and testing against that.
Since this is all on a closed network simply saying try a newer version of boost or Debian is not an option because I am contractually obligated to only use Debian "Buster" and Boost 1.67 as the newest revisions, so if the package is unavailable (newer) in Buster it is out of the question, without having a new contract be drafted and go through approvals which could take months.
So to the point of this question, is there an issue with the out of the box version of Boost in Buster?
I don't think there's gonna be an issue with the package in Buster.
My best bet is that either
you're relinking old objects with the new libraries - and they don't match (did you do a full make clean e.g. to eliminate this possibility?).
Often build systems do not do complete header dependencies, so the
build system might not notice that the boost headers changed,
requiring the objects to be be rebuilt.
if that doesn't explain it, there could be another version of boost on the include path, leading to the same problem as under #1 even when rebuilding.
You could establish this by inspecting the command lines (make -Bsn or compile_commands.json e.g. depending on your tools). Another trick is to include boost/version.hpp and see what BOOST_VERSION evaluates to
Lastly, there could be a problem where the library was built with different compiler version or compiler flags, leading to incompatible synbols (this is a QoI issue that you might want to report with the Boost Developers).
This is assuming ABI/ODR issues, in case you want to validate this possibility.

How does one find what C++11 features have been implemented given a GLIBCXX version

Given a GLIBCXX version of the stdc++ library (example GLIBCXX_3.4.17) given this version, where would one find documentation which specifies what features have been implemented?
Further is there a way to which given the SO NAME version will provide the this same document.
I am working on an embedded system which has an existing version of libstdc++; unfortunately the supplied cross compiler (g++) is at a greater version than what the stdc++ library on the target supports. Upgrading the stdc++ library on the target is not an option. Before I write a lot of code, to only find that it does not run on the target; I would like to know beforehand what is and is not supported.
I have found the GNU Documentation to be useful; however, I am hoping there is a document in which one can get what has been implemented given the symbol version and/or the SO NAME and I just have somehow missed it.
Thanks for any help in advance
given this version, where would one find documentation which specifies what features have been implemented?
You can map a GLIBCXX_A.B.C symbol version to a GCC release by checking
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
N.B. that won't be precise, because e.g. GCC 5.1 and GCC 5.2 both use GLIBCXX_3.4.21 in the shared library. To tell them apart check the __GLIBCXX__ macro defined by the libstdc++ headers, also documented on that page.
The manuals for libstdc++ releases are at
gcc.gnu.org/onlinedocs/gcc-[X.Y.Z]/libstdc++/manual/
e.g.
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/libstdc++/manual/
Within that manual is a status table showing the implementation status for each standard, the table for C++11 support in GCC 5.3.0 is at
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/libstdc++/manual/manual/status.html#status.iso.2011
Before I write a lot of code, to only find that it does not run on the target; I would like to know beforehand what is and is not supported.
It's not enough to simply avoid using features that aren't supported by the library on the target system. If you link with the cross-compiler then it will depend on the libstdc++.so from that cross-compiler, and will fail to run on the target system if it only has an older libstdc++.so
Upgrading the stdc++ library on the target is not an option.
Then you either need to link statically (creating large executables) or downgrade your cross-compiler to match the target. Or at least force it to use the headers and dynamic library from the same version as found on the target (by overriding the header and library search paths to point to copies of the older files), although that might not work, as the newer g++ might not be able to compile the older headers if they contain some invalid C++ that the older g++ didn't diagnose.

ADA static library - compatibility with different versions of compilers

I have built a ADA static library and I share it by providing '.a' and ALI files.
Everything works fine while I use the same GNAT compiler version than the one used to build the static library.
But with another compiler version, the ALI files are considered as not valid (the compiler version is stored in all ALI files), and the compiler needs source files to rebuild ALI files.
Is there a solution to avoid this problem ?
updated on 12/11/2015 : We did some tests (with ALI library files in ready only), but we still have the following errors :
error: "package1.adb" and "prog.adb" compiled with different GNAT versions
error: "prog.adb" must be recompiled ("system.ads" has been modified)
So, I think we have to use the same compiler version for the library and the program.
If you are using gnatmake, make the ALI files read-only, so that the compiler does not try to recompile them (you are of course responsible for ensure that the object files are compatible, but this is in general the case).
If you are using project files, add a
for Externally_Built use "True";
attribute to achieve the same effect.
Answer from AdaCore :
This isn't supported: the Ada ABI (Application Binary Interface) is not guaranteed to stay the same across versions (and indeed does change regularly), so you cannot mix objects compiled with different versions of GNAT, you really need to ensure consistency in all your libraries.
So, it's not possible.

what does shared library .so.5 mean?

I have compile a shared library(libcurl). Finally I found it generated "libcurl.so.5".
".so" means a shared library. But what does the number 5 means?
How can I generate library without number 5? just like "libcurl.so"
Most fundamentally, it's simply a version number. If the version number increases from, say 5 to 6, then it's supposed to indicate that all previous programs that were linked against version 5 are binary-incompatible with version 6 and thus need to be recompiled. For example, if a function was removed from version 6 then clearly any application that used it wouldn't work any longer, so it's clearly unsafe for the application to automatically switch to the newer library version. Bug fixes to an existing function, on the other hand, wouldn't require that the application be recompiled or ported and thus it's safe to use the .5 version with dynamically loading even thought the application was compiled against "a previous version (which is, um, still 5)".
In practice it's a bit more messy, as different people use the version number in different ways (often increasing it when they really didn't need to).
The libtool project has a much more strict, and helpful, guide about when you should update the library version number.
In the end, you should not generate a library without the version number. It's a promise to your users about whether the library is binary compatible in the future or not.

Resources