Compare commits
10 Commits
da023273d8
...
3738012c3e
Author | SHA1 | Date |
---|---|---|
Anne de Jong | 3738012c3e | |
Anne de Jong | a91640cd8d | |
Anne de Jong | 0bf621e45c | |
Anne de Jong | 1f7deca3fd | |
Anne de Jong | 1fb98412b2 | |
Anne de Jong | d50dd35745 | |
Anne de Jong | 1765042d20 | |
Anne de Jong | 46d1eda94d | |
Anne de Jong | 3005f17400 | |
Casper Jansen | 33439354f8 |
|
@ -115,7 +115,6 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto -mfpmath=sse -march=x86-64 -mtune=native
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall ")
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall ")
|
||||||
|
|
||||||
# ############################# End compilation flags
|
# ############################# End compilation flags
|
||||||
include_directories(/usr/lib/python3.10/site-packages/numpy/core/include)
|
|
||||||
|
|
||||||
# ####################################### End of user-adjustable variables section
|
# ####################################### End of user-adjustable variables section
|
||||||
include(OSSpecific)
|
include(OSSpecific)
|
||||||
|
|
64
README.md
64
README.md
|
@ -1,4 +1,5 @@
|
||||||
# Library for Acoustic Signal Processing
|
Library for Acoustic Signal Processing
|
||||||
|
======================================
|
||||||
|
|
||||||
|
|
||||||
Welcome to LASP: Library for Acoustic Signal Processing. LASP is a C++ library
|
Welcome to LASP: Library for Acoustic Signal Processing. LASP is a C++ library
|
||||||
|
@ -45,17 +46,14 @@ If you have any question(s), please feel free to contact us: [email](info@ascee.
|
||||||
|
|
||||||
# Installation - Linux (Ubuntu-based)
|
# Installation - Linux (Ubuntu-based)
|
||||||
|
|
||||||
## From wheel (recommended for non-developers)
|
## Prerequisites
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
Run the following on the command line to install all prerequisites on
|
Run the following on the command line to install all prerequisites on
|
||||||
Debian-based Linux:
|
Debian-based Linux:
|
||||||
|
|
||||||
- `sudo apt install python3-pip libfftw3-3 libopenblas-base libusb-1.0-0
|
- `sudo apt install python3-pip libfftw3-3 libopenblas-base libusb-1.0-0 libpulse0`
|
||||||
libpulse0`
|
|
||||||
|
|
||||||
### Download and install LASP
|
## Installation from wheel (recommended for non-developers)
|
||||||
|
|
||||||
Go to: [LASP releases](https://code.ascee.nl/ASCEE/lasp/releases/latest/) and
|
Go to: [LASP releases](https://code.ascee.nl/ASCEE/lasp/releases/latest/) and
|
||||||
download the latest `.whl`. Then run:
|
download the latest `.whl`. Then run:
|
||||||
|
@ -84,35 +82,43 @@ If building RtAudio with the Jack Audio Connection Kit (JACK) backend, you will
|
||||||
- `$ cd lasp`
|
- `$ cd lasp`
|
||||||
- `pip install -e .`
|
- `pip install -e .`
|
||||||
|
|
||||||
# Installation - (x86_64) Windows (with WinPython), build with MSYS2 (NOT YET UPDATED!!)
|
# Installation - (x86_64) Windows (with WinPython), build with MSYS2
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Download and install [WinPython](https://winpython.github.io)
|
- Download and install [WinPython](https://winpython.github.io)
|
||||||
|
|
||||||
|
## From wheel
|
||||||
|
|
||||||
|
- Download latest wheel from [LASP releases](https://code.ascee.nl/ASCEE/lasp/releases/latest/) and
|
||||||
|
download the latest `.whl`. Then install with `pip`.
|
||||||
|
|
||||||
|
## From source
|
||||||
|
|
||||||
- Download and install [MSYS2](https://msys2.org). Make sure to install the
|
- Download and install [MSYS2](https://msys2.org). Make sure to install the
|
||||||
x86_64 version.
|
x86_64 version.
|
||||||
- Download and install [Git for Windows](https://git-scm.com)
|
|
||||||
|
|
||||||
- When unzipping WinPython, make sure to choose a proper and simple path, i.e.
|
- When unzipping WinPython, make sure to choose a proper and simple path, i.e.
|
||||||
C:\winpython
|
C:\winpython
|
||||||
- Append C:\winpython\ to the PATH environment variable.
|
- Download and install [Git for Windows](https://git-scm.com)
|
||||||
- Run Python and install Pybind11
|
- Open an MSYS2 **MINGW64** terminal, and install some tools we require:
|
||||||
- `python -m pip install pybind11`
|
- `$ pacman -S git`
|
||||||
|
- Create a new virtualenv:
|
||||||
|
- `$ /c/winpython/<py-distr-dir>/python.exe -m venv venv`
|
||||||
- Open a msys2 **MINGW64** terminal. And run:
|
- Add the venv-python to the path (eases a lot of commands)
|
||||||
|
- `$ export PATH=$PATH:~/venv/Scripts`
|
||||||
- `pacman -S git`
|
- Install `build`:
|
||||||
|
- `$ pip install build`
|
||||||
- Then clone the LASP repo:
|
- Clone LASP:
|
||||||
|
- `$ git clone --recurse-submodules https://code.ascee.nl/ascee/lasp && cd lasp`
|
||||||
- `git clone https://code.ascee.nl/ascee/lasp`
|
- If run for the first time, we have to install the libraries we depend on in
|
||||||
- `cd lasp`
|
MSYS2 (this only has to be done on a fresh MSYS2 installation):
|
||||||
|
- `$ scripts/install_msys2_builddeps.sh`
|
||||||
- Configure MSYS2 further, and run cmake:
|
- Copy over required DLL's to be included in distribution:
|
||||||
|
- `scripts/copy_windows_dlls.sh`
|
||||||
- `scripts/install_msys2_buiddeps.sh`
|
- And... build!
|
||||||
- `scripts/configur_cmake_msys2.sh`
|
- `pyproject-build`
|
||||||
|
- Lastly: the generated wheel can be installed in the current virtualenv:
|
||||||
|
- `pip install dist/lasp*.whl`
|
||||||
|
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
@ -121,7 +127,7 @@ If building RtAudio with the Jack Audio Connection Kit (JACK) backend, you will
|
||||||
|
|
||||||
[Online LASP documentation](https://lasp.ascee.nl/).
|
[Online LASP documentation](https://lasp.ascee.nl/).
|
||||||
|
|
||||||
## In directory
|
## In directory (Linux/Debian)
|
||||||
|
|
||||||
`$ sudo apt install doxygen graphviz`
|
`$ sudo apt install doxygen graphviz`
|
||||||
`$ pip install doxypypy`
|
`$ pip install doxypypy`
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
if(LASP_HAS_PORTAUDIO)
|
if(LASP_HAS_PORTAUDIO)
|
||||||
message("Building with Portaudio backend")
|
message("Building with Portaudio backend")
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
set(PA_USE_ALSA FALSE CACHE BOOL "Build PortAudio with ALSA backend")
|
||||||
|
set(PA_USE_ASIO TRUE CACHE BOOL "Build PortAudio with ASIO backend")
|
||||||
|
set(PA_USE_DS FALSE CACHE BOOL "Build PortAudio with Directsound backend")
|
||||||
|
set(PA_USE_WMME FALSE CACHE BOOL "Build PortAudio with WMME backend")
|
||||||
|
set(PA_USE_WDMKS FALSE CACHE BOOL "Build PortAudio with WDMKS backend")
|
||||||
else()
|
else()
|
||||||
# Unix
|
# Unix
|
||||||
set(PA_USE_ALSA TRUE CACHE BOOL "Build PortAudio with ALSA backend")
|
set(PA_USE_ALSA TRUE CACHE BOOL "Build PortAudio with ALSA backend")
|
||||||
|
@ -9,7 +14,15 @@ if(LASP_HAS_PORTAUDIO)
|
||||||
set(PA_USE_PULSEAUDIO FALSE CACHE BOOL "Build PortAudio with PulseAudio backend")
|
set(PA_USE_PULSEAUDIO FALSE CACHE BOOL "Build PortAudio with PulseAudio backend")
|
||||||
set(PA_BUILD_SHARED_LIBS FALSE CACHE BOOL "Build static library")
|
set(PA_BUILD_SHARED_LIBS FALSE CACHE BOOL "Build static library")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(third_party/portaudio)
|
add_subdirectory(third_party/portaudio)
|
||||||
include_directories(third_party/portaudio/include)
|
include_directories(third_party/portaudio/include)
|
||||||
link_directories(third_party/portaudio)
|
link_directories(third_party/portaudio)
|
||||||
|
|
||||||
|
if(PA_USE_ALSA)
|
||||||
|
add_definitions(-DLASP_HAS_PA_ALSA=1)
|
||||||
|
else()
|
||||||
|
add_definitions(-DLASP_HAS_PA_ALSA=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -38,18 +38,26 @@ pybind11_add_module(lasp_cpp MODULE lasp_cpp.cpp
|
||||||
target_link_libraries(lasp_cpp PRIVATE lasp_device_lib lasp_dsp_lib
|
target_link_libraries(lasp_cpp PRIVATE lasp_device_lib lasp_dsp_lib
|
||||||
${OpenMP_CXX_LIBRARIES} ${LASP_FFT_LIBS} ${TARGET_OS_LINKLIBS})
|
${OpenMP_CXX_LIBRARIES} ${LASP_FFT_LIBS} ${TARGET_OS_LINKLIBS})
|
||||||
|
|
||||||
|
target_compile_definitions(lasp_cpp PRIVATE
|
||||||
|
MODULE_NAME=$<TARGET_FILE_BASE_NAME:lasp_cpp>
|
||||||
|
VERSION_INFO="${PY_FULL_VERSION}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Hide all symbols by default (including external libraries on Linux)
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
set_target_properties(lasp_cpp PROPERTIES
|
||||||
|
CXX_VISIBILITY_PRESET "hidden"
|
||||||
|
VISIBILITY_INLINES_HIDDEN true)
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
target_link_options(lasp_cpp PRIVATE "LINKER:--exclude-libs,ALL")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(DEFINED PY_BUILD_CMAKE_MODULE_NAME)
|
if(DEFINED PY_BUILD_CMAKE_MODULE_NAME)
|
||||||
# Install the Python module
|
# Install the Python module
|
||||||
install(TARGETS lasp_cpp
|
install(TARGETS lasp_cpp
|
||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
COMPONENT python_modules
|
COMPONENT python_modules
|
||||||
DESTINATION ${PY_BUILD_CMAKE_MODULE_NAME})
|
DESTINATION ${PY_BUILD_CMAKE_MODULE_NAME})
|
||||||
# Install the debug file for the Python module (Windows only)
|
|
||||||
if (WIN32)
|
|
||||||
install(FILES $<TARGET_PDB_FILE:_add_module>
|
|
||||||
EXCLUDE_FROM_ALL
|
|
||||||
COMPONENT python_modules
|
|
||||||
DESTINATION ${PY_BUILD_CMAKE_MODULE_NAME}
|
|
||||||
OPTIONAL)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
|
@ -75,7 +75,7 @@ StreamMgr::StreamMgr()
|
||||||
{
|
{
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
// Trigger a scan for the available devices, in the background.
|
// Trigger a scan for the available devices, in the background.
|
||||||
rescanDAQDevices(false);
|
rescanDAQDevices(true);
|
||||||
}
|
}
|
||||||
#if LASP_DEBUG == 1
|
#if LASP_DEBUG == 1
|
||||||
void StreamMgr::checkRightThread() const {
|
void StreamMgr::checkRightThread() const {
|
||||||
|
@ -107,13 +107,44 @@ void StreamMgr::rescanDAQDevices(bool background,
|
||||||
_pool.push_task(&StreamMgr::rescanDAQDevices_impl, this, callback);
|
_pool.push_task(&StreamMgr::rescanDAQDevices_impl, this, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if LASP_HAS_PORTAUDIO && LASP_HAS_PA_ALSA
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
void empty_handler(const char *file, int line, const char *function, int err,
|
||||||
|
const char *fmt, ...) {}
|
||||||
|
|
||||||
|
// Temporarily set the ALSA eror handler to something that does nothing, to
|
||||||
|
// prevent ALSA from spitting out all kinds of misconfiguration errors.
|
||||||
|
class MuteErrHandler {
|
||||||
|
private:
|
||||||
|
snd_lib_error_handler_t _default_handler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MuteErrHandler() {
|
||||||
|
_default_handler = snd_lib_error;
|
||||||
|
snd_lib_error_set_handler(empty_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MuteErrHandler() { snd_lib_error_set_handler(_default_handler); }
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
// Does nothin in case of no ALSA
|
||||||
|
class MuteErrHandler {};
|
||||||
|
#endif
|
||||||
|
|
||||||
void StreamMgr::rescanDAQDevices_impl(std::function<void()> callback) {
|
void StreamMgr::rescanDAQDevices_impl(std::function<void()> callback) {
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
|
assert(!_inputStream && !_outputStream);
|
||||||
Lck lck(_mtx);
|
Lck lck(_mtx);
|
||||||
_devices = DeviceInfo::getDeviceInfo();
|
// Alsa spits out annoying messages that are not useful
|
||||||
|
{
|
||||||
|
MuteErrHandler guard;
|
||||||
|
|
||||||
|
_devices = DeviceInfo::getDeviceInfo();
|
||||||
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
_scanningDevices = false;
|
_scanningDevices = false;
|
||||||
}
|
}
|
||||||
void StreamMgr::inCallback(const DaqData &data) {
|
void StreamMgr::inCallback(const DaqData &data) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ void fillPortAudioDeviceInfo(DeviceInfoList &devinfolist) {
|
||||||
d.api = portaudioALSAApi;
|
d.api = portaudioALSAApi;
|
||||||
break;
|
break;
|
||||||
case paASIO:
|
case paASIO:
|
||||||
|
hasDuplexMode = true;
|
||||||
d.api = portaudioASIOApi;
|
d.api = portaudioASIOApi;
|
||||||
break;
|
break;
|
||||||
case paDirectSound:
|
case paDirectSound:
|
||||||
|
|
|
@ -5,7 +5,7 @@ requires-python = ">=3.10"
|
||||||
description = "Library for Acoustic Signal Processing"
|
description = "Library for Acoustic Signal Processing"
|
||||||
license = { "file" = "LICENSE" }
|
license = { "file" = "LICENSE" }
|
||||||
authors = [{ "name" = "J.A. de Jong", "email" = "j.a.dejong@ascee.nl" }]
|
authors = [{ "name" = "J.A. de Jong", "email" = "j.a.dejong@ascee.nl" }]
|
||||||
version = "1.5.1"
|
version = "1.6.0"
|
||||||
|
|
||||||
keywords = ["DSP", "DAQ", "Signal processing"]
|
keywords = ["DSP", "DAQ", "Signal processing"]
|
||||||
|
|
||||||
|
@ -59,10 +59,3 @@ install_components = ["python_modules"]
|
||||||
# This might not work properly on Windows. Comment this out when testing on
|
# This might not work properly on Windows. Comment this out when testing on
|
||||||
# Windows.
|
# Windows.
|
||||||
mode = "symlink"
|
mode = "symlink"
|
||||||
|
|
||||||
[tool.commitizen]
|
|
||||||
name = "cz_conventional_commits"
|
|
||||||
tag_format = "v$version"
|
|
||||||
version_scheme = "semver"
|
|
||||||
version_provider = "pep621"
|
|
||||||
update_changelog_on_bump = true
|
|
||||||
|
|
|
@ -423,7 +423,7 @@ class Measurement:
|
||||||
# Try to find it in the dictionary of of open measurements
|
# Try to find it in the dictionary of of open measurements
|
||||||
if required_uuid in Measurement.uuid_s.keys():
|
if required_uuid in Measurement.uuid_s.keys():
|
||||||
m = Measurement.uuid_s[required_uuid]
|
m = Measurement.uuid_s[required_uuid]
|
||||||
logging.info(f'Returned reference measurement {m.name} from list of open measurements')
|
logging.debug(f'Returned reference measurement {m.name} from list of open measurements')
|
||||||
|
|
||||||
# Not found in list of openend measurements. See if we can open it using its last stored file name we know of
|
# Not found in list of openend measurements. See if we can open it using its last stored file name we know of
|
||||||
if m is None:
|
if m is None:
|
||||||
|
|
|
@ -3,7 +3,8 @@ Provides class MeasurementSet, a class used to perform checks and adjustments
|
||||||
on a group of measurements at the same time.
|
on a group of measurements at the same time.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__all__ = ['MeasurementSet']
|
|
||||||
|
__all__ = ["MeasurementSet"]
|
||||||
from .lasp_measurement import Measurement, MeasurementType
|
from .lasp_measurement import Measurement, MeasurementType
|
||||||
from typing import List
|
from typing import List
|
||||||
import time
|
import time
|
||||||
|
@ -16,7 +17,7 @@ class MeasurementSet(list):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, mlist: List[Measurement]=[]):
|
def __init__(self, mlist: List[Measurement] = []):
|
||||||
"""
|
"""
|
||||||
Initialize a measurement set
|
Initialize a measurement set
|
||||||
|
|
||||||
|
@ -25,8 +26,10 @@ class MeasurementSet(list):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if any([not isinstance(i, Measurement) for i in mlist]):
|
if any([not isinstance(i, Measurement) for i in mlist]):
|
||||||
raise TypeError('Object in list should be of Measurement type')
|
raise TypeError("Object in list should be of Measurement type")
|
||||||
|
|
||||||
|
# Sort by time stamp, otherwise the order is random
|
||||||
|
mlist.sort(key=lambda x: x.time, reverse=True)
|
||||||
super().__init__(mlist)
|
super().__init__(mlist)
|
||||||
|
|
||||||
def getNewestReferenceMeasurement(self, mtype: MeasurementType):
|
def getNewestReferenceMeasurement(self, mtype: MeasurementType):
|
||||||
|
@ -44,7 +47,19 @@ class MeasurementSet(list):
|
||||||
if mnewest.time < m.time:
|
if mnewest.time < m.time:
|
||||||
mnewest = m
|
mnewest = m
|
||||||
return mnewest
|
return mnewest
|
||||||
|
|
||||||
|
def getReferenceMeasurements(self, mtype: MeasurementType):
|
||||||
|
"""Get all available reference measurements of a certain type in the
|
||||||
|
current set.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mtype (MeasurementType): The type of which to list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
a new measurement set including all measurements of a certain type
|
||||||
|
"""
|
||||||
|
return [m for m in self if m.measurementType() == mtype]
|
||||||
|
|
||||||
def getNewestReferenceMeasurements(self):
|
def getNewestReferenceMeasurements(self):
|
||||||
"""Returns a dictionary with newest measurement of each type that is not specific returns None in case no measurement is found."""
|
"""Returns a dictionary with newest measurement of each type that is not specific returns None in case no measurement is found."""
|
||||||
newest = {}
|
newest = {}
|
||||||
|
@ -61,16 +76,15 @@ class MeasurementSet(list):
|
||||||
|
|
||||||
def newestReferenceOlderThan(self, secs):
|
def newestReferenceOlderThan(self, secs):
|
||||||
"""Returns a dictionary of references with the newest reference, that is still
|
"""Returns a dictionary of references with the newest reference, that is still
|
||||||
older than `secs` seconds. """
|
older than `secs` seconds."""
|
||||||
curtime = time.time()
|
curtime = time.time()
|
||||||
newest = self.getNewestReferenceMeasurements()
|
newest = self.getNewestReferenceMeasurements()
|
||||||
newest_older_than = {}
|
newest_older_than = {}
|
||||||
for key, m in newest.items():
|
for key, m in newest.items():
|
||||||
if curtime - m.time >= secs:
|
if curtime - m.time >= secs:
|
||||||
newest_older_than[key] = m
|
newest_older_than[key] = m
|
||||||
return newest_older_than
|
return newest_older_than
|
||||||
|
|
||||||
|
|
||||||
def measTimeSame(self):
|
def measTimeSame(self):
|
||||||
"""
|
"""
|
||||||
Returns True if all measurements have the same measurement
|
Returns True if all measurements have the same measurement
|
||||||
|
@ -106,4 +120,3 @@ class MeasurementSet(list):
|
||||||
return all([first == meas.channelConfig for meas in self])
|
return all([first == meas.channelConfig for meas in self])
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
cmake . -G"Ninja" -DLASP_HAS_ULDAQ=OFF -DPython3_ROOT_DIR=C:\\winpython\\python-3.10.9.amd64
|
arch=mingw64
|
||||||
arch=ucrt64
|
# DLL's that are required by lasp_cpp
|
||||||
#arch=mingw64
|
|
||||||
|
|
||||||
files_to_cpy="libfftw3-3.dll libgcc_s_seh-1.dll libgfortran-5.dll libgomp-1.dll libopenblas.dll libquadmath-0.dll libstdc++-6.dll libwinpthread-1.dll"
|
files_to_cpy="libfftw3-3.dll libgcc_s_seh-1.dll libgfortran-5.dll libgomp-1.dll libopenblas.dll libquadmath-0.dll libstdc++-6.dll libwinpthread-1.dll"
|
||||||
|
|
||||||
for fn in ${files_to_cpy}; do
|
for fn in ${files_to_cpy}; do
|
||||||
cp /c/msys64/${arch}/bin/${fn} src/lasp
|
cp /c/msys64/${arch}/bin/${fn} python_src/lasp
|
||||||
done
|
done
|
|
@ -5,8 +5,8 @@
|
||||||
if [ -z $CI ]; then
|
if [ -z $CI ]; then
|
||||||
PACMAN_OPTIONS="--needed --noconfirm"
|
PACMAN_OPTIONS="--needed --noconfirm"
|
||||||
fi
|
fi
|
||||||
# arch=mingw-w64-x86_64
|
arch=mingw-w64-x86_64
|
||||||
arch=mingw-w64-ucrt-x86_64
|
# arch=mingw-w64-ucrt-x86_64
|
||||||
|
|
||||||
pacman -S ${PACMAN_OPTIONS} make
|
pacman -S ${PACMAN_OPTIONS} make
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit daaf637f6f9fce670031221abfd7dfde92e5cce3
|
Subproject commit 88ab584e7bf4358599744cd662cfbc978f41efbf
|
Loading…
Reference in New Issue