diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index ec1e094..e1a8267 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -2,24 +2,108 @@ name: build on: push: - branches: [ master ] + branches: [ master, meson ] pull_request: branches: [ master ] jobs: - build: - + ubuntu-build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install libraries - run: sudo apt-get install libsndfile1-dev libliquid-dev - - name: autoreconf - run: ./autogen.sh - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check + - uses: actions/checkout@v4 + - name: Install dependencies (apt) + run: sudo apt install python3-pip ninja-build libsndfile1-dev libliquid-dev + - name: Install meson (pip3) + run: pip3 install --user meson + - name: meson setup + run: meson setup build + - name: compile + run: cd build && meson compile + + macos-build: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + - name: Install dependencies (brew) + run: brew install meson libsndfile liquid-dsp + - name: meson setup + run: meson setup build + - name: compile + run: cd build && meson compile + + windows-msys2-mingw-build: + runs-on: windows-latest + + steps: + - uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + autoconf + automake + git + make + mingw-w64-x86_64-gcc + mingw-w64-x86_64-libiconv + mingw-w64-x86_64-libsndfile + mingw-w64-x86_64-meson + mingw-w64-x86_64-python3 + - name: Patch & build liquid-dsp + shell: msys2 {0} + run: | + git clone https://github.com/jgaeddert/liquid-dsp.git && cd liquid-dsp + perl -i -p -e 's/(AC_CHECK_LIB\(\[c\].+| sys\/resource.h)//g' configure.ac + ./bootstrap.sh && ./configure --prefix=/mingw64 && make + make install + - uses: actions/checkout@v4 + - name: Build redsea + shell: msys2 {0} + run: | + meson setup build && cd build && meson compile + - name: Package into distrib + shell: msys2 {0} + run: >- + mkdir -p distrib && cp build/redsea.exe distrib/ && + ldd build/redsea.exe | + grep -iv windows | + grep -iv system32 | + grep -v :$ | + cut -f2 -d\> | + cut -f1 -d\( | + wk '{$1=$1};1' | + xargs -I{} cp {} distrib/ + + windows-cygwin-build: + runs-on: windows-latest + + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v4 + - uses: cygwin/cygwin-install-action@v4 + with: + packages: >- + autoconf + automake + bzip2 + gcc-core + gcc-g++ + git + libiconv-devel + libsndfile-devel + make + meson + patch + perl + tar + xz + - name: Build liquid-dsp + shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}' + run: git clone https://github.com/jgaeddert/liquid-dsp.git && cd liquid-dsp && ./bootstrap.sh && ./configure --prefix=/usr && make && make install + - name: Patch liquid-dsp + shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}' + run: perl -i -p -e 's/(?<=\s)(_[A-Z])(?=[,\)])/\L\1__/g' /usr/include/liquid/liquid.h + - name: Build redsea + shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}' + run: meson setup build && cd build && meson compile diff --git a/CHANGES.md b/CHANGES.md index bb273ee..72e9a1d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,9 @@ ## HEAD +* Migrate build system from autotools to meson (#90) +* Add GitHub Workflows CI builds for macOS and Windows (MSYS2/MinGW + Cygwin) +* Remove unmaintained build options for non-liquid, non-TMC builds * Add support for enhanced RadioText (eRT) * Add support for Long PS in Group 15A * Fix detection of invalid date/time (timestamps >2000 years ago) diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index c6231c2..0000000 --- a/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -SUBDIRS = src -dist_doc_DATA = README.md diff --git a/README.md b/README.md index 4ec7a4c..2a319f9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ supports a large [subset of RDS features][Wiki: Features]. [![release](https://img.shields.io/github/release/windytan/redsea.svg)](https://github.com/windytan/redsea/releases/latest) ![build](https://github.com/windytan/redsea/workflows/build/badge.svg) -Decoded RDS groups are printed to the terminal as [line-delimited JSON][https://jsonlines.org/] objects +Decoded RDS groups are printed to the terminal as [line-delimited JSON](https://jsonlines.org/) objects or, optionally, undecoded hex blocks (`-x`). Please refer to the wiki for [input data formats][Wiki: Input]. @@ -50,11 +50,12 @@ beginning. 1. Install the prerequisites. On Ubuntu: - $ sudo apt install git build-essential autoconf libsndfile1-dev libliquid-dev + $ sudo apt install git ninja-build build-essential python3-pip libsndfile1-dev libliquid-dev + $ pip3 install --user meson -Or on macOS (OSX) using Homebrew: +Or on macOS using Homebrew: - $ brew install autoconf automake libsndfile liquid-dsp + $ brew install meson libsndfile liquid-dsp $ xcode-select --install 2. Clone the repository (unless you downloaded a release zip file): @@ -64,23 +65,12 @@ Or on macOS (OSX) using Homebrew: 3. Compile redsea: - $ ./autogen.sh && ./configure && make - -4. Install: - - $ make install + $ meson setup build && cd build && meson compile How to later get the latest updates and recompile: $ git pull - $ ./autogen.sh && ./configure && make clean && make - $ make install - -For a slower machine it can take some time to compile the TMC support. This can -be disabled (`./configure --disable-tmc`). - -If you only need to decode hex or binary input and don't need demodulation, -you can compile redsea without liquid-dsp (`./configure --without-liquid`). + $ cd build && meson compile [liquid-dsp]: https://github.com/jgaeddert/liquid-dsp/releases/tag/v1.3.2 @@ -174,7 +164,7 @@ type: * For realtime decoding, a Raspberry Pi 1 or faster * ~8 MB of free memory (~128 MB for RDS-TMC) * C++14 compiler -* GNU autotools +* meson + ninja (for building) * libiconv 1.16 * libsndfile 1.0.31 * [liquid-dsp][liquid-dsp] release 1.3.2 @@ -185,7 +175,7 @@ type: ### Can't find liquid-dsp on macOS -If you've installed [liquid-dsp][liquid-dsp] yet `configure` can't find it, it's +If you've installed [liquid-dsp][liquid-dsp] yet meson can't find it, it's possible that XCode command line tools aren't installed. Run this command to fix it: diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 6976ccd..0000000 --- a/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -autoreconf --install || exit 1 diff --git a/configure.ac b/configure.ac deleted file mode 100644 index ba63365..0000000 --- a/configure.ac +++ /dev/null @@ -1,91 +0,0 @@ -AC_PREREQ([2.69]) -AC_INIT([redsea], [0.22-SNAPSHOT], [oona@kapsi.fi], [redsea], - [https://github.com/windytan/redsea]) -AM_INIT_AUTOMAKE([1.10 -Wall -Werror foreign subdir-objects]) -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([ - Makefile - src/Makefile -]) - -AC_ARG_WITH([liquid], - [AS_HELP_STRING([--without-liquid], - [disable support for demodulation using liquid-dsp])]) - -AC_ARG_WITH([macports], - [AS_HELP_STRING([--without-macports], - [disable check for MacPorts directories when compiling])]) - -AC_ARG_ENABLE([tmc], - [AS_HELP_STRING([--disable-tmc], - [disable support for Traffic Message Channel (TMC)])]) - -AS_IF([test "x$enable_tmc" != xno], - [AC_DEFINE([ENABLE_TMC], [1], - [Define to compile TMC]) - ]) - -LIQUID= -AS_IF([test "x$with_liquid" != xno], - [AC_CHECK_LIB([liquid], [symtrack_cccf_create], - [AC_SUBST([LIQUID], ["-lliquid"]) - AC_DEFINE([HAVE_LIQUID], [1], - [Define if you have liquid]) - ], - [AC_MSG_FAILURE( - [Could not find liquid-dsp (use --without-liquid to disable)])])]) - -AS_IF([test "x$with_liquid" != xno], - [AC_CHECK_LIB([liquid], [modemcf], - [AC_DEFINE([MODEM_IS_MODEMCF], [1], - [modem is called modemcf])])]) - -MACPORTS_LD= -AS_IF([test "x$with_macports" != xno], - [AC_CHECK_FILE(/opt/local/lib, - [AC_SUBST([MACPORTS_LD], ["-L/opt/local/lib"])])]) - -MACPORTS_CF= -AS_IF([test "x$with_macports" != xno], - [AC_CHECK_FILE(/opt/local/lib, - [AC_SUBST([MACPORTS_CF], ["-I/opt/local/include"])])]) - -AC_CHECK_LIB([sndfile], [main], - [AC_SUBST([SNDFILE], ["-lsndfile"]) - AC_DEFINE([HAVE_SNDFILE], [1], - [Define if you have libsndfile]) - ], - [AC_MSG_FAILURE( - [Could not find libsndfile])]) - -WIN_CF= -LIBC= - -AC_MSG_CHECKING([whether compiling for Windows]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#if !defined(_WIN32) && !defined(_WIN64) -#error not compiling for Windows -#endif -]])], - # Windows - [AC_MSG_RESULT([yes]); AC_SUBST([WIN_CF], ["-D_USE_MATH_DEFINES=1"])], - # Unix - [AC_MSG_RESULT([no]); AC_SUBST([LIBC], ["-lc"])]) - -CPP_STD=c++14 -AC_CANONICAL_HOST -case "${host_os}" in - darwin*|msys*|mingw*) - AC_SUBST([ICONV], ["-liconv"]) - ;; - cygwin*) - AC_SUBST([ICONV], ["-liconv"]) - AC_SUBST([CPP_STD], ["gnu++14"]) - ;; -esac - -AC_PROG_CXX -AC_PROG_RANLIB -AC_LANG([C++]) - -AC_OUTPUT diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..33c2617 --- /dev/null +++ b/meson.build @@ -0,0 +1,68 @@ +project('redsea', 'cpp', default_options : ['cpp_std=c++14', 'warning_level=3', 'buildtype=release'], + version: '0.22-SNAPSHOT') + +# Store version number to be compiled in +conf = configuration_data() +conf.set_quoted('VERSION', meson.project_version()) +configure_file(output : 'config.h', + configuration : conf) + +### Compiler options ### + +cc = meson.get_compiler('cpp') +add_project_arguments(cc.get_supported_arguments([ + '-Wno-unknown-pragmas']), language: 'cpp') + +if get_option('buildtype') == 'release' + add_project_arguments('-O3', language : 'cpp') +endif + +### Dependencies ### + +iconv = dependency('iconv') +sndfile = dependency('sndfile') + +# Detecting liquid-dsp in a portable fashion +if build_machine.system() == 'darwin' + fs = import('fs') + # Homebrew system + if fs.is_dir('/opt/homebrew/lib') + liquid_lib = cc.find_library('liquid', + dirs : ['/opt/homebrew/lib']) + liquid_inc = include_directories('/opt/homebrew/include') + # MacPorts system + else + liquid_lib = cc.find_library('liquid', + dirs : ['/opt/local/lib']) + liquid_inc = include_directories('/opt/local/include') + endif + liquid = declare_dependency(dependencies : liquid_lib, + include_directories : liquid_inc) +else + liquid = cc.find_library('liquid') +endif + +# M_PI +if build_machine.system() == 'windows' + add_project_arguments('-D_USE_MATH_DEFINES=1', language : 'cpp') +endif + +sources = [ + 'ext/json/jsoncpp.cpp', + 'src/block_sync.cc', + 'src/channel.cc', + 'src/common.cc', + 'src/groups.cc', + 'src/input.cc', + 'src/liquid_wrappers.cc', + 'src/options.cc', + 'src/rdsstring.cc', + 'src/redsea.cc', + 'src/subcarrier.cc', + 'src/tables.cc', + 'src/tmc/tmc.cc', + 'src/tmc/locationdb.cc', + 'src/util.cc' +] + +executable('redsea', sources, dependencies: [iconv, sndfile, liquid]) diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 497846d..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -bin_PROGRAMS = redsea -redsea_CPPFLAGS = -std=$(CPP_STD) -Wall -Wextra -Wstrict-overflow -Wshadow -Wdouble-promotion \ - -Wundef -Wpointer-arith -Wcast-align -Wcast-qual -Wuninitialized -pedantic \ - -Wno-deprecated-declarations \ - $(MACPORTS_CF) $(RFLAGS) $(WIN_CF) -redsea_LDADD = $(MACPORTS_LD) $(LIBC) $(LIQUID) $(ICONV) $(SNDFILE) -redsea_SOURCES = redsea.cc common.cc input.cc subcarrier.cc block_sync.cc groups.cc \ - tables.cc rdsstring.cc tmc/tmc.cc tmc/locationdb.cc util.cc \ - channel.cc options.cc liquid_wrappers.cc ../ext/json/jsoncpp.cpp diff --git a/src/block_sync.h b/src/block_sync.h index 76e9518..f0435a0 100644 --- a/src/block_sync.h +++ b/src/block_sync.h @@ -20,7 +20,6 @@ #include #include -#include "config.h" #include "src/groups.h" #include "src/options.h" diff --git a/src/channel.h b/src/channel.h index ff8957d..398a164 100644 --- a/src/channel.h +++ b/src/channel.h @@ -17,8 +17,6 @@ #ifndef CHANNEL_H_ #define CHANNEL_H_ -#include "config.h" - #include "src/block_sync.h" #include "src/common.h" #include "src/options.h" diff --git a/src/groups.cc b/src/groups.cc index 7c5f797..f2ec48a 100644 --- a/src/groups.cc +++ b/src/groups.cc @@ -221,11 +221,7 @@ Station::Station() : Station(0x0000, Options(), 0) { } Station::Station(uint16_t _pi, const Options& options, int which_channel, bool has_pi) : - pi_(_pi), has_pi_(has_pi), options_(options), which_channel_(which_channel) -#ifdef ENABLE_TMC - , tmc_(options) -#endif -{ + pi_(_pi), has_pi_(has_pi), options_(options), which_channel_(which_channel), tmc_(options) { writer_builder_["indentation"] = ""; writer_builder_["precision"] = 7; writer_builder_.settings_["emitUTF8"] = true; @@ -323,12 +319,9 @@ void Station::updateAndPrint(const Group& group, std::ostream* stream) { } else if (type.number == 7 && type.version == GroupType::Version::A) { decodeType7A(group); } else if (type.number == 8 && type.version == GroupType::Version::A) { -#ifdef ENABLE_TMC - if (group.has(BLOCK2) && group.has(BLOCK3) && group.has(BLOCK4)) tmc_.receiveUserGroup(getBits<5>(group.getBlock2(), 0), group.getBlock3(), group.getBlock4(), &json_); -#endif } else if (type.number == 9 && type.version == GroupType::Version::A) { decodeType9A(group); @@ -666,11 +659,7 @@ void Station::decodeType3A(const Group& group) { // RDS-TMC case 0xCD46: case 0xCD47: -#ifdef ENABLE_TMC tmc_.receiveSystemGroup(oda_message, &json_); -#else - json_["debug"].append("redsea compiled without TMC support"); -#endif break; default: @@ -1024,11 +1013,9 @@ void Station::decodeODAGroup(const Group& group) { // RDS-TMC case 0xCD46: case 0xCD47: -#ifdef ENABLE_TMC if (group.has(BLOCK2) && group.has(BLOCK3) && group.has(BLOCK4)) tmc_.receiveUserGroup(getBits<5>(group.getBlock2(), 0), group.getBlock3(), group.getBlock4(), &json_); -#endif break; default: diff --git a/src/groups.h b/src/groups.h index 355be25..17aa244 100644 --- a/src/groups.h +++ b/src/groups.h @@ -28,7 +28,6 @@ #include -#include "config.h" #include "src/common.h" #include "src/options.h" #include "src/rdsstring.h" @@ -250,9 +249,7 @@ class Station { std::unique_ptr writer_; Json::Value json_; -#ifdef ENABLE_TMC tmc::TMCService tmc_; -#endif }; void parseRadioTextPlus(const Group& group, RadioText& rt, Json::Value& json_el); diff --git a/src/input.h b/src/input.h index e8c70bc..ae4a2b3 100644 --- a/src/input.h +++ b/src/input.h @@ -22,8 +22,6 @@ #include #include -#include "config.h" - #include #include "src/common.h" diff --git a/src/liquid_wrappers.cc b/src/liquid_wrappers.cc index 39776df..aa31fab 100644 --- a/src/liquid_wrappers.cc +++ b/src/liquid_wrappers.cc @@ -16,14 +16,12 @@ */ #include "src/liquid_wrappers.h" -#include "config.h" -#ifdef HAVE_LIQUID - #include #include -// https://github.com/jgaeddert/liquid-dsp/issues/229 #pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +// https://github.com/jgaeddert/liquid-dsp/issues/229 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage" extern "C" { #include "liquid/liquid.h" @@ -195,5 +193,3 @@ unsigned int Resampler::execute(float in, } } // namespace liquid - -#endif diff --git a/src/liquid_wrappers.h b/src/liquid_wrappers.h index 309161e..f01ff4e 100644 --- a/src/liquid_wrappers.h +++ b/src/liquid_wrappers.h @@ -17,15 +17,13 @@ #ifndef LIQUID_WRAPPERS_H_ #define LIQUID_WRAPPERS_H_ -#include "config.h" -#ifdef HAVE_LIQUID - #include #include #include -// https://github.com/jgaeddert/liquid-dsp/issues/229 #pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +// https://github.com/jgaeddert/liquid-dsp/issues/229 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage" extern "C" { #include "liquid/liquid.h" @@ -126,6 +124,4 @@ class Resampler { } // namespace liquid -#endif // HAVE_LIQUID - #endif // LIQUID_WRAPPERS_H_ diff --git a/src/rdsstring.cc b/src/rdsstring.cc index 06ec436..0c77cb1 100644 --- a/src/rdsstring.cc +++ b/src/rdsstring.cc @@ -159,6 +159,8 @@ std::string RDSString::str() const { case Encoding::UTF8: return std::string((const char*)bytes.data(), bytes.size()); } + + return ""; } std::vector RDSString::getData() const { diff --git a/src/redsea.cc b/src/redsea.cc index b4efa5b..4b826e6 100644 --- a/src/redsea.cc +++ b/src/redsea.cc @@ -18,7 +18,7 @@ #include #include -#include "config.h" +#include "build/config.h" #include "src/channel.h" #include "src/common.h" #include "src/groups.h" @@ -92,20 +92,13 @@ void printUsage() { void printVersion() { #ifdef DEBUG - std::cout << PACKAGE_STRING << "-debug by OH2EIQ" << '\n'; + std::cout << "redsea " << VERSION << "-debug by OH2EIQ" << '\n'; #else - std::cout << PACKAGE_STRING << " by OH2EIQ" << '\n'; + std::cout << "redsea " << VERSION << " by OH2EIQ" << '\n'; #endif } int processMPXInput(Options options) { - -#ifndef HAVE_LIQUID - std::cerr << "error: redsea was compiled without liquid-dsp" - << '\n'; - return EXIT_FAILURE; -#endif - MPXReader mpx; try { diff --git a/src/subcarrier.cc b/src/subcarrier.cc index 45fa130..f17b814 100644 --- a/src/subcarrier.cc +++ b/src/subcarrier.cc @@ -16,8 +16,6 @@ */ #include "src/subcarrier.h" -#ifdef HAVE_LIQUID - #include #include #include @@ -189,5 +187,3 @@ float Subcarrier::getSecondsSinceLastReset() const { } } // namespace redsea - -#endif // HAVE_LIQUID diff --git a/src/subcarrier.h b/src/subcarrier.h index 3b42303..997d9bd 100644 --- a/src/subcarrier.h +++ b/src/subcarrier.h @@ -22,15 +22,11 @@ #include #include -#include "config.h" - #include "src/common.h" #include "src/input.h" #include "src/liquid_wrappers.h" #include "src/options.h" -#ifdef HAVE_LIQUID - namespace redsea { class BiphaseDecoder { @@ -88,5 +84,4 @@ class Subcarrier { } // namespace redsea -#endif // HAVE_LIQUID #endif // SUBCARRIER_H_ diff --git a/src/tmc/locationdb.cc b/src/tmc/locationdb.cc index fcb2ab4..44acf1c 100644 --- a/src/tmc/locationdb.cc +++ b/src/tmc/locationdb.cc @@ -16,9 +16,6 @@ */ #include "src/tmc/locationdb.h" -#include "config.h" -#ifdef ENABLE_TMC - #include #include #include @@ -198,5 +195,3 @@ std::ostream& operator<<(std::ostream& strm, const LocationDatabase& locdb) { } // namespace tmc } // namespace redsea - -#endif // ENABLE_TMC diff --git a/src/tmc/locationdb.h b/src/tmc/locationdb.h index 7f17a6c..df4ee03 100644 --- a/src/tmc/locationdb.h +++ b/src/tmc/locationdb.h @@ -17,9 +17,6 @@ #ifndef TMC_LOCATIONDB_H_ #define TMC_LOCATIONDB_H_ -#include "config.h" -#ifdef ENABLE_TMC - #include #include #include @@ -77,5 +74,4 @@ uint16_t readLTN(const std::string& directory); } // namespace tmc } // namespace redsea -#endif // ENABLE_TMC #endif // TMC_LOCATIONDB_H_ diff --git a/src/tmc/tmc.cc b/src/tmc/tmc.cc index b1938be..2c8c98d 100644 --- a/src/tmc/tmc.cc +++ b/src/tmc/tmc.cc @@ -16,9 +16,6 @@ */ #include "src/tmc/tmc.h" -#include "config.h" -#ifdef ENABLE_TMC - #include #include #include @@ -926,5 +923,3 @@ void Message::decrypt(const ServiceKey& key) { } // namespace tmc } // namespace redsea - -#endif // ENABLE_TMC diff --git a/src/tmc/tmc.h b/src/tmc/tmc.h index 6b5586f..caaee44 100644 --- a/src/tmc/tmc.h +++ b/src/tmc/tmc.h @@ -17,9 +17,6 @@ #ifndef TMC_TMC_H_ #define TMC_TMC_H_ -#include "config.h" -#ifdef ENABLE_TMC - #include #include @@ -213,5 +210,4 @@ class TMCService { } // namespace tmc } // namespace redsea -#endif // ENABLE_TMC #endif // TMC_H_