CMake builds for modern C++14, C++17, C++20

Non-standard language options and incomplete feature support are normal for compilers across virtually all programming languages from BASIC to Fortran and here C++. Modern C++ features typically require using specific compiler flags to enable support. Knowing what compiler flags to set can be confusing for those new to modern C++ features. Setup of C++ compiler flags for modern C++ features is easily and automatically handled by CMake or Meson.

cmake_minimum_required(VERSION 3.0)
project(fs CXX)


add_executable(filesep_cpp filesep.cpp)
set_property(TARGET filesep_cpp PROPERTY CXX_STANDARD 17)

Compilers supporting C++17 filesystem include:

  • g++ ≥ 8
  • clang++
  • Microsoft Visual Studio

brew-like Scoop for Windows

Scoop brings easy install like scoop install gcc of developer programs to Microsoft Windows. Scoop works from a fresh Windows install, for example via free Windows virtual machine image.

Like Homebrew, Scoop does NOT require administrator/root access, so users in restrictive (but Internet connected) environments can use Scoop to get the latest development tools.

The Scoop package list is built from little JSON snippets, so Scoop is lightweight to maintain, and easy to add new packages to.


  1. From PowerShell:

    iex (new-object net.webclient).downloadstring('')
  2. Install Git and SSH via Scoop, so that Scoop can update its recipes:

    scoop install git openssh
  3. open a new PowerShell to use scoop.


These are the most common development tools you may want:

  • gcc/gfortran: scoop install gcc
  • make/cmake: scoop install make cmake
  • clang/LLVM: scoop install clang
  • GNU Octave: scoop install octave

sh.exe error with cmake

The nuisance error from cmake about sh.exe being on the Path is eliminated by adding -DCMAKE_SH="CMAKE_SH-NOTFOUND" to my cmake command, like:

cmake -G "MinGW Makefiles" -DCMAKE_SH="CMAKE_SH-NOTFOUND" ..

Updating packages

From time to time, you can simply scoop update gcc or similar to update individual packages.


nmap in Cygwin - seamlessly

The original Windows Subsystem for Linux WSL1 (2016 - 2019) doesn’t work with Nmap. However, the new WSL2 introduced for Windows 10 beta testers in summer 2019 and the general public in 2020 does work with Nmap directly. For those not able to use Nmap in WSL2 in Windows, the procedure below uses Cygwin. On Windows, use Nmap from Windows itself or via Cygwin (which is just calling native Windows Nmap).


  1. Download nmap
  2. Install nmap “self-installer” .exe. When asked, also install Npcap.
  3. Cygwin: add to ~/.bash_profile the following. Note the \ and \( are vital for Cygwin shell to interpret the command correctly.

    alias nmap="/cygdrive/c/Program\ Files\ \(x86\)/Nmap/nmap.exe"

Open a new Cygwin window to start using nmap



results in

Starting Nmap ( ) 
Nmap scan report for
Host is up (0.0092s latency).
Not shown: 998 filtered ports
53/tcp open domain
443/tcp open https

Nmap done: 1 IP address (1 host up) scanned in 7.41 seconds


  • errors about interface → try running Cygwin as Administrator (right click on Cygwin icon).
  • find interface names available to nmap

    nmap --iflist


  • to find servers with a particular port open on a subnet, try my Python findssh program that scans for servers without nmap.
  • If you don’t install Npcap when asked in the nmap installer, nmap does not work. Nmap claimed no host existed at a known working IP address.

Why isn’t nmap built into Cygwin?

nmap requires deeper access to the Windows networking stack that would go beyond the normal scope of Cygwin. Note that Nmap itself needs the separate program Npcap (forked from WinPcap) to work on Windows.

Install PGI free Fortran compiler

Related: Install Flang LLVM Fortran compiler

The PGI Community Edition compilers are a set of no-cost, non-open-source, high performance compilers for:

  • C pgcc
  • C++ pgc++ (Mac / Linux only)
  • Fortran pgfortran including CUDA Fortran support.

Like Flang, PGI supports significant portions of modern Fortran 2008 / 2018 syntax.


Download and install PGI Community Edition:

  • Linux / Mac: ~/.local/pgi sudo not required, but must be on symbolic-link-aware drive (not ExFAT)
  • Windows: d:\PGI (can be on any drive, including ExFAT). Requires Visual Studio as well.

PGI compiler is over 2 GB download. You don’t need to install CUDA support unless you have and want to use a CUDA-capable GPU.

Linux / Mac

add to ~/.bashrc:

export PATH="$PATH:$HOME/.local/pgi/linux86-64/2019/bin/"

or whichever directory you find with

find $HOME/.local/pgi -name pgfortran

Open a new terminal to use PGI pgfortran pgcc pgc++


use PGI command prompt–you may need to do

set FC=pgfortran
set CC=pgcc

Note that there is no pgc++ on Windows.

PGI requires Visual Studio to compile even the most basic programs. If you upgrade Visual Studio (even a minor update) after installing PGI, you may get errors on PGI compiling like

pgfortran my.f90

pgfortran-Error-Required tool link was not found

The easiest solution is to just reinstall the PGI compilers.


Typically we invoke compilers from a build system such as Meson or CMake.


Meson ≥ 0.50 supports PGI and Flang compilers.


fc = meson.get_compiler('fortran')
if fc.get_id() == 'pgi'
  message('PGI compiler')


CMake ≥ 3.10 distinguishes between PGI and Flang compilers. Set compiler-specific options in CMakeLists.txt for various Fortran compilers like:

cmake_minimum_required (VERSION 3.10)
project(myproj Fortran)


select the PGI compilers at CMake configure step:

FC=pgfortran CC=pgcc CXX=pgc++ cmake -B build

PGI Debugger

Sadly, PGI 19.7 deprecated PGI debugger. PGI Java-based pgdbg graphical debugger was for Fortran, C and C++ and was in the no-cost Community Edition as well. The program to be debugged needs compile options -g -O0 to provide maximum debugging information.

Example with hello.f90:

  1. pgfortran -g hello.f90
  2. pgdbg a.out opened the graphical Fortran debugger.

If you don’t see code in the upper left of the graphical PGI debugger for your program, be sure you compiled the executable with -g -O0 options.

Fix Python 3 on Windows error Microsoft Visual C++ 14.0 is required

Related: Fix Python 2 error Visual C++ 10.0 missing vcvarsall.bat

Fix the error for Python on Windows:

error Microsoft Visual C++ 14.0 is required

as follows.

Visual Studio changed the Build Tools from being C++ specific in late 2017. Thus newer Visual Studio versions work in place of older versions.

  1. Install using any ONE of these choices:
  2. Select: Workloads → C++ build tools.
  3. Install options: select only the “Windows 10 SDK” (assuming the computer is Windows 10). To use MSVC cl.exe C / C++ compiler from the command line, additionally select the C++ build tools.


Windows Python needs Visual C++ libraries installed via the SDK to build code, such as via setuptools.extension.Extension or numpy.distutils.core.Extension. For example, building f2py modules in Windows with Python requires Visual C++ SDK as installed above. On Linux and Mac, the C++ libraries are installed with the compiler.


This was the former link to Microsoft Visual C++ Build Tools–no longer active:

Fix Python on Windows error Microsoft Visual C++ 10.0 is required unable to find vcvarsall.bat

Related: Fix Python3 error Visual C++ 14.0 required

To fix the error for Python 2.7 on Windows

error Microsoft Visual C++ 10.0 is required (unable to find vcvarsall.bat)

Install Microsoft Visual C++ Compiler for Python 2.7.


Visual Studio is used for Python on Windows whenever C, C++ or other compiled language extension modules are used from Python. For example, a C library may be used for better performance, seamlessly called from Python.

Install GCC, GFortran, and GNU Make on Windows via MinGW

The GNU compilers and GNU Make are available using MinGW for native Windows:

  1. Download MinGW-w64 compiler (gcc, g++ gfortran)
  2. Install to C:\mingw using:

    • Architecture: x86_64
    • Threads: posix
    • Exception: seh

    This also installs GNU make at C:\mingw\bin\mingw32-make.exe.

  3. add c:\mingw\bin to your PATH under Control Panel → System → Advanced.

  4. For convenience, symlink make to mingw32-make:

    cd C:\mingw\bin
    mklink make.exe mingw32-make.exe

CMake on Windows is often used as well.


  • Windows Subsystem for Linux gives near-native Linux functionality in a Windows window. It’s much easier to do certain development tasks in WSL.
  • MSYS2 is a more powerful way to use MinGW, giving newer packages and a wider selection of programs.

PNG stack to animated GIF using FFmpeg

FFmpeg converts all PNGs in a directory into an animated GIF by:

ffmpeg -pattern_type glob -i '*.png' out.gif
-pattern_type glob -i '*.png'
collect all .png files in this directory

Windows FFmpeg file globbing

FFmpeg file globbing does NOT work on Windows, even with FFMPEG 4.x. The error on Windows is like:

Pattern type ‘glob’ was selected but globbing is not supported by this libavformat build

Windows FFmpeg users, consider using Windows Subsystem for Linux for file globbing with FFmpeg.

PNG stack to AVI using FFMPEG

FFmpeg losslessly converts all PNGs in a directory into a single lossless AVI video file by:

ffmpeg -framerate 5 -pattern_type glob -i '*.png' -c:v ffv1 out.avi
-framerate 5
show 5 PNG image frames per second.
-pattern_type glob -i '*.png'
collect all .png files in this directory
-c:v ffv1

use the lossless FFV1 codec

if you have problems playing back the .avi file, try omitting the -c:v ffv1 parameter.

don’t go below a framerate of about 3 frames/second because some viewers won’t work (e.g. VLC).

Windows FFmpeg file globbing

FFmpeg file globbing does NOT work on Windows, even with FFMPEG 4.x. The error on Windows is like:

Pattern type ‘glob’ was selected but globbing is not supported by this libavformat build

Windows FFmpeg users, consider using Windows Subsystem for Linux for file globbing with FFmpeg.

Overloading functions in Matlab and GNU Octave

Matlab and GNU Octave are constantly adding new functionality. However, legacy versions remain in use for years. One in general may not be able to overload a Matlab function in Octave because of how Octave provides many functions as files, and cannot distinguish them from user files.

The “overloading” we do here is to provide a similarly but distinctively named function that seamlessly uses the new syntax when available, with a simple fallback. In this isfile example that was added in Matlab R2017b, the fallback only works for single files.

isfile fallback

Create a file “is_file.m” containing:

function ret = is_file(path)

if exist('isfile', 'builtin') == 5 || exist('isfile', 'file') == 2
  ret = isfile(path);
  ret = exist(path, 'file') == 2;

end % function