Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active December 13, 2018 21:58
Show Gist options
  • Select an option

  • Save gvanem/1cb9f81742ea3935a0e6cfdbc8187a05 to your computer and use it in GitHub Desktop.

Select an option

Save gvanem/1cb9f81742ea3935a0e6cfdbc8187a05 to your computer and use it in GitHub Desktop.
GNU Makefile for RTL_433 (MinGW / MSVC / clang-cl). Ref: https://github.com/merbanan/rtl_433
#
# GNU Makefile for RTL_433 (MinGW / MSVC / clang-cl).
#
# By G. Vanem <gvanem@yahoo.no> 2017.
#
# Ref: https://github.com/merbanan/rtl_433
#
# Choose your weapons:
#
# Set 'USE_STATIC_RTLSDR=1' to link with a static rtlsdr.lib.
# This needs a static 'libusb-1.0.lib' / 'libusb-1.0.a' too.
# Otherwise link to 'rtlsdr_imp.lib' / 'librtlsdr.dll.a'.
#
USE_STATIC_RTLSDR ?= 1
#
# Use CRT debug-mode (clang-cl / MSVC only)
#
USE_CRT_DEBUG ?= 0
#
# Compile several .c-files at once (MSVC only)
#
USE_MP_COMPILE ?= 1
#
# Use RTL-SDR library.
#
USE_RTLSDR ?= 1
#
# Use SoapySDR abstraction library.
#
USE_SOAPYSDR ?= 0
#
# Use WsockTrace; a tracing Winsock replacement (clang-cl/MSVC only)
# Ref:
# https://github.com/gvanem/wsock-trace
#
USE_WSOCK_TRACE ?= 0
#
# For the C-preprocess rule below.
#
USE_CLANG_FORMATER ?= 1
VPATH = src src/devices tests
PYTHON ?= python
THIS_FILE = $(firstword $(MAKEFILE_LIST))
#
# libusb from http://libusb.info is needed to use the static version of rtlsdr.
# Change the location to suite:
#
RTLSDR_ROOT ?= ../Osmocom-SDR
SOAPYSDR_ROOT ?= ../SoapySDR
LIBUSB_ROOT ?= f:/MinGW32/src/USB/libusb
INSTALL_ROOT ?= $(realpath $(VCINSTALLDIR))
VERSION_MAJOR = 1
VERSION_MINOR = 0
define USAGE
Usage: "make -f $(THIS_FILE) [CC=gcc | cl | clang-cl] [all | clean | vclean | depend]")
Specify CC=gcc - use MinGW
Specify CC=cl - use MSVC
Specify CC=clang-cl - use clang-cl
endef
ifeq ($(CC),gcc)
O = o
OBJ_DIR = MinGW_obj
select_lib = $(strip $(1))
else ifeq ($(CC),cl)
O = obj
OBJ_DIR = MSVC_obj
select_lib = $(strip $(2))
else ifeq ($(CC),clang-cl)
export CL=
O = obj
OBJ_DIR = Clang_obj
select_lib = $(strip $(2))
else
$(error $(USAGE))
endif
ifeq ($(CC),gcc)
CFLAGS = -m32 -O2 -Wall
LDFLAGS = -m32 -s -Wl,--print-map,--sort-common
CFLAGS += -Wno-unused-variable \
-Wno-unused-function \
-Wunused-but-set-variable
else
CFLAGS = -nologo -Zi -Zo
LDFLAGS = -nologo -debug -map -incremental:no -verbose
ifeq ($(USE_CRT_DEBUG),1)
CFLAGS += -MDd -GS -RTCu -RTCs -RTCc
else
CFLAGS += -MD -Ox -GS- -Gs0
endif
ifeq ($(CC),clang-cl)
CFLAGS += -W4 -fms-compatibility \
-Wno-unused-variable \
-Wno-unused-function \
-Wno-unused-parameter \
-Wno-pointer-sign
else
CFLAGS += -W3 -wd4100 -wd4101 -wd4244 -wd4090 -wd4245 -wd4305
endif
CFLAGS += -D_CRT_SECURE_NO_WARNINGS \
-D_CRT_SECURE_NO_DEPRECATE \
-D_CRT_NONSTDC_NO_WARNINGS
endif
ifneq ($(CC),cl)
USE_MP_COMPILE = 0
endif
CFLAGS += -I./include -I./src
ifeq ($(USE_RTLSDR),1)
CFLAGS += -DRTLSDR -I$(RTLSDR_ROOT)/include
endif
ifeq ($(USE_SOAPYSDR),1)
CFLAGS += -DSOAPYSDR -I$(SOAPYSDR_ROOT)/include
endif
#
# Libraries to use for rtl_433.exe:
# Use the static versions of rtlsdr (and hence 'libusb-1.0.lib' and 'advapi32.lib').
#
ifeq ($(USE_RTLSDR),1)
ifeq ($(USE_STATIC_RTLSDR),1)
PROGRAM_LIBS = $(RTLSDR_ROOT)/src/$(call select_lib, librtlsdr.a, rtlsdr.lib) \
$(LIBUSB_ROOT)/$(call select_lib, libusb-1.0.a, libusb-1.0.lib)
PROGRAM_LIBS += $(call select_lib, -ladvapi32, advapi32.lib)
CFLAGS += -Drtlsdr_STATIC
else
PROGRAM_LIBS = $(RTLSDR_ROOT)/src/$(call select_lib, \
librtlsdr.dll.a, \
rtlsdr_imp.lib)
endif
endif
ifeq ($(USE_SOAPYSDR),1)
PROGRAM_LIBS += $(SOAPYSDR_ROOT)/lib/$(call select_lib, \
libSoapySDR.dll.a, \
SoapySDR.lib)
endif
ifeq ($(USE_WSOCK_TRACE),1)
WS2_32_LIB = $(call select_lib, -lws2_32, wsock_trace.lib)
else
WS2_32_LIB =$(call select_lib, -lws2_32, ws2_32.lib)
endif
#
# The following codes used in macro 'colour_msg' assumes you have
# MSys/Cygwin's echo with colour support.
#
BRIGHT_RED = \e[1;31m
BRIGHT_GREEN = \e[1;32m
BRIGHT_YELLOW = \e[1;33m
colour_msg = @echo -e "$(1)\e[0m"
#
# What to build:
#
TARGETS = rtl_433.exe \
data-test.exe \
baseband-test.exe
MAIN_SRC = $(addprefix src/, \
am_analyze.c \
baseband.c \
bitbuffer.c \
confparse.c \
data.c \
decoder_util.c \
fileformat.c \
optparse.c \
pulse_demod.c \
pulse_detect.c \
rtl_433.c \
samp_grab.c \
sdr.c \
util.c \
util-gv.c)
DEVICE_SRC = $(addprefix src/devices/, \
acurite.c \
akhan_100F14.c \
alecto.c \
ambient_weather.c \
ambientweather_tx8300.c \
ambientweather_wh31e.c \
blyss.c \
brennenstuhl_rcs_2044.c \
bresser_3ch.c \
bresser_5in1.c \
bt_rain.c \
calibeur.c \
cardin.c \
chuango.c \
current_cost.c \
danfoss.c \
dish_remote_6_3.c \
dsc.c \
efergy_e2_classic.c \
efergy_optical.c \
elro_db286a.c \
elv.c \
emontx.c \
esa.c \
esperanza_ews.c \
fineoffset.c \
fineoffset_wh1050.c \
fineoffset_wh1080.c \
flex.c \
fordremote.c \
ft004b.c \
generic_motion.c \
generic_remote.c \
generic_temperature_sensor.c \
ge_coloreffects.c \
gt_wt_02.c \
hideki.c \
hondaremote.c \
honeywell.c \
honeywell_wdb.c \
ht680.c \
ibis_beacon.c \
infactory.c \
inovalley-kw9015b.c \
interlogix.c \
intertechno.c \
kedsum.c \
kerui.c \
lacrosse.c \
lacrossews.c \
lacrosse_tx35.c \
lacrosse_TX141TH_Bv2.c \
lightwave_rf.c \
maverick_et73.c \
maverick_et73x.c \
mebus.c \
m_bus.c \
newkaku.c \
new_template.c \
nexa.c \
nexus.c \
oil_standard.c \
oil_watchman.c \
oregon_scientific.c \
oregon_scientific_sl109h.c \
oregon_scientific_v1.c \
philips.c \
prologue.c \
proove.c \
quhwa.c \
radiohead_ask.c \
rftech.c \
rubicson.c \
s3318p.c \
schraeder.c \
silvercrest.c \
simplisafe.c \
smoke_gs558.c \
solight_te44.c \
springfield.c \
steelmate.c \
tfa_pool_thermometer.c \
tfa_twin_plus_30.3049.c \
thermopro_tp11.c \
thermopro_tp12.c \
tpms_citroen.c \
tpms_ford.c \
tpms_pmv107j.c \
tpms_renault.c \
tpms_toyota.c \
ttx201.c \
vaillant_vrt340f.c \
waveman.c \
wg_pb12v1.c \
wssensor.c \
wt0124.c \
wt450.c \
x10_rf.c \
x10_sec.c)
ifneq ($(CC),gcc)
VPATH += src/getopt
MAIN_SRC += src/getopt/getopt.c
endif
MAIN_OBJ = $(addprefix $(OBJ_DIR)/, $(notdir $(MAIN_SRC:.c=.$(O))) )
DEVICE_OBJ = $(addprefix $(OBJ_DIR)/, $(notdir $(DEVICE_SRC:.c=.$(O))) )
PROGRAM_OBJ = $(MAIN_OBJ) $(DEVICE_OBJ)
all: $(OBJ_DIR) $(TARGETS)
@echo 'Welcome to RTL_433.'
install: $(TARGETS)
cp --update rtl_433.exe $(INSTALL_ROOT)/bin
$(OBJ_DIR):
- mkdir $(OBJ_DIR)
rtl_433.exe: $(PROGRAM_OBJ)
$(call link_EXE, $@, $^ $(PROGRAM_LIBS) $(WS2_32_LIB))
data-test.exe: $(OBJ_DIR)/data-test.$(O) $(OBJ_DIR)/data.$(O)
$(call link_EXE, $@, $^ $(WS2_32_LIB))
baseband-test.exe: $(OBJ_DIR)/baseband-test.$(O) $(OBJ_DIR)/baseband.$(O)
$(call link_EXE, $@, $^)
ifeq ($(USE_MP_COMPILE),1)
$(MAIN_OBJ): $(MAIN_SRC)
$(CC) -c $(CFLAGS) -MP -Fo$(OBJ_DIR)\\ $(MAIN_SRC)
@echo
$(DEVICE_OBJ): $(DEVICE_SRC)
$(CC) -c $(CFLAGS) -MP -Fo$(OBJ_DIR)\\ $(DEVICE_SRC)
@echo
endif
$(OBJ_DIR)/%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
@echo
$(OBJ_DIR)/%.obj: %.c
$(CC) -c $(CFLAGS) -Fo$@ $<
@echo
clean:
- rm -f $(TARGETS:.exe=.map) $(TARGETS:.exe=.pdb) link.tmp vc1*.pdb cpp_filter.py
- rm -f $(OBJ_DIR)/*.$(O)
- rmdir $(OBJ_DIR)
vclean realclean: clean
rm -f $(TARGETS) .depend.Windows
rtl_433_tests: rtl_433.exe
$(PYTHON) ./rtl_433_tests/bin/run_test.py --rtl433-cmd=rtl_433.exe acurite*
#
# .$(O) -> .exe macro
# arg1, $(1): The .exe file.
# arg2, $(2): The .obj file(s), extras and libs.
#
define link_EXE
$(call colour_msg,$(BRIGHT_GREEN)Linking $(strip $(1)))
$(call link_EXE_$(CC), $(1), $(2))
@echo
endef
link_EXE_gcc = $(CC) $(LDFLAGS) -o $(1) $(2) > $(1:.exe=.map)
link_EXE_clang-cl = $(call link_EXE_cl, $(1), $(2))
define link_EXE_cl
link $(LDFLAGS) -out:$(strip $(1)) $(2) > link.tmp
@cat link.tmp >> $(1:.exe=.map)
@rm -f link.tmp
endef
ifeq ($(USE_CLANG_FORMATER),1)
C_FORMATER = | clang-format -style=Mozilla -assume-filename=c
endif
define C_preprocess
@echo "The result of preprocessing $(strip $(1)) with CC=$(CC) and these CFLAGS:" > $(2)
@echo "--------------------------------- " >> $(2)
@$(foreach c, $(CFLAGS), echo " $(c)" >> $(2) ; )
@echo "--------------------------------- " >> $(2)
$(CC) -c -E $(CFLAGS) $(1) | cpp_filter.py $(3) >> $(2)
endef
%.i: %.c cpp_filter.py
$(call C_preprocess, $<, $@, $(C_FORMATER))
FORCE:
define CPP_FILTER_PY
import sys, os
try:
import ntpath
except ImportError as e:
print ("Failed to import ntpath: %s" % e)
sys.exit(1)
def _win32_abspath (path):
path = ntpath.abspath (path)
return path.replace ('\\', '/')
def skip_cwd (s1, s2):
''' Skip the leading part that is in common with s1 and s2
'''
i = 0
while i < len(s1) and s1[i] == s2[i]:
i += 1
return s2[i:]
cwd = _win32_abspath (os.getcwd()) + '/'
last_line = '??'
last_fname = '??'
empty_lines = 0
while True:
line = sys.stdin.readline()
if not line:
break
if line.startswith('\n') or line.startswith('\r'):
empty_lines += 1
continue
if line.lstrip().startswith("#line"):
line = line.replace ("\\\\", "/")
fname = None
quote = line.find ('\"')
if line.startswith ("#line ") and quote > 0:
fname = _win32_abspath (line[quote:])
last_fname = fname
if line.strip() != '' and last_line != '':
if fname is None or fname != last_fname:
print (line, end="")
if line.strip() == '}' or line.strip() == '};': # Print a newline after a functions or structs
print ("")
last_line = line
if empty_lines > 0:
sys.stderr.write ("Removed %d empty lines." % empty_lines)
endef
cpp_filter.py: $(THIS_FILE)
@echo 'Generating $@...'
$(file > $@,#!/usr/bin/env python)
$(file >> $@,#)
$(file >> $@,# DO NOT EDIT! This file was generated automatically)
$(file >> $@,# from $(realpath $<). Edit that file instead.)
$(file >> $@,#)
$(file >> $@,from __future__ import print_function)
$(file >> $@,if 1:)
$(file >> $@,$(CPP_FILTER_PY))
DEP_CFLAGS = -MM $(filter -D% -I%, $(CFLAGS))
DEP_REPLACE = sed -e 's/\(.*\)\.o: /\n$$(OBJ_DIR)\/\1.$$(O): /'
depend:
$(call colour_msg,$(BRIGHT_GREEN)Generating .depend.Windows ...)
@echo '# Generated by $(realpath $(THIS_FILE)).' > .depend.Windows
@echo '# DO NOT EDIT.' >> .depend.Windows
gcc $(DEP_CFLAGS) $(MAIN_SRC) $(DEVICE_SRC) tests/data-test.c | \
$(DEP_REPLACE) >> .depend.Windows
-include .depend.Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment