I found some very interesting about the ranlib -c used in bufr, and a couple other packages on macOS. Turns out that setting:
if(APPLE)
# The linker on macOS does not include `common symbols` by default
# Passing the -c flag includes them and fixes an error with undefined symbols
set(CMAKE_Fortran_ARCHIVE_FINISH "<CMAKE_RANLIB> -c <TARGET>")
endif()
Doesn't work as expected when installing libraries. ranlib is run correctly when creating the archive, but when running make install, ranlib is run again (without the -c) and the archive header is regenerated, negating its effect. This works in UPP because it's built internally as part of UFS (no make install). As far as I can tell there is no way to control ranlib flags used during the install phase (unless you manually edit the CMake install script), but I did a little research and found something better.
The -fno-common flag can be used in both ifort and gfortran and prevents variables being added to the common section at compile time. Interestingly, I ran into this when compiling with gfortran. I had only ever experienced this with ifort.
I was adding the MET package which links to bufr and even though I saw ranlib -c being used in the library build, my build would fail with missing symbols. Then, if I ran ranlib -c manually on the installed library the build would work.
https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/data-options/fcommon.html
On macOS*, if a library built with the ar utility contains objects with Fortran module data but no executable functions, the symbols corresponding to the module data may not be resolved when an object referencing them is linked against the library. You can work around this by compiling with option -fno-common.
Another interesting tidbit is that GCC-10 defaults to using -fno-common, so I wouldn't have experienced this had I not been using GCC-9.
https://gcc.gnu.org/gcc-10/porting_to.html
Not directly a spack-stack related issue, but I thought this would be a good place to document it.
I found some very interesting about the
ranlib -cused in bufr, and a couple other packages on macOS. Turns out that setting:Doesn't work as expected when installing libraries. ranlib is run correctly when creating the archive, but when running
make install, ranlib is run again (without the -c) and the archive header is regenerated, negating its effect. This works in UPP because it's built internally as part of UFS (nomake install). As far as I can tell there is no way to control ranlib flags used during the install phase (unless you manually edit the CMake install script), but I did a little research and found something better.The
-fno-commonflag can be used in both ifort and gfortran and prevents variables being added to the common section at compile time. Interestingly, I ran into this when compiling with gfortran. I had only ever experienced this with ifort.I was adding the MET package which links to bufr and even though I saw
ranlib -cbeing used in the library build, my build would fail with missing symbols. Then, if I ranranlib -cmanually on the installed library the build would work.https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/data-options/fcommon.html
Another interesting tidbit is that GCC-10 defaults to using
-fno-common, so I wouldn't have experienced this had I not been using GCC-9.https://gcc.gnu.org/gcc-10/porting_to.html
Not directly a spack-stack related issue, but I thought this would be a good place to document it.