Windows shared library caveats

In general on any project, “shared” libraries on Windows using .DLL files have numerous caveats that aren’t an issue on macOS and Windows due to decades-old stark differences in how Windows links and runs shared libraries. One key distinction is that Windows has no concept of Rpath as Unix-like OS have, which means the .DLL have to be on PATH environment variable for all shared libraries used in an executable. This can be a key drawback for Windows shared libraries in non-trivial projects using 3rd party libraries. In general we strongly recommend using “static” libraries on Windows, as the downsides of shared libraries on Windows are significant.

In the past year or so, GitHub Actions runners for Windows broke most “shared” library runs across projects. The projects would run in “shared” on physical Windows machines reliably, but not on CI. We have disabled Windows shared builds on GitHub Actions CI across all projects.

Windows Git symlinks

Windows Git requires one-time settings to enable Git symbolic links. If a computer doesn’t have these settings, it can create problems with inability to reset a Git repo, where the repo may have to be erased and re-cloned to fix. If an existing local Git repo on a Windows PC has problems with symbolic links, it may be necessary to re-clone the repo after first making these one-time settings.

Set Windows user permission to create symbolic links. Configure Git globally on the Windows PC to handle symlinks:

git config --global core.symlinks true

Git symlinks should only refers to paths within the Git repo. Where possible it is preferable to avoid symlinks, but this method above often works on Windows PCs for Git symlinks.

Hugo Chroma code highlight

Hugo uses Chroma for code syntax highlighting. That is, when putting a code fence block into the Markdown source that is rendered by Hugo into a webpage, Hugo uses Chroma to highlight syntactical elements of the code similar to a modern IDE or Gist-like services, making the code more readable. Auto-detection of code languages is a computationally-intensive task, particularly for unlabeled code snippets. The webpage author specifies the code language using the Chroma alias.

For example, for Fortran or PowerShell scripts, the leading code fence is like:

```fortran
```ps1

PowerShell pass all command line arguments

Rather than putting a lot of development environment paths into environment variable PATH, it can be preferable to make little shell / PowerShell scripts and invoke the programs that way. For example, when testing multiple versions of the Python interpreter on a script, a simple method can be to create a one-liner Powershell script for each Python version, passing all command line arguments to the Python interpreter.

& $env:LOCALAPPDATA\\Programs\\Python\\Python3x\\python.exe $args

the preceding ampersand “&” makes this a Call so that the command line is expanded properly.


For Unix-like shells:

$HOME/python3.x/bin/python "$@"

CMake .gitignore out-of-source build tree

CMake can place a .gitignore file in the top-level build directory to allow making build directories with arbitrary names not cause Git clutter. Rather than adding arbitrary directory names to the project-wide .gitignore, be programmatic by having CMake create a .gitignore in the out-of-source build directory.

In general, it is recommended to use out-of-source builds with CMake as well as other build systems in general. Meson build system does not allow in-source builds.

Put this line of code in the top-level CMakeLists.txt to auto-ignore out-of-source build directory tree.

if(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
  # Git auto-ignore out-of-source build directory
  file(GENERATE OUTPUT .gitignore CONTENT "*")
endif()

CMake language standard for check* functions

A key feature of meta-build systems is dynamically testing system capabilities. Dynamic checks are easier to maintain and use versus large if-else trees or requiring the user to manually include specific Makefiles, etc. In CMake, dynamic testing via check* module functions generally wrap try_compile with logic to only run the check once. try_compile() will run each time CMake runs unless additional if() guard logic is put around try_compile().

check_source_compiles shows the influence six variables CMAKE_REQUIRED* have on the check* functions. Rather than manually setting CMAKE_REQUIRED_FLAGS with compiler language standard flags, instead we recommend setting CMAKE_CXX_STANDARD or similar variable for the code language being checked. The CMAKE_CXX_STANDARD (or similar for C etc.) takes effect in the check* functions.

Git HTTPS Overleaf

For practical purposes, Git over HTTPS works with Overleaf if others aren’t editing the same document at the same time via the web interface. Overleaf has a single Git branch and requires a linear Git commit history (no force Git push). If other users are using the normal web interface of Overleaf to edit the same document, Git merge will be frequently needed on local Git, which may be inconvenient. Practically speaking, if coworkers on the same Overleaf LaTeX document are using Git to push local edits, and they use Overleaf just to view, it can work OK.

The Git repo URL is given from the Overleaf project, under Menu → Sync → Git. The Git URL is a long hexadecimal number. As usual with Git, clone to a human-friendly directory name like “paper1”.

git clone https://git.overleaf.com/<hash> paper1

Git HTTPS configuration

Store Overleaf username for Git operations. Use the same email address as Overleaf login.

git config credential."https://git.overleaf.com".username your@email.address

Computer-wide Git pre-commit hooks may be bothersome when uploading. To disable Git pre-commit hooks for the repo:

git config core.hooksPath " "

Git HTTPS password cache

For non-public Overleaf projects the Overleaf password is required for Git operations.

If a Git credential helper was previously setup, it may need to be disabled for the Overleaf repo if caching is not desired.

git config credential.helper " "

Git can use HTTPS credential cache mechanisms–on Windows consider Microsoft Git Credential Manager. A Git credential cache can avoid typing the password for each remote Git operation. The command below remembers the Git HTTPS password for 300 seconds (5 minutes).

git config credential.helper 'cache --timeout=300'

CMake execute_process flush

CMake execute_process doesn’t print to stdout until the process ends or flushes the stdout buffer. This is shown by example. The stdout print before flush behavior may be platform-dependent in general, but we observed that CMake didn’t print till flushed.