diff --git a/.gitignore b/.gitignore index cf5868ec..638124c4 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ missing stamp-h1 autotools-stamp build-stamp +forked-daapd.spec +forked-daapd.conf +forked-daapd.service # ignore debian packaging for convenience debian/ diff --git a/Makefile.am b/Makefile.am index 1d766499..93e782c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,48 @@ ACLOCAL_AMFLAGS = -I m4 -sysconf_DATA = forked-daapd.conf +RPM_SPEC_FILE = forked-daapd.spec +CONF_FILE = forked-daapd.conf +SYSTEMD_SERVICE_FILE = forked-daapd.service + +sysconf_DATA = $(CONF_FILE) + +BUILT_SOURCES = $(CONF_FILE) $(SYSTEMD_SERVICE_FILE) -EXTRA_DIST = configure SUBDIRS = sqlext src -man_MANS = forked-daapd.8 +dist_man_MANS = forked-daapd.8 + +nobase_dist_doc_DATA = \ + UPGRADING \ + README.md \ + README_PULSE.md \ + README_SMARTPL.md \ + scripts/antlr35_install.sh \ + scripts/freebsd_install_10.1.sh \ + scripts/freebsd_start_10.1.sh \ + scripts/pairinghelper.sh + +EXTRA_DIST = \ + $(CONF_FILE).in \ + $(SYSTEMD_SERVICE_FILE).in \ + $(RPM_SPEC_FILE) install-data-hook: - $(MKDIR_P) $(DESTDIR)$(localstatedir)/cache/forked-daapd/libspotify + $(MKDIR_P) "$(DESTDIR)$(localstatedir)/cache/$(PACKAGE)/libspotify" +CLEANFILES = $(BUILT_SOURCES) + +do_subst = $(SED) -e 's|@sbindir[@]|$(sbindir)|g' \ + -e 's|@localstatedir[@]|$(localstatedir)|g' \ + -e 's|@PACKAGE[@]|$(PACKAGE)|g' \ + -e 's|@DAAPD_USER[@]|$(DAAPD_USER)|g' + +# these files use $prefix, which is determined at build (not configure) time +$(CONF_FILE) $(SYSTEMD_SERVICE_FILE): Makefile + $(AM_V_at)rm -f $@ $@-t + $(AM_V_GEN)$(do_subst) "$(srcdir)/$@.in" > $@-t + $(AM_V_at)mv $@-t $@ + +$(CONF_FILE): $(srcdir)/$(CONF_FILE).in + +$(SYSTEMD_SERVICE_FILE): $(srcdir)/$(SYSTEMD_SERVICE_FILE).in diff --git a/config.rpath b/build-aux/config.rpath similarity index 100% rename from config.rpath rename to build-aux/config.rpath diff --git a/configure.ac b/configure.ac index 1357cb9b..4bef2391 100644 --- a/configure.ac +++ b/configure.ac @@ -1,258 +1,305 @@ dnl Process this file with autoconf to produce a configure script. +AC_PREREQ([2.60]) AC_INIT([forked-daapd], [24.2]) + AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) -AC_DEFINE_UNQUOTED([BUILDDATE], ["`date -Idate`"], [Build date]) -AM_INIT_AUTOMAKE([foreign -Wno-portability subdir-objects]) - +AM_INIT_AUTOMAKE([foreign subdir-objects]) +dnl Requires autoconf 2.60 AC_USE_SYSTEM_EXTENSIONS dnl Checks for programs. AC_PROG_CC -AM_PROG_CC_C_O +AC_PROG_CC_C_O +AC_PROG_SED +AC_PROG_MKDIR_P LT_INIT([disable-static]) -AC_CHECK_PROG(GPERF, [gperf], [gperf]) -if test "x$GPERF" = x; then - AC_MSG_ERROR([GNU gperf not found, please install it]) -fi -AC_SUBST(GPERF) +AC_PATH_PROG([GPERF], [[gperf]]) +AS_IF([[test -z "$GPERF"]], + [AS_IF([[test -f "$srcdir/src/dmap_fields_hash.h"]], + [AM_MISSING_PROG([GPERF], [[gperf]]) + AC_MSG_NOTICE([[ -AC_CHECK_PROG(ANTLR, [antlr3], [antlr3]) -if test "x$ANTLR" = x; then - if test -d $srcdir/src/pregen; then - for f in $srcdir/src/pregen/*; do - bf=`basename $f` - ln -sf pregen/$bf $srcdir/src/$bf - done - AC_MSG_NOTICE([antlr3 wrapper not found, using pre-generated files]) - else - AC_MSG_ERROR([antlr3 wrapper not found and pre-generated files not available]) - fi -fi -AC_SUBST(ANTLR) -AM_CONDITIONAL(COND_ANTLR, test "x$ANTLR" != x) +GNU gperf not found, but it's output appears to be present. +If you modify any gperf or ANTLR grammar files (.g), you will need +to install it.]])], + [AC_MSG_ERROR([[GNU gperf required, please install it.]])]) + ]) -CFLAGS="$CFLAGS -Wall -D_LARGEFILE_SOURCE" +AC_PATH_PROG([ANTLR], [[antlr3]]) +AS_IF([[test -z "$ANTLR"]], + [AS_IF([[test -f "$srcdir/src/SMARTPLLexer.h"]], + [AM_MISSING_PROG([ANTLR], [[antlr3]]) + AC_MSG_NOTICE([[ -AC_CHECK_HEADERS([sys/wait.h]) -AC_CHECK_HEADERS([sys/param.h]) -AC_CHECK_HEADERS([sys/select.h]) -AC_CHECK_HEADERS([dirent.h]) -AC_CHECK_HEADERS([regex.h]) -AC_CHECK_HEADERS([pthread_np.h]) -AC_CHECK_FUNCS(posix_fadvise) -AC_CHECK_FUNCS(strptime) -AC_CHECK_FUNCS(strtok_r) -AC_CHECK_FUNCS(timegm) -AC_CHECK_FUNCS(euidaccess) -AC_CHECK_FUNCS(pipe2) +antlr3 not found, but it's output appears to be present. +If you modify any ANTLR grammar files (.g), you will need to install it.]])], + [AC_MSG_ERROR([[antlr3 wrapper required, please install it.]])]) + ]) +dnl Enable all warnings by default. +AM_CPPFLAGS="-Wall" +AC_SUBST([AM_CPPFLAGS]) + +dnl Checks for header files. +AC_CHECK_HEADERS_ONCE([regex.h pthread_np.h]) +AC_CHECK_HEADERS([sys/wait.h sys/param.h dirent.h getopt.h stdint.h], [], + [AC_MSG_ERROR([[Missing header required to build forked-daapd]])]) +AC_CHECK_HEADERS([time.h], [], + [AC_MSG_ERROR([[Missing header required to build forked-daapd]])]) +AC_CHECK_FUNCS_ONCE([posix_fadvise euidaccess pipe2]) +AC_CHECK_FUNCS([strptime strtok_r], [], + [AC_MSG_ERROR([[Missing function required to build forked-daapd]])]) + +dnl check for clock_gettime +AC_SEARCH_LIBS([clock_gettime], [rt], [], + [AC_MSG_ERROR([[Missing clock_gettime]])]) + +dnl check for timer_settime +AC_SEARCH_LIBS([timer_settime], [rt], [], + [AC_MSG_ERROR([[Missing timer_settime]])]) + +AC_SEARCH_LIBS([pthread_exit], [pthread], [], + [AC_MSG_ERROR([[pthreads library is required]])]) AC_SEARCH_LIBS([pthread_setname_np], [pthread], - AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Define to 1 if you have pthread_setname_np]), - AC_SEARCH_LIBS([pthread_set_name_np], [pthread], AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [Define to 1 if you have pthread_set_name_np])) -) -AC_SEARCH_LIBS([inotify_add_watch], [inotify], [], AC_MSG_ERROR([inotify not found])) + [dnl Validate pthread_setname_np with 2 args (some have 1) + AC_MSG_CHECKING([[for two-parameter pthread_setname_np]]) + AC_TRY_LINK([@%:@include ], + [pthread_setname_np(pthread_self(), "name");], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_PTHREAD_SETNAME_NP], 1, + [Define to 1 if you have pthread_setname_np])], + [AC_MSG_RESULT([[no]])])], + [AC_SEARCH_LIBS([pthread_set_name_np], [pthread], + [AC_CHECK_FUNCS([pthread_set_name_np])])]) dnl Large File Support (LFS) AC_SYS_LARGEFILE AC_TYPE_OFF_T dnl Checks for libraries. -gl_LIBUNISTRING -if test x$HAVE_LIBUNISTRING != xyes; then - AC_MSG_ERROR([GNU libunistring is required]) -fi +AC_SUBST([COMMON_LIBS]) +AC_SUBST([COMMON_CPPFLAGS]) +AC_SUBST([FORKED_LIBS]) +AC_SUBST([FORKED_CPPFLAGS]) -PKG_CHECK_MODULES(ZLIB, [ zlib ]) -PKG_CHECK_MODULES(CONFUSE, [ libconfuse ]) -PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6.24 ]) -PKG_CHECK_MODULES(SQLITE3, [ sqlite3 >= 3.5.0 ]) +AM_ICONV +dnl All FORK_ macros defined in m4/fork_checks.m4 +FORK_FUNC_REQUIRE([COMMON], [GNU libunistring], [LIBUNISTRING], [unistring], + [u8_strconv_from_locale], [uniconv.h], [], + [dnl Retry test with iconv library + FORK_VARS_APPEND([COMMON], [LIBICONV], [INCICONV]) + FORK_FUNC_REQUIRE([COMMON], [GNU libunistring], [LIBUNISTRING], + [unistring], [u8_strconv_from_locale], [uniconv.h])]) -save_LIBS="$LIBS" -LIBS="$SQLITE3_LIBS" -dnl Check that SQLite3 has the unlock notify API built-in -AC_CHECK_LIB([sqlite3], [sqlite3_unlock_notify], [], AC_MSG_ERROR([SQLite3 was built without unlock notify support])) -dnl Check that SQLite3 has been built with threadsafe operations -AC_MSG_CHECKING([if SQLite3 was built with threadsafe operations support]) -AC_LANG_PUSH([C]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([dnl - #include - ], [dnl - int ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - if (ret != SQLITE_OK) - return 1; - return 0;])], - [AC_MSG_RESULT([yes])], [AC_MSG_ERROR([SQLite3 was not built with threadsafe operations support])], - [AC_MSG_RESULT([runtime will tell])]) -AC_LANG_POP([C]) -LIBS="$save_LIBS" +FORK_MODULES_CHECK([FORKED], [ZLIB], [zlib], [deflate], [zlib.h]) +FORK_MODULES_CHECK([FORKED], [CONFUSE], [libconfuse], [cfg_init], [confuse.h]) +FORK_MODULES_CHECK([FORKED], [MINIXML], [mxml], [mxmlNewElement], [mxml.h], + [AC_CHECK_FUNCS([mxmlGetOpaque])]) -PKG_CHECK_MODULES(LIBAV, [ libavformat libavcodec libswscale libavutil libavfilter ]) +FORK_MODULES_CHECK([FORKED], [AVAHI], [avahi-client >= 0.6.24], + [avahi_client_new], [avahi-client/client.h]) -dnl Checks for misc libav and ffmpeg API differences -save_LIBS="$LIBS" -AC_CHECK_LIB([avcodec], [avcodec_find_best_pix_fmt_of_list], - AC_DEFINE(HAVE_FFMPEG, 1, [Define to 1 if you have ffmpeg/libav with avcodec_find_best_pix_fmt_of_list]),,[-lavutil]) +dnl SQLite3 requires extra checks +FORK_MODULES_CHECK([COMMON], [SQLITE3], [sqlite3 >= 3.5.0], + [sqlite3_initialize], [sqlite3.h], + [dnl Check that SQLite3 has the unlock notify API built-in + AC_CHECK_FUNC([[sqlite3_unlock_notify]], [], + [AC_MSG_ERROR([[SQLite3 was built without unlock notify support]])]) + dnl Check that SQLite3 has been built with threadsafe operations + AC_MSG_CHECKING([[if SQLite3 was built with threadsafe operations support]]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include + ]], [[ + int ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); + if (ret != SQLITE_OK) + return 1;]])], + [AC_MSG_RESULT([[yes]])], + [AC_MSG_RESULT([[no]]) + AC_MSG_ERROR([[SQLite3 was not built with threadsafe operations support]])], + [AC_MSG_RESULT([[runtime will tell]])]) + ]) -AC_CHECK_LIB([avfilter], [av_buffersrc_add_frame_flags], - AC_DEFINE(HAVE_LIBAV_BUFFERSRC_ADD_FRAME_FLAGS, 1, [Define to 1 if you have ffmpeg/libav with av_buffersrc_add_frame_flags])) -AC_CHECK_LIB([avfilter], [av_buffersink_get_frame], - AC_DEFINE(HAVE_LIBAV_BUFFERSINK_GET_FRAME, 1, [Define to 1 if you have ffmpeg/libav with av_buffersink_get_frame])) -AC_CHECK_LIB([avfilter], [avfilter_graph_parse_ptr], - AC_DEFINE(HAVE_LIBAV_GRAPH_PARSE_PTR, 1, [Define to 1 if you have ffmpeg/libav with avfilter_graph_parse_ptr])) -AC_CHECK_LIB([avcodec], [av_packet_unref], - AC_DEFINE(HAVE_LIBAV_PACKET_UNREF, 1, [Define to 1 if you have ffmpeg/libav with av_packet_unref]),,[-lavutil]) -AC_CHECK_LIB([avcodec], [av_packet_rescale_ts], - AC_DEFINE(HAVE_LIBAV_PACKET_RESCALE_TS, 1, [Define to 1 if you have ffmpeg/libav with av_packet_rescale_ts]),,[-lavutil]) -AC_CHECK_LIB([avformat], [avformat_alloc_output_context2], - AC_DEFINE(HAVE_LIBAV_ALLOC_OUTPUT_CONTEXT2, 1, [Define to 1 if you have ffmpeg/libav with avformat_alloc_output_context2])) -AC_CHECK_LIB([avutil], [av_frame_alloc], - AC_DEFINE(HAVE_LIBAV_FRAME_ALLOC, 1, [Define to 1 if you have ffmpeg/libav with av_frame_alloc])) -AC_CHECK_LIB([avutil], [av_frame_get_best_effort_timestamp], - AC_DEFINE(HAVE_LIBAV_BEST_EFFORT_TIMESTAMP, 1, [Define to 1 if you have ffmpeg/libav with av_frame_get_best_effort_timestamp])) -AC_CHECK_LIB([avutil], [av_image_fill_arrays], - AC_DEFINE(HAVE_LIBAV_IMAGE_FILL_ARRAYS, 1, [Define to 1 if you have ffmpeg/libav with av_image_fill_arrays])) -AC_CHECK_LIB([avutil], [av_image_get_buffer_size], - AC_DEFINE(HAVE_LIBAV_IMAGE_GET_BUFFER_SIZE, 1, [Define to 1 if you have ffmpeg/libav with av_image_get_buffer_size])) +dnl libav/ffmpeg requires many feature checks +FORK_MODULES_CHECK([FORKED], [LIBAV], + [libavformat libavcodec libswscale libavutil libavfilter], + [av_init_packet], [libavcodec/avcodec.h], + [dnl Checks for misc libav and ffmpeg API differences + AC_CHECK_FUNCS([avcodec_find_best_pix_fmt_of_list], + [AC_DEFINE([HAVE_FFMPEG], 1, + [Define to 1 if you have ffmpeg (not libav)])]) + AC_CHECK_FUNCS([av_buffersrc_add_frame_flags]) + AC_CHECK_FUNCS([av_buffersink_get_frame]) + AC_CHECK_FUNCS([avfilter_graph_parse_ptr]) + AC_CHECK_FUNCS([av_packet_unref]) + AC_CHECK_FUNCS([av_packet_rescale_ts]) + AC_CHECK_FUNCS([avformat_alloc_output_context2]) + AC_CHECK_FUNCS([av_frame_alloc]) + AC_CHECK_FUNCS([av_frame_get_best_effort_timestamp]) + AC_CHECK_FUNCS([av_image_fill_arrays]) + AC_CHECK_FUNCS([av_image_get_buffer_size]) + AC_CHECK_HEADERS([libavutil/channel_layout.h libavutil/mathematics.h]) + ]) -AC_CHECK_HEADERS([libavutil/channel_layout.h]) -AC_CHECK_HEADERS([libavutil/mathematics.h]) -LIBS="$save_LIBS" +dnl libevent2 requires version checks +FORK_MODULES_CHECK([FORKED], [LIBEVENT], [libevent >= 2], + [event_base_new], [event2/event.h], + [dnl check for old version + PKG_CHECK_EXISTS([libevent >= 2.1.4], [], + [AC_DEFINE([HAVE_LIBEVENT2_OLD], 1, + [Define to 1 if you have libevent 2 (<2.1.4)])]) + ]) -PKG_CHECK_MODULES(MINIXML, [ mxml ]) +dnl antlr version checks +FORK_FUNC_REQUIRE([FORKED], [ANTLR3 C runtime], [ANTLR3C], [antlr3c], + [antlr3BaseRecognizerNew], [antlr3.h], + [AC_CHECK_FUNC([[antlr3NewAsciiStringInPlaceStream]], + [AC_DEFINE([ANTLR3C_NEW_INPUT], 0, + [define if antlr3 C runtime uses new input routines])], + [AC_DEFINE([ANTLR3C_NEW_INPUT], 1, + [define if antlr3 C runtime uses new input routines])]) + ]) -PKG_CHECK_MODULES(LIBEVENT, [ libevent >= 2 ]) -PKG_CHECK_EXISTS([ libevent >= 2.1.4 ], , - AC_DEFINE(HAVE_LIBEVENT2_OLD, 1, [Define to 1 if you have libevent 2 (<2.1.4)]) -) +AM_PATH_LIBGCRYPT([1:1.2.0]) +FORK_FUNC_REQUIRE([FORKED], [GNU Crypt Library], [LIBGCRYPT], [gcrypt], + [gcry_control], [gcrypt.h]) +AM_PATH_GPG_ERROR([1.6]) +FORK_FUNC_REQUIRE([FORKED], [GNUPG Error Values], [GPG_ERROR_MT], [gpg-error], + [gpg_err_init], [gpg-error.h]) -AC_CHECK_HEADER(antlr3.h, , AC_MSG_ERROR([antlr3.h not found])) -AC_CHECK_LIB([antlr3c], [antlr3BaseRecognizerNew], [ANTLR3C_LIBS="-lantlr3c"], AC_MSG_ERROR([ANTLR3 C runtime (libantlr3c) not found])) -AC_CHECK_LIB([antlr3c], [antlr3NewAsciiStringInPlaceStream], - AC_DEFINE(ANTLR3C_NEW_INPUT, 0, [define if antlr3 C runtime uses new input routines]), - AC_DEFINE(ANTLR3C_NEW_INPUT, 1, [define if antlr3 C runtime uses new input routines])) -AC_SUBST(ANTLR3C_LIBS) +AC_CHECK_HEADER([sys/eventfd.h], [AC_CHECK_FUNCS([eventfd])]) -AM_PATH_LIBGCRYPT([1:1.2.0], , AC_MSG_ERROR([libgcrypt not found])) -AM_PATH_GPG_ERROR([1.6], , AC_MSG_ERROR([libgpg-error not found])) +AC_CHECK_HEADER([sys/timerfd.h], [AC_CHECK_FUNC([timerfd_create], + [AC_DEFINE([HAVE_TIMERFD], 1, [Define to 1 if you have timerfd])])]) -case "$host" in - *-*-linux-*) - AC_CHECK_HEADERS([sys/eventfd.h]) - AC_CHECK_FUNC(eventfd_write, AC_DEFINE(HAVE_EVENTFD, 1, [Define to 1 if you have eventfd])) +FORK_FUNC_REQUIRE([FORKED], [inotify], [INOTIFY], [inotify], + [inotify_add_watch], [sys/inotify.h]) - AC_CHECK_HEADER(sys/signalfd.h, , AC_MSG_ERROR([signalfd required; glibc 2.9+ recommended])) +have_signal=no +AC_CHECK_HEADER([sys/signalfd.h], [AC_CHECK_FUNCS([signalfd], [have_signal=yes])]) +AC_CHECK_HEADER([sys/event.h], [AC_CHECK_FUNCS([kqueue], [have_signal=yes])]) +AS_IF([[test "$have_signal" = "no"]], + [AC_MSG_ERROR([[Either signalfd or kqueue are required]])]) - AC_CHECK_HEADER(sys/timerfd.h, , AC_MSG_ERROR([timerfd required; glibc 2.8+ recommended])) - AC_CHECK_FUNC(timerfd_create, , AC_MSG_ERROR([timerfd required; glibc 2.8+ recommended])) - ;; -esac +AC_CHECK_HEADERS_ONCE([endian.h sys/endian.h]) +AC_CHECK_DECL([htobe16], [], + [AC_MSG_FAILURE([[Missing functions to swap byte order]])], + [AC_INCLUDES_DEFAULT[ +#ifdef HAVE_ENDIAN_H +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#endif + ]]) -AC_CHECK_SIZEOF(void *) - -AC_CHECK_HEADERS(getopt.h,,) -AC_CHECK_HEADERS(stdint.h,,) +AC_CHECK_SIZEOF([void *]) dnl --- Begin configuring the options --- dnl ALSA -AC_ARG_WITH(alsa, AS_HELP_STRING([--without-alsa], [without ALSA support (default=no)])) -AS_IF([test "x$with_alsa" != "xno"], [ - AC_DEFINE(ALSA, 1, [Define to 1 to build with ALSA support]) - PKG_CHECK_MODULES(ALSA, [ alsa ]) -]) -AM_CONDITIONAL(COND_ALSA, [test "x$with_alsa" != "xno"]) +FORK_ARG_WITH_CHECK([FORKED], [ALSA support], [alsa], [ALSA], + [alsa], [snd_mixer_open], [asoundlib.h]) +AM_CONDITIONAL([COND_ALSA], [[test "x$with_alsa" = "xyes"]]) dnl PULSEAUDIO -AC_ARG_WITH(pulseaudio, AS_HELP_STRING([--with-pulseaudio], [with Pulseaudio support (default=no)])) -AS_IF([test "x$with_pulseaudio" = "xyes"], [ - AC_DEFINE(PULSEAUDIO, 1, [Define to 1 to build with Pulseaudio support]) - PKG_CHECK_MODULES(LIBPULSE, [ libpulse ]) - AC_SEARCH_LIBS([pa_threaded_mainloop_set_name], [pulse], - AC_DEFINE(HAVE_PULSE_MAINLOOP_SET_NAME, 1, [Define to 1 if you have Pulseaudio with pa_threaded_mainloop_set_name]) - ) -]) -AM_CONDITIONAL(COND_PULSEAUDIO, [test "x$with_pulseaudio" = "xyes"]) +FORK_ARG_WITH_CHECK([FORKED], [Pulseaudio support], [pulseaudio], [LIBPULSE], + [libpulse], [pa_stream_get_state], [pulse/pulseaudio.h], + [AC_CHECK_FUNCS([pa_threaded_mainloop_set_name])]) +AM_CONDITIONAL([COND_PULSEAUDIO], [[test "x$with_pulseaudio" = "xyes"]]) dnl Build with libcurl -AC_ARG_WITH([libcurl], AS_HELP_STRING([--without-libcurl], [without libcurl (default=no)])) -AS_IF([test "x$with_libcurl" != "xno"], [ - AC_DEFINE(HAVE_LIBCURL, 1, [Define to 1 to build with libcurl]) - PKG_CHECK_MODULES(LIBCURL, [ libcurl ]) -]) +FORK_ARG_WITH_CHECK([FORKED], [libcurl support], [libcurl], [LIBCURL], + [libcurl], [curl_global_init], [curl/curl.h]) dnl Build with json-c -AC_ARG_WITH([json], AS_HELP_STRING([--without-json-c], [without json-c (default=no)])) -AS_IF([test "x$with_json" != "xno"], [ - AC_DEFINE(HAVE_JSON, 1, [Define to 1 to build with json-c]) - PKG_CHECK_EXISTS([ json-c >= 0.11 ], - [ PKG_CHECK_MODULES(JSON_C, [ json-c ]) ], - [ PKG_CHECK_MODULES(JSON_C, [ json ], AC_DEFINE(HAVE_JSON_C_OLD, 1, [Define 1 to if you have json-c < 0.11])) ] - ) -]) +FORK_ARG_WITH_CHECK([FORKED], [json-c support], [json], [JSON_C], + [json-c >= 0.11], [json_tokener_parse], [json.h], [], + [FORK_MODULES_CHECK([FORKED], [JSON_C], [json], + [json_tokener_parse], [json.h], + [[with_json=yes] + AC_DEFINE([HAVE_JSON_C_OLD], 1, + [Define to 1 if you have json-c < 0.11])], + [AS_IF([[test "x$with_json" != "xcheck"]], + [AC_MSG_FAILURE([[--with-json was given, but test for json-c failed]])]) + [with_json=no]] + )]) dnl iTunes playlists with libplist -AC_ARG_ENABLE(itunes, AS_HELP_STRING([--enable-itunes], [enable iTunes Music Library XML support (default=no)])) -AS_IF([test "x$enable_itunes" = "xyes"], [ - AC_DEFINE(ITUNES, 1, [Define to 1 to enable iTunes XML support]) - PKG_CHECK_MODULES(LIBPLIST, [ libplist >= 0.16 ]) -]) -AM_CONDITIONAL(COND_ITUNES, [test "x$enable_itunes" = "xyes"]) +FORK_ARG_ENABLE([iTunes Music Library XML support], [itunes], [ITUNES], + [FORK_MODULES_CHECK([FORKED], [LIBPLIST], [libplist >= 0.16], + [plist_dict_get_item], [plist/plist.h])]) +AM_CONDITIONAL([COND_ITUNES], [[test "x$enable_itunes" = "xyes"]]) dnl Spotify with dynamic linking to libspotify -AC_ARG_ENABLE(spotify, AS_HELP_STRING([--enable-spotify], [enable Spotify support (default=no)])) -AS_IF([test "x$enable_spotify" = "xyes"], [ - AC_DEFINE(SPOTIFY, 1, [Define to 1 to enable Spotify support]) - AS_IF([test "x$with_json" = "xno"], AC_MSG_ERROR([Spotify support requires json-c])) - AC_CHECK_HEADER(libspotify/api.h, , AC_MSG_ERROR([libspotify/api.h not found])) - AC_DEFINE(HAVE_SPOTIFY_H, 1, [Define to 1 if you have the header file.]) - - dnl Don't link to libspotify, but instead enable dynamic linking - SPOTIFY_CFLAGS="-rdynamic" - SPOTIFY_LIBS="-ldl" - AC_SUBST(SPOTIFY_CFLAGS) - AC_SUBST(SPOTIFY_LIBS) -]) -AM_CONDITIONAL(COND_SPOTIFY, [test "x$enable_spotify" = "xyes"]) +FORK_ARG_ENABLE([Spotify support], [spotify], [SPOTIFY], + [AS_IF([[test "x$with_json" = "xno"]], + [AC_MSG_ERROR([[Spotify support requires json-c]])]) + AC_CHECK_HEADER([[libspotify/api.h]], [], + [AC_MSG_ERROR([[libspotify/api.h not found]])]) + AC_DEFINE([HAVE_SPOTIFY_H], 1, + [Define to 1 if you have the header file.]) + dnl Don't link to libspotify, but instead enable dynamic linking + AC_SEARCH_LIBS([dlopen], [dl], [], + [AC_MSG_ERROR([[Spotify support requires dlopen]])]) + AC_LIB_APPENDTOVAR([FORKED_CPPFLAGS], [-rdynamic]) + ]) +AM_CONDITIONAL([COND_SPOTIFY], [[test "x$enable_spotify" = "xyes"]]) dnl LastFM support with libcurl -AC_ARG_ENABLE(lastfm, AS_HELP_STRING([--enable-lastfm], [enable LastFM support (default=no)])) -AS_IF([test "x$enable_lastfm" = "xyes"], [ - AC_DEFINE(LASTFM, 1, [Define to 1 to enable LastFM support]) - AS_IF([test "x$with_libcurl" = "xno"], AC_MSG_ERROR([LastFM support requires libcurl])) - AC_CHECK_LIB([mxml], [mxmlGetOpaque], AC_DEFINE(HAVE_MXML_GETOPAQUE, 1, [Define to 1 if your mxml has mxmlGetOpaque.])) -]) -AM_CONDITIONAL(COND_LASTFM, [test "x$enable_lastfm" = "xyes"]) +FORK_ARG_ENABLE([LastFM support], [lastfm], [LASTFM], + [AS_IF([[test "x$with_libcurl" = "xno"]], + [AC_MSG_ERROR([[LastFM support requires libcurl]])])]) +AM_CONDITIONAL([COND_LASTFM], [[test "x$enable_lastfm" = "xyes"]]) dnl ChromeCast support with libprotobuf-c -AC_ARG_ENABLE(chromecast, AS_HELP_STRING([--enable-chromecast], [enable ChromeCast support (default=no)])) -AS_IF([test "x$enable_chromecast" = "xyes"], [ - AC_DEFINE(CHROMECAST, 1, [Define to 1 to enable Chromecast support]) - AS_IF([test "x$with_json" = "xno"], AC_MSG_ERROR([Chromecast support requires json-c])) - PKG_CHECK_MODULES(LIBPROTOBUF_C, [ libprotobuf-c >= 1.0.0 ], , [ protobuf_old="yes" ]) - PKG_CHECK_MODULES(GNUTLS, [ gnutls ]) -]) -AS_IF([test "x$protobuf_old" = "xyes"], [ - AC_DEFINE(HAVE_PROTOBUF_OLD, 1, [Define to 1 if you have libprotobuf < 1.0.0]) - LDFLAGS="${LDFLAGS} -lprotobuf-c" -]) -AM_CONDITIONAL(COND_CHROMECAST, [test "x$enable_chromecast" = "xyes"]) -AM_CONDITIONAL(COND_PROTOBUF_OLD, [test "x$protobuf_old" = "xyes"]) +FORK_ARG_ENABLE([Chromecast support], [chromecast], [CHROMECAST], + [AS_IF([[test "x$with_json" = "xno"]], + [AC_MSG_ERROR([[Chromecast support requires json-c]])]) + FORK_MODULES_CHECK([FORKED], [LIBPROTOBUF_C], + [libprotobuf-c >= 1.0.0], [protobuf_c_message_pack], + [protobuf-c/protobuf-c.h], [], + [FORK_FUNC_REQUIRE([FORKED], [v0 libprotobuf-c], + [LIBPROTOBUF_OLD], [protobuf-c], + [protobuf_c_message_pack], + [google/protobuf-c/protobuf-c.h], + [AC_DEFINE([HAVE_PROTOBUF_OLD], 1, + [Define to 1 if you have libprotobuf < 1.0.0]) + [protobuf_old=yes]], + [AC_MSG_ERROR([[Chromecast support requires protobuf-c]])]) + ]) + FORK_MODULES_CHECK([FORKED], [GNUTLS], [gnutls], [gnutls_init], + [gnutls/gnutls.h]) + ]) +AM_CONDITIONAL([COND_CHROMECAST], [[test "x$enable_chromecast" = "xyes"]]) +AM_CONDITIONAL([COND_PROTOBUF_OLD], [[test "x$protobuf_old" = "xyes"]]) dnl MPD support -AC_ARG_ENABLE(mpd, AS_HELP_STRING([--disable-mpd], [disable MPD client protocol support (default=no)])) -AS_IF([test "x$enable_mpd" != "xno"], [ - AC_DEFINE(MPD, 1, [Define to 1 to enable MPD support]) -]) -AM_CONDITIONAL(COND_MPD, [test "x$enable_mpd" != "xno"]) +FORK_ARG_DISABLE([MPD client protocol support], [mpd], [MPD]) +AM_CONDITIONAL([COND_MPD], [[test "x$enable_mpd" = "xyes"]]) + +dnl Defining users and groups +AC_ARG_WITH([daapd_user], + [AS_HELP_STRING([--with-daapd-user=USER], + [User for running forked-daapd (default=daapd)])], + [[test x"$withval" = xyes && withval=]], [[withval=]]) +DAAPD_USER=${withval:-daapd} +AC_SUBST([DAAPD_USER]) + +AC_ARG_WITH([daapd_group], + [AS_HELP_STRING([--with-daapd-group=GROUP], + [Group for daapd user (default=USER)])], + [[test x"$withval" = xyes && withval=]], [[withval=]]) +DAAPD_GROUP=${withval:-$DAAPD_USER} +AC_SUBST([DAAPD_GROUP]) dnl --- End options --- -dnl Checks for header files. -AC_HEADER_STDC -AC_HEADER_SYS_WAIT - -AC_OUTPUT(src/Makefile sqlext/Makefile Makefile) +AC_CONFIG_FILES([ + src/Makefile + sqlext/Makefile + Makefile + forked-daapd.spec +]) +AC_OUTPUT diff --git a/forked-daapd.conf b/forked-daapd.conf.in similarity index 97% rename from forked-daapd.conf rename to forked-daapd.conf.in index 2f23e69f..ca4ee9b3 100644 --- a/forked-daapd.conf +++ b/forked-daapd.conf.in @@ -11,14 +11,14 @@ general { # Username # Make sure the user has read access to the library directories you set # below, and full access to the databases, log and local audio - uid = "daapd" + uid = "@DAAPD_USER@" # Database location -# db_path = "/var/cache/forked-daapd/songs3.db" +# db_path = "@localstatedir@/cache/@PACKAGE@/songs3.db" # Log file and level # Available levels: fatal, log, warning, info, debug, spam - logfile = "/var/log/forked-daapd.log" + logfile = "@localstatedir@/log/@PACKAGE@.log" loglevel = log # Admin password for the non-existent web interface @@ -28,7 +28,7 @@ general { ipv6 = yes # Location of cache database -# cache_path = "/var/cache/forked-daapd/cache.db" +# cache_path = "@localstatedir@/cache/@PACKAGE@/cache.db" # DAAP requests that take longer than this threshold (in msec) get their # replies cached for next time. Set to 0 to disable caching. @@ -203,7 +203,7 @@ audio { # Spotify settings (only have effect if Spotify enabled - see README/INSTALL) spotify { # Directory where user settings should be stored (credentials) -# settings_dir = "/var/cache/forked-daapd/libspotify" +# settings_dir = "@localstatedir@/cache/@PACKAGE@/libspotify" # Cache directory # cache_dir = "/tmp" diff --git a/forked-daapd.service b/forked-daapd.service.in old mode 100755 new mode 100644 similarity index 80% rename from forked-daapd.service rename to forked-daapd.service.in index d2bccbc2..ff987df8 --- a/forked-daapd.service +++ b/forked-daapd.service.in @@ -1,9 +1,10 @@ [Unit] Description=DAAP/DACP (iTunes), RSP and MPD server, supports AirPlay and Remote +Documentation=man:forked-daapd(8) After=network.target sound.target [Service] -ExecStart=/usr/sbin/forked-daapd -f +ExecStart=@sbindir@/forked-daapd -f # Restart, but not more than once every 10 minutes Restart=on-failure diff --git a/forked-daapd.spec.in b/forked-daapd.spec.in new file mode 100644 index 00000000..0f2a1de1 --- /dev/null +++ b/forked-daapd.spec.in @@ -0,0 +1,174 @@ +# -*- Mode:rpm-spec -*- +# @configure_input@ +%global username @DAAPD_USER@ +%global groupname @DAAPD_GROUP@ + +%bcond_without alsa +%bcond_with pulseaudio +%bcond_without libcurl +%bcond_without json +%bcond_with itunes +%bcond_with spotify +%bcond_with lastfm +%bcond_with chromecast +%bcond_without mpd + +%global _hardened_build 1 + +Summary: iTunes-compatible DAAP server with MPD and RSP support +Name: @PACKAGE_NAME@ +Version: @PACKAGE_VERSION@ +Release: 1%{?dist} +License: GPLv2+ +Group: Applications/Multimedia +Url: https://github.com/ejurgensen/forked-daapd +Source: https://github.com/ejurgensen/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz +%{?systemd_ordering} +BuildRequires: systemd +BuildRequires: pkgconfig +BuildRequires: pkgconfig(sqlite3) >= 3.5.0 +BuildRequires: pkgconfig(libconfuse) +BuildRequires: libunistring-devel +BuildRequires: pkgconfig(mxml) +BuildRequires: pkgconfig(libevent) >= 2.0.0 +BuildRequires: pkgconfig(avahi-client) >= 0.6.24 +BuildRequires: libgcrypt-devel >= 1.2.0 +BuildRequires: libgpg-error-devel >= 1.6 +BuildRequires: pkgconfig(zlib) +BuildRequires: antlr3-C-devel +BuildRequires: pkgconfig(libavformat) +BuildRequires: pkgconfig(libavcodec) +BuildRequires: pkgconfig(libswscale) +BuildRequires: pkgconfig(libavutil) +BuildRequires: pkgconfig(libavfilter) +Requires(pre): shadow-utils +Requires: systemd-units +%if %{with alsa} +BuildRequires: pkgconfig(alsa) +%endif +%if %{with pulseaudio} +BuildRequires: pkgconfig(libpulse) +%endif +%if %{with libcurl} +BuildRequires: pkgconfig(libcurl) +%endif +%if %{with json} +BuildRequires: pkgconfig(json-c) +%endif +%if %{with itunes} +BuildRequires: pkgconfig(libplist) >= 0.16 +%endif +%if %{with spotify} +BuildRequires: libspotify-devel +%endif +%if %{with chromecast} +BuildRequires: pkgconfig(gnutls) +BuildRequires: pkgconfig(libprotobuf-c) +%endif + +%global homedir %{_localstatedir}/lib/%{name} +%global gecos %{name} User +%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} + +%description +forked-daapd is a DAAP/DACP (iTunes), MPD (Music Player Daemon) +and RSP (Roku) media server. + +It has support for AirPlay devices/speakers, Apple Remote (and compatibles), +MPD clients, Chromecast, network streaming, internet radio, Spotify and LastFM. + +It does not support streaming video by AirPlay nor Chromecast. + +DAAP stands for Digital Audio Access Protocol, and is the protocol used +by iTunes and friends to share/stream media libraries over the network. + +forked-daapd is a complete rewrite of mt-daapd (Firefly Media Server). + +%prep +%if %{with spotify} && %{without json} +echo "ERROR: Option '-with spotify' cannot be used with '-without json'" >&2 && exit 1 +%endif +%if %{with lastfm} && %{without libcurl} +echo "ERROR: Option '-with lastfm' cannot be used with '-without libcurl'" >&2 && exit 1 +%endif +%if %{with chromecast} && %{without json} +echo "ERROR: Option '-with chromecast' cannot be used with '-without json'" >&2 && exit 1 +%endif + +%setup -q + +%build +%configure \ +%if %{without alsa} + --without-alsa \ +%endif +%if %{without pulseaudio} + --without-pulseaudio \ +%endif +%if %{without libcurl} + --without-libcurl \ +%endif +%if %{without json} + --without-json \ +%endif +%if %{with itunes} + --enable-itunes \ +%endif +%if %{with spotify} + --enable-spotify \ +%endif +%if %{with lastfm} + --enable-lastfm \ +%endif +%if %{with chromecast} + --enable-chromecast \ +%endif +%if %{with mpd} + --enable-mpd \ +%endif + --with-daapd-user=%{username} \ + --with-daapd-group=%{groupname} +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} docdir=%{_pkgdocdir} +rm -f %{buildroot}%{_pkgdocdir}/INSTALL +mkdir -p %{buildroot}%{homedir} +mkdir -p %{buildroot}%{_localstatedir}/log +touch %{buildroot}%{_localstatedir}/log/%{name}.log +mkdir -p %{buildroot}%{_unitdir} +install -m 0644 forked-daapd.service %{buildroot}%{_unitdir}/%{name}.service +rm -f %{buildroot}%{_libdir}/%{name}/*.la + +%pre +getent group %{groupname} >/dev/null || groupadd -r %{groupname} +getent passwd %{username} >/dev/null || \ + useradd -r -g %{groupname} -d %{homedir} -s /sbin/nologin \ + -c '%{gecos}' %{username} +exit 0 + +%post +%systemd_post %{name}.service + +%preun +%systemd_preun %{name}.service + +%postun +%systemd_postun_with_restart %{name}.service + +%files +%{!?_licensedir:%global license %%doc} +%license COPYING +%{_pkgdocdir} +%config(noreplace) %{_sysconfdir}/forked-daapd.conf +%{_sbindir}/forked-daapd +%{_libdir}/* +%{_unitdir}/%{name}.service +%attr(0750,%{username},%{groupname}) %{_localstatedir}/cache/%{name} +%attr(0750,%{username},%{groupname}) %{homedir} +%ghost %{_localstatedir}/log/%{name}.log +%{_mandir}/man?/* + +%changelog +* Tue Dec 20 2016 Scott Shambarger - 24.2-1 + - Initial RPM release candidate. diff --git a/m4/fork_checks.m4 b/m4/fork_checks.m4 new file mode 100644 index 00000000..dea124a9 --- /dev/null +++ b/m4/fork_checks.m4 @@ -0,0 +1,193 @@ +# fork_checks.m4 serial 1 +dnl Copyright (c) Scott Shambarger +dnl +dnl Copying and distribution of this file, with or without modification, are +dnl permitted in any medium without royalty provided the copyright notice +dnl and this notice are preserved. This file is offered as-is, without any +dnl warranty. + +dnl _FORK_CFLAGS_APPEND(TARGET, SOURCE) +dnl ----------------------------------- +dnl Internal use only. Shamelessly copied from AC_LIB_APPENDTOVAR, +dnl but without prefix expansion that breaks nesting. +m4_define([_FORK_CFLAGS_APPEND], +[[ + for element in $2; do + haveit= + for x in $$1; do + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + $1="${$1}${$1:+ }$element" + fi + done +]]) + +dnl FORK_VARS_APPEND(TARGET, LIBS_ENV, CFLAGS_ENV) +dnl ---------------------------------------------- +dnl Prepend LIBS_ENV to LIBS and TARGET_LIBS +dnl Append CFLAGS_ENV to CPPFLAGS and TARGET_CPPFLAGS. +AC_DEFUN([FORK_VARS_APPEND], +[[ + LIBS="$$2 $LIBS" + $1_LIBS="$$2 $$1_LIBS"] + _FORK_CFLAGS_APPEND([CPPFLAGS], [$$3]) + _FORK_CFLAGS_APPEND([$1_CPPFLAGS], [$$3]) +]) + +dnl _FORK_VARS_ADD_PREFIX(TARGET) +dnl ----------------------------- +dnl Internal use only. Add libdir prefix to {TARGET_}LIBS and +dnl includedir prefix to {TARGET_}CPPFLAGS as fallback search paths +dnl expanding all variables. +AC_DEFUN([_FORK_VARS_ADD_PREFIX], +[AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_LIB_WITH_FINAL_PREFIX([[ + eval LIBS=\"-L$libdir $LIBS\" + eval $1_LIBS=\"-L$libdir $$1_LIBS\" + eval fork_tmp_cppflags=\"-I$includedir\"] + _FORK_CFLAGS_APPEND([CPPFLAGS], [$fork_tmp_cppflags]) + _FORK_CFLAGS_APPEND([$1_CPPFLAGS], [$fork_tmp_cppflags]) + ]) +]) + +dnl FORK_FUNC_REQUIRE(TARGET, DESCRIPTION, ENV, LIBRARY, FUNCTION, [HEADER], +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------------ +dnl Check for software which lacks pkg-config support, setting TARGET_CPPFLAGS +dnl and TARGET_LIBS with working values if FUNCTION found, or failing if +dnl it's not. If ENV_CFLAGS and ENV_LIBS overrides are set (ENV is prefix), +dnl tries to link FUNCTION/include HEADER with them. Without overrides, +dnl expands like AC_SEARCH_LIBS on FUNCTION (trying without and with LIBRARY), +dnl adding $prefix paths if necessary. If FUNCTION found, verifies optional +dnl HEADER can be included (or fails with error), and expands optional +dnl ACTION-IF-FOUND with working CPPFLAGS/LIBS for additional checks. +dnl DESCRIPTION used as friendly name in error messages to help user +dnl identify software to install. If FUNCTION not found, either displays +dnl error suggested use of ENV_* overrides, or if ENV_* were not set +dnl expands optional ACTION-IF-NOT-FOUND in place of error. +dnl Restores original CPPFLAGS and LIBS when done. +AC_DEFUN([FORK_FUNC_REQUIRE], +[AS_VAR_PUSHDEF([FORK_MSG], [fork_msg_$3]) + AC_ARG_VAR([$3_CFLAGS], [C compiler flags for $2, overriding search]) + AC_ARG_VAR([$3_LIBS], [linker flags for $2, overriding search]) + [fork_save_$3_LIBS=$LIBS; fork_save_$3_CPPFLAGS=$CPPFLAGS + fork_found_$3=yes] + AS_IF([[test -n "$$3_CFLAGS" && test -n "$$3_LIBS"]], + [dnl ENV variables provided, just verify they work + AS_VAR_SET([FORK_MSG], [[" +Library specific environment variables $3_LIBS and +$3_CFLAGS were used, verify they are correct..."]]) + FORK_VARS_APPEND([$1], [$3_LIBS], [$3_CFLAGS]) + AC_CHECK_FUNC([[$5]], [], + [AC_MSG_FAILURE([[Unable to link function $5 with $2.$]FORK_MSG])])], + [dnl Search w/o LIBRARY, w/ LIBRARY, and finally adding $prefix path + AS_VAR_SET([FORK_MSG], [[" +Install $2 in the default include path, or alternatively set +library specific environment variables $3_CFLAGS +and $3_LIBS."]]) + AC_MSG_CHECKING([[for library containing $5...]]) + AC_TRY_LINK_FUNC([[$5]], [AC_MSG_RESULT([[none required]])], + [[LIBS="-l$4 $LIBS" + $1_LIBS="-l$4 $$1_LIBS"] + AC_TRY_LINK_FUNC([[$5]], [AC_MSG_RESULT([[-l$4]])], + [_FORK_VARS_ADD_PREFIX([$1]) + AC_TRY_LINK_FUNC([[$5]], [AC_MSG_RESULT([[-l$4]])], + [AC_MSG_RESULT([[no]]) + fork_found_$3=no])]) + ]) + ]) + AS_IF([[test "$fork_found_$3" != "no"]], + [dnl check HEADER, then expand FOUND + m4_ifval([$6], [AC_CHECK_HEADER([[$6]], [], + [AC_MSG_FAILURE([[Unable to find header $6 for $2.$]FORK_MSG])])]) + $7]) + [LIBS=$fork_save_$3_LIBS; CPPFLAGS=$fork_save_$3_CPPFLAGS] + dnl Expand NOT-FOUND after restoring saved flags to allow recursive expansion + AS_IF([[test "$fork_found_$3" = "no"]], + [m4_default_nblank([$8], + [AC_MSG_FAILURE([[Function $5 in lib$4 not found.$]FORK_MSG])])]) + AS_VAR_POPDEF([FORK_MSG]) +]) + +dnl FORK_MODULES_CHECK(TARGET, ENV, MODULES, [FUNCTION], [HEADER], +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Expands PKG_CHECK_MODULES, but when found also attempt to link +dnl FUNCTION and include HEADER. Appends working package values to +dnl TARGET_CPPFLAGS and TARGET_LIBS. Expands optional ACTION-IF-FOUND with +dnl working CPPFLAGS/LIBS for additional checks. Expands +dnl ACTION-IF-NOT-FOUND only if package not found (not link/include failures) +dnl overriding default error. Restores original CPPFLAGS and LIBS when done. +AC_DEFUN([FORK_MODULES_CHECK], +[PKG_CHECK_MODULES([$2], [[$3]], + [[fork_save_$2_LIBS=$LIBS; fork_save_$2_CPPFLAGS=$CPPFLAGS] + FORK_VARS_APPEND([$1], [$2_LIBS], [$2_CFLAGS]) + m4_ifval([$4], [AC_CHECK_FUNC([[$4]], [], + [AC_MSG_ERROR([[Unable to link function $4]])])]) + m4_ifval([$5], [AC_CHECK_HEADER([[$5]], [], + [AC_MSG_ERROR([[Unable to find header $5]])])]) + $6 + [LIBS=$fork_save_$2_LIBS; CPPFLAGS=$fork_save_$2_CPPFLAGS]], + m4_default_nblank_quoted([$7])) +]) + +dnl FORK_ARG_WITH_CHECK(TARGET, DESCRIPTION, OPTION, ENV, MODULES, [FUNCTION], +dnl [HEADER], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------------------- +dnl Create an --with-OPTION with a default of "check" (include MODULES +dnl if they are available). Expands FORK_MODULES_CHECK with remaining +dnl arguments. Defines HAVE_ENV to 1 if package found. DESCRIPTION is used +dnl in option help. Shell variable with_OPTION set to yes before +dnl ACTION-IF-FOUND. Default ACTION-IF-NOT-FOUND will fail +dnl if --with-OPTION given and MODULES not found, or sets shell var +dnl with_OPTION to no if option was check. A non-empty ACTION-IF-NOT-FOUND +dnl overrides this behavior to allow alternate checks. +AC_DEFUN([FORK_ARG_WITH_CHECK], +[AC_ARG_WITH([[$3]], [AS_HELP_STRING([--with-$3], + [with $2 (default=check)])], [], + [[with_$3=check]]) + AS_IF([[test "x$with_$3" != "xno"]], + [FORK_MODULES_CHECK([$1], [$4], [$5], [$6], [$7], + [[with_$3=yes] + AC_DEFINE([HAVE_$4], 1, [Define to 1 to build with $2]) + $8], + [m4_default_nblank([$9], + [AS_IF([[test "x$with_$3" != "xcheck"]], + [AC_MSG_FAILURE([[--with-$3 was given, but test for $5 failed]])]) + [with_$3=no]]) + ]) + ]) +]) + +dnl FORK_ARG_ENABLE(DESCRIPTION, OPTION, DEFINE, [ACTION-IF-ENABLE]) +dnl ---------------------------------------------------------------- +dnl Create an --enable-OPTION, setting shell variable enable_OPTION +dnl to no by default. If feature is enabled, defines DEFINE to 1 +dnl and expand ACTION-IF_ENABLE. DESCRIPTION is used in option help. +AC_DEFUN([FORK_ARG_ENABLE], +[AC_ARG_ENABLE([[$2]], [AS_HELP_STRING([--enable-$2], + [enable $1 (default=no)])]) + AS_IF([[test "x$enable_$2" = "xyes"]], + [AC_DEFINE([$3], 1, [Define to 1 to enable $1]) + $4], + [[enable_$2=no]]) +]) + +dnl FORK_ARG_DISABLE(DESCRIPTION, OPTION, DEFINE, [ACTION-IF-ENABLE]) +dnl ---------------------------------------------------------------- +dnl Create an --disable-OPTION, setting shell variable enable_OPTION +dnl to yes by default. If feature is enabled, defines DEFINE to 1 +dnl and expand ACTION-IF_ENABLE. DESCRIPTION is used in option help. +AC_DEFUN([FORK_ARG_DISABLE], +[AC_ARG_ENABLE([[$2]], [AS_HELP_STRING([--disable-$2], + [disable $1 (default=no)])]) + AS_IF([[test "x$enable_$2" = "x" || test "x$enable_$2" = "xyes"]], + [AC_DEFINE([$3], 1, [Define to 1 to enable $1]) + [enable_$2=yes] + $4], + [[enable_$2=no]]) +]) diff --git a/m4/libunistring.m4 b/m4/libunistring.m4 deleted file mode 100644 index ac9d11ac..00000000 --- a/m4/libunistring.m4 +++ /dev/null @@ -1,41 +0,0 @@ -# libunistring.m4 serial 4 -dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl gl_LIBUNISTRING -dnl Searches for an installed libunistring. -dnl If found, it sets and AC_SUBSTs HAVE_LIBUNISTRING=yes and the LIBUNISTRING -dnl and LTLIBUNISTRING variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIBUNISTRING to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIBUNISTRING=no and LIBUNISTRING and LTLIBUNISTRING to empty. - -AC_DEFUN([gl_LIBUNISTRING], -[ - dnl First, try to link without -liconv. libunistring often depends on - dnl libiconv, but we don't know (and often don't need to know) where - dnl libiconv is installed. - AC_LIB_HAVE_LINKFLAGS([unistring], [], - [#include ], [u8_strconv_from_locale((char*)0);], - [no, consider installing GNU libunistring]) - if test "$ac_cv_libunistring" != yes; then - dnl Second try, with -liconv. - AC_REQUIRE([AM_ICONV]) - if test -n "$LIBICONV"; then - dnl We have to erase the cached result of the first AC_LIB_HAVE_LINKFLAGS - dnl invocation, otherwise the second one will not be run. - unset ac_cv_libunistring - glus_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_LIB_HAVE_LINKFLAGS([unistring], [], - [#include ], [u8_strconv_from_locale((char*)0);], - [no, consider installing GNU libunistring]) - if test -n "$LIBUNISTRING"; then - LIBUNISTRING="$LIBUNISTRING $LIBICONV" - LTLIBUNISTRING="$LTLIBUNISTRING $LTLIBICONV" - fi - LIBS="$glus_save_LIBS" - fi - fi -]) diff --git a/sqlext/Makefile.am b/sqlext/Makefile.am index 3dde67c4..74155a6f 100644 --- a/sqlext/Makefile.am +++ b/sqlext/Makefile.am @@ -2,4 +2,8 @@ pkglib_LTLIBRARIES = forked-daapd-sqlext.la forked_daapd_sqlext_la_SOURCES = sqlext.c forked_daapd_sqlext_la_LDFLAGS = -avoid-version -module -shared -forked_daapd_sqlext_la_LIBADD = @LIBUNISTRING@ +AM_CPPFLAGS += \ + $(COMMON_CPPFLAGS) + +forked_daapd_sqlext_la_LIBADD = \ + $(COMMON_LIBS) diff --git a/src/.gitignore b/src/.gitignore index 0770c261..df342490 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,13 +3,10 @@ forked-daapd *.tokens *Lexer.[ch] *Parser.[ch] -DAAP2SQL.[ch] -RSP2SQL.[ch] -SMARTPL2SQL.[ch] - +*2SQL.[ch] *.u -daap_query_hash.c -rsp_query_hash.c -dacp_prop_hash.c -dmap_fields_hash.c +daap_query_hash.h +rsp_query_hash.h +dacp_prop_hash.h +dmap_fields_hash.h diff --git a/src/DAAP2SQL.g b/src/DAAP2SQL.g index 348885a7..50a1776b 100644 --- a/src/DAAP2SQL.g +++ b/src/DAAP2SQL.g @@ -44,7 +44,7 @@ options { }; /* gperf static hash, daap_query.gperf */ - #include "daap_query_hash.c" + #include "daap_query_hash.h" } query returns [ pANTLR3_STRING result ] diff --git a/src/Makefile.am b/src/Makefile.am index cc0149d5..ca9027f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,18 +39,18 @@ GPERF_FILES = \ dacp_prop.gperf \ dmap_fields.gperf -GPERF_PRODUCTS = \ - daap_query_hash.c \ - rsp_query_hash.c \ - dacp_prop_hash.c \ - dmap_fields_hash.c +GPERF_SRC = $(GPERF_FILES:.gperf=_hash.h) ANTLR_GRAMMARS = \ RSP.g RSP2SQL.g \ DAAP.g DAAP2SQL.g \ SMARTPL.g SMARTPL2SQL.g -ANTLR_SOURCES = \ +ANTLR_TOKENS = $(ANTLR_GRAMMARS:.g=.tokens) + +ANTLR_DEPS = $(ANTLR_GRAMMARS:%.g=$(srcdir)/%.u) + +ANTLR_SRC = \ RSPLexer.c RSPLexer.h RSPParser.c RSPParser.h \ RSP2SQL.c RSP2SQL.h \ DAAPLexer.c DAAPLexer.h DAAPParser.c DAAPParser.h \ @@ -58,24 +58,19 @@ ANTLR_SOURCES = \ SMARTPLLexer.c SMARTPLLexer.h SMARTPLParser.c SMARTPLParser.h \ SMARTPL2SQL.c SMARTPL2SQL.h -ANTLR_PRODUCTS = +AM_CPPFLAGS += \ + $(FORKED_CPPFLAGS) \ + $(COMMON_CPPFLAGS) \ + \ + -D_GNU_SOURCE \ + -DDATADIR=\"$(pkgdatadir)\" \ + -DCONFDIR=\"$(sysconfdir)\" \ + -DSTATEDIR=\"$(localstatedir)\" \ + -DPKGLIBDIR=\"$(pkglibdir)\" -forked_daapd_CPPFLAGS = -D_GNU_SOURCE \ - -DDATADIR="\"$(pkgdatadir)\"" -DCONFDIR="\"$(sysconfdir)\"" \ - -DSTATEDIR="\"$(localstatedir)\"" -DPKGLIBDIR="\"$(pkglibdir)\"" - -forked_daapd_CFLAGS = \ - @ZLIB_CFLAGS@ @AVAHI_CFLAGS@ @SQLITE3_CFLAGS@ @LIBAV_CFLAGS@ \ - @CONFUSE_CFLAGS@ @MINIXML_CFLAGS@ @LIBPLIST_CFLAGS@ @SPOTIFY_CFLAGS@ \ - @LIBGCRYPT_CFLAGS@ @GPG_ERROR_CFLAGS@ @ALSA_CFLAGS@ @LIBPULSE_CFLAGS@ \ - @LIBCURL_CFLAGS@ @LIBPROTOBUF_C_CFLAGS@ @GNUTLS_CFLAGS@ @JSON_C_CFLAGS@ - -forked_daapd_LDADD = -lrt \ - @ZLIB_LIBS@ @AVAHI_LIBS@ @SQLITE3_LIBS@ @LIBAV_LIBS@ \ - @CONFUSE_LIBS@ @LIBEVENT_LIBS@ @LIBUNISTRING@ \ - @MINIXML_LIBS@ @ANTLR3C_LIBS@ @LIBPLIST_LIBS@ @SPOTIFY_LIBS@ \ - @LIBGCRYPT_LIBS@ @GPG_ERROR_LIBS@ @ALSA_LIBS@ @LIBPULSE_LIBS@ \ - @LIBCURL_LIBS@ @LIBPROTOBUF_C_LIBS@ @GNUTLS_LIBS@ @JSON_C_LIBS@ +forked_daapd_LDADD = \ + $(FORKED_LIBS) \ + $(COMMON_LIBS) forked_daapd_SOURCES = main.c \ db.c db.h \ @@ -109,63 +104,42 @@ forked_daapd_SOURCES = main.c \ outputs.h outputs.c \ outputs/raop.c outputs/streaming.c outputs/dummy.c outputs/fifo.c \ $(ALSA_SRC) $(PULSEAUDIO_SRC) $(CHROMECAST_SRC) \ - evrtsp/rtsp.c evrtp/evrtsp.h evrtsp/rtsp-internal.h evrtsp/log.h \ + evrtsp/rtsp.c evrtsp/evrtsp.h evrtsp/rtsp-internal.h evrtsp/log.h \ $(SPOTIFY_SRC) \ $(LASTFM_SRC) \ $(MPD_SRC) \ listener.c listener.h \ - commands.c commands.h - -nodist_forked_daapd_SOURCES = \ - $(ANTLR_SOURCES) + commands.c commands.h \ + ffmpeg-compat.h \ + $(GPERF_SRC) \ + $(ANTLR_SRC) +# built by maintainers, and distributed. Clean with maintainer-clean BUILT_SOURCES = \ - $(GPERF_PRODUCTS) + $(GPERF_SRC) \ + $(ANTLR_SRC) \ + $(ANTLR_TOKENS) \ + $(ANTLR_DEPS) EXTRA_DIST = \ - $(ANTLR_GRAMMARS) - -CLEANFILES = \ - $(GPERF_PRODUCTS) - + $(GPERF_FILES) \ + $(ANTLR_GRAMMARS) \ + $(ANTLR_TOKENS) \ + $(ANTLR_DEPS) # gperf construction rules -%_hash.c: %.gperf - if $(GPERF) $< > $@.tmp; then \ - mv $@.tmp $@; \ - elif $(GPERF) --version >/dev/null 2>&1; then \ - rm $@.tmp; \ - exit 1; \ - else \ - rm $@.tmp; \ - touch $@; \ - fi - -# Support for building the parsers when ANTLR3 is available -if COND_ANTLR -SUFFIXES = .g .u +%_hash.h: %.gperf + $(AM_V_GEN)$(GPERF) --output-file=$@ $< +# ANTLR grammar products %.tokens %.c %Lexer.c %Parser.c %Lexer.h %Parser.h %.h: %.g - $(ANTLR) -Xconversiontimeout 30000 $(ANTLR_OPTIONS) $< + @$(AM_V_P) || echo " GEN " $< "products" + $(AM_V_at)$(ANTLR) -Xconversiontimeout 30000 $(ANTLR_OPTIONS) -fo . $< +# ANTLR dependency files (bypass circular dependency of .g on .tokens) %.u: %.g - $(ANTLR) -depend $< > $@ - @echo -n "ANTLR_PRODUCTS += " > $@.tmp - @grep : $@ | cut -d : -f 1 | tr -d ' ' | { while read f; do test "$$f" != "$<" && echo -n "$$f "; done } >> $@.tmp - @cat $@.tmp >> $@ - @rm $@.tmp + $(AM_V_GEN)$(ANTLR) -depend -fo . $< > $@ + $(AM_V_at)$(SED) -n -e '/^.*\.g[ ]*:\(.*\)/ { s//\1/;h;d; }' -e '/\.tokens.*:/ { p;d; }' -e '/:/ { G;s/\n/ /;p; }' $@ > $@-t + $(AM_V_at)mv $@-t $@ -BUILT_SOURCES += $(ANTLR_SOURCES) - -CLEANFILES += \ - $(ANTLR_PRODUCTS) \ - $(ANTLR_GRAMMARS:.g=.u) - -else !COND_ANTLR -DISTCLEANFILES = \ - $(ANTLR_PRODUCTS) \ - $(ANTLR_GRAMMARS:.g=.u) - -endif - --include $(ANTLR_GRAMMARS:.g=.u) +-include $(ANTLR_DEPS) diff --git a/src/RSP2SQL.g b/src/RSP2SQL.g index c22b9312..78c67593 100644 --- a/src/RSP2SQL.g +++ b/src/RSP2SQL.g @@ -50,7 +50,7 @@ options { }; /* gperf static hash, rsp_query.gperf */ - #include "rsp_query_hash.c" + #include "rsp_query_hash.h" } query returns [ pANTLR3_STRING result ] diff --git a/src/artwork.c b/src/artwork.c index 76ed13d9..423bdebc 100644 --- a/src/artwork.c +++ b/src/artwork.c @@ -505,7 +505,7 @@ artwork_rescale(struct evbuffer *evbuf, AVFormatContext *src_ctx, int s, int out goto out_free_frames; } -#ifdef HAVE_LIBAV_IMAGE_FILL_ARRAYS +#ifdef HAVE_AV_IMAGE_FILL_ARRAYS av_image_fill_arrays(o_frame->data, o_frame->linesize, buf, dst->pix_fmt, src->width, src->height, 1); #else avpicture_fill((AVPicture *)o_frame, buf, dst->pix_fmt, src->width, src->height); diff --git a/src/commands.c b/src/commands.c index cdccda6b..91752357 100644 --- a/src/commands.c +++ b/src/commands.c @@ -183,11 +183,11 @@ commands_base_new(struct event_base *evbase, command_exit_cb exit_cb) return NULL; } -# if defined(__linux__) +#ifdef HAVE_PIPE2 ret = pipe2(cmdbase->command_pipe, O_CLOEXEC); -# else +#else ret = pipe(cmdbase->command_pipe); -# endif +#endif if (ret < 0) { DPRINTF(E_LOG, L_MAIN, "Could not create command pipe: %s\n", strerror(errno)); diff --git a/src/dmap_common.c b/src/dmap_common.c index d79675ef..250a2d13 100644 --- a/src/dmap_common.c +++ b/src/dmap_common.c @@ -31,7 +31,7 @@ /* gperf static hash, dmap_fields.gperf */ -#include "dmap_fields_hash.c" +#include "dmap_fields_hash.h" const struct dmap_field * diff --git a/src/ffmpeg-compat.h b/src/ffmpeg-compat.h index 604de122..e262f39a 100644 --- a/src/ffmpeg-compat.h +++ b/src/ffmpeg-compat.h @@ -13,24 +13,24 @@ # define avcodec_find_best_pix_fmt_of_list(a, b, c, d) avcodec_find_best_pix_fmt2((enum AVPixelFormat *)(a), (b), (c), (d)) #endif -#ifndef HAVE_LIBAV_FRAME_ALLOC +#ifndef HAVE_AV_FRAME_ALLOC # define av_frame_alloc() avcodec_alloc_frame() # define av_frame_free(x) avcodec_free_frame((x)) #endif -#ifndef HAVE_LIBAV_BEST_EFFORT_TIMESTAMP +#ifndef HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP # define av_frame_get_best_effort_timestamp(x) (x)->pts #endif -#ifndef HAVE_LIBAV_IMAGE_GET_BUFFER_SIZE +#ifndef HAVE_AV_IMAGE_GET_BUFFER_SIZE # define av_image_get_buffer_size(a, b, c, d) avpicture_get_size((a), (b), (c)) #endif -#ifndef HAVE_LIBAV_PACKET_UNREF +#ifndef HAVE_AV_PACKET_UNREF # define av_packet_unref(a) av_free_packet((a)) #endif -#ifndef HAVE_LIBAV_PACKET_RESCALE_TS +#ifndef HAVE_AV_PACKET_RESCALE_TS static void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) { @@ -45,7 +45,7 @@ av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) } #endif -#ifndef HAVE_LIBAV_ALLOC_OUTPUT_CONTEXT2 +#ifndef HAVE_AVFORMAT_ALLOC_OUTPUT_CONTEXT2 # include static int diff --git a/src/filescanner.c b/src/filescanner.c index 7ebd55ce..5779ffd4 100644 --- a/src/filescanner.c +++ b/src/filescanner.c @@ -113,14 +113,15 @@ static struct deferred_pl *playlists; static struct stacked_dir *dirstack; static struct commands_base *cmdbase; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#ifndef __linux__ struct deferred_file { struct watch_info wi; - struct inotify_event ie; char path[PATH_MAX]; struct deferred_file *next; + /* variable sized, must be at the end */ + struct inotify_event ie; }; static struct deferred_file *filestack; @@ -1068,9 +1069,9 @@ process_directory(char *path, int parent_id, int flags) // Add inotify watch (for FreeBSD we limit the flags so only dirs will be // opened, otherwise we will be opening way too many files) -#if defined(__linux__) +#ifdef __linux__ wi.wd = inotify_add_watch(inofd, path, IN_ATTRIB | IN_CREATE | IN_DELETE | IN_CLOSE_WRITE | IN_MOVE | IN_DELETE | IN_MOVE_SELF); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#else wi.wd = inotify_add_watch(inofd, path, IN_CREATE | IN_DELETE | IN_MOVE); #endif if (wi.wd < 0) @@ -1260,7 +1261,7 @@ filescanner(void *arg) { int clear_queue_on_stop_disabled; int ret; -#if defined(__linux__) +#ifdef __linux__ struct sched_param param; /* Lower the priority of the thread so forked-daapd may still respond @@ -1724,9 +1725,10 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie } } -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -/* Since FreeBSD doesn't really have inotify we only get a IN_CREATE. That is - * a bit too soon to start scanning the file, so we defer it for 10 seconds. +#ifndef __linux__ +/* Since kexec based inotify doesn't really have inotify we only get + * a IN_CREATE. That is a bit too soon to start scanning the file, + * so we defer it for 10 seconds. */ static void inotify_deferred_cb(int fd, short what, void *arg) @@ -1765,6 +1767,7 @@ process_inotify_file_defer(struct watch_info *wi, char *path, struct inotify_eve f = calloc(1, sizeof(struct deferred_file)); f->wi = *wi; f->wi.path = strdup(wi->path); + /* ie->name not copied here, so don't use in process_inotify_* */ f->ie = *ie; strcpy(f->path, path); @@ -1876,9 +1879,9 @@ inotify_cb(int fd, short event, void *arg) if ((ie->mask & IN_ISDIR) || (ie->len == 0)) process_inotify_dir(&wi, path, ie); else -#if defined(__linux__) +#ifdef __linux__ process_inotify_file(&wi, path, ie); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#else process_inotify_file_defer(&wi, path, ie); #endif free(wi.path); @@ -1903,7 +1906,7 @@ inofd_event_set(void) inoev = event_new(evbase_scan, inofd, EV_READ, inotify_cb, NULL); -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#ifndef __linux__ deferred_inoev = evtimer_new(evbase_scan, inotify_deferred_cb, NULL); if (!deferred_inoev) { @@ -1920,7 +1923,7 @@ inofd_event_set(void) static void inofd_event_unset(void) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#ifndef __linux__ event_free(deferred_inoev); #endif event_free(inoev); diff --git a/src/filescanner_ffmpeg.c b/src/filescanner_ffmpeg.c index e5103aae..847bf453 100644 --- a/src/filescanner_ffmpeg.c +++ b/src/filescanner_ffmpeg.c @@ -25,9 +25,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/src/httpd.c b/src/httpd.c index aa31645b..e3966122 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -39,8 +39,7 @@ #include #include -#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) -# define USE_EVENTFD +#ifdef HAVE_EVENTFD # include #endif #include @@ -133,7 +132,7 @@ static const struct content_type_map ext2ctype[] = struct event_base *evbase_httpd; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD static int exit_efd; #else static int exit_pipe[2]; @@ -1453,7 +1452,7 @@ httpd_init(void) streaming_init(); -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD exit_efd = eventfd(0, EFD_CLOEXEC); if (exit_efd < 0) { @@ -1477,7 +1476,7 @@ httpd_init(void) } exitev = event_new(evbase_httpd, exit_pipe[0], EV_READ, exit_cb, NULL); -#endif /* USE_EVENTFD */ +#endif /* HAVE_EVENTFD */ if (!exitev) { DPRINTF(E_FATAL, L_HTTPD, "Could not create exit event\n"); @@ -1549,7 +1548,7 @@ httpd_init(void) bind_fail: evhttp_free(evhttpd); event_fail: -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); @@ -1574,7 +1573,7 @@ httpd_deinit(void) { int ret; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD ret = eventfd_write(exit_efd, 1); if (ret < 0) { @@ -1607,7 +1606,7 @@ httpd_deinit(void) dacp_deinit(); daap_deinit(); -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); diff --git a/src/httpd_dacp.c b/src/httpd_dacp.c index 6897d98f..56a5430f 100644 --- a/src/httpd_dacp.c +++ b/src/httpd_dacp.c @@ -32,8 +32,7 @@ #include #include -#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) -# define USE_EVENTFD +#ifdef HAVE_EVENTFD # include #endif @@ -136,11 +135,11 @@ dacp_propset_userrating(const char *value, struct evkeyvalq *query); /* gperf static hash, dacp_prop.gperf */ -#include "dacp_prop_hash.c" +#include "dacp_prop_hash.h" /* Play status update */ -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD static int update_efd; #else static int update_pipe[2]; @@ -322,7 +321,7 @@ playstatusupdate_cb(int fd, short what, void *arg) size_t len; int ret; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD eventfd_t count; ret = eventfd_read(update_efd, &count); @@ -406,7 +405,7 @@ dacp_playstatus_update_handler(enum listener_event_type type) if (type != LISTENER_PLAYER) return; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD ret = eventfd_write(update_efd, 1); if (ret < 0) DPRINTF(E_LOG, L_DACP, "Could not send status update event: %s\n", strerror(errno)); @@ -2728,7 +2727,7 @@ dacp_init(void) current_rev = 2; update_requests = NULL; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD update_efd = eventfd(0, EFD_CLOEXEC); if (update_efd < 0) { @@ -2748,7 +2747,7 @@ dacp_init(void) return -1; } -#endif /* USE_EVENTFD */ +#endif /* HAVE_EVENTFD */ for (i = 0; dacp_handlers[i].handler; i++) { @@ -2762,7 +2761,7 @@ dacp_init(void) } } -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD updateev = event_new(evbase_httpd, update_efd, EV_READ, playstatusupdate_cb, NULL); #else updateev = event_new(evbase_httpd, update_pipe[0], EV_READ, playstatusupdate_cb, NULL); @@ -2788,7 +2787,7 @@ dacp_init(void) return 0; regexp_fail: -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(update_efd); #else close(update_pipe[0]); @@ -2827,7 +2826,7 @@ dacp_deinit(void) event_free(updateev); -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(update_efd); #else close(update_pipe[0]); diff --git a/src/lastfm.c b/src/lastfm.c index 434263b6..1d81cd39 100644 --- a/src/lastfm.c +++ b/src/lastfm.c @@ -216,7 +216,7 @@ param_sign(struct keyval *kv) } /* For compability with mxml 2.6 */ -#ifndef HAVE_MXML_GETOPAQUE +#ifndef HAVE_MXMLGETOPAQUE const char * /* O - Opaque string or NULL */ mxmlGetOpaque(mxml_node_t *node) /* I - Node to get */ { diff --git a/src/logger.c b/src/logger.c index b84dd364..fa216e2a 100644 --- a/src/logger.c +++ b/src/logger.c @@ -184,7 +184,7 @@ logger_libevent(int severity, const char *msg) DPRINTF(severity, L_EVENT, "%s\n", msg); } -#ifdef ALSA +#ifdef HAVE_ALSA void logger_alsa(const char *file, int line, const char *function, int err, const char *fmt, ...) { @@ -194,7 +194,7 @@ logger_alsa(const char *file, int line, const char *function, int err, const cha vlogger(E_LOG, L_LAUDIO, fmt, ap); va_end(ap); } -#endif /* ALSA */ +#endif /* HAVE_ALSA */ void logger_reinit(void) diff --git a/src/logger.h b/src/logger.h index 7e4f0829..e506edf0 100644 --- a/src/logger.h +++ b/src/logger.h @@ -55,7 +55,7 @@ logger_ffmpeg(void *ptr, int level, const char *fmt, va_list ap); void logger_libevent(int severity, const char *msg); -#ifdef ALSA +#ifdef HAVE_ALSA void logger_alsa(const char *file, int line, const char *function, int err, const char *fmt, ...); #endif diff --git a/src/main.c b/src/main.c index 46c71948..ef7eb84e 100644 --- a/src/main.c +++ b/src/main.c @@ -37,9 +37,9 @@ #include #include -#if defined(__linux__) +#ifdef HAVE_SIGNALFD # include -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#else # include # include #endif @@ -334,7 +334,7 @@ register_services(char *ffid, int no_rsp, int no_daap, int mdns_no_mpd) } -#if defined(__linux__) +#ifdef HAVE_SIGNALFD static void signal_signalfd_cb(int fd, short event, void *arg) { @@ -374,7 +374,7 @@ signal_signalfd_cb(int fd, short event, void *arg) event_add(sig_event, NULL); } -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#else static void signal_kqueue_cb(int fd, short event, void *arg) @@ -468,7 +468,7 @@ main(int argc, char **argv) const char *gcry_version; sigset_t sigs; int sigfd; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#ifdef HAVE_KQUEUE struct kevent ke_sigs[4]; #endif int ret; @@ -607,14 +607,14 @@ main(int argc, char **argv) #ifdef MPD strcat(buildopts, " --enable-mpd"); #endif -#ifdef ALSA +#ifdef HAVE_ALSA strcat(buildopts, " --with-alsa"); #endif -#ifdef PULSEAUDIO +#ifdef HAVE_LIBPULSE strcat(buildopts, " --with-pulseaudio"); #endif - DPRINTF(E_LOG, L_MAIN, "Built %s with:%s\n", BUILDDATE, buildopts); + DPRINTF(E_LOG, L_MAIN, "Built %s with:%s\n", __DATE__, buildopts); ret = av_lockmgr_register(ffmpeg_lockmgr); if (ret < 0) @@ -813,7 +813,7 @@ main(int argc, char **argv) /* Register this CNAME with mDNS for OAuth */ mdns_cname("forked-daapd.local"); -#if defined(__linux__) +#ifdef HAVE_SIGNALFD /* Set up signal fd */ sigfd = signalfd(-1, &sigs, SFD_NONBLOCK | SFD_CLOEXEC); if (sigfd < 0) @@ -825,7 +825,7 @@ main(int argc, char **argv) } sig_event = event_new(evbase_main, sigfd, EV_READ, signal_signalfd_cb, NULL); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#else sigfd = kqueue(); if (sigfd < 0) { diff --git a/src/mdns_avahi.c b/src/mdns_avahi.c index 1f9fe5f1..63b9dce4 100644 --- a/src/mdns_avahi.c +++ b/src/mdns_avahi.c @@ -636,6 +636,11 @@ entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_U } } +#ifndef HOST_NAME_MAX +/* some systems want programs to query this, just define a reasonable limit */ +#define HOST_NAME_MAX 64 +#endif + static int create_group_entry(struct mdns_group_entry *ge, int commit) { diff --git a/src/misc.h b/src/misc.h index 8a8d2eec..7aa615c1 100644 --- a/src/misc.h +++ b/src/misc.h @@ -2,6 +2,10 @@ #ifndef __MISC_H__ #define __MISC_H__ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include diff --git a/src/mpd.c b/src/mpd.c index b984d997..05c0db45 100644 --- a/src/mpd.c +++ b/src/mpd.c @@ -43,11 +43,6 @@ #include #include -#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) -# define USE_EVENTFD -# include -#endif - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) # include #endif diff --git a/src/outputs.c b/src/outputs.c index c6cd1bb4..42db1b5a 100644 --- a/src/outputs.c +++ b/src/outputs.c @@ -35,10 +35,10 @@ extern struct output_definition output_raop; extern struct output_definition output_streaming; extern struct output_definition output_dummy; extern struct output_definition output_fifo; -#ifdef ALSA +#ifdef HAVE_ALSA extern struct output_definition output_alsa; #endif -#ifdef PULSEAUDIO +#ifdef HAVE_LIBPULSE extern struct output_definition output_pulse; #endif #ifdef CHROMECAST @@ -51,10 +51,10 @@ static struct output_definition *outputs[] = { &output_streaming, &output_dummy, &output_fifo, -#ifdef ALSA +#ifdef HAVE_ALSA &output_alsa, #endif -#ifdef PULSEAUDIO +#ifdef HAVE_LIBPULSE &output_pulse, #endif #ifdef CHROMECAST diff --git a/src/outputs.h b/src/outputs.h index 52b16a6d..380a9d0a 100644 --- a/src/outputs.h +++ b/src/outputs.h @@ -53,10 +53,10 @@ enum output_types OUTPUT_TYPE_STREAMING, OUTPUT_TYPE_DUMMY, OUTPUT_TYPE_FIFO, -#ifdef ALSA +#ifdef HAVE_ALSA OUTPUT_TYPE_ALSA, #endif -#ifdef PULSEAUDIO +#ifdef HAVE_LIBPULSE OUTPUT_TYPE_PULSE, #endif #ifdef CHROMECAST diff --git a/src/outputs/cast.c b/src/outputs/cast.c index 2f5b368a..cc75e989 100644 --- a/src/outputs/cast.c +++ b/src/outputs/cast.c @@ -30,18 +30,19 @@ #include #include #include +#include +#include #include #include #include -#include +#ifdef HAVE_ENDIAN_H +# include +#elif defined(HAVE_SYS_ENDIAN_H) +# include +#endif #include #include - -#ifdef HAVE_JSON_C_OLD -# include -#else -# include -#endif +#include #include "conffile.h" #include "mdns.h" @@ -368,7 +369,11 @@ tcp_connect(const char *address, unsigned int port, int family) // TODO Open non-block right away so we don't block the player while connecting // and during TLS handshake (we would probably need to introduce a deferredev) +#ifdef SOCK_CLOEXEC fd = socket(family, SOCK_STREAM | SOCK_CLOEXEC, 0); +#else + fd = socket(family, SOCK_STREAM, 0); +#endif if (fd < 0) { DPRINTF(E_LOG, L_CAST, "Could not create socket: %s\n", strerror(errno)); diff --git a/src/outputs/pulse.c b/src/outputs/pulse.c index 9132b6de..859c0553 100644 --- a/src/outputs/pulse.c +++ b/src/outputs/pulse.c @@ -903,7 +903,7 @@ pulse_init(void) if (!(pulse.cmdbase = commands_base_new(evbase_player, NULL))) goto fail; -#ifdef HAVE_PULSE_MAINLOOP_SET_NAME +#ifdef HAVE_PA_THREADED_MAINLOOP_SET_NAME pa_threaded_mainloop_set_name(pulse.mainloop, "pulseaudio"); #endif diff --git a/src/outputs/raop.c b/src/outputs/raop.c index c0249b41..8ae51354 100644 --- a/src/outputs/raop.c +++ b/src/outputs/raop.c @@ -47,10 +47,9 @@ #include #include -#if defined(__linux__) || defined(__GLIBC__) +#ifdef HAVE_ENDIAN_H # include -# include -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(HAVE_SYS_ENDIAN_H) # include #endif @@ -2688,7 +2687,7 @@ raop_v2_timing_start_one(struct raop_service *svc, int family) int len; int ret; -#ifdef __linux__ +#ifdef SOCK_CLOEXEC svc->fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0); #else svc->fd = socket(family, SOCK_DGRAM, 0); @@ -3020,7 +3019,7 @@ raop_v2_control_start_one(struct raop_service *svc, int family) int len; int ret; -#ifdef __linux__ +#ifdef SOCK_CLOEXEC svc->fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0); #else svc->fd = socket(family, SOCK_DGRAM, 0); @@ -3418,7 +3417,7 @@ raop_v2_stream_open(struct raop_session *rs) int len; int ret; -#ifdef __linux__ +#ifdef SOCK_CLOEXEC rs->server_fd = socket(rs->sa.ss.ss_family, SOCK_DGRAM | SOCK_CLOEXEC, 0); #else rs->server_fd = socket(rs->sa.ss.ss_family, SOCK_DGRAM, 0); diff --git a/src/player.c b/src/player.c index 3acf2175..23bbd789 100644 --- a/src/player.c +++ b/src/player.c @@ -35,7 +35,7 @@ # include #endif -#if defined(__linux__) +#ifdef HAVE_TIMERFD # include #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) # include @@ -193,7 +193,7 @@ static char shuffle; static char consume; /* Playback timer */ -#if defined(__linux__) +#ifdef HAVE_TIMERFD static int pb_timer_fd; #else timer_t pb_timer; @@ -389,7 +389,7 @@ pb_timer_start(void) tick.it_interval = tick_interval; tick.it_value = tick_interval; -#if defined(__linux__) +#ifdef HAVE_TIMERFD ret = timerfd_settime(pb_timer_fd, 0, &tick, NULL); #else ret = timer_settime(pb_timer, 0, &tick, NULL); @@ -412,7 +412,7 @@ pb_timer_stop(void) memset(&tick, 0, sizeof(struct itimerspec)); -#if defined(__linux__) +#ifdef HAVE_TIMERFD ret = timerfd_settime(pb_timer_fd, 0, &tick, NULL); #else ret = timer_settime(pb_timer, 0, &tick, NULL); @@ -1451,7 +1451,7 @@ player_playback_cb(int fd, short what, void *arg) // Check if we missed any timer expirations overrun = 0; -#if defined(__linux__) +#ifdef HAVE_TIMERFD ret = read(fd, &overrun, sizeof(overrun)); if (ret <= 0) DPRINTF(E_LOG, L_PLAYER, "Error reading timer\n"); @@ -1463,7 +1463,7 @@ player_playback_cb(int fd, short what, void *arg) DPRINTF(E_LOG, L_PLAYER, "Error getting timer overrun\n"); else overrun = ret; -#endif /* __linux__ */ +#endif /* HAVE_TIMERFD */ // The reason we get behind the playback timer may be that we are playing a // network stream OR that the source is slow to open OR some interruption. @@ -3479,7 +3479,7 @@ player_init(void) tick_interval.tv_nsec = interval; // Create the playback timer -#if defined(__linux__) +#ifdef HAVE_TIMERFD pb_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); ret = pb_timer_fd; #else @@ -3512,7 +3512,7 @@ player_init(void) goto evbase_fail; } -#if defined(__linux__) +#ifdef HAVE_TIMERFD pb_timer_ev = event_new(evbase_player, pb_timer_fd, EV_READ | EV_PERSIST, player_playback_cb, NULL); #else pb_timer_ev = event_new(evbase_player, SIGALRM, EV_SIGNAL | EV_PERSIST, player_playback_cb, NULL); @@ -3557,7 +3557,7 @@ player_init(void) evbase_fail: evbuffer_free(audio_buf); audio_fail: -#if defined(__linux__) +#ifdef HAVE_TIMERFD close(pb_timer_fd); #else timer_delete(pb_timer); @@ -3586,7 +3586,7 @@ player_deinit(void) free(history); pb_timer_stop(); -#if defined(__linux__) +#ifdef HAVE_TIMERFD close(pb_timer_fd); #else timer_delete(pb_timer); diff --git a/src/remote_pairing.c b/src/remote_pairing.c index 49ca5c08..0f586e9b 100644 --- a/src/remote_pairing.c +++ b/src/remote_pairing.c @@ -41,8 +41,7 @@ #include #include -#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) -# define USE_EVENTFD +#ifdef HAVE_EVENTFD # include #endif @@ -80,7 +79,7 @@ struct remote_info { /* Main event base, from main.c */ extern struct event_base *evbase_main; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD static int pairing_efd; #else static int pairing_pipe[2]; @@ -389,7 +388,7 @@ add_remote_pin_data(char *devname, char *pin) static void kickoff_pairing(void) { -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD int ret; ret = eventfd_write(pairing_efd, 1); @@ -642,7 +641,7 @@ pairing_cb(int fd, short event, void *arg) { struct remote_info *ri; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD eventfd_t count; int ret; @@ -908,7 +907,7 @@ remote_pairing_init(void) remote_list = NULL; -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD pairing_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (pairing_efd < 0) { @@ -933,7 +932,7 @@ remote_pairing_init(void) return -1; } -#endif /* USE_EVENTFD */ +#endif /* HAVE_EVENTFD */ // No ipv6 for remote at the moment ret = mdns_browse("_touch-remote._tcp", AF_INET, touch_remote_cb); @@ -944,7 +943,7 @@ remote_pairing_init(void) goto mdns_browse_fail; } -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD pairingev = event_new(evbase_main, pairing_efd, EV_READ, pairing_cb, NULL); #else pairingev = event_new(evbase_main, pairing_pipe[0], EV_READ, pairing_cb, NULL); @@ -962,7 +961,7 @@ remote_pairing_init(void) pairingev_fail: mdns_browse_fail: -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(pairing_efd); #else close(pairing_pipe[0]); @@ -985,7 +984,7 @@ remote_pairing_deinit(void) free_remote(ri); } -#ifdef USE_EVENTFD +#ifdef HAVE_EVENTFD close(pairing_efd); #else close(pairing_pipe[0]); diff --git a/src/spotify.c b/src/spotify.c index 93bb4907..53ea8805 100644 --- a/src/spotify.c +++ b/src/spotify.c @@ -43,12 +43,7 @@ #include #include - -#ifdef HAVE_JSON_C_OLD -# include -#else -# include -#endif +#include #include "spotify.h" #include "logger.h" diff --git a/src/transcode.c b/src/transcode.c index 5d065ff0..6be2447d 100644 --- a/src/transcode.c +++ b/src/transcode.c @@ -34,6 +34,9 @@ #include #ifdef HAVE_LIBAVFILTER +# ifdef HAVE_LIBAVUTIL_CHANNEL_LAYOUT_H +# include +# endif # include #else # include "ffmpeg-compat.h" @@ -402,7 +405,7 @@ encode_write_frame(struct encode_ctx *ctx, AVFrame *filt_frame, unsigned int str return ret; } -#if defined(HAVE_LIBAV_BUFFERSRC_ADD_FRAME_FLAGS) && defined(HAVE_LIBAV_BUFFERSINK_GET_FRAME) +#if defined(HAVE_AV_BUFFERSRC_ADD_FRAME_FLAGS) && defined(HAVE_AV_BUFFERSINK_GET_FRAME) static int filter_encode_write_frame(struct encode_ctx *ctx, AVFrame *frame, unsigned int stream_index) { @@ -857,7 +860,7 @@ close_output(struct encode_ctx *ctx) avformat_free_context(ctx->ofmt_ctx); } -#ifdef HAVE_LIBAV_GRAPH_PARSE_PTR +#ifdef HAVE_AVFILTER_GRAPH_PARSE_PTR static int open_filter(struct filter_ctx *filter_ctx, AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, const char *filter_spec) {