Homebrew revert to GCC 10

Any new version of a program may add new bugs even as it adds new features and fixes other bugs. GCC is no exception–the GCC 11.1 release introduced Fortran syntax bugs. As Homebrew is often among the first easy sources of new GCC releases, we upgraded quickly before realizing the new bug was intolerable for us. For Intel CPU Macs, simply do:

brew install gcc@10

For Apple Silicon ARM64 Macs, there is a unique problem–GCC 10 is no longer available as binary downloads from Homebrew. This is because backports and hacks were necessary to get GCC 10 working on ARM64, and the Homebrew team wanted to encourage moving to mainstream supported GCC 11. The Homebrew maintainers provided hints for a workaround to install GCC 10 on ARM64.

CentOS 8 Stream SSH and VNC

CentOS and Red Hat add a few complexities on top of the “plain” Debian-based Linux distros one may be more likely to run on a laptop or Raspberry Pi. SELinux in particular is another layer to consider.

For SSH connection problems, suggest setting /etc/ssh/sshd_config to have

LogLevel DEBUG

then:

systemctl restart sshd.service

then:

journalctl -f

and try to login. This will print a good amount of information streaming and helps reveal .ssh/authorized_keys permissions issues and more.

In general, if one is puzzled if SELinux is causing an issue, as a last resort one may temporarily and carefully edit /etc/selinux/config to have

SELINUX=permissive

and reboot. Be sure to put that back to enforcing and reboot when done.

Check that firewalld is allowing the desired SSH port through.

tcpdump port 22 -n -Q inout

should show packets from the client–if not the SSH server firewall may be blocking them.


For VNC in general we avoid the fancy graphical desktop. To use the 2D simple “classic” desktop on VNC, edit ~/.vnc/xstartup to have:

export GNOME_SHELL_SESSION_MODE=classic

before the “xinitrc” line

Major changes in GCC Gfortran by version

GCC Gfortran and Intel oneAPI are the most advanced, widely available modern Fortran compilers. Useful Fortran 2018 enhancements include: select rank assumed array rank, error stop within pure procedures, random_init to initialize random number seed, and implicit none (type, external) to require external procedures to be explicitly declared. GCC 8 is the oldest version currently maintained. Intel oneAPI has full Fortran 2018 support.

To get recent GCC is usually straightforward. Red Hat should use GCC Toolset. MacOS Homebrew quickly adds the latest GCC version. If Ubuntu gfortran repo defaults aren’t adequate, get recent Gfortran via PPA.

Here are some of the major changes in Gfortran by version:

  • Gfortran 11 completed OpenMP 4.5 support
  • Gfortran 10 added select rank
  • Gfortran 9 added random_init() to initialize the random generator seed…randomly
  • Gfortran 8 added automatic nested loop exchange with do concurrent, actual argument array with too few elements for dummy argument now errors, initial support for parameterized derived types (simply define kind at initialization) and coarray support for teams. Standard flag -std=f2018 added and deprecated -std=f2008ts.
  • Gfortran 7 added derived type IO select type. Complete Fortran 2003 support, Fortran 2018 non-constant stop and error stop codes, and -fdec- options to help compile very old non-standard code.

Gfortran 6 added Fortran 2008 submodule support, useful for large projects to save compilation time and allow powerful use scenarios. Fortran 2003 deferred-length character are useful for avoiding bothersome trim() everywhere.

GCC 5 added full support for OpenMP 4.0, Fortran 2003 ieee_ intrinsics, Fortran 2008 error stop in pure procedures with constant error code. GCC 4.9 added Fortran 2003 deferred-length character variables in derived types. GCC 4.8 supported Fortran 2008 polymorphism, including select type, class(*), type(*), and assumed rank dimension(..). GCC 4.6 was the first version of Gfortran reaching beyond Fortran 95, with Fortran 2003 deferred-length character variable and Fortran 2008 impure elemental support. GCC 4.5 added Fortran 2008 iso_fortran_env. GCC 4.4 added initial support for polymorphism and OpenMP 3.

CMake allows switching parameters based on compiler version. This is very useful for modern Fortran programs.

Example CMakeLists.txt for Fortran compiler version dependent options.

if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)

  # option applying to any language for this compiler
  add_compile_options(-mtune=native)

  # language-specific, note LEADING space
  string(APPEND CMAKE_Fortran_FLAGS " -fimplicit-none")

  if(CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 8)
    string(APPEND CMAKE_Fortran_FLAGS " -std=f2018")
  endif()

endif()

add_executable(myprog main.f90)

Reference: Gfortran changelog

CMake temporary directory

A temporary directory for build system use should be created under the build directory. Some CIs and systems do not define the environment variables “TMPDIR” or “TEMP” for temporary directory. Virus scanners can false detect activity in the system temporary directory as malicious.

Create a temporary directory in CMake using random string like:

if(NOT DEFINED tmpdir)
  string(RANDOM LENGTH 24 _s)
  set(tmpdir ${CMAKE_CURRENT_BINARY_DIR}/${_s} CACHE PATH "temporary directory")
endif()

Pacman autoremove unused packages

Package managers can detect which packages were manually installed (at user or script explicit request) and which were implicitly installed as a prerequisite. When uninstalling the manually installed package, the prerequisite packages are often not auto-uninstalled. To recover the possibly significant amount of disk space from these now unused packages, an autoremove command is useful. For systems using “apt”, the command is:

apt autoremove

Pacman shows the auto-installed prerequisites with:

pacman -Qdtq

This can be piped into the Pacman remove command upon verifying the packages above are indeed OK to remove:

pacman -Qdtq | pacman -Rs -

CMake TLS VERIFY global

TLS verification defaults to OFF in CMake, yet there is a significant security benefit from globally setting TLS verification ON. This is accomplished via CMake variable CMAKE_TLS_VERIFY.

CMAKE_TLS_VERIFY allows a user to globally configure certificate verification. TLS verification can be an important part of cybersecurity. It’s often better to not have to worry about commands missing this parameter–just set it once. In case of suspected broken certificates, verification can then be easily switched off temporarily.

We suggest near the beginning of the CMake project:

set(CMAKE_TLS_VERIFY true)

Dropbox URL download options

Dropbox URL share can be readily used in scripts and programs including cURL and Wget. Be aware that Dropbox treats user agents like cURL distinctively to ease automation. When using less common web clients like Matlab, it may be necessary to set the URL options correctly–as should also be used for cURL and Wget. For example, Dropbox share URLs commonly end in “dl=0”, which will result in a webpage download instead of the intended file. We suggest changing the link to end in “dl=1”, which may resolve the unexpected behavior with automated clients.

Extracting zstd archive with tar

Zstd is a faster file archiving standard that is widely used as a better compressing replacement for .zip, gzip, etc. We have created interfaces for Matlab to extract .zst files. While ideally one would be able to extract .zst directly with tar --use-compress-program=zstd -xf myfile.zst, this doesn’t work on older tar like Windows includes from the factory.

zstd: error 25 : Write error : Broken pipe (cannot write compressed block) tar: Error opening archive: Child process exited with status 25

In this case, use a two-step process to extract the .zst file fully:

zstd -d myfile.zst   # creates tar file "myfile"
tar -xf myfile       # extract the original file/directory hierarchy