From faec0f2acad1f61710284b1c04641a9ace4da8a5 Mon Sep 17 00:00:00 2001 From: Yifeng Li Date: Mon, 9 Dec 2024 00:03:08 +0000 Subject: [PATCH] CI: Add Continuous Integration. This Pull Request introduces Continuous Integration via GitHub Actions on multiple operating systems, including Debian, Debian oldstable, Debian oldoldstable, Fedora, AlmaLinux 8, AlmaLinux 9, and macOS on ARM. To ensure POSIX compatibility, Alpine Linux is tested due to its non-GNU C library, and FreeBSD is tested due to its non-Linux environment. For legacy compatibility, Ubuntu 14.04 and CentOS 7 is also tested (may be dropped in the future). Two simple simulation examples are also used as "smoketests" to ensure Octave and Python scripts can be executed without errors. The simulations are limited to 1000 timesteps, so they can finish almost immediately wihout wasting CPU time. Signed-off-by: Yifeng Li --- .github/smoketests/octave/MSL_NotchFilter.m | 81 +++ .github/smoketests/python/MSL_NotchFilter.py | 100 ++++ .github/workflows/ci.yml | 554 +++++++++++++++++++ 3 files changed, 735 insertions(+) create mode 100644 .github/smoketests/octave/MSL_NotchFilter.m create mode 100644 .github/smoketests/python/MSL_NotchFilter.py create mode 100644 .github/workflows/ci.yml diff --git a/.github/smoketests/octave/MSL_NotchFilter.m b/.github/smoketests/octave/MSL_NotchFilter.m new file mode 100644 index 0000000..73f6cd8 --- /dev/null +++ b/.github/smoketests/octave/MSL_NotchFilter.m @@ -0,0 +1,81 @@ +% +% Tutorials / MSL_NotchFilter +% +% Description at: +% http://openems.de/index.php/Tutorial:_Microstrip_Notch_Filter +% +% (C) 2011-2015 Thorsten Liebig + +close all +clear +clc + +%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +physical_constants; +unit = 1e-6; % specify everything in um +MSL_length = 50000; +MSL_width = 600; +substrate_thickness = 254; +substrate_epr = 3.66; +stub_length = 12e3; +f_max = 7e9; + +%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% It's only a smoke test, terminate as soon as possible, otherwise we waste +% CPU time on GitHub Actions (especially for emulated ARM64 systems). +FDTD = InitFDTD('NrTS', 1000); + +FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 ); +BC = {'PML_8' 'PML_8' 'MUR' 'MUR' 'PEC' 'MUR'}; +FDTD = SetBoundaryCond( FDTD, BC ); + +%% setup CSXCAD geometry & mesh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CSX = InitCSX(); +resolution = c0/(f_max*sqrt(substrate_epr))/unit /50; % resolution of lambda/50 +mesh.x = SmoothMeshLines( [0 MSL_width/2+[2*resolution/3 -resolution/3]/4], resolution/4, 1.5 ,0 ); +mesh.x = SmoothMeshLines( [-MSL_length -mesh.x mesh.x MSL_length], resolution, 1.5 ,0 ); +mesh.y = SmoothMeshLines( [0 MSL_width/2+[-resolution/3 +resolution/3*2]/4], resolution/4 , 1.5 ,0); +mesh.y = SmoothMeshLines( [-15*MSL_width -mesh.y mesh.y stub_length+[-resolution/3 +resolution/3*2]/4 15*MSL_width+stub_length], resolution, 1.3 ,0); +mesh.z = SmoothMeshLines( [linspace(0,substrate_thickness,5) 10*substrate_thickness], resolution ); +CSX = DefineRectGrid( CSX, unit, mesh ); + +%% substrate +CSX = AddMaterial( CSX, 'RO4350B' ); +CSX = SetMaterialProperty( CSX, 'RO4350B', 'Epsilon', substrate_epr ); +start = [mesh.x(1), mesh.y(1), 0]; +stop = [mesh.x(end), mesh.y(end), substrate_thickness]; +CSX = AddBox( CSX, 'RO4350B', 0, start, stop ); + +%% MSL port +CSX = AddMetal( CSX, 'PEC' ); +portstart = [ mesh.x(1), -MSL_width/2, substrate_thickness]; +portstop = [ 0, MSL_width/2, 0]; +[CSX,port{1}] = AddMSLPort( CSX, 999, 1, 'PEC', portstart, portstop, 0, [0 0 -1], 'ExcitePort', true, 'FeedShift', 10*resolution, 'MeasPlaneShift', MSL_length/3); + +portstart = [mesh.x(end), -MSL_width/2, substrate_thickness]; +portstop = [0 , MSL_width/2, 0]; +[CSX,port{2}] = AddMSLPort( CSX, 999, 2, 'PEC', portstart, portstop, 0, [0 0 -1], 'MeasPlaneShift', MSL_length/3 ); + +%% Filter-stub +start = [-MSL_width/2, MSL_width/2, substrate_thickness]; +stop = [ MSL_width/2, MSL_width/2+stub_length, substrate_thickness]; +CSX = AddBox( CSX, 'PEC', 999, start, stop ); + +%% write/show/run the openEMS compatible xml-file +Sim_Path = 'tmp'; +Sim_CSX = 'msl.xml'; + +[status, message, messageid] = rmdir( Sim_Path, 's' ); % clear previous directory +[status, message, messageid] = mkdir( Sim_Path ); % create empty simulation folder + +WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX ); +RunOpenEMS( Sim_Path, Sim_CSX ); + +%% post-processing +close all +f = linspace( 1e6, f_max, 1601 ); +port = calcPort( port, Sim_Path, f, 'RefImpedance', 50); + +s11 = port{1}.uf.ref./ port{1}.uf.inc; +s21 = port{2}.uf.ref./ port{1}.uf.inc; diff --git a/.github/smoketests/python/MSL_NotchFilter.py b/.github/smoketests/python/MSL_NotchFilter.py new file mode 100644 index 0000000..7e7d85f --- /dev/null +++ b/.github/smoketests/python/MSL_NotchFilter.py @@ -0,0 +1,100 @@ +""" + Microstrip Notch Filter Tutorial + (c) 2016-2023 Thorsten Liebig +""" + +### Import Libraries +import os, tempfile + +# Don't delete this line, we need to test if matplotlib can be imported, +# although it's never used. Incompatible binaries between system and +# PyPI can cause this, see: +# https://github.com/thliebig/openEMS/issues/165 +from pylab import * + +from CSXCAD import ContinuousStructure +from openEMS import openEMS +from openEMS.physical_constants import * + +### Setup the simulation +Sim_Path = os.path.join(tempfile.gettempdir(), 'NotchFilter') + +unit = 1e-6 # specify everything in um +MSL_length = 50000 +MSL_width = 600 +substrate_thickness = 254 +substrate_epr = 3.66 +stub_length = 12e3 +f_max = 7e9 + +### Setup FDTD parameters & excitation function + +# It's only a smoke test, terminate as soon as possible, otherwise we waste +# CPU time on GitHub Actions (especially for emulated ARM64 systems). +FDTD = openEMS(NrTS=1000) + +FDTD.SetGaussExcite( f_max/2, f_max/2 ) +FDTD.SetBoundaryCond( ['PML_8', 'PML_8', 'MUR', 'MUR', 'PEC', 'MUR'] ) + +### Setup Geometry & Mesh +CSX = ContinuousStructure() +FDTD.SetCSX(CSX) +mesh = CSX.GetGrid() +mesh.SetDeltaUnit(unit) + +resolution = C0/(f_max*sqrt(substrate_epr))/unit/50 # resolution of lambda/50 +third_mesh = array([2*resolution/3, -resolution/3])/4 + +## Do manual meshing +mesh.AddLine('x', 0) +mesh.AddLine('x', MSL_width/2+third_mesh) +mesh.AddLine('x', -MSL_width/2-third_mesh) +mesh.SmoothMeshLines('x', resolution/4) + +mesh.AddLine('x', [-MSL_length, MSL_length]) +mesh.SmoothMeshLines('x', resolution) + +mesh.AddLine('y', 0) +mesh.AddLine('y', MSL_width/2+third_mesh) +mesh.AddLine('y', -MSL_width/2-third_mesh) +mesh.SmoothMeshLines('y', resolution/4) + +mesh.AddLine('y', [-15*MSL_width, 15*MSL_width+stub_length]) +mesh.AddLine('y', (MSL_width/2+stub_length)+third_mesh) +mesh.SmoothMeshLines('y', resolution) + +mesh.AddLine('z', linspace(0,substrate_thickness,5)) +mesh.AddLine('z', 3000) +mesh.SmoothMeshLines('z', resolution) + +## Add the substrate +substrate = CSX.AddMaterial( 'RO4350B', epsilon=substrate_epr) +start = [-MSL_length, -15*MSL_width, 0] +stop = [+MSL_length, +15*MSL_width+stub_length, substrate_thickness] +substrate.AddBox(start, stop ) + +## MSL port setup +port = [None, None] +pec = CSX.AddMetal( 'PEC' ) +portstart = [ -MSL_length, -MSL_width/2, substrate_thickness] +portstop = [ 0, MSL_width/2, 0] +port[0] = FDTD.AddMSLPort( 1, pec, portstart, portstop, 'x', 'z', excite=-1, FeedShift=10*resolution, MeasPlaneShift=MSL_length/3, priority=10) + +portstart = [MSL_length, -MSL_width/2, substrate_thickness] +portstop = [0 , MSL_width/2, 0] +port[1] = FDTD.AddMSLPort( 2, pec, portstart, portstop, 'x', 'z', MeasPlaneShift=MSL_length/3, priority=10 ) + +## Filter-Stub Definition +start = [-MSL_width/2, MSL_width/2, substrate_thickness] +stop = [ MSL_width/2, MSL_width/2+stub_length, substrate_thickness] +pec.AddBox(start, stop, priority=10 ) + +FDTD.Run(Sim_Path, cleanup=True) + +### Post-processing +f = linspace( 1e6, f_max, 1601 ) +for p in port: + p.CalcPort( Sim_Path, f, ref_impedance = 50) + +s11 = port[0].uf_ref / port[0].uf_inc +s21 = port[1].uf_ref / port[0].uf_inc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a90a353 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,554 @@ +name: "CI" + +on: + push: + branches: ["master"] + pull_request: + branches: ["master"] + +jobs: + Linux: + runs-on: ubuntu-latest + defaults: + run: + shell: bash + + strategy: + matrix: + os: + # name: OS name (only a name for humans to read). + # libc: userland libc, "GNU" or "musl" + # (only a name for humans to read) + # ancient: true or false. + # true: incompatible with GitHub's actions/checkout due to + # node.js compatibility problem. Manual git checkout + # required. + # false: use standard GitHub's actions/checkout. + # docker-image: string, image on DockerHub to use + - name: "CentOS 7" + libc: "GNU" + ancient: true + docker-image: "centos:7" + + - name: "Ubuntu 14.04" + libc: "GNU" + ancient: true + docker-image: "ubuntu:14.04" + + - name: "Debian oldoldstable" + libc: "GNU" + ancient: false + docker-image: "debian:oldoldstable" + + - name: "Debian oldstable" + libc: "GNU" + ancient: false + docker-image: "debian:oldstable" + + - name: "Debian" + libc: "GNU" + ancient: false + docker-image: "debian:latest" + + - name: "Ubuntu" + libc: "GNU" + ancient: false + docker-image: "ubuntu:latest" + + - name: "Fedora" + libc: "GNU" + ancient: false + docker-image: "fedora:latest" + + - name: "AlmaLinux 8" + libc: "GNU" + ancient: false + docker-image: "almalinux:8" + + - name: "AlmaLinux Latest" + libc: "GNU" + ancient: false + docker-image: "almalinux:latest" + + - name: "Alpine" + libc: "musl" + ancient: false + docker-image: "alpine:latest" + + container: + image: ${{ matrix.os.docker-image }} + + name: "${{ matrix.os.libc }}/Linux (${{ matrix.os.name }})" + + steps: + - name: Check for dockerenv file + # bash is not installed on Alpine at this point + shell: sh + run: (ls /.dockerenv && echo Found dockerenv) || exit 1 + + - name: Install dependencies + shell: sh + run: | + cat /etc/os-release + + touch ~/.bash_profile + echo 'export CXXFLAGS="-std=c++11"' >> ~/.bash_profile + + if grep -q "ID=fedora" /etc/os-release; then + dnf install -y git + dnf install -y gcc gcc-c++ cmake git boost-devel tinyxml-devel vtk-devel hdf5-devel \ + CGAL-devel octave python3-Cython python3-h5py \ + python3-matplotlib + elif grep -q 'ID="almalinux"' /etc/os-release; then + dnf install -y epel-release + dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled crb + + dnf install -y git + dnf install -y gcc gcc-c++ cmake git boost-devel tinyxml-devel vtk-devel hdf5-devel \ + CGAL-devel octave python3-Cython python3-h5py \ + python3-matplotlib + elif grep -q "ID=debian" /etc/os-release || grep -q "ID=ubuntu" /etc/os-release; then + # retry failed downloads 3 times + echo 'Acquire::Retries "3";' > /etc/apt/apt.conf.d/80-retries + apt-get update + + apt-get install -y build-essential git \ + libhdf5-dev libtinyxml-dev \ + octave \ + python3-setuptools python3-numpy \ + python3-matplotlib python3-h5py + + # VTK9 or VTK7, at least one must succeed (depending on Debian version) + # VTK9, VTK7, or VTK6, at least one must succeed (depending on Debian version) + apt-get install -y libvtk9-dev || \ + apt-get install -y libvtk7-dev || \ + apt-get install -y libvtk6-dev + + if grep -q 'VERSION_ID="14.04"' /etc/os-release; then + # Ubuntu 14.04 has CMake 2 by default, but we require CMake 3 + apt-get install -y cmake3 + + # Ubuntu 14.04 ships Boost 1.54 and is required by libcgal-dev, + # but we need Boost 1.55, so we install Boost 1.55 first, then + # install CGAL from source. + apt-get install -y boost1.55 boost1.55-dev + + # CGAL v4.14.3 was old enough to be compatible with GCC 4.8. Otherwise, + # you get: The compiler feature "cxx_decltype_auto" is not known + # to CXX compiler "GNU" version 4.8.5. + apt-get install -y libgmp-dev libmpfr-dev + git clone $GITHUB_SERVER_URL/CGAL/cgal.git --depth=1 --branch=v4.14.3 + cd cgal && mkdir build && cd build + cmake ../ && make && make install + + # Ubuntu 14.04's cython3 package is ancient, install via pip instead + apt-get install -y python3-pip + + pip3 install cython + else + apt-get install -y libboost-all-dev + apt-get install -y libcgal-dev + apt-get install -y cmake + apt-get install -y cython3 + fi + elif grep -q "ID=alpine" /etc/os-release; then + apk add bash \ + build-base gmp-dev mpfr-dev git cmake \ + boost-dev tinyxml-dev hdf5-dev cgal-dev vtk-dev \ + octave \ + python3-dev cython \ + py3-setuptools \ + py3-matplotlib py3-numpy py3-h5py + elif [ -f /etc/centos-release ]; then + # IPv6 on GitHub Actions is broken, causing random network failures + # if a CDN rosolves to IPv6. + echo "ip_resolve=4" >> /etc/yum.conf + + # CentOS repos are EOL and desupported + sed -i 's|^mirrorlist|#mirrorlist|g; s|^#baseurl|baseurl|g; s|mirror.centos.org|vault.centos.org|g' \ + /etc/yum.repos.d/CentOS-Base.repo + + yum install -y centos-release-scl || true + sed -i 's|^mirrorlist|#mirrorlist|g; s|^#baseurl|baseurl|g; + s|^# baseurl|baseurl|g; s|mirror.centos.org|vault.centos.org|g' \ + /etc/yum.repos.d/CentOS-SCLo-scl.repo \ + /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo + cat /etc/yum.repos.d/CentOS-SCLo-scl.repo + cat /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo + + yum install -y epel-release + yum install -y git + yum install -y gcc gcc-c++ gmp-devel mpfr-devel \ + cmake3 git tinyxml-devel vtk-devel hdf5-devel \ + octave python3-pip python3-devel python3-Cython + + # use cmake3 instead of default cmake2 + alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 99 + + # To upgrade GCC, one can use GCC 7 from centos-release-scl, required by CGAL. + # Even GCC 10+ is provided. + # Not used for now, since openEMS is still compatible with GCC 4.8! But we may + # need it in the future. + # yum install -y devtoolset-7-gcc devtoolset-7-gcc-c++ + # alternatives --install /usr/local/bin/gcc gcc /opt/rh/devtoolset-7/root/usr/bin/gcc 99 + # alternatives --install /usr/local/bin/g++ g++ /opt/rh/devtoolset-7/root/usr/bin/g++ 99 + + # boost-predef is only available on Boost 1.55 and later. + # /usr/local/include/CGAL/config.h:210:10: fatal error: boost/predef.h: + # No such file or directory + # We borrow a copy of Boost 1.58 from rh repo's mariadb backport package. + yum install -y rh-mariadb101-boost-devel + + # copy rh repo's Boost to /usr/local because CMake doesn't support CPATH + ln -s /opt/rh/rh-mariadb101/root/usr/include/boost /usr/local/include/boost + mkdir /usr/local/lib64 && cd /usr/local/lib64 + for i in /opt/rh/rh-mariadb101/root/usr/lib64/libboost*; do + ln -s $i /usr/local/lib64/ + done + + # setup.py is broken on CentOS 7, installing openEMS shows: + # error: Couldn't find a setup script in /tmp/easy_install-8fl5smm_/numpy-2.2.0.tar.gz + # Error: Process completed with exit code 1. + pip3 install numpy h5py matplotlib --user + + # not package on CentOS + # CGAL v4.14.3 was old enough to be compatible with GCC 4.8. Otherwise, + # you get: The compiler feature "cxx_decltype_auto" is not known + # to CXX compiler "GNU" version 4.8.5. + git clone $GITHUB_SERVER_URL/CGAL/cgal.git --depth=1 --branch=v4.14.3 + cd cgal && mkdir build && cd build + cmake ../ && make && make install + else + echo "Unknown system!" + exit 1 + fi + + - if: ${{ ! matrix.os.ancient }} + name: Checkout openEMS.git + uses: actions/checkout@v4 + with: + path: openEMS + # checkout must be deep, not shallow. + # We need tags for "git describe", otherwise build fails. + fetch-depth: 0 + + - if: ${{ ! matrix.os.ancient }} + name: Checkout fparser.git + uses: actions/checkout@v4 + with: + repository: "${{ github.repository_owner }}/fparser" + path: fparser + + - if: ${{ ! matrix.os.ancient }} + name: Checkout CSXCAD.git + uses: actions/checkout@v4 + with: + repository: "${{ github.repository_owner }}/CSXCAD" + path: CSXCAD + # checkout must be deep, not shallow. + # We need tags for "git describe", otherwise build fails. + fetch-depth: 0 + + - if: ${{ matrix.os.ancient }} + name: Checkout openEMS.git (legacy system only) + run: | + git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git openEMS + cd $GITHUB_WORKSPACE/openEMS + + git fetch --force $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git "+refs/heads/*:refs/remotes/origin/*" + git fetch --force $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git "+refs/pull/*/merge:refs/remotes/origin/pr/*" + git checkout $GITHUB_SHA + + - if: ${{ matrix.os.ancient }} + name: Checkout fparser.git (legacy system only) + run: git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY_OWNER/fparser.git + + - if: ${{ matrix.os.ancient }} + name: Checkout CSXCAD.git (legacy system only) + run: git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY_OWNER/CSXCAD.git + + - name: Build and install fparser + run: | + source ~/.bash_profile + cd $GITHUB_WORKSPACE/fparser + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + - name: Build and install CSXCAD + run: | + # cmake may fail with "fatal: No names found, cannot describe anything." + # if it happens, check if you're using a shallow clone, or if it's a GitHub + # fork created with "Copy the master branch only". If so, you need to FULL + # fork or clone. + # + # MPI may also fail, but this error is not fatal. The real error is often + # the error above! There's no need to install MPI. + source ~/.bash_profile + cd $GITHUB_WORKSPACE/CSXCAD + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + - name: Build and install CSXCAD Python module + run: | + source ~/.bash_profile + cd $GITHUB_WORKSPACE/CSXCAD/python + python3 setup.py build_ext -I $HOME/opt/include -L $HOME/opt/lib -R $HOME/opt/lib + python3 setup.py install --user + + - name: Build and install openEMS + run: | + source ~/.bash_profile + + # Hack: openEMS requires Boost Predef (1.55+), but CSXCAD requires CGAL, on + # Ubuntu 14.04's libcgal-dev requires Boost 1.54. So we install Boost 1.55 + # after CSXCAD but before openEMS - this uninstalls libcgal-dev (but libcgal + # itself is okay) + if grep -q 'VERSION_ID="14.04"' /etc/os-release; then + apt-get install -y boost1.55-dev + apt-get install -y boost1.55 + fi + + cd $GITHUB_WORKSPACE/openEMS + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt -DFPARSER_ROOT_DIR=$HOME/opt + make -j`nproc` && make install + + echo "addpath('~/opt/share/openEMS/matlab')" >> ~/.octaverc + echo "addpath('~/opt/share/CSXCAD/matlab')" >> ~/.octaverc + + - name: Build and install openEMS Python module + run: | + source ~/.bash_profile + cd $GITHUB_WORKSPACE/openEMS/python + python3 setup.py build_ext -I $HOME/opt/include -L $HOME/opt/lib -R $HOME/opt/lib + python3 setup.py install --user + + - name: Smoketest Octave execution + run: | + cd $GITHUB_WORKSPACE/openEMS/.github/smoketests/octave + octave MSL_NotchFilter.m + + - name: Smoketest Python execution + run: | + source ~/.bash_profile + cd $GITHUB_WORKSPACE/openEMS/.github/smoketests/python + python3 MSL_NotchFilter.py + + macOS: + name: "macOS (ARM, latest)" + + runs-on: macos-latest + steps: + - name: Install dependencies + run: | + echo 'export CXXFLAGS="-std=c++11"' >> ~/.zprofile + + brew install cmake boost tinyxml hdf5 cgal vtk python3 octave + + # cython is keg-only, which means it was not symlinked into /opt/homebrew, + # because this formula is mainly used internally by other formulae. + # Users are advised to use `pip` to install cython. + # + # So Python will NOT be able to find cython from "site-package", nor + # will the shell finds a cython executable from "bin" + # + # But then, `pip` can't be used directly due to PEP 668, which asks us + # to install cython via the system's package manager, buh Howebrew does + # not provide a fully-function package (unless you hack the symlinks + # manually). + # + # So, the real solution is creating a virtualenv specifically for openEMS + # usage. + # + # TODO: completely update openEMS documentation and scripts to enable and + # teach users about virtualenv + python3 -m venv $HOME/opt + $HOME/opt/bin/pip3 install setuptools cython numpy h5py matplotlib + + - name: Checkout openEMS.git + uses: actions/checkout@v4 + with: + path: openEMS + # checkout must be deep, not shallow. + # We need tags for "git describe", otherwise build fails. + fetch-depth: 0 + + - name: Checkout fparser.git + uses: actions/checkout@v4 + with: + repository: "${{ github.repository_owner }}/fparser" + path: fparser + + - name: Checkout CSXCAD.git + uses: actions/checkout@v4 + with: + repository: "${{ github.repository_owner }}/CSXCAD" + path: CSXCAD + # checkout must be deep, not shallow. + # We need tags for "git describe", otherwise build fails. + fetch-depth: 0 + + - name: Build and install fparser + run: | + source ~/.zprofile + cd $GITHUB_WORKSPACE/fparser + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + - name: Build and install CSXCAD + run: | + # cmake may fail with "fatal: No names found, cannot describe anything." + # if it happens, check if you're using a shallow clone, or if it's a GitHub + # fork created with "Copy the master branch only". If so, you need to FULL + # fork or clone. + # + # MPI may also fail, but this error is not fatal. The real error is often + # the error above! There's no need to install MPI. + source ~/.zprofile + cd $GITHUB_WORKSPACE/CSXCAD + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + - name: Build and install CSXCAD Python module + run: | + source ~/.zprofile + cd $GITHUB_WORKSPACE/CSXCAD/python + $HOME/opt/bin/python3 setup.py build_ext -I $HOME/opt/include -L $HOME/opt/lib -R $HOME/opt/lib + $HOME/opt/bin/python3 setup.py install + + - name: Build and install openEMS + run: | + source ~/.zprofile + cd $GITHUB_WORKSPACE/openEMS + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt -DFPARSER_ROOT_DIR=$HOME/opt + make -j`nproc` && make install + + echo "addpath('~/opt/share/openEMS/matlab')" >> ~/.octaverc + echo "addpath('~/opt/share/CSXCAD/matlab')" >> ~/.octaverc + + - name: Build and install openEMS Python module + run: | + source ~/.zprofile + cd $GITHUB_WORKSPACE/openEMS/python + + $HOME/opt/bin/python3 setup.py build_ext \ + -I "$HOME/opt/include:/opt/homebrew/include" \ + -L "$HOME/opt/lib:/opt/homebrew/lib" \ + -R $HOME/opt/lib + $HOME/opt/bin/python3 setup.py install + + - name: Smoketest Octave execution + run: | + cd $GITHUB_WORKSPACE/openEMS/.github/smoketests/octave + octave MSL_NotchFilter.m + + - name: Smoketest Python execution + run: | + cd $GITHUB_WORKSPACE/openEMS/.github/smoketests/python + $HOME/opt/bin/python3 MSL_NotchFilter.py + + FreeBSD: + runs-on: ubuntu-latest + + strategy: + matrix: + machine: + - name: "FreeBSD 14.2" + os: freebsd + arch: x86-64 + version: '14.2' + + # macOS already tests ARM for us, so disable the slow ARM emulator + # for now + #- name: "FreeBSD 14.2 (ARM emulator)" + # os: freebsd + # arch: arm64 + # version: '14.2' + + name: "${{ matrix.machine.name }}" + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Test in FreeBSD ${{ matrix.machine.version }} ${{ matrix.machine.arch }} + uses: cross-platform-actions/action@v0.26.0 + with: + cpu_count: 4 + architecture: ${{ matrix.machine.arch }} + operating_system: ${{ matrix.machine.os }} + version: ${{ matrix.machine.version }} + run: | + echo "Install dependencies..." + sudo pkg install -y cmake git boost-libs tinyxml vtk9 hdf5 cgal octave python3 \ + py311-cython3 py311-numpy py311-h5py py311-matplotlib + # prefix must match FreeBSD's default python + # version. FreeBSD 14.2 uses Python 3.11 so + # use "py311-" + + echo "Clone repos..." + cd ~/ + git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git openEMS + + cd ~/openEMS + git fetch --force $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git "+refs/heads/*:refs/remotes/origin/*" + git fetch --force $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git "+refs/pull/*/merge:refs/remotes/origin/pr/*" + git checkout $GITHUB_SHA + + cd ~/ + git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY_OWNER/fparser.git + git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY_OWNER/CSXCAD.git + + echo "Build and install fparser..." + cd ~/fparser + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + echo "Build and install CSXCAD..." + # cmake may fail with "fatal: No names found, cannot describe anything." + # if it happens, check if you're using a shallow clone, or if it's a GitHub + # fork created with "Copy the master branch only". If so, you need to FULL + # fork or clone. + # + # MPI may also fail, but this error is not fatal. The real error is often + # the error above! There's no need to install MPI. + cd ~/CSXCAD + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt + make -j`nproc` && make install + + echo "Build and install CSXCAD Python module..." + cd ~/CSXCAD/python + python3 setup.py build_ext -I $HOME/opt/include -L $HOME/opt/lib -R $HOME/opt/lib + python3 setup.py install --user + + echo "Build and install openEMS..." + cd ~/openEMS + mkdir build && cd build + cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME/opt -DFPARSER_ROOT_DIR=$HOME/opt + make -j`nproc` && make install + + echo "addpath('~/opt/share/openEMS/matlab')" >> ~/.octaverc + echo "addpath('~/opt/share/CSXCAD/matlab')" >> ~/.octaverc + + echo "Build and install openEMS Python module..." + cd ~/openEMS/python + python3 setup.py build_ext \ + -I "$HOME/opt/include:/usr/local/include" \ + -L "$HOME/opt/lib:/usr/local/lib" \ + -R $HOME/opt/lib + python3 setup.py install --user + + echo "Smoketest Octave execution..." + cd ~/openEMS/.github/smoketests/octave/ + octave MSL_NotchFilter.m + + echo "Smoketest Python execution..." + cd ~/openEMS/.github/smoketests/python + python3 MSL_NotchFilter.py