3a0538b
# MUSIC depends on MPI for communication, so a non-MPI version is not being
3a0538b
# built.
3a0538b
# https://github.com/INCF/MUSIC/issues/55
3a0538b
a7318bc
# Fix for CC CXX
a7318bc
# https://lists.fedoraproject.org/archives/list/scitech@lists.fedoraproject.org/thread/BNKLXKY4O7BOTZ7LH7XDUTQO6FG2UWUT/
3a0538b
758fea8
%global commit 8c6b77a5780c0c66191aa7e8f07f9d33614dcc16
3a0538b
%global shortcommit %(c=%{commit}; echo ${c:0:7})
3a0538b
3a0538b
# For debugging
3a0538b
%bcond_without mpich
0b6c50e
%bcond_without openmpi
3a0538b
3a0538b
%global lname music
3a0538b
3a0538b
%global _description %{expand:
3a0538b
MUSIC is an API allowing large scale neuron simulators using MPI internally to
3a0538b
exchange data during runtime.  MUSIC provides mechanisms to transfer massive
3a0538b
amounts of event information and continuous values from one parallel
3a0538b
application to another.  Special care has been taken to ensure that existing
3a0538b
simulators can be adapted to MUSIC.  In particular, MUSIC handles data transfer
3a0538b
between applications that use different time steps and different data
3a0538b
allocation strategies.
3a0538b
3a0538b
This is the MUSIC pilot implementation.
3a0538b
3a0538b
The two most important components built from this software distribution is the
3a0538b
music library `libmusic.a' and the music utility `music'.  A MUSIC-aware
3a0538b
simulator links against the C++ library and can be launched using mpirun
3a0538b
together with the music utility as described below.  MUSIC can also be used
3a0538b
from a C program using the API in music-c.h.
3a0538b
3a0538b
MUSIC is distributed under the GNU General Public License v3.}
3a0538b
3a0538b
3a0538b
Name:           MUSIC
a7318bc
Version:        1.1.16
0b6c50e
Release:        5.20201002git%{shortcommit}%{?dist}
3a0538b
Summary:        The MUltiSimulation Coordinator
3a0538b
3a0538b
License:        GPLv3+
3a0538b
URL:            https://github.com/INCF/%{name}/
3a0538b
Source0:        https://github.com/INCF/%{name}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz
a7318bc
Patch0:         0001-Disable-sysguess.patch
a7318bc
Patch1:         0002-Enable-tests-and-extras.patch
a7318bc
Patch2:         0003-Make-python-bits-ourselves.patch
a7318bc
Patch3:         0004-Make-bundled-rudeconfig-also-follow-all-flags.patch
a7318bc
Patch4:         0005-Remove-src-flags.patch
3a0538b
3a0538b
# Bundled rudeconfig
3a0538b
Provides:       bundled(rudeconfig) = 5.0.5-1
3a0538b
758fea8
BuildRequires:  make
3a0538b
BuildRequires:  automake
3a0538b
BuildRequires:  autoconf
3a0538b
BuildRequires:  freeglut-devel
3a0538b
BuildRequires:  gcc-c++
3a0538b
BuildRequires:  libtool
3a0538b
BuildRequires:  patch
3a0538b
BuildRequires:  hwloc-devel
3a0538b
BuildRequires:  python3-devel
3a0538b
BuildRequires:  python3-Cython
3a0538b
# Currently bundles a modified version of rudeconfig which cannot be unbundled
3a0538b
# until MUSIC upstream sends their changes upstream to rudeconfig.
3a0538b
# https://github.com/INCF/MUSIC/issues/56
3a0538b
# BuildRequires:  rudeconfig-devel
3a0538b
3a0538b
%description %_description
3a0538b
3a0538b
%package common
3a0538b
Summary:    Architecture independent test and example files for %{name}
3a0538b
BuildArch:  noarch
3a0538b
3a0538b
%description common %_description
3a0538b
3a0538b
%if %{with mpich}
3a0538b
%package mpich
3a0538b
Summary:        %{name} built with mpich
3a0538b
BuildRequires:  mpich-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
Requires:       mpich
3a0538b
3a0538b
%description mpich %_description
3a0538b
3a0538b
%package mpich-devel
3a0538b
Summary:        %{name} built with mpich
3a0538b
BuildRequires:  mpich-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
Requires:       mpich
3a0538b
Requires:       %{name}-mpich%{?_isa} = %{version}-%{release}
3a0538b
3a0538b
%description mpich-devel
3a0538b
Development files for %{name} built with MPICH.
3a0538b
3a0538b
%package -n python3-%{name}-mpich
3a0538b
Summary:        Python3 support for %{name} built with mpich
3a0538b
BuildRequires:  mpich-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
BuildRequires:  python3-mpi4py-mpich
3a0538b
Requires:       python3-mpi4py-mpich
3a0538b
Requires:       mpich
3a0538b
Requires:       %{name}-mpich%{?_isa} = %{version}-%{release}
3a0538b
3a0538b
%description -n python3-%{name}-mpich %_description
3a0538b
%endif
3a0538b
3a0538b
%if %{with openmpi}
3a0538b
%package openmpi
3a0538b
Summary:        %{name} built with openmpi
3a0538b
BuildRequires:  openmpi-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
Requires:       openmpi
3a0538b
3a0538b
%description openmpi %_description
3a0538b
3a0538b
%package openmpi-devel
3a0538b
Summary:        %{name} built with openmpi
3a0538b
BuildRequires:  openmpi-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
Requires:       openmpi
3a0538b
Requires:       %{name}-openmpi%{?_isa} = %{version}-%{release}
3a0538b
3a0538b
%description openmpi-devel
3a0538b
Development files for %{name} built with MPICH.
3a0538b
3a0538b
%package -n python3-%{name}-openmpi
3a0538b
Summary:        Python3 support for %{name} built with openmpi
3a0538b
BuildRequires:  openmpi-devel
3a0538b
BuildRequires:  rpm-mpi-hooks
3a0538b
BuildRequires:  python3-mpi4py-openmpi
3a0538b
Requires:       python3-mpi4py-openmpi
3a0538b
Requires:       openmpi
3a0538b
Requires:       %{name}-openmpi%{?_isa} = %{version}-%{release}
3a0538b
3a0538b
%description -n python3-%{name}-openmpi %_description
3a0538b
%endif
3a0538b
3a0538b
%prep
3a0538b
%autosetup -c -n %{name}-%{commit} -N
3a0538b
# Unable to use autosetup directly because we need three copies of the source
3a0538b
# in here now
3a0538b
# Apply patches
3a0538b
pushd %{name}-%{commit}
a7318bc
%patch -p1 -P 0 1 2 3 4
3a0538b
# on Fedora, we have mpichversion, not mpich2version
3a0538b
sed -i 's|mpich2version|mpichversion|' configure.ac
3a0538b
popd
3a0538b
3a0538b
cp %{name}-%{commit}/LICENSE .
3a0538b
cp %{name}-%{commit}/README .
3a0538b
3a0538b
%if %{with mpich}
3a0538b
    cp -a %{name}-%{commit} %{name}-%{commit}-mpich
3a0538b
%endif
3a0538b
3a0538b
%if %{with openmpi}
3a0538b
    cp -a %{name}-%{commit} %{name}-%{commit}-openmpi
3a0538b
%endif
3a0538b
3a0538b
%build
3a0538b
3a0538b
%global do_build %{expand:
3a0538b
echo "** BUILDING $MPI_COMPILE_TYPE **"
3a0538b
pushd %{name}-%{commit}$MPI_COMPILE_TYPE
3a0538b
./autogen.sh &&
3a0538b
%{set_build_flags}
3a0538b
MPI_CXXFLAGS="$CXXFLAGS $(pkg-config --cflags $MPI_VARIANT)"
3a0538b
MPI_CFLAGS="$CFLAGS $(pkg-config --cflags $MPI_VARIANT)"
758fea8
MPI_LDFLAGS="$LDFLAGS $(pkg-config --libs $MPI_VARIANT | sed 's|-Lsystem/lib||')"
a7318bc
./configure LAUNCHSTYLE="_mpirun" SYSGUESS="$SYSGUESS" CXX=mpicxx CC=mpicc MPI_CXXFLAGS="$MPI_CXXFLAGS" MPI_CFLAGS="$MPI_CFLAGS" MPI_LDFLAGS="$MPI_LDFLAGS" PYTHON="$PYTHON_BIN" \\\
3a0538b
--disable-static \\\
3a0538b
--prefix=$MPI_HOME \\\
3a0538b
--libdir=$MPI_LIB \\\
3a0538b
--includedir=$MPI_INCLUDE \\\
3a0538b
--bindir=$MPI_BIN \\\
3a0538b
--mandir=$MPI_MAN
3a0538b
3a0538b
%make_build
3a0538b
3a0538b
# Make python bits ourselves
3a0538b
pushd pymusic
3a0538b
%{py3_build}
3a0538b
popd
3a0538b
3a0538b
popd
3a0538b
}
3a0538b
3a0538b
3a0538b
# Mpich
3a0538b
%if %{with mpich}
3a0538b
%{_mpich_load}
3a0538b
MPI_VARIANT="mpich"
a7318bc
SYSGUESS="mpich"
3a0538b
3a0538b
MPI_COMPILE_TYPE="-mpich"
3a0538b
PYTHON_VERSION=3
3a0538b
PYTHON_BIN="%{__python3}"
3a0538b
%{do_build}
3a0538b
3a0538b
%{_mpich_unload}
3a0538b
%endif
3a0538b
3a0538b
# Openmpi
3a0538b
%if %{with openmpi}
3a0538b
%{_openmpi_load}
3a0538b
MPI_VARIANT="ompi-cxx"
a7318bc
SYSGUESS="openmpi"
3a0538b
3a0538b
MPI_COMPILE_TYPE="-openmpi"
3a0538b
PYTHON_VERSION=3
3a0538b
PYTHON_BIN="%{__python3}"
3a0538b
%{do_build}
3a0538b
%{_openmpi_unload}
3a0538b
%endif
3a0538b
3a0538b
%install
3a0538b
%global do_install %{expand:
3a0538b
%make_install -C %{name}-%{commit}$MPI_COMPILE_TYPE
3a0538b
mv $RPM_BUILD_ROOT/$MPI_HOME/lib/%{lname}-%{version}/* $RPM_BUILD_ROOT/$MPI_BIN/ -v && rm -vrf $RPM_BUILD_ROOT/$MPI_HOME/lib/%{lname}-%{version}
3a0538b
for f in contsink eventcounter eventgenerator eventlogger eventselect eventsink eventsource messagesource music viewevents waveconsumer waveproducer clocksource constsource contdelay eventdelay launchtest multiport musicrun test_ag
3a0538b
do
3a0538b
    if [ -e  "$RPM_BUILD_ROOT/$MPI_BIN/$f" ]; then
3a0538b
        echo "Renaming $f"
3a0538b
        mv "$RPM_BUILD_ROOT/$MPI_BIN/$f" "$RPM_BUILD_ROOT/$MPI_BIN/$f$MPI_SUFFIX" -v
3a0538b
    fi
3a0538b
done
3a0538b
# Delete script for tests
3a0538b
rm -f "$RPM_BUILD_ROOT/$MPI_BIN/music_tests.sh"
3a0538b
3a0538b
# Install python bits
3a0538b
pushd %{name}-%{commit}$MPI_COMPILE_TYPE/pymusic
3a0538b
%{__python3} setup.py install --skip-build --root $RPM_BUILD_ROOT --install-lib=$MPI_PYTHON3_SITEARCH
3a0538b
popd
3a0538b
3a0538b
# Move other files to correct location also
3a0538b
mv -v "$RPM_BUILD_ROOT/$MPI_HOME/lib/python%{python3_version}/site-packages/music/config" "$RPM_BUILD_ROOT/$MPI_PYTHON3_SITEARCH/%{lname}/"
3a0538b
mv -v "$RPM_BUILD_ROOT/$MPI_HOME/%{_lib}/python%{python3_version}/site-packages/music/pymusic.so" "$RPM_BUILD_ROOT/$MPI_PYTHON3_SITEARCH/%{lname}"
3a0538b
mv -v "$RPM_BUILD_ROOT/$MPI_HOME/%{_lib}/python%{python3_version}/site-packages/music/pybuffer.so" "$RPM_BUILD_ROOT/$MPI_PYTHON3_SITEARCH/%{lname}"
3a0538b
3a0538b
# Delete the folders
3a0538b
rm -vrf "$RPM_BUILD_ROOT/$MPI_HOME/lib/python%{python3_version}/site-packages/music"
3a0538b
# If 64 bit, then we also need to delete this folder
7037d58
%if "%{_lib}" == "lib64"
3a0538b
    rm -vrf "$RPM_BUILD_ROOT/$MPI_HOME/%{_lib}/python%{python3_version}/site-packages/music"
3a0538b
%endif
3a0538b
}
3a0538b
3a0538b
3a0538b
# Mpich
3a0538b
%if %{with mpich}
3a0538b
%{_mpich_load}
3a0538b
MPI_COMPILE_TYPE="-mpich"
3a0538b
%{do_install}
3a0538b
%{_mpich_unload}
3a0538b
%endif
3a0538b
3a0538b
# Openmpi
3a0538b
%if %{with openmpi}
3a0538b
%{_openmpi_load}
3a0538b
MPI_COMPILE_TYPE="-openmpi"
3a0538b
%{do_install}
3a0538b
%{_openmpi_unload}
3a0538b
%endif
3a0538b
3a0538b
# Move arch independent examples and tests to datadir
3a0538b
%if %{with mpich} || %{with openmpi}
3a0538b
# Tests
3a0538b
install -m 0755 -d $RPM_BUILD_ROOT/%{_datadir}/%{lname}/
3a0538b
mv $RPM_BUILD_ROOT/%{_libdir}/mpich/share/%{lname}-%{version}/tests $RPM_BUILD_ROOT/%{_datadir}/%{lname}/ || exit 0
3a0538b
3a0538b
# Docs
3a0538b
install -m 0755 -d $RPM_BUILD_ROOT/%{_datadir}/doc/%{lname}/
3a0538b
mv $RPM_BUILD_ROOT/%{_libdir}/mpich/share/%{lname}-%{version}/examples $RPM_BUILD_ROOT/%{_datadir}/doc/%{lname}/ || exit 0
3a0538b
3a0538b
# Delete the folders
3a0538b
rm -vrf $RPM_BUILD_ROOT/%{_libdir}/mpich/share || exit 0
3a0538b
rm -vrff $RPM_BUILD_ROOT/%{_libdir}/openmpi/share || exit 0
3a0538b
%endif
3a0538b
3a0538b
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
3a0538b
3a0538b
3a0538b
%files common
3a0538b
%license LICENSE
3a0538b
%{_datadir}/%{lname}
3a0538b
%{_datadir}/doc/%{lname}
3a0538b
3a0538b
3a0538b
%if %{with mpich}
3a0538b
%files mpich
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_libdir}/mpich/bin/contsink_mpich
3a0538b
%{_libdir}/mpich/bin/eventcounter_mpich
3a0538b
%{_libdir}/mpich/bin/eventgenerator_mpich
3a0538b
%{_libdir}/mpich/bin/eventlogger_mpich
3a0538b
%{_libdir}/mpich/bin/eventselect_mpich
3a0538b
%{_libdir}/mpich/bin/eventsink_mpich
3a0538b
%{_libdir}/mpich/bin/eventsource_mpich
3a0538b
%{_libdir}/mpich/bin/messagesource_mpich
3a0538b
%{_libdir}/mpich/bin/music_mpich
3a0538b
%{_libdir}/mpich/bin/viewevents_mpich
3a0538b
%{_libdir}/mpich/bin/waveconsumer_mpich
3a0538b
%{_libdir}/mpich/bin/waveproducer_mpich
3a0538b
%{_libdir}/mpich/bin/constsource_mpich
3a0538b
%{_libdir}/mpich/bin/clocksource_mpich
3a0538b
%{_libdir}/mpich/bin/contdelay_mpich
3a0538b
%{_libdir}/mpich/bin/eventdelay_mpich
3a0538b
%{_libdir}/mpich/bin/launchtest_mpich
3a0538b
%{_libdir}/mpich/bin/multiport_mpich
3a0538b
%{_libdir}/mpich/bin/musicrun_mpich
3a0538b
%{_libdir}/mpich/bin/test_ag_mpich
a7318bc
%{_libdir}/mpich/bin/music_tests
3a0538b
%{_libdir}/mpich/lib/libmusic.so.1
3a0538b
%{_libdir}/mpich/lib/libmusic-c.so.1
3a0538b
%{_libdir}/mpich/lib/libmusic.so.1.0.0
3a0538b
%{_libdir}/mpich/lib/libmusic-c.so.1.0.0
3a0538b
%{_mandir}/mpich-%{_arch}/man1/*
3a0538b
3a0538b
%files mpich-devel
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_includedir}/mpich*/%{lname}
3a0538b
%{_includedir}/mpich*/%{lname}*.*
3a0538b
%{_includedir}/mpich*/predict_rank-c.h
3a0538b
%{_libdir}/mpich/lib/libmusic.so
3a0538b
%{_libdir}/mpich/lib/libmusic-c.so
3a0538b
3a0538b
%files -n python3-%{name}-mpich
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_libdir}/python%{python3_version}/site-packages/mpich/%{lname}
3a0538b
%{_libdir}/python%{python3_version}/site-packages/mpich/%{lname}-%{version}-py%{python3_version}.egg-info
3a0538b
%endif
3a0538b
3a0538b
%if %{with openmpi}
3a0538b
%files openmpi
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_libdir}/openmpi/bin/contsink_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventcounter_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventgenerator_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventlogger_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventselect_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventsink_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventsource_openmpi
3a0538b
%{_libdir}/openmpi/bin/messagesource_openmpi
3a0538b
%{_libdir}/openmpi/bin/music_openmpi
3a0538b
%{_libdir}/openmpi/bin/viewevents_openmpi
3a0538b
%{_libdir}/openmpi/bin/waveconsumer_openmpi
3a0538b
%{_libdir}/openmpi/bin/waveproducer_openmpi
3a0538b
%{_libdir}/openmpi/bin/constsource_openmpi
3a0538b
%{_libdir}/openmpi/bin/clocksource_openmpi
3a0538b
%{_libdir}/openmpi/bin/contdelay_openmpi
3a0538b
%{_libdir}/openmpi/bin/eventdelay_openmpi
3a0538b
%{_libdir}/openmpi/bin/launchtest_openmpi
3a0538b
%{_libdir}/openmpi/bin/multiport_openmpi
3a0538b
%{_libdir}/openmpi/bin/musicrun_openmpi
3a0538b
%{_libdir}/openmpi/bin/test_ag_openmpi
a7318bc
%{_libdir}/openmpi/bin/music_tests
3a0538b
%{_libdir}/openmpi/lib/libmusic.so.1
3a0538b
%{_libdir}/openmpi/lib/libmusic-c.so.1
3a0538b
%{_libdir}/openmpi/lib/libmusic.so.1.0.0
3a0538b
%{_libdir}/openmpi/lib/libmusic-c.so.1.0.0
3a0538b
%{_mandir}/openmpi-%{_arch}/man1/*
3a0538b
3a0538b
%files openmpi-devel
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_includedir}/openmpi*/%{lname}
3a0538b
%{_includedir}/openmpi*/%{lname}*.*
3a0538b
%{_includedir}/openmpi*/predict_rank-c.h
3a0538b
%{_libdir}/openmpi/lib/libmusic.so
3a0538b
%{_libdir}/openmpi/lib/libmusic-c.so
3a0538b
3a0538b
%files -n python3-%{name}-openmpi
3a0538b
%license LICENSE
3a0538b
%doc README
3a0538b
%{_libdir}/python%{python3_version}/site-packages/openmpi/%{lname}
3a0538b
%{_libdir}/python%{python3_version}/site-packages/openmpi/%{lname}-%{version}-py%{python3_version}.egg-info
3a0538b
%endif
3a0538b
3a0538b
%changelog
0b6c50e
* Sun Jul 04 2021 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.16-5.20210507git8c6b77a
0b6c50e
- Re-enable openmpi builds (disabled by mistake!)
0b6c50e
758fea8
* Sat Jul 03 2021 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.16-4.20210507git8c6b77a
758fea8
- Update to latest upstream commit
758fea8
9d21b87
* Fri Jun 04 2021 Python Maint <python-maint@redhat.com> - 1.1.16-3.20201002git262f6f5
9d21b87
- Rebuilt for Python 3.10
9d21b87
05ce3c0
* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.16-2.20201002git262f6f5
05ce3c0
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
05ce3c0
a7318bc
* Fri Oct 02 2020 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.16-1.20201002git262f6f5
a7318bc
- Update to latest commit
a7318bc
508e838
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.15-8.20190717gita78a8e2
508e838
- Second attempt - Rebuilt for
508e838
  https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
508e838
4982f02
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.15-7.20190717gita78a8e2
4982f02
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
4982f02
c179c6a
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 1.1.15-6.20190717gita78a8e2
c179c6a
- Rebuilt for Python 3.9
c179c6a
65feef7
* Thu Apr 02 2020 Björn Esser <besser82@fedoraproject.org> - 1.1.15-5.20190717gita78a8e2
65feef7
- Fix string quoting for rpm >= 4.16
65feef7
d1a18b6
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.1.15-4.20190717gita78a8e2
d1a18b6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
d1a18b6
3a0538b
* Tue Oct 15 2019 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.15-3.20190717git78a8e2
3a0538b
- Add bundled provides
3a0538b
- Remove ldconfig scriptlets
3a0538b
- Move arch independent bits to _datadir in separate sub-package
3a0538b
3a0538b
* Mon Sep 09 2019 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.15-2.20190717git78a8e2
3a0538b
- Add hwloc dep
3a0538b
3a0538b
* Fri Jul 19 2019 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 1.1.15-2.20190717gita78a8e2
3a0538b
- Build python ourselves
3a0538b
- Bundle rudeconfig
3a0538b
- Remove python 2 subpackage
3a0538b
3a0538b
* Sat Oct 20 2018 Ankur Sinha <ankursinha AT fedoraproject DOT org> - 0-1.20181020gita77e5787
3a0538b
- Depend on packaged rudeconfig
3a0538b
- Remove non MPI packages
3a0538b
- Use macros
3a0538b
- Put common files into separate sub package
3a0538b
- Correct autosetup usage
3a0538b
- Initial build