# Implicit rules are implemented in make as suffix rules. The following rule # empties the suffix list to disable the predefined implicit rules. This # increases performance and avoids hard-to-debug behaviour. .SUFFIXES: MAKEFLAGS += -Rrj ifeq ("$(origin CC)", "default") CC := cc endif .ONESHELL: .SHELLFLAGS := -ec .SECONDARY: # don't remove intermediate files PACKAGE := paraslash DEFINES = \ $(call DEFINE,PACKAGE,$(PACKAGE)) \ $(call DEFINE,SLOGAN,network audio streaming) \ $(call DEFINE,AUTHOR,Andre Noll) \ $(call DEFINE,EMAIL,maan@tuebingen.mpg.de) \ $(call DEFINE,COPYRIGHT_YEAR,1997) \ $(call DEFINE,PROJECT_WEBSITE,https://people.tuebingen.mpg.de/maan/$(PACKAGE)/) \ $(call DEFINE,CLONE_URL,https://git.tuebingen.mpg.de/$(PACKAGE)) \ $(call DEFINE,GITWEB_URL,https://git.tuebingen.mpg.de/$(PACKAGE).git) \ $(call DEFINE,HOME_URL,https://people.tuebingen.mpg.de/maan/) \ $(call DEFINE,LICENSE,GPL-2.0) \ $(call DEFINE,LICENSE_URL,https://www.gnu.org/licenses/) DEFINE = -D '$(1)=$(2)' M4 += $(DEFINES) DEFINE = $(1)='$(2)' SHELL_DEFINES := $(DEFINES) LOGLEVELS := LL_DEBUG,LL_INFO,LL_NOTICE,LL_WARNING,LL_ERROR,LL_CRIT,LL_EMERG SEVERITIES := \"debug\",\"info\",\"notice\",\"warning\",\"error\",\"crit\",\"emerg\" vardir := /var/paraslash mandir := $(datarootdir)/man/man1 MKDIR_P := mkdir -p RM := rm -f ifeq ("$(origin O)", "command line") build_dir := $(O) else build_dir := build endif version_dir := $(build_dir)/version-gen object_dir := $(build_dir)/objects dep_dir := $(build_dir)/deps man_dir := $(build_dir)/man/man1 m4depdir := $(build_dir)/m4deps lls_suite_dir := $(build_dir)/lls lls_m4_dir := m4/lls test_dir := t yy_src_dir := yy yy_build_dir := $(build_dir)/yy GIT_VERSION := $(shell $(MKDIR_P) $(object_dir) $(dep_dir) $(man_dir) \ $(m4depdir) $(lls_suite_dir) $(yy_build_dir) && \ $(SHELL_DEFINES) ./version-gen.sh $(PACKAGE) $(version_dir)/version.c) executables := recv filter audioc write afh ifneq ($(CRYPTOLIB),) ifeq ($(HAVE_OSL),yes) executables += server server_objs := $(addsuffix .o, \ server afh_common vss command net string \ signal time daemon http_send \ crypt_common ipc fd \ afs aft mood mp score attribute blob \ playlist sched udp_send color fec \ wma_afh wma_common sideband lsu version \ ) ifeq ($(HAVE_ID3TAG),yes) server_objs += mp3_afh.o endif ifeq ($(CRYPTOLIB),openssl) server_objs += openssl.o else server_objs += gcrypt.o endif ifeq ($(NEED_OGG_OBJECTS),yes) server_objs += ogg_afh_common.o endif ifeq ($(NEED_VORBIS_OBJECTS),yes) server_objs += ogg_afh.o endif ifeq ($(NEED_SPEEX_OBJECTS),yes) server_objs += spx_afh.o spx_common.o endif ifeq ($(NEED_OPUS_OBJECTS),yes) server_objs += opus_afh.o opus_common.o endif ifeq ($(NEED_FLAC_OBJECTS),yes) server_objs += flac_afh.o endif ifeq ($(HAVE_FAAD),yes) server_objs += aac_afh.o mp4.o endif endif endif ifneq ($(CRYPTOLIB),) executables += client audiod client_objs := $(addsuffix .o, \ client net string fd lsu sched stdin stdout time sideband client_common \ buffer_tree crypt_common $(CRYPTOLIB) version \ ) ifeq ($(HAVE_READLINE),yes) client_objs += interactive.o endif audiod_objs := $(addsuffix .o, \ audiod signal string daemon stat net crypt_common sideband \ time grab_client filter_common wav_filter compress_filter amp_filter \ http_recv recv_common fd sched write_common file_write \ audiod_command fecdec_filter client_common udp_recv color fec \ prebuffer_filter bitstream imdct wma_common wmadec_filter \ buffer_tree sync_filter lsu $(CRYPTOLIB) version \ ) audiod_audio_formats := "wma" ifeq ($(NEED_VORBIS_OBJECTS),yes) audiod_objs += oggdec_filter.o audiod_audio_formats += ,"ogg" endif ifeq ($(NEED_SPEEX_OBJECTS),yes) audiod_objs += spxdec_filter.o spx_common.o audiod_audio_formats += ,"spx" endif ifeq ($(NEED_OPUS_OBJECTS),yes) audiod_objs += opusdec_filter.o opus_common.o audiod_audio_formats += ,"opus" endif ifeq ($(NEED_FLAC_OBJECTS),yes) audiod_objs += flacdec_filter.o audiod_audio_formats += ,"flac" endif ifeq ($(HAVE_FAAD),yes) audiod_objs += aacdec_filter.o audiod_audio_formats += ,"aac" endif ifeq ($(HAVE_MAD),yes) audiod_objs += mp3dec_filter.o audiod_audio_formats += ,"mp3" endif ifeq ($(HAVE_OSS),yes) audiod_objs += oss_write.o endif ifeq ($(HAVE_ALSA),yes) audiod_objs += alsa_write.o endif ifeq ($(NEED_AO_OBJECTS),yes) audiod_objs += ao_write.o endif endif ifneq ($(HAVE_OSS)-$(HAVE_ALSA),no-no) executables += mixer mixer_objs := $(addsuffix .o, mixer exec string fd time lsu version) ifeq ($(HAVE_OSS),yes) mixer_objs += oss_mix.o endif ifeq ($(HAVE_ALSA),yes) mixer_objs += alsa_mix.o endif endif ifeq ($(HAVE_CURSES),yes) executables += gui gui_objs := $(addsuffix .o, exec signal string stat ringbuffer fd \ gui gui_theme lsu time sched version audioc_common net sideband) endif filter_objs := $(addsuffix .o, \ filter_common wav_filter compress_filter filter string stdin stdout \ sched fd amp_filter fecdec_filter fec lsu prebuffer_filter \ time bitstream imdct wma_common wmadec_filter buffer_tree net \ sync_filter version \ ) ifeq ($(NEED_VORBIS_OBJECTS),yes) filter_objs += oggdec_filter.o endif ifeq ($(NEED_SPEEX_OBJECTS),yes) filter_objs += spxdec_filter.o spx_common.o endif ifeq ($(NEED_OPUS_OBJECTS),yes) filter_objs += opusdec_filter.o opus_common.o endif ifeq ($(NEED_FLAC_OBJECTS),yes) filter_objs += flacdec_filter.o endif ifeq ($(HAVE_FAAD),yes) filter_objs += aacdec_filter.o endif ifeq ($(HAVE_MAD),yes) filter_objs += mp3dec_filter.o endif recv_objs := $(addsuffix .o, \ http_recv recv_common recv time string net fd sched stdout \ udp_recv buffer_tree afh_recv afh_common wma_afh wma_common version \ ) ifeq ($(HAVE_ID3TAG),yes) recv_objs += mp3_afh.o endif ifeq ($(NEED_OGG_OBJECTS),yes) recv_objs += ogg_afh_common.o endif ifeq ($(NEED_VORBIS_OBJECTS),yes) recv_objs += ogg_afh.o endif ifeq ($(NEED_SPEEX_OBJECTS),yes) recv_objs += spx_afh.o spx_common.o endif ifeq ($(NEED_OPUS_OBJECTS),yes) recv_objs += opus_afh.o opus_common.o endif ifeq ($(NEED_FLAC_OBJECTS),yes) recv_objs += flac_afh.o endif ifeq ($(HAVE_FAAD),yes) recv_objs += aac_afh.o mp4.o endif audio_format_handlers := wma afh_objs := $(addsuffix .o, afh string fd afh_common time wma_afh wma_common \ version) ifeq ($(HAVE_ID3TAG),yes) afh_objs += mp3_afh.o audio_format_handlers += mp3 endif ifeq ($(NEED_OGG_OBJECTS),yes) afh_objs += ogg_afh_common.o endif ifeq ($(NEED_VORBIS_OBJECTS),yes) afh_objs += ogg_afh.o audio_format_handlers += ogg endif ifeq ($(NEED_SPEEX_OBJECTS),yes) afh_objs += spx_common.o audio_format_handlers += spx endif ifeq ($(NEED_OPUS_OBJECTS),yes) afh_objs += opus_afh.o opus_common.o audio_format_handlers += opus endif ifeq ($(NEED_FLAC_OBJECTS),yes) afh_objs += flac_afh.o audio_format_handlers += flac endif ifeq ($(HAVE_FAAD),yes) afh_objs += aac_afh.o mp4.o audio_format_handlers += aac endif ifeq ($(HAVE_READLINE),yes) executables += play play_objs := $(addsuffix .o, \ play fd sched buffer_tree time string net afh_recv afh_common \ wma_afh wma_common recv_common udp_recv http_recv \ filter_common fec bitstream imdct wav_filter compress_filter \ amp_filter prebuffer_filter fecdec_filter wmadec_filter write_common \ file_write sync_filter lsu interactive version \ ) ifeq ($(HAVE_ID3TAG),yes) play_objs += mp3_afh.o endif ifeq ($(NEED_OGG_OBJECTS),yes) play_objs += ogg_afh_common.o endif ifeq ($(NEED_VORBIS_OBJECTS),yes) play_objs += oggdec_filter.o ogg_afh.o endif ifeq ($(NEED_SPEEX_OBJECTS),yes) play_objs += spxdec_filter.o spx_afh.o spx_common.o endif ifeq ($(NEED_OPUS_OBJECTS),yes) play_objs += opusdec_filter.o opus_afh.o opus_common.o endif ifeq ($(NEED_FLAC_OBJECTS),yes) play_objs += flacdec_filter.o flac_afh.o endif ifeq ($(HAVE_FAAD),yes) play_objs += aac_afh.o aacdec_filter.o mp4.o endif ifeq ($(HAVE_MAD),yes) play_objs += mp3dec_filter.o endif ifeq ($(HAVE_OSS),yes) play_objs += oss_write.o endif ifeq ($(HAVE_ALSA),yes) play_objs += alsa_write.o endif ifeq ($(NEED_AO_OBJECTS),yes) play_objs += ao_write.o endif endif write_objs := $(addsuffix .o, write write_common file_write time fd \ string sched stdin buffer_tree version) ifeq ($(NEED_AO_OBJECTS),yes) write_objs += ao_write.o endif ifeq ($(HAVE_OSS),yes) write_objs += oss_write.o endif ifeq ($(HAVE_ALSA),yes) write_objs += alsa_write.o endif audioc_objs := $(addsuffix .o, audioc string lsu net fd time version sideband \ audioc_common) ifeq ($(HAVE_READLINE),yes) audioc_objs += buffer_tree.o interactive.o sched.o endif # sort removes duplicate words, which is all we need here dep_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ $(audiod_objs) $(audioc_objs) $(mixer_objs) $(server_objs) \ $(write_objs) $(afh_objs) $(play_objs) mp.bison mp.flex) deps := $(addprefix $(dep_dir)/, $(dep_objs:.o=.d)) afh_objs += afh.lsg.o audioc_objs += audioc.lsg.o audiod_objs += $(addsuffix _cmd.lsg.o, recv filter audiod write) \ client.lsg.o audiod.lsg.o client_objs += client.lsg.o mixer_objs += mixer.lsg.o filter_objs += filter_cmd.lsg.o filter.lsg.o gui_objs += gui.lsg.o play_objs += $(addsuffix _cmd.lsg.o, recv filter play write) play.lsg.o recv_objs += recv_cmd.lsg.o recv.lsg.o server_objs += server_cmd.lsg.o server.lsg.o write_objs += write_cmd.lsg.o write.lsg.o cmd_suites := $(addsuffix _cmd, audiod server play recv filter write) suites := $(addprefix $(lls_suite_dir)/, $(cmd_suites) $(executables)) m4_lls_deps := $(addsuffix .m4d, $(suites)) lsg_h := $(addsuffix .lsg.h, $(suites)) # flex/bison objects and headers are only needed if para_server is built ifeq ("$(findstring server, $(executables))", "server") server_objs += mp.flex.o mp.bison.o yy_h := $(yy_build_dir)/mp.bison.h endif # now prefix all objects with object dir recv_objs := $(addprefix $(object_dir)/, $(recv_objs)) filter_objs := $(addprefix $(object_dir)/, $(filter_objs)) client_objs := $(addprefix $(object_dir)/, $(client_objs)) gui_objs := $(addprefix $(object_dir)/, $(gui_objs)) audiod_objs := $(addprefix $(object_dir)/, $(audiod_objs)) audioc_objs := $(addprefix $(object_dir)/, $(audioc_objs)) mixer_objs := $(addprefix $(object_dir)/, $(mixer_objs)) server_objs := $(addprefix $(object_dir)/, $(server_objs)) write_objs := $(addprefix $(object_dir)/, $(write_objs)) afh_objs := $(addprefix $(object_dir)/, $(afh_objs)) play_objs := $(addprefix $(object_dir)/, $(play_objs)) prefixed_executables := $(addprefix para_, $(executables)) man_pages := $(patsubst %, $(man_dir)/%.1, $(prefixed_executables)) all: $(prefixed_executables) $(man_pages) .PHONY: all mostlyclean clean distclean maintainer-clean install \ install-strip man dist man: $(man_pages) include $(lls_m4_dir)/makefile include $(test_dir)/makefile include $(yy_src_dir)/makefile ifeq ($(findstring clean, $(MAKECMDGOALS)),) -include $(deps) -include $(m4_lls_deps) endif XCPPFLAGS := -DLOGLEVELS='$(LOGLEVELS)' XCPPFLAGS += -DSEVERITIES=$(SEVERITIES) XCPPFLAGS += -I$(lls_suite_dir) XCPPFLAGS += -I$(yy_build_dir) XCPPFLAGS += $(lopsub_cppflags) XCPPFLAGS += -Wunused-macros XCPPFLAGS += $(shell \ printf '__attribute__ ((nonstring)) char buf[1] = "x";' \ | $(CC) -Werror -c -x c - -o /dev/null > /dev/null 2>&1 \ && printf -- '-D__nonstring="__attribute__ ((nonstring))"' \ || printf -- '-D__nonstring=' \ ) XCFLAGS := -fno-strict-aliasing XCFLAGS += -ftrapv XCFLAGS += -g XCFLAGS += -Os XCFLAGS += -Wundef -Wextra XCFLAGS += -Wchar-subscripts XCFLAGS += -Werror-implicit-function-declaration XCFLAGS += -Wmissing-noreturn XCFLAGS += -Wbad-function-cast XCFLAGS += -Wredundant-decls XCFLAGS += -Wno-sign-compare -Wno-unknown-pragmas XCFLAGS += -Wdeclaration-after-statement XCFLAGS += -Wformat -Wformat-security -Wmissing-format-attribute XCFLAGS += -fdata-sections -ffunction-sections XCFLAGS += -Wstrict-prototypes XCFLAGS += -Wshadow XCFLAGS += -Wunused -Wall LDFLAGS += -Wl,--gc-sections ifeq ($(ENABLE_UBSAN), yes) XCFLAGS += -fsanitize=undefined LDFLAGS += -lubsan endif cc-option = $(shell \ $(CC) $(1) -Werror -c -x c /dev/null -o /dev/null > /dev/null 2>&1 \ && echo "$(1)" \ ) XCFLAGS += $(call cc-option, -Wformat-signedness) XCFLAGS += $(call cc-option, -Wdiscarded-qualifiers) XCFLAGS += $(call cc-option, -Wsuggest-attribute=malloc) # To put more focus on warnings, be less verbose as default # Use 'make V=1' to see the full commands ifeq ("$(origin V)", "command line") SAY = else SAY = @echo '$(strip $(1))' endif audiod_commands := $(addprefix $(lls_suite_dir)/, \ $(addsuffix _cmd.lsg.man, audiod recv filter write)) filter_commands := $(lls_suite_dir)/filter_cmd.lsg.man play_commands := $(lls_suite_dir)/play_cmd.lsg.man recv_commands := $(lls_suite_dir)/recv_cmd.lsg.man server_commands := $(lls_suite_dir)/server_cmd.lsg.man write_commands := $(lls_suite_dir)/write_cmd.lsg.man $(man_dir)/para_audiod.1: $(audiod_commands) $(man_dir)/para_filter.1: $(filter_commands) $(man_dir)/para_play.1: $(play_commands) $(man_dir)/para_recv.1: $(recv_commands) $(man_dir)/para_server.1: $(server_commands) $(man_dir)/para_write.1: $(write_commands) $(man_dir)/para_audiod.1: all_commands := $(audiod_commands) $(man_dir)/para_filter.1: all_commands := $(filter_commands) $(man_dir)/para_play.1: all_commands := $(play_commands) $(man_dir)/para_recv.1: all_commands := $(recv_commands) $(man_dir)/para_server.1: all_commands := $(server_commands) $(man_dir)/para_write.1: all_commands := $(write_commands) $(man_dir)/para_%.1: $(lls_suite_dir)/%.lsg.man \ $(lls_m4_dir)/copyright.m4 $(call SAY, LLSMAN $<) cat $< $(all_commands) > $@ $(M4) $(lls_m4_dir)/copyright.m4 >> $@ $(object_dir)/%.o: %.c OD = $(addsuffix .d, $(addprefix $(dep_dir)/, $(1))) \ $(addsuffix .o, $(addprefix $(object_dir)/, $(1))) $(call OD, audiod): \ XCPPFLAGS += -DAUDIOD_AUDIO_FORMAT_ARRAY='$(audiod_audio_formats)' $(call OD, afh command): \ XCPPFLAGS += -DAUDIO_FORMAT_HANDLERS='"$(audio_format_handlers)"' $(call OD, opus%): XCPPFLAGS += $(opus_cppflags) $(call OD, gui gui%): XCPPFLAGS += $(curses_cppflags) $(call OD, spx%): XCPPFLAGS += $(speex_cppflags) $(call OD, flac%): XCPPFLAGS += $(flac_cppflags) $(call OD, mp3_afh): XCPPFLAGS += $(id3tag_cppflags) $(call OD, openssl): XCPPFLAGS += $(openssl_cppflags) $(call OD, gcrypt): XCPPFLAGS += $(gcrypt_cppflags) $(call OD, ao_write): XCPPFLAGS += $(ao_cppflags) $(call OD, alsa%): XCPPFLAGS += $(alsa_cppflags) $(call OD, interactive): XCPPFLAGS += $(readline_cppflags) $(call OD, oss_write): XCPPFLAGS += $(oss_cppflags) $(call OD, ao_write): XCPPFLAGS += $(ao_cppflags) $(pthread_cppflags) $(call OD, mp3dec_filter): XCPPFLAGS += $(mad_cppflags) $(call OD, aacdec_filter aac_afh): XCPPFLAGS += $(faad_cppflags) $(call OD, ogg_afh oggdec_filter): XCPPFLAGS += $(vorbis_cppflags) $(call OD, spx_common spxdec_filter spx_afh oggdec_filter ogg_afh \ ogg_afh_common opus%): XCPPFLAGS += $(ogg_cppflags) $(call OD, afs aft attribute blob mood playlist score server vss command \ http_send udp_send mm.o): \ XCPPFLAGS += $(osl_cppflags) $(call OD, compress_filter): XCFLAGS += -O3 define CC_CMD $(call SAY, CC $<) $(CC) -c -o $(object_dir)/$(*F).o -MMD -MP -MF \ $(dep_dir)/$(*F).d -MT $(object_dir)/$(*F).o \ $(XCPPFLAGS) $(CPPFLAGS) $(XCFLAGS) $(CFLAGS) $< endef CC_PREREQUISITES := %.c | $(lsg_h) $(yy_h) # There should be a # better way to write these. $(object_dir)/%.o: $(version_dir)/%.c $(CC_CMD) $(object_dir)/%.o: $(CC_PREREQUISITES) $(CC_CMD) $(dep_dir)/%.d: $(CC_PREREQUISITES) $(CC_CMD) para_recv para_afh para_play para_server: LDFLAGS += $(id3tag_ldflags) para_write para_play para_audiod: LDFLAGS += $(ao_ldflags) $(pthread_ldflags) para_client para_audioc para_play: LDFLAGS += $(readline_ldflags) para_server: LDFLAGS += $(osl_ldflags) para_gui: LDFLAGS += $(curses_ldflags) para_server \ para_client \ para_audiod \ :LDFLAGS += \ $(crypto_ldflags) para_audiod \ para_filter \ para_play \ : LDFLAGS += \ $(mad_ldflags) \ $(faad_ldflags) \ -lm para_mixer: LDFLAGS += -lm para_write \ para_play \ para_audiod \ para_mixer \ : LDFLAGS += \ $(oss_ldflags) \ $(alsa_ldflags) para_afh \ para_audioc \ para_audiod \ para_client \ para_mixer \ para_filter \ para_gui \ para_play \ para_recv \ para_server \ para_write \ : LDFLAGS += $(lopsub_ldflags) para_server \ para_filter \ para_audiod \ para_play \ para_afh \ para_recv \ : LDFLAGS += \ $(ogg_ldflags) \ $(vorbis_ldflags) \ $(speex_ldflags) \ $(opus_ldflags) \ $(faad_ldflags) \ $(flac_ldflags) para_afh para_recv para_server para_play: LDFLAGS += $(iconv_ldflags) $(foreach exe,$(executables),$(eval para_$(exe): $$($(exe)_objs))) $(prefixed_executables): $(call SAY, LD $@) $(CC) $^ -o $@ $(LDFLAGS) mostlyclean: $(RM) para_* clean: mostlyclean $(RM) -r $(object_dir) distclean: clean test-clean $(RM) -r $(build_dir) maintainer-clean: distclean $(RM) Makefile config.status config.log config.h configure config.h.in INSTALL ?= install INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= $(INSTALL) -m 644 ifneq ($(findstring strip, $(MAKECMDGOALS)),) strip_option := -s endif install install-strip: all man $(MKDIR_P) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir) $(INSTALL) $(strip_option) $(prefixed_executables) $(DESTDIR)$(bindir) $(INSTALL_DATA) $(man_pages) $(DESTDIR)$(mandir) $(MKDIR_P) $(DESTDIR)$(vardir) >/dev/null 2>&1 || true # not fatal, so don't complain