Closed mithro closed 1 year ago
conda doesn't force a C++ standard. Newer C++ standards are not 100% backwards compatible with older C++ standards which is why C++ compilers let you specify the C++ standard.
Our activation scripts are designed for building packages for AD and we want to use the most modern C++ standard whenever possible so we have decided to take a stance here. You cannot mix C++98 packages with C++17 packages due to the ABI differences so we explicitly do not want backwards compatibility here since it's not possible. Also we want packages that implement 'naive' auto-detection of C++ language features (#if __cplusplus >= 201103L
) to compile that codepath
If you are not able to update the package to C++17 support then you should filter that out from CXXFLAGS
. When I have to do this I do it in build.sh as:
if [[ ${target_platform} =~ .*linux.* ]]; then
CXXFLAGS="${CXXFLAGS//-std=c++17/}"
fi
or:
re='(.*[[:space:]])\-std\=[^[:space:]]*(.*)'
if [[ "${CXXFLAGS}" =~ $re ]]; then
export CXXFLAGS="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
fi
Another alternative that I do not recommend is to depend on gxx-impl_linux-64
and gxx-impl_linux32
instead but there are numerous downsides to that (lack of run_exports
probably).
We will not be changing the CXXFLAGS
our compilers set though so I am closing this.
Also, nowhere in your output do I see any error.
Forgive me, I'm no expert here but it was my understanding the C++ ABI is not necessarily tied to the C++ standard being used? Does C++17 and the packages standard requires a specific ABI?
Looking at https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html it seems what you actually want is -fabi-version
?
(On the actual issues causing problems was running into with -std=c++17
was around bools and ++
operator.)
No it is. I'd you are trying to limk to stuff compiled with an old pre-C++11 ABI and mix that with one using the new ABI (SSO change) you're in for a bad time. If the old module loads first it'll load the system libstdc++ instead of ours then the module that uses C++11 ABI will fall to find it's symbols. We decided to make the jump to the new ABI in July to September last year.
But regardless you get the new ABI with our compilers and the default std for GCC >6 is c++11 nowadays I believe.
Building everything with the latest standard available is something we will strive to continue doing.
From what I can understand, you can compile code with -std=c++98
and -fabi-version=0 -fabi-compat-version=8
and it will link fine against C++ code compile with -std=c++17
and -fabi-version=0 -fabi-compat-version=8
?
It might be good to document the workaround for removing the -std=c++17
flag?
The worry is if someone uses an old system compiler (where those flags do not even exist, nor any concept of the 'new C++ ABI') and will use the system libstdc++ and tries to mix it with stuff compiled with our compilers as I stated above. Using our compilers you can reduce or remove flags as appropriate.
A PR would be welcome but I don't really know to which repository it'd be applied (the compilers and compiler activation scripts are just packages like any other, they're not a feature of conda or conda-build as such) also I'd consider if pretty obvious that this is what needs to be done; I even print out the flag changes made so a package builder can easily see what we've set.
To sum up:
We target the cutting edge here, we stay current with the latest compiler features so will not contemplate reducing the default or messing with -fabi-version=0 -fabi-compat-version=8
which are not the latest versions.
For your own package builds feel free to play around but we are not going to risk compatibility by playing with these flags in our compiler activation packages.
The C++ ABI version the compiler uses != C++ standard -- these are separate concepts (and settings).
If your goal is to have a specific ABI version then you should be explicitly setting the -fabi-version=n
and -fabi-compat-version=n
or -Wabi
flags. By not providing the ABI version flags, you are using a "floating" ABI. IE You will always get the latest ABI. From the page you linked;
The default is version 0. Version 0 refers to the version conforming most closely to the C++ ABI specification. Therefore, the ABI obtained using version 0 will change in different versions of G++ as ABI bugs are fixed.
I can't find any documentation which says that -std=c++17
implies any given C++ ABI (but some C++17 features need at least a certain ABI version). As you are only setting -std=c++17
, then you are not getting the static, well known C++ ABI it sounds like you are after.
For the documentation changes, I would recommend something like https://github.com/conda/conda-docs/commit/779ad11463f8b1f85fffd965e0842b3433cfa767#diff-2165fd095fe8f92aea74fe3ad04e1659R199
I agree it's a little complicated. I was looking at the Environment variables set during the build process
section of the docs here -> https://conda.io/docs/user-guide/tasks/build-packages/environment-variables.html#environment-variables-set-during-the-build-process and was a bit tripped up by the lack of pointers to the fact that the compiler packages "extend" the build environment further.
We explicitly want the latest ABI.
GCC attempted to implement -fabi-compat-version
during the GCC 6 series but according to the clang developers it never worked right. Again, we are not interested in playing with this stuff or mixing any system GCC with our GCC.
We build hundreds of packages (actually thousands if you consider the different python and R variants) with these settings and the advised way of dropping back the --std=c++?? setting. I don't see any value in continuing this discussion.
I'm going to reopen this, but strictly as a docs issue. Conda-build does not set these variables - the compiler activation scripts do. The docs should reflect that "in addition to these variables, packages installed in the host environment may also set environment variables. For example, the default compilers used by Anaconda, which are what you get when you use "{{ compiler() }}" expressions, set several compiler variables. If you need to change or unset those variables, you need to do so in your build script."
Sorry about going on about the ABI stuff - just trying to relay a more polite version of the long rant I got from my GCC developer friends when asked about the ABI topic.
Did the documentation change make any sense? Maybe a link to the Anaconda Compiler section from the environment would help? I was thinking of trying to update the environment page (https://conda.io/docs/user-guide/tasks/build-packages/environment-variables.html#) to more explicitly call out the conda-build environment around the activate.
That's fine, and I don't claim to be an expert here, but I am happy with the job GCC has made of backwards compat. since GCC 6, but I do not want to risk GCC introducing functions that convert from the old ABI to the new one as I expect that will have performance issues and possibly tricky linking issues, but more importantly, AD doesn't provide packages built with the old ABI (except the free
channel which contains legacy stuff built on a mix of CentOS5 and 6 using system compilers) and I do not want it to either. We made a huge effort to cross that line last year.
Adding the env var change information to that page would be good yes! I am in two minds as to whether or not to mention that this stuff only works with our compilers. The reason for that is that I believe using our compilers is definitely a better idea than using devtoolset (which statically links parts of the C++ standard library into every thing that uses C++) or system compilers on CentOS6 (which are then not able to support modern language features).
Sorry about going on about the ABI stuff
Your questions are certainly going to be helpful for others who will have the same queries so no need to apologise. I will defend the decisions we made though as I am convinced they are right (at least from the perspective of building out AD).
Since you also hack on crosstool-ng
(which our compilers are based upon) I hope you may be able to help out on that if you find any issues and have time to look into them. I do a few icky things to fix issues in ctng and the various components. Currently we apply 31 patches on top of the upstream project (though some of the biggest ones were added for CentOS5 and those are not needed anymore).
As I just mentioned in https://github.com/conda/conda-docs/issues/607#issuecomment-416002384, I'm hoping to port our cross compilers to be based on your packages which used crosstool-ng. (I'm also hoping that it will make it easier for us to provide Mac + Windows packages too.)
Will definitely try and help here! My time availability is sadly very bursty which can make it hard to finish of things like this. :-/
Hi there, thank you for your contribution!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further activity occurs.
If you would like this issue to remain open please:
NOTE: If this issue was closed prematurely, please leave a comment.
Thanks!
Actual Behavior
conda build sets
-std=c++17
in theCXXFLAGS
build environment.See the following output;
Expected Behavior
conda doesn't force a C++ standard. Newer C++ standards are not 100% backwards compatible with older C++ standards which is why C++ compilers let you specify the C++ standard.
Steps to Reproduce
conda build a package using
{{ compiler('cxx') }}
with source code that is not C++17 compatible.Output of conda info