Post comments, questions, concerns, PR links, etc. here for anything related to creating a new GCC package for Mac and Linux.
We need to address:
CC @conda-forge/core @wesm @njsmith
cc @stuarteberg @tkelman
PR for gcc 6 at #873 - not building for me with errors like:
ld: library not found for -lcrt1.10.6.o
Any tips much appreciated...
The how and why of library renaming (e.g. for shipping a version of libstdc++ that never collides with the system version):
On OS X/MacOS, libraries are always looked up via install-name/rpath/whatever, and symbols are always bound to a specific library, so if your program can find libstdc++ at all then it will always find the right one (unless someone explicitly messes with $DYLD_LIBRARY_PATH -- if you're worried about that then renaming the library might be a good idea).
On Windows and Linux, library lookup is by name, and the _first_ thing that's checked is whether this process ever loaded another library called libstdc++.so (or whatever) -- if so then the linker will just use that and skip the regular lookup algorithm altogether. So if you want to avoid accidental collisions between libraries you ship and system libraries, or libraries other people ship (_cough_ MATLAB _cough_) then it's a good idea to give the libraries you ship unique names.
On Linux:
patchelf --set-soname so that the filename field embedded inside the .so matches its new name. If you don't, then IIRC bad things happen. (Specifically, I think that when looking for foo.so, the linker first checks whether it's previously loaded any files that _thought_ they were named foo.so, and then looks on disk for files named foo.so. So if bar.so thinks it's named foo.so, then it can collide with a real foo.so.)-lthe-new-name, or you can link using the regular name and then do patchelf --replace-needed original.so renamed.so. auditwheel does the latter, because it isn't hooked into your build system or anything.On Windows:
.lib / .a file, and that file has the real name of the .dll _inside_ it. So if you just rename the .dll alone, then it'll get out of sync with the .lib / .a file. Three options:.lib / .a file from scratch, using something like dlltool. Downsides: kinda awkward, and in theory the .lib / .a file might not be reconstructible from the .dll (though it is in 99% of cases).lib / .a file so that it refers to the renamed .dll. The .lib file format (technically, the "ILF format") turns out to be pretty trivial, so this would be easy to do, but AFAIK no-one has implemented it. .a files are more awkward to work with, but you should probably be using .lib files anyway..lib / .a file, and then use redll to patch the resulting binary so that instead of linking to your original .dll, it links to the renamed .dll (basically the equivalent of patchelf --replace-needed, but for PE instead of ELF).GCC 6 has some nice new features like -mmusl and nicer warnings and errors. ABI-wise I think it's worth using if any Linux distributions have switched to it yet. I'd recommend being maximally granular in creating different packages for different runtime libraries, avoid doing the homebrew thing of cramming even runtime-only libgfortran dependences into a single mega "gcc" package.
I have already commented on #873 with fixes for OS X compilation. I would like to just put my 2 cents here:
$ conda install -c conda-forge -c salford_systems gcc-5
OR
$ conda install -c conda-forge -c salford_systems gcc-6
Thanks @frol @njsmith @tkelman - your answers here are gold.
@frol I think if gcc 6 is incompatible, we could have both? I would prefer to have both be named simply "gcc" - but allow people to specify version specs, such that if you wanted to use the Intel compilers, you could say:
requirements:
build:
- gcc 5.*
or something like that? At conda-forge, we have generally supported multiple versions of things by having a branch for each supported version.
@njsmith thanks for the detailed reply. I'll follow your instructions carefully. This compiler is only going to be used on Mac and Linux, but I'll heed your advice on Windows for future Conda-build development.
@msarahan The package can be named just gcc with no issues. However, since GCC receives updates in older releases after a new one is released, e.g.:
it makes sense to keep the recipes apart (different branches will do the job) instead of rolling updates.
So, here is the list of packages that broke when Fedora went to gcc 6.x. Presumably some of these may already be fixed. The main thing they point out is that on gcc 6.x C++14 is the default mode for C++ instead of C++98. A sizable number of things were not compliant with C++11 yet and as such had issues with the new compiler.
Also, here is the list of gcc 6.x package build issues for Debian.
Additionally, a list of Ubuntu build failures with gcc 6.x in a thread that accompanies some fixes.
Just to add a problem we had on the company I work for. We have to support CentOS5, but we also develop under Ubuntu and other recent distributions.
We use a gcc that is much newer than the one shipped by CentOS5, but not newer than some Ubuntu versions. As we get basically all dependencies from conda when possible everything was fine except when we had to use a system library that was compiled with the system's gcc on Ubuntu and hence needed a newer libstdc++ than the one available through our conda channel.
In this case was the Nvidia OpenGL proprietary implementation, but could be any other library that we cannot ship.
Our solution until now is to provide an activate script with the gcc package, which checks which version is newer (system's or the shipped one) and if needed set LD_LIBRARY_PATH to always use the newest.
But as using LD_LIBRARY_PATH is not considered a good practice and is against conda philosophy I think the solution presented by @njsmith would be better. The gcc package should provide a renamed libstdc++, so that all conda packages linked to it. This should work fine for most situations except, I think, if a C++ library provided by conda had to interact with a system library C++ API. For example, if we had to use Nvidia OpenGL c++ API if there was one.
But at least for now this should not happen as most (if not all) basic system libraries has a C API.
Another thing to consider is the ABI change that gcc5 brings. It provides both the old and the new ABI and it is possible to run and compile binaries with either one. So there should be a conda-build feature on C++ packages indicating the ABI, the same way is done with vc9, vc10 and vc14, otherwise we could risk mixing libraries that talk to each other using different ABIs.
Btw, there are some ABI incompatibilities between gcc 4.9 and 5.1, even if there are fewer. 4.9 is shipped with ubuntu 14 and 5.1 with ubuntu 16.
May I ask if there are updates on this?
Just in case someone is still pursuing this, I faced a tricky issue that I believe anyone building gcc should be aware of: https://github.com/conda-forge/conda-forge.github.io/issues/388
@conda-forge/core sorry - I couldn't follow the development in conda-forge for a while. Can you give an update what's the current status here?
Would read up on issue ( https://github.com/conda-forge/conda-forge.github.io/issues/460 ). Should we close this issue @msarahan?
Have closed as this has been subsumed by other discussions elsewhere.
Most helpful comment
Just to add a problem we had on the company I work for. We have to support CentOS5, but we also develop under Ubuntu and other recent distributions.
We use a gcc that is much newer than the one shipped by CentOS5, but not newer than some Ubuntu versions. As we get basically all dependencies from conda when possible everything was fine except when we had to use a system library that was compiled with the system's gcc on Ubuntu and hence needed a newer libstdc++ than the one available through our conda channel.
In this case was the Nvidia OpenGL proprietary implementation, but could be any other library that we cannot ship.
Our solution until now is to provide an activate script with the gcc package, which checks which version is newer (system's or the shipped one) and if needed set LD_LIBRARY_PATH to always use the newest.
But as using LD_LIBRARY_PATH is not considered a good practice and is against conda philosophy I think the solution presented by @njsmith would be better. The gcc package should provide a renamed libstdc++, so that all conda packages linked to it. This should work fine for most situations except, I think, if a C++ library provided by conda had to interact with a system library C++ API. For example, if we had to use Nvidia OpenGL c++ API if there was one.
But at least for now this should not happen as most (if not all) basic system libraries has a C API.
Another thing to consider is the ABI change that gcc5 brings. It provides both the old and the new ABI and it is possible to run and compile binaries with either one. So there should be a conda-build feature on C++ packages indicating the ABI, the same way is done with vc9, vc10 and vc14, otherwise we could risk mixing libraries that talk to each other using different ABIs.