Files
wdsp/Makefile.windows
Uladzimir Karpenka c1964817dd wfm: compile wfmd/wfmmod in the Windows build
Makefile.windows arrived from main, which predates the wfm module, so its
SOURCES list omitted wfmd.c/wfmmod.c even though RXA.c/TXA.c reference their
symbols -- the MinGW link failed on the missing objects. Add both to SOURCES,
matching Makefile and Makefile.android.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:03:03 +03:00

295 lines
13 KiB
Makefile
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#
# 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 (тянет mingw-w64-headers автоматически)
# Debian: sudo apt install mingw-w64 (мета-пакет: компилятор + заголовки + CRT)
# Fedora: sudo dnf install mingw64-gcc (тянет mingw64-headers автоматически)
# + wget или curl, tar
#
MINGW_PREFIX ?= x86_64-w64-mingw32
CC := $(MINGW_PREFIX)-gcc
AR := $(MINGW_PREFIX)-ar
RANLIB := $(MINGW_PREFIX)-ranlib
CFLAGS ?= -O3 -Wno-parentheses -Wno-incompatible-pointer-types
LDFLAGS ?=
# ── FFTW: сборка из исходников ────────────────────────────────────────────────
FFTW_VERSION := 3.3.11
FFTW_TAR := fftw-$(FFTW_VERSION).tar.gz
FFTW_URL := https://fftw.org/pub/fftw/$(FFTW_TAR)
# Абсолютные пути — нужны для configure --prefix и sub-make -C
FFTW_SRC := $(CURDIR)/third_party/fftw-$(FFTW_VERSION)
FFTW_INST := $(CURDIR)/third_party/fftw-win64
# Раздельные build-директории для double и float precision
FFTW_BUILD_D := $(FFTW_INST)/build-double
FFTW_BUILD_F := $(FFTW_INST)/build-float
# FFTW_MARCH задаёт минимальный набор инструкций для Windows-бинарника.
# haswell (2013+) гарантирует AVX2+FMA — оптимальный выбор для SDR на современном ПК.
# Для совместимости со старыми машинами замените на -march=sandybridge (AVX, 2011+)
# или -march=core2 (SSSE3, 2007+).
FFTW_MARCH ?= -march=haswell
FFTW_CONF_COMMON = \
--host=$(MINGW_PREFIX) \
CC=$(CC) \
CFLAGS="$(FFTW_MARCH)" \
--prefix=$(FFTW_INST) \
--enable-shared \
--disable-static \
--with-our-malloc \
--enable-sse2 \
--enable-avx \
--enable-avx2 \
--disable-fortran \
--quiet
# Sentinel-файлы для отслеживания готовности FFTW
FFTW_HEADER := $(FFTW_INST)/include/fftw3.h
FFTW_LIB_D := $(FFTW_INST)/lib/libfftw3.dll.a
FFTW_LIB_F := $(FFTW_INST)/lib/libfftw3f.dll.a
FFTW_DLL_D := $(FFTW_INST)/bin/libfftw3-3.dll
FFTW_DLL_F := $(FFTW_INST)/bin/libfftw3f-3.dll
# ── Выходные директории и файлы ───────────────────────────────────────────────
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 wfmd.c wfmmod.c wisdom.c zetaHat.c
OBJS := $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o))
# ── NR3/NR4: исходники third-party ────────────────────────────────────────────
#
# Компилируем rnnoise и libspecbleach напрямую в obj_win/, минуя их sub-make.
# Это исключает конфликт с Linux-сборкой: third_party/*.a содержат ELF-объекты,
# и если они "свежее" исходников, sub-make считает их up-to-date и не пересобирает.
RNNOISE_DIR := third_party/rnnoise
SPECBLEACH_DIR := third_party/libspecbleach
RNNOISE_SRCS := \
src/denoise.c src/celt_lpc.c src/kiss_fft.c src/nnet.c \
src/nnet_default.c src/parse_lpcnet_weights.c src/pitch.c \
src/rnn.c src/rnnoise_data.c \
src/rnnoise_data_1.c src/rnnoise_data_2.c src/rnnoise_data_3.c \
src/rnnoise_data_4.c src/rnnoise_data_5.c src/rnnoise_data_6.c \
src/rnnoise_tables.c
SPECBLEACH_SRCS := \
src/processors/specbleach_adenoiser.c \
src/processors/specbleach_denoiser.c \
src/processors/adaptivedenoiser/adaptive_denoiser.c \
src/shared/gain_estimation/gain_estimators.c \
src/shared/noise_estimation/adaptive_noise_estimator.c \
src/shared/pre_estimation/absolute_hearing_thresholds.c \
src/shared/pre_estimation/critical_bands.c \
src/shared/pre_estimation/masking_estimator.c \
src/shared/pre_estimation/noise_scaling_criterias.c \
src/shared/pre_estimation/spectral_smoother.c \
src/shared/pre_estimation/transient_detector.c \
src/shared/post_estimation/noise_floor_manager.c \
src/shared/post_estimation/postfilter.c \
src/shared/post_estimation/spectral_whitening.c \
src/shared/utils/denoise_mixer.c \
src/shared/utils/general_utils.c \
src/shared/utils/spectral_features.c \
src/shared/utils/spectral_utils.c \
src/shared/stft/stft_processor.c \
src/shared/stft/fft_transform.c \
src/shared/stft/stft_buffer.c \
src/shared/stft/stft_windows.c
RNNOISE_OBJS := $(addprefix $(OBJDIR)/rnnoise/, $(RNNOISE_SRCS:.c=.o))
SPECBLEACH_OBJS := $(addprefix $(OBJDIR)/specbleach/, $(SPECBLEACH_SRCS:.c=.o))
RNNOISE_LIB := $(OUTDIR)/librnnoise.a
SPECBLEACH_LIB := $(OUTDIR)/libspecbleach.a
# ── Флаги компиляции ──────────────────────────────────────────────────────────
NR34_INC := -I$(RNNOISE_DIR)/include -I$(SPECBLEACH_DIR)/include
FFTW_INC := -I$(FFTW_INST)/include
COMPILE := $(CC) $(CFLAGS) $(FFTW_INC) $(NR34_INC)
NR34_DEPS := $(RNNOISE_LIB) $(SPECBLEACH_LIB)
# avrt нужен т.к. comm.h включает <avrt.h> под _WIN32
LINK_LIBS := $(NR34_DEPS) \
-L$(FFTW_INST)/lib -lfftw3 -lfftw3f \
-lavrt -lm
# ── Цели ──────────────────────────────────────────────────────────────────────
.PHONY: all dll static fftw fftw-double fftw-float 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 mingw-w64"; \
echo " Fedora: sudo dnf install mingw64-gcc"; \
echo ""; exit 1; }
@echo '#include <windows.h>' | $(CC) -x c - -fsyntax-only -Wno-pragma-once-outside-header 2>/dev/null || { \
echo ""; \
echo "ОШИБКА: Windows API заголовки не найдены."; \
echo "Установите пакет с заголовками MinGW-w64:"; \
echo " Arch: sudo pacman -S mingw-w64-headers"; \
echo " Debian: sudo apt install mingw-w64 # не gcc-mingw-w64-x86-64!"; \
echo " Fedora: sudo dnf install mingw64-headers"; \
echo ""; exit 1; }
@(command -v wget >/dev/null 2>&1 || command -v curl >/dev/null 2>&1) || { \
echo "ОШИБКА: требуется wget или curl"; exit 1; }
# ── FFTW: скачать исходники → собрать double → собрать float ──────────────────
fftw: fftw-double fftw-float
# Шаг 1: скачать tarball
third_party/$(FFTW_TAR):
mkdir -p third_party
@echo ">>> Скачиваем FFTW $(FFTW_VERSION)..."
@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
# Шаг 2: распаковать
$(FFTW_SRC)/configure: third_party/$(FFTW_TAR)
@echo ">>> Распаковываем FFTW..."
tar xf $< -C third_party/
@touch $@
# Шаг 3a: configure для double precision
$(FFTW_BUILD_D)/Makefile: $(FFTW_SRC)/configure
mkdir -p $(FFTW_BUILD_D)
@echo ">>> Конфигурируем FFTW (double)..."
cd $(FFTW_BUILD_D) && $(FFTW_SRC)/configure $(FFTW_CONF_COMMON)
# Шаг 4a: сборка и установка double precision
fftw-double: $(FFTW_LIB_D)
$(FFTW_LIB_D): $(FFTW_BUILD_D)/Makefile
@echo ">>> Собираем FFTW (double)..."
$(MAKE) -C $(FFTW_BUILD_D) install
# Шаг 3b: configure для float precision (--enable-float)
$(FFTW_BUILD_F)/Makefile: $(FFTW_SRC)/configure
mkdir -p $(FFTW_BUILD_F)
@echo ">>> Конфигурируем FFTW (float)..."
cd $(FFTW_BUILD_F) && $(FFTW_SRC)/configure $(FFTW_CONF_COMMON) --enable-float
# Шаг 4b: сборка и установка float precision
# Зависит от fftw-double чтобы install-шаги не конкурировали за prefix
fftw-float: $(FFTW_LIB_F)
$(FFTW_LIB_F): $(FFTW_BUILD_F)/Makefile $(FFTW_LIB_D)
@echo ">>> Собираем FFTW (float)..."
$(MAKE) -C $(FFTW_BUILD_F) install
# ── Third-party библиотеки (кросс-компиляция) ─────────────────────────────────
third-party: $(NR34_DEPS)
$(RNNOISE_LIB): $(RNNOISE_OBJS) | $(OUTDIR)
$(AR) rv $@ $^
$(RANLIB) $@
$(SPECBLEACH_LIB): $(SPECBLEACH_OBJS) | $(OUTDIR)
$(AR) rv $@ $^
$(RANLIB) $@
# % в GNU make совпадает через '/', поэтому паттерн покрывает вложенные пути
$(OBJDIR)/rnnoise/%.o: $(RNNOISE_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -I$(RNNOISE_DIR)/include -I$(RNNOISE_DIR)/src -c -o $@ $<
$(OBJDIR)/specbleach/%.o: $(SPECBLEACH_DIR)/%.c | $(FFTW_LIB_D)
@mkdir -p $(@D)
$(CC) $(CFLAGS) -I$(FFTW_INST)/include \
-I$(SPECBLEACH_DIR)/include -I$(SPECBLEACH_DIR)/src -I$(SPECBLEACH_DIR)/src/shared \
-c -o $@ $<
# ── Основная библиотека ───────────────────────────────────────────────────────
$(OUTDIR) $(OBJDIR):
mkdir -p $@
$(DLL): $(OBJS) $(NR34_DEPS) $(FFTW_LIB_D) $(FFTW_LIB_F) | $(OUTDIR)
@echo ">>> Линкуем $@..."
$(CC) -shared \
-Wl,--out-implib,$(IMPLIB) \
$(LDFLAGS) \
-o $@ \
$(OBJS) $(LINK_LIBS)
@cp $(FFTW_DLL_D) $(FFTW_DLL_F) $(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_INST)/lib -lfftw3 -lfftw3f -lavrt -lm"
$(OBJDIR)/%.o: %.c | $(OBJDIR) $(FFTW_LIB_D)
$(COMPILE) -c -o $@ $<
# ── Очистка ───────────────────────────────────────────────────────────────────
clean:
-rm -rf $(OBJDIR) $(OUTDIR)
# distclean удаляет собранный и скачанный FFTW — при следующем запуске пересоберётся
distclean: clean
-rm -rf $(FFTW_INST) $(FFTW_SRC) third_party/$(FFTW_TAR)