I am trying to maintain a large C++ toolkit: GDCM. The core library is compatible with C++11, but one component (CharLS) is a C++98 only library.
How can I use CMake (monolithic project) so that C++ flags from the toplevel project are not passed down to C++98 only library.
For instance a user may want to exercise the library using clang-3.9 new option: -Wundefined-func-template, however this flag should not propagate down to the CharLS compilation line.
I've used an naive fix (here), but I (actually upstream too) would rather keep CharLS a C++98 (only!) library and not stuff in a C++11 construct.
How one would do that since -Wundefined-func-template is not deactivated when used in combination with -std=c++98.
Related
Ubuntu 16.04 comes with GCC 5.4 which does support c++11 and it is the default compiler. By default c++11 is not enabled in that particular version of GCC.
My intent is to use some of the binary libraries (not header only) from their repository (e.g. boost). In my projects I will enable c++ 11.
How were c++ libraries from the repository compiled? Is it possible to use them with c++ 11 enabled? I know that c++ libraries can be called from different languages (Java, Pythons, C# etc) by hiding all c++ stuff behind plain C interface. With boost it is not a case. If a certain function returns me a string or a vector or anything from STL then it is a problem. AFAIK STL objects binary representation depends on compiler flags (eg. std=c++11).
Thank you.
Which exact libraries are you talking about?
If you are talking about the standard library, libstdc++ is a part of gcc. It is always okay to link it no matter which standard you compile at. gcc also made a decision to include ABI tags, so that they can be ABI compatible with code compiled at C++11 and pre C++11. See for instance TC's really nice answer to a question I asked here:
Is this simple C++ program using <locale> correct?
If by
How were c++ libraries from the repository compiled?
you mean, how are all of the C++ libraries in the ubuntu repositories compiled, the answer is, it may be different for each one.
For instance if you want to use libfreetype6-dev or libsdl2-dev, these are C libraries, they will be okay to link to no matter what standard you target.
If you want to use libsilly-dev from CEGUI, that is a C++ library, and it is usually best to use the exact same compiler for your project and the C++ lib that you are linking to. If it appears in ubuntu repository, you can assume it was built with the default g++ version that ubuntu is shipping. If you need to use a different compiler, it's probably best to build the C++ lib yourself -- in general C++ is not ABI stable across different compilers, or even different versions of the same compiler.
If you want to use compiled boost libraries, it's probably best to use the libs they give you and use the compiler they give you. If you only use header-only boost, then the compiler doesn't matter since you don't actually have to link with something they built. So you then have more flexibility with respect to compilers.
Often, if you need to use C++ libraries, it's best to integrate their build system into yours so that it can be easily rebuilt from source and you only have to configure the compiler once. (At least in my experience.) This can save a lot of time when you decide to upgrade compilers later. If you use cmake then it's often feasible, but sometimes this can be hard, especially if you have a lot of C++ dependencies. If you don't use cmake, well, many libraries use cmake and it won't be that easy to integrate them this way. cmake is still kind of a pain anyways, so this might not be such a loss.
I have to compile and run a modern program on a cluster with an outdated OS. The program employs some c++11 features and STL templates. The cluster's compiler toolchain (g++ v 4.4.7) supports almost all of c++11 features, but some important STL templates/classes are missing.
To make it work I'll have to either:
modify the program's source code, or
compile a newer version of STL library on a cluster and link against it instead of system-wide STL libs.
The 1'st route seems sub-optimal, because the program is currently in an active development by our lab, and it means we'll need to patch it by hand daily, or make a separate branch and regularly merge from trunk, or drop the support for c++11 features altogether.
So, is it possible to build a libstdc++ version that is newer than the one installed system-wide, and link against it? And if it is possible, how could it be done?
My understanding is that libgcc shouldn't be used in embedded systems and uclibc need to be used wherever possible. During buildroot build it is seen that it is generating libgcc as well. If I have to remove libgcc dependency completely (no static as well as shared) and only rely on uclibc, is it possible ? Is there any configuration which can effect this change ?
Thanks.
You are confusing glibc with libgcc. The latter contains helper functions for your architecture (e.g. integer division on ARM Application Profile) and not the standard C library functions. These functions may be part of the "run-time ABI" and might be required regardless of the C library you are using (even when compiling for bare-metal).
The uClibc is a drop-in replacement for glibc, not for libgcc.
We have Oracle 11 running on HP-UX 11.31 and gcc 4.4.3. It seems that there is no way to link to occi, because it was built with aCC. Is there any workaround for this?
I had the silly idea that I could somehow build a library that basically proxied the connection - build the library with aCC in some way that could be linked to by gcc. Is this possible?
No, there isn't a way around that.
Different C compilers have interchangeable code using a standard ABI. You can mix and match their object code more or less with impunity.
However, different C++ compilers have a variety of different conventions that mean that their object code is not compatible. These relate to class layout (especially in multiple inheritance hierarchies and the dreaded 'diamond-of-death'), but also in name mangling conventions and exception handling. The name mangling schemes are deliberately made different so that you cannot accidentally link objects from one compiler with another.
Generally, if libraries are built using a C++ compiler, you have to link your code using the same - or at least a compatible - C++ compiler. And that almost invariably means a compiler from the same family. For example, you might be able to use G++ 4.5.0 even if the code was built with G++ 4.4.2. However, you won't be able to mix aCC with G++.
I have encountered an unexpected Access Error while running a project I've built using two different versions of Visual Studio. My general configuration is as follows:
LibA is a static lib, static runtime linkage, msvc 8.0
LibB is a static lib, static runtime linkage, msvc 9.0
My target project for integration is a msvc 9.0 COM dll, which statically links the above libraries
This project builds, but crashes up at runtime with an access violation in some STL code. The stack seems to indicate that I've passed through headers both versions (8 and 9) during a call into a stream insertion operator. I realize that this is a problem.
Somehow, this call:
ost << std::dec << port_; //(originating from an object in LibA)
...descends through the following stack trace:
std::basic_ostream::operator<<(...) (ostream:283, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::put(...) (xlocnum:888, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::do_put(...) (xlocnum:1158, msvc 9.0 version!! !##$!%! <-- not expected, since LibA was built with msvc 8.0)
std::ios_base::flags() (xiosbase:374, msvc 9.0 version <-- follows from above)
The access violation happens in std::ios_base::flags(). I suspect it is due to the mix of implementations in the call stack (although I am not sure).
My questions are.
1.) Is the likely cause of this access violation the mixing of msvc header implementations?
2.) Is there a way to prevent these implementations from mixing?
3.) Is there a better way to configure these three projects for integration (assuming moving LibA from msvc 8.0 is undesirable)?
I am aware of the ideas raised in this question and this one. Here I am most interested in this specific problem, and if there is some way to avoid it.
Any insights would be appreciated.
You can't use different STL implementation in the same project. This means even different versions from the same compiler. If your LibA has a function that accepts std::vector as an argument you are only allowed to pass vector object from STL that LibA was built with. This is why many C++ libraries expose only C API.
Either you change your API or you rebuild all your projects using the same compiler.
You are doing something that you shouldn't. You are in the world of undefined behavior. There is no point in trying to debug this particular crash. Even if you managed to make this line work you would get a new crash somewhere else.
There is no guarantee of library binary compatibility between major versions of MSVC. STL code is mostly template code that gets expanded into your code. So you're static libraries probably have incompatible chunks of STL code inside of them.
In general, this shouldn't be a problem, unless that STL code is part of the interface to the library. For example, if you pass iterators or a reference to a vector from one library to another, you're in trouble.
The best solution is to build everything with the same version of the compiler. If you can't do that (e.g., if the one of the libraries is from a third-party), you're probably stuck.