Scientific Computing

Git set executable file permission on Windows

When interacting between Windows and Unix filesystems using Git, setting a file to be executable takes a particular Git command from the Windows computer. With standalone Unix systems, just chmod +x myfile.sh is tracked by Git. However, with Windows Subsystem for Linux or Cygwin, this chmod +x change is not tracked if the file resides on a Windows filesystem and not within the WSL internal filesystem.

Windows file mode permission for executable aren’t as trivial as Unix-like chmod. Unix-like file systems such as Linux and macOS need the executable bit set correctly to execute shell scripts and binary executables as expected. On Unix-like file systems, Git propagates the executable permission of files.

To add executable permission on Windows and for all other systems, use Git command:

git update-index --chmod=+x /path/to/exe

To remove executable permission on Windows and for all other systems, use Git command:

git update-index --chmod=-x /path/to/exe

Verify the change to executable permission by:

git status --porcelain=2

which will have output including:

1 M. N… 100644 100755 100755 … /path/to/exe

Measure joystick input lag on PC

Measuring controller / joystick input lag to a computer is not as trivial as one might think. We encourage at least skimming the references below, especially the Lagmeter readme to get background. In short, take a video camera or smartphone capable of 60 frames/second or faster and use an LED wired to the joystick input and video it and the computer display while pressing a button. Video display lag (put the monitor in “game mode” if available) and USB polling cadence are two of several significant factors in input lag. In difficult absolute measurement scenarios such as this, where so many confounding factors are present, a more useful metric may be relative delay measurements, for example wired vs. wireless controllers.

References:

curl build native Windows Schannel

curl is a universal command line tool for network data transfer. Build curl from source on Windows including native TLS support with Visual Studio and CMake. No external libraries are required for SSL using curl native Windows Schannel. The build is done “static” to avoid the hassle of DLL path.

From the Visual Studio Developer Command Prompt, clone the curl repo and build:

git clone https://github.com/curl/curl.git
cd curl

cmake -DCURL_USE_SCHANNEL=on -DBUILD_SHARED_LIBS=off -Bbuild

cmake --build build --config Release

Test the standalone “curl.exe” like:

build/src/Release/curl.exe -L https://hsts.badssl.com/

curl Schannel TLS 1.3 on Windows

We helped discover a curl bug when using native Schannel TLS 1.3 support on Windows for curl 7.85 and 7.86. The symptoms include that downloads may fail on Windows 11 with TLS 1.3 enabled on HTTPS or other TLS 1.3 server downloads. The bug is revealed when building curl on Windows using Schannel. We first observed this in CMake 3.25.0-rc3,rc4 that use vendored curl 7.86.

rclone for Google Drive and Dropbox

rclone seamlessly connects to remote cloud storage for cloud storage services including Google Shared Drive, Dropbox, Microsoft OneDrive and many more providers. The rclone CLI is easier than rsync. rclone works with encrypted filesystems.

Setup Rclone:

  • Linux: apt install rclone
  • macOS / Homebrew: brew install rclone
  • Windows: winget install Rclone.Rclone

Add various remote file shares (Google Drive, Dropbox, etc.) by:

rclone config

In these examples, remote is the particular drive name chosen during rclone config.

Tell the location of the Rclone config file by:

rclone config file

Rclone command examples

List remote directories:

rclone lsd remote:

List remote directories under path/to

rclone lsd remote:path/to

List remote files under path/to

rclone ls remote:path/to

Count number of files in path/to

rclone ls remote:path/to | wc -l

copy in rclone by default does not clobber existing remote files, if they haven’t been changed.

Recursively copy local computer ~/path to remote

rclone copy ~/path remote:path -v

Copy only this directory contents ~/path to remote

rclone copy --max-depth 0  ~/path remote:path -v

Using rclone sync requires caution, because sync DELETES files on remote that are not also on local PC!

Sync local computer ~/path to the remote

rclone sync ~/path remote:path -v

Dropbox

Why not use Dropbox’s unofficial dbxcli? At the time of writing, the last release was in 2019 with many unsolved issues.

Linux swap file

If too much swap space is filled, the system could become unusable until force-rebooted due to very slow hard drive (or SSD) I/O relative to RAM. It can be better to have the application terminated automatically due to running out of RAM instead of having the system become inaccessible until force-rebooted. There are disadvantages for no swap file.

If not using hibernation, 100 MB swap size is a general starting point for laptop, desktop and embedded systems. Consider the specific situation and test before deployment to avoid unexpected impacts. Setting swapfile size is only for systems using a swapfile versus a swap partition.

For systems using Dphys-swapfile such as Raspberry Pi, check swap status:

systemctl status dphys-swapfile

Persistently disable swap by:

systemctl stop dphys-swapfile
systemctl disable dphys-swapfile

User home path in Matlab, Octave, and Python

The tilde “~” character is used by most terminal shells as shorthand for the user home directory. The home directory is typically a safer place to write files than the system root directory, so ~ give a convenient way to refer to an absolute path generic across systems. Many code languages require parsing the tilde, including Python, C++, Fortran and Matlab. GNU Octave understands that ~ tilde is the user’s home directory on any operating system, even Windows. Matlab does not consistently understand ~ as the user home directory, particularly on Windows.

The stdlib for Matlab has a function stdlib.expanduser() that expands the tilde character ~ to the user home directory on all operating systems, including Windows.

stdlib.expanduser('~/Downloads/foo')
OS expanded
Linux /home/username/Downloads/foo
Windows C:/users/username/Downloads/foo
macOS /Users/username/Downloads/foo

Python paths starting with ~ need pathlib.Path(’~/mypath’).expanduser() method to expand the ~ into the user home directory.

import pathlib
pathlib.Path('~/Downloads/foo').expanduser()

Related: CMake expanduser

Matlab system() environment variables

Matlab system() discards the shell environment variables. Set environment variables in name-value pairs like:

if ispc
  system("echo %test_var%", test_var="hello")
else
  system("echo $test_var", test_var="hello")
end

Multiple environment variables can be set in a single command by adding more name-value pairs.

To set specific environment variables desired to set in the system command, do like this example for “CC”:

system("make", CC=getenv("CC"))

To set multiple environment variables:

env = namedargs2cell(struct(CC="gcc", CXX="g++"));

system("make", env{:});

For more advanced Python-like subprocess control from Matlab, use matlab-stdlib subprocess_run() that allows setting environment variables, cwd, stdin pipe, timeout, and more.

CMake environment variable scope

Environment variables in CMake set outside of CMake before a CMake process is started have global scope in CMake. Setting environment variables in a CMake script don’t have visibility outside the current CMake process. That includes CMake ExternalProject, which will NOT see environment variables set(ENV{name}) in the parent CMake project. Also, build and test processes will NOT see environment variables set in the CMake script.

To make environment variables take effect in a CMake script or CMake configure, set the environment variable before running CMake, or on a Unix-like OS on the command line. For example, to tell CMake the HDF5 library location, set environment variable HDF5_ROOT before the first CMake configure command:

# Unix-like
HDF5_ROOT=~/mylib cmake -Bbuild

# Windows PowerShell
$env:HDF5_ROOT="~/mylib"
cmake -B build

Of course, one could also set the CMake variable at configure like:

cmake -Bbuild -DHDF5_ROOT=~/mylib

To make environment variables present during a CMake build, for example for an ExternalProject, do as above for the configure.

To control environment variables present for CTest tests, including for individual tests, set test properties.