diff --git a/Makefile.windows b/Makefile.windows new file mode 100644 index 0000000..30dc5bd --- /dev/null +++ b/Makefile.windows @@ -0,0 +1,197 @@ +# +# Makefile.windows — кросс-компиляция WDSP для 64-bit Windows на Linux (MinGW-w64) +# +# Использование: +# make -f Makefile.windows # DLL + статическая библиотека +# make -f Makefile.windows dll # только DLL +# make -f Makefile.windows static # только статическая библиотека +# make -f Makefile.windows clean # удалить артефакты сборки +# make -f Makefile.windows distclean # + удалить скачанный FFTW +# +# Зависимости (установить до запуска): +# Arch: sudo pacman -S mingw-w64-gcc unzip +# Debian: sudo apt install gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64 unzip +# Fedora: sudo dnf install mingw64-gcc mingw64-binutils unzip +# + wget или curl +# + +MINGW_PREFIX ?= x86_64-w64-mingw32 + +CC := $(MINGW_PREFIX)-gcc +AR := $(MINGW_PREFIX)-ar +RANLIB := $(MINGW_PREFIX)-ranlib +DLLTOOL := $(MINGW_PREFIX)-dlltool + +CFLAGS ?= -O3 -Wno-parentheses +LDFLAGS ?= + +# ── FFTW Windows binaries ───────────────────────────────────────────────────── + +FFTW_VERSION := 3.3.11 +FFTW_ZIP := fftw-$(FFTW_VERSION)-dll64.zip +FFTW_URL := https://fftw.org/pub/fftw/$(FFTW_ZIP) +FFTW_DIR := third_party/fftw-win64 + +# ── Выходные директории и файлы ─────────────────────────────────────────────── + +OBJDIR := obj_win +OUTDIR := lib_win + +DLL := $(OUTDIR)/libwdsp.dll +IMPLIB := $(OUTDIR)/libwdsp.dll.a +STATIC_LIB := $(OUTDIR)/libwdsp.a + +# ── Исходники (копия из основного Makefile) ─────────────────────────────────── + +SOURCES = \ + amd.c ammod.c amsq.c analyzer.c anf.c anr.c apfshadow.c \ + bandpass.c calcc.c calculus.c cblock.c cfcomp.c cfir.c \ + channel.c cmath.c compress.c delay.c dexp.c div.c doublepole.c \ + eer.c emnr.c emph.c eq.c fcurve.c FDnoiseIQ.c fir.c firmin.c \ + fmd.c fmmod.c fmsq.c gain.c gaussian.c gen.c icfir.c iir.c \ + impulse_cache.c iobuffs.c iqc.c linux_port.c lmath.c main.c \ + matchedCW.c meter.c meterlog10.c nbp.c nob.c nobII.c osctrl.c \ + patchpanel.c resample.c rmatch.c rnnr.c RXA.c sbnr.c sender.c \ + shift.c siphon.c slew.c snb.c ssql.c syncbuffs.c TXA.c \ + utilities.c varsamp.c version.c wcpAGC.c wisdom.c zetaHat.c + +OBJS := $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o)) + +# ── Флаги компиляции ────────────────────────────────────────────────────────── + +# Абсолютные пути, т.к. используются в sub-make из других директорий +FFTW_ABS := $(CURDIR)/$(FFTW_DIR) +NR34_INC := -I third_party/rnnoise/include -I third_party/libspecbleach/include +FFTW_INC := -I$(FFTW_ABS) + +COMPILE := $(CC) $(CFLAGS) $(FFTW_INC) $(NR34_INC) + +NR34_DEPS := third_party/rnnoise/librnnoise.a \ + third_party/libspecbleach/libspecbleach.a + +# avrt нужен т.к. comm.h включает под _WIN32; fftw3f нужен libspecbleach +LINK_LIBS := $(NR34_DEPS) \ + -L$(FFTW_ABS) -lfftw3-3 -lfftw3f-3 \ + -lavrt -lm + +# ── Цели ────────────────────────────────────────────────────────────────────── + +.PHONY: all dll static fftw third-party check-tools clean distclean + +all: dll static + +dll: check-tools fftw third-party $(DLL) +static: check-tools fftw third-party $(STATIC_LIB) + +# ── Проверка инструментов ───────────────────────────────────────────────────── + +check-tools: + @command -v $(CC) >/dev/null 2>&1 || { \ + echo ""; \ + echo "ОШИБКА: $(CC) не найден. Установите mingw-w64:"; \ + echo " Arch: sudo pacman -S mingw-w64-gcc"; \ + echo " Debian: sudo apt install gcc-mingw-w64-x86-64"; \ + echo " Fedora: sudo dnf install mingw64-gcc"; \ + echo ""; exit 1; } + @command -v $(DLLTOOL) >/dev/null 2>&1 || { \ + echo "ОШИБКА: $(DLLTOOL) не найден"; exit 1; } + @(command -v wget >/dev/null 2>&1 || command -v curl >/dev/null 2>&1) || { \ + echo "ОШИБКА: требуется wget или curl"; exit 1; } + @command -v unzip >/dev/null 2>&1 || { \ + echo "ОШИБКА: требуется unzip"; exit 1; } + +# ── FFTW: скачать → распаковать → сгенерировать import-библиотеки ───────────── + +fftw: $(FFTW_DIR)/libfftw3-3.dll.a $(FFTW_DIR)/libfftw3f-3.dll.a + +$(FFTW_DIR)/$(FFTW_ZIP): + mkdir -p $(FFTW_DIR) + @echo ">>> Скачиваем FFTW $(FFTW_VERSION) (Windows 64-bit)..." + @if command -v wget >/dev/null 2>&1; then \ + wget -q --show-progress -O $@ "$(FFTW_URL)"; \ + else \ + curl -L --progress-bar -o $@ "$(FFTW_URL)"; \ + fi + +$(FFTW_DIR)/fftw3.h: $(FFTW_DIR)/$(FFTW_ZIP) + @echo ">>> Распаковываем $(FFTW_ZIP)..." + unzip -o -q -d $(FFTW_DIR) $< + @touch $@ + +# MinGW ld ищет libfoo.dll.a при -lfoo, поэтому такое имя +$(FFTW_DIR)/libfftw3-3.dll.a: $(FFTW_DIR)/fftw3.h + @echo ">>> Генерируем import lib: libfftw3-3.dll.a" + $(DLLTOOL) --input-def $(FFTW_DIR)/libfftw3-3.def \ + --dllname libfftw3-3.dll \ + --output-lib $@ + +$(FFTW_DIR)/libfftw3f-3.dll.a: $(FFTW_DIR)/fftw3.h + @echo ">>> Генерируем import lib: libfftw3f-3.dll.a" + $(DLLTOOL) --input-def $(FFTW_DIR)/libfftw3f-3.def \ + --dllname libfftw3f-3.dll \ + --output-lib $@ + +# ── Third-party библиотеки (кросс-компиляция) ───────────────────────────────── + +third-party: $(NR34_DEPS) + +third_party/rnnoise/librnnoise.a: + @echo ">>> Собираем rnnoise для Windows..." + $(MAKE) -C third_party/rnnoise \ + CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" \ + CFLAGS="$(CFLAGS) -Iinclude -Isrc" + +# libspecbleach/Makefile жёстко вызывает pkg-config через FFTWINCLUDE=`...` +# и использует результат только в CFLAGS?= — переопределяем CFLAGS целиком, +# чтобы обойти pkg-config и прописать путь к нашему FFTW вручную. +third_party/libspecbleach/libspecbleach.a: $(FFTW_DIR)/fftw3.h + @echo ">>> Собираем libspecbleach для Windows..." + $(MAKE) -C third_party/libspecbleach \ + CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" \ + CFLAGS="$(CFLAGS) -I$(FFTW_ABS) -Iinclude -Isrc -Isrc/shared" + +# ── Основная библиотека ─────────────────────────────────────────────────────── + +$(OUTDIR) $(OBJDIR): + mkdir -p $@ + +$(DLL): $(OBJS) $(NR34_DEPS) | $(OUTDIR) + @echo ">>> Линкуем $@..." + $(CC) -shared \ + -Wl,--out-implib,$(IMPLIB) \ + $(LDFLAGS) \ + -o $@ \ + $(OBJS) $(LINK_LIBS) + @cp $(FFTW_DIR)/libfftw3-3.dll $(FFTW_DIR)/libfftw3f-3.dll $(OUTDIR)/ + @echo "" + @echo "=== Готово ===" + @echo " DLL: $(DLL)" + @echo " Import lib: $(IMPLIB)" + @echo " Заголовок: wdsp.h" + @echo "" + @echo " FFTW DLL скопированы в $(OUTDIR)/ — включите их в дистрибутив" + @echo " рядом с libwdsp.dll." + +$(STATIC_LIB): $(OBJS) | $(OUTDIR) + $(AR) rv $@ $(OBJS) + $(RANLIB) $@ + @echo "" + @echo "=== Готово ===" + @echo " Статическая: $(STATIC_LIB)" + @echo " Линкуйте приложение с:" + @echo " $(STATIC_LIB) $(NR34_DEPS)" + @echo " -L$(FFTW_ABS) -lfftw3-3 -lfftw3f-3 -lavrt -lm" + +$(OBJDIR)/%.o: %.c | $(OBJDIR) + $(COMPILE) -c -o $@ $< + +# ── Очистка ─────────────────────────────────────────────────────────────────── + +clean: + -rm -rf $(OBJDIR) $(OUTDIR) + -$(MAKE) -C third_party/rnnoise clean + -$(MAKE) -C third_party/libspecbleach clean + +# distclean удаляет и скачанный FFTW — при следующем запуске скачается заново +distclean: clean + -rm -rf $(FFTW_DIR) diff --git a/README.md b/README.md index 3887eb6..4c56398 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,18 @@ wdsp/ ├── org_openhpsdr_dsp_Wdsp.c/.h — JNI bridge ├── Makefile — host build (Linux / macOS) ├── Makefile.android — Android cross-build +├── Makefile.windows — Windows cross-build (MinGW-w64, runs on Linux) ├── java/ │ └── org/openhpsdr/dsp/Wdsp.java ├── third_party/ -│ ├── fftw/ — FFTW source (download manually, see below) +│ ├── fftw/ — FFTW source (download manually, Android only) +│ ├── fftw-win64/ — FFTW Windows binaries (downloaded automatically) │ ├── rnnoise/ — RNNoise noise suppression │ └── libspecbleach/ — spectral noise reduction ├── obj/ — object files (generated) -└── lib/ — built libraries (generated) +├── obj_win/ — Windows object files (generated) +├── lib/ — built libraries (generated) +└── lib_win/ — Windows libraries (generated) ``` --- @@ -81,6 +85,85 @@ make clean --- +## Windows build (кросс-компиляция с Linux) + +Сборка выполняется на Linux с помощью MinGW-w64. FFTW скачивается автоматически. + +### Зависимости + +```bash +# Arch +sudo pacman -S mingw-w64-gcc unzip + +# Debian / Ubuntu +sudo apt install gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64 unzip + +# Fedora +sudo dnf install mingw64-gcc mingw64-binutils unzip +``` + +Также нужен `wget` или `curl`. + +### Сборка + +```bash +# DLL + статическая библиотека (рекомендуется) +make -f Makefile.windows + +# Только DLL +make -f Makefile.windows dll + +# Только статическая библиотека +make -f Makefile.windows static +``` + +Результат в `lib_win/`: + +| Файл | Назначение | +|---|---| +| `libwdsp.dll` | DLL для Windows | +| `libwdsp.dll.a` | Import library для MinGW (`-lwdsp`) | +| `libwdsp.a` | Статическая библиотека | +| `libfftw3-3.dll` | Runtime dependency — распространять вместе с DLL | +| `libfftw3f-3.dll` | Runtime dependency — распространять вместе с DLL | + +### Линковка приложения + +**MinGW:** +```bash +gcc myapp.c -Llib_win -lwdsp -o myapp.exe +``` + +**MSVC** — переименовать `libwdsp.dll.a` в `libwdsp.lib` и подключить обычным образом. + +**Статически** (MinGW): +```bash +gcc myapp.c libwdsp.a third_party/rnnoise/librnnoise.a \ + third_party/libspecbleach/libspecbleach.a \ + -Lthird_party/fftw-win64 -lfftw3-3 -lfftw3f-3 -lavrt -lm -o myapp.exe +``` + +### Параметры + +| Переменная | По умолчанию | Описание | +|---|---|---| +| `MINGW_PREFIX` | `x86_64-w64-mingw32` | Префикс MinGW toolchain | +| `FFTW_VERSION` | `3.3.11` | Версия FFTW | +| `CFLAGS` | `-O3 -Wno-parentheses` | Флаги компилятора | + +```bash +make -f Makefile.windows MINGW_PREFIX=i686-w64-mingw32 # 32-bit Windows +``` + +### Очистка + +```bash +make -f Makefile.windows clean # артефакты сборки +make -f Makefile.windows distclean # + удалить скачанный FFTW +``` + +--- + ## Android build ### Prerequisites @@ -89,9 +172,9 @@ make clean 2. **FFTW source** — download and extract into `third_party/fftw/`: ```bash -wget https://www.fftw.org/fftw-3.3.10.tar.gz -tar xf fftw-3.3.10.tar.gz -mv fftw-3.3.10 third_party/fftw +wget https://www.fftw.org/fftw-3.3.11.tar.gz +tar xf fftw-3.3.11.tar.gz +mv fftw-3.3.11 third_party/fftw ``` 3. **Java compiler** — for building the `.class` file (Android Studio's JBR or any JDK)