On Linux (case-sensitive filesystem) MinGW-w64 installs the header as windows.h (lowercase) while comm.h included <Windows.h> (capital W), causing a fatal compile error when cross-compiling for Windows. Changed to <windows.h> which works on both Linux/MinGW-w64 and native Windows/MSVC (Windows header includes are case-insensitive on NTFS). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
240 lines
10 KiB
Makefile
240 lines
10 KiB
Makefile
#
|
||
# 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
|
||
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_CONF_COMMON = \
|
||
--host=$(MINGW_PREFIX) \
|
||
CC=$(CC) \
|
||
--prefix=$(FFTW_INST) \
|
||
--enable-shared \
|
||
--disable-static \
|
||
--with-our-malloc \
|
||
--enable-sse2 \
|
||
--enable-avx \
|
||
--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 wisdom.c zetaHat.c
|
||
|
||
OBJS := $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o))
|
||
|
||
# ── Флаги компиляции ──────────────────────────────────────────────────────────
|
||
|
||
NR34_INC := -I third_party/rnnoise/include -I third_party/libspecbleach/include
|
||
FFTW_INC := -I$(FFTW_INST)/include
|
||
|
||
COMPILE := $(CC) $(CFLAGS) $(FFTW_INC) $(NR34_INC)
|
||
|
||
NR34_DEPS := third_party/rnnoise/librnnoise.a \
|
||
third_party/libspecbleach/libspecbleach.a
|
||
|
||
# После сборки из исходников import lib называется libfftw3.dll.a → линкуем -lfftw3
|
||
# 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)
|
||
|
||
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_LIB_D)
|
||
@echo ">>> Собираем libspecbleach для Windows..."
|
||
$(MAKE) -C third_party/libspecbleach \
|
||
CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" \
|
||
CFLAGS="$(CFLAGS) -I$(FFTW_INST)/include -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_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)
|
||
-$(MAKE) -C third_party/rnnoise clean
|
||
-$(MAKE) -C third_party/libspecbleach clean
|
||
|
||
# distclean удаляет собранный и скачанный FFTW — при следующем запуске пересоберётся
|
||
distclean: clean
|
||
-rm -rf $(FFTW_INST) $(FFTW_SRC) third_party/$(FFTW_TAR)
|