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

Matlab cURL instead of websave

Matlab websave might not work in cases where a plain “curl” or “wget” command works. A symptom of this issue is HTML is downloaded instead of the intended binary file. Websites such as Dropbox recognize the HTTP User Agent of cURL and Wget and mutate the web server response to be automation-friendly. Since Matlab is much less commonly used than Python, cURL, Wget, etc. this user agent-dependent behavior results. We recommend understanding why Matlab websave doesn’t work, or use the low-level Matlab HTTP Interface.


If you truly need to use cURL from Matlab, recognize this may require unique setup for each system, despite that cURL is included (preinstalled) in modern operating systems including Windows.

The extra quotes around “url” allow for arbitrary characters to be used in the URL that can confuse shells like zsh. The “-L” option to cURL allows redirects.

function curlsave(filename, url)

cmd = "curl -L -o " + filename + " '" + url + "'";

assert(system(cmd) == 0, "download failed: " + url)

end

Linux systems with multiple cURL versions installed may need to set an environment variable to prioritize. Set the filename as appropriate for computer (ensure the file exists).

export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libcurl.so.4

Even this doesn’t always work, so we recommend understanding why Matlab websave doesn’t work, or use the low-level Matlab HTTP Interface.

Matlab with GitHub Actions CI

Matlab CI services include GitHub Actions. Matlab GitHub Actions CI is useful to automatically unit test Matlab code on each “git push” as with other coding languages. As with other GitHub Actions workflows, use a file like “.github/workflows/ci_matlab.yml” file in the Git repo to control CI behavior. A top-level file named like “TestAll.m” is also needed to control the CI run.

This Matlab .github/workflows/ci_matlab.yml will test a Matlab project on GitHub Actions CI at no cost. The top level TestAll.m is also necessary to discover and run the tests.

We have several projects using GitHub Actions with Matlab in this manner.

CMake generate Fortran from template

CMake configure_file can serve to generate source code files including Fortran. For templates beyond a few lines of code, it may be useful to read the template from a file. This requires setting CMake directory property CMAKE_CONFIGURE_DEPENDS to have CMake regenerate the file if the template file changes as in the example below.

file(READ my_template.in.f90 template_code)
configure_file(my.in.f90 my.f90 @ONLY)

set_directory_properties(PROPERTIES CMAKE_CONFIGURE_DEPENDS my_template.in.f90)

#example use
add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/my.f90)