diff --git a/configure.ac b/configure.ac index 73b6e830..aa082195 100644 --- a/configure.ac +++ b/configure.ac @@ -352,9 +352,9 @@ AC_ARG_WITH([prebuilt-webinterface], )], [[with_prebuilt_webinterface=]]) if test "x$with_prebuilt_webinterface" = "xyes"; then - BUILD_WEBINTERFACE= + BUILD_WEBINTERFACE= else - BUILD_WEBINTERFACE=true + BUILD_WEBINTERFACE=true fi AC_SUBST([BUILD_WEBINTERFACE]) @@ -414,4 +414,234 @@ AC_CONFIG_FILES([ Makefile owntone.spec ]) + +WEBSRC_SUBDIRS="\ + public \ + src \ + src/components \ + src/filter \ + src/i18n \ + src/lib \ + src/pages \ + src/router \ + src/stores \ + src/templates \ + src/webapi" +AC_SUBST([WEBSRC_SUBDIRS]) + +WEBSRC_SOURCE_FILES="\ + public/android-chrome-512x512.png \ + public/mstile-150x150.png \ + public/browserconfig.xml \ + public/site.webmanifest \ + public/favicon.ico \ + public/android-chrome-192x192.png \ + public/safari-pinned-tab.svg \ + public/apple-touch-icon.png \ + public/favicon-16x16.png \ + public/logo.svg \ + public/favicon-32x32.png \ + src/components/ModalDialogAddRss.vue \ + src/components/ModalDialogPlaylistSpotify.vue \ + src/components/ListPlaylistsSpotify.vue \ + src/components/ListArtistsSpotify.vue \ + src/components/ModalDialogComposer.vue \ + src/components/ListArtists.vue \ + src/components/ControlSlider.vue \ + src/components/ModalDialogArtist.vue \ + src/components/ListPlaylists.vue \ + src/components/ModalDialogArtistSpotify.vue \ + src/components/ModalDialogPlaylistSave.vue \ + src/components/ModalDialogGenre.vue \ + src/components/ModalDialogTrackSpotify.vue \ + src/components/ListTracks.vue \ + src/components/ListGenres.vue \ + src/components/ModalDialogAlbumSpotify.vue \ + src/components/TabsAudiobooks.vue \ + src/components/IndexButtonList.vue \ + src/components/TabsSettings.vue \ + src/components/ModalDialogAddUrlStream.vue \ + src/components/ModalDialogDirectory.vue \ + src/components/ListComposers.vue \ + src/components/CoverArtwork.vue \ + src/components/NavbarItemOutput.vue \ + src/components/ModalDialogAlbum.vue \ + src/components/ControlDropdown.vue \ + src/components/ModalDialogPlaylist.vue \ + src/components/ListDirectories.vue \ + src/components/ModalDialog.vue \ + src/components/ListAlbums.vue \ + src/components/ListAlbumsSpotify.vue \ + src/components/ListItemQueueItem.vue \ + src/components/ListTracksSpotify.vue \ + src/components/LyricsPane.vue \ + src/components/ModalDialogQueueItem.vue \ + src/components/ModalDialogRemotePairing.vue \ + src/components/ModalDialogTrack.vue \ + src/components/ModalDialogUpdate.vue \ + src/components/NavbarBottom.vue \ + src/components/NavbarItemLink.vue \ + src/components/NavbarTop.vue \ + src/components/NotificationList.vue \ + src/components/PlayerButtonConsume.vue \ + src/components/PlayerButtonLyrics.vue \ + src/components/PlayerButtonNext.vue \ + src/components/PlayerButtonPlayPause.vue \ + src/components/PlayerButtonPrevious.vue \ + src/components/PlayerButtonRepeat.vue \ + src/components/PlayerButtonSeekBack.vue \ + src/components/PlayerButtonSeekForward.vue \ + src/components/PlayerButtonShuffle.vue \ + src/components/SettingsCheckbox.vue \ + src/components/SettingsIntfield.vue \ + src/components/SettingsTextfield.vue \ + src/components/TabsMusic.vue \ + src/components/TabsSearch.vue \ + src/filter/index.js \ + src/i18n/index.js \ + src/i18n/de.json \ + src/i18n/en.json \ + src/i18n/fr.json \ + src/i18n/zh-CN.json \ + src/i18n/zh-TW.json \ + src/lib/Audio.js \ + src/lib/SVGRenderer.js \ + src/lib/GroupedList.js \ + src/pages/PageMusicRecentlyPlayed.vue \ + src/pages/PageMusicSpotifyFeaturedPlaylists.vue \ + src/pages/PageAudiobooksArtists.vue \ + src/pages/PageAudiobooksGenres.vue \ + src/pages/PageAlbum.vue \ + src/pages/PageComposerAlbums.vue \ + src/pages/PageMusicSpotify.vue \ + src/pages/PagePlaylistTracks.vue \ + src/pages/PagePodcast.vue \ + src/pages/PageMusicSpotifyNewReleases.vue \ + src/pages/PageRadioStreams.vue \ + src/pages/PageAudiobooksAlbums.vue \ + src/pages/PageComposers.vue \ + src/pages/PageAudiobooksArtist.vue \ + src/pages/PageGenres.vue \ + src/pages/PageMusic.vue \ + src/pages/PageGenreAlbums.vue \ + src/pages/PageAbout.vue \ + src/pages/PageAlbumSpotify.vue \ + src/pages/PageAlbums.vue \ + src/pages/PageArtist.vue \ + src/pages/PageArtistSpotify.vue \ + src/pages/PageArtistTracks.vue \ + src/pages/PageArtists.vue \ + src/pages/PageComposerTracks.vue \ + src/pages/PageFiles.vue \ + src/pages/PageGenreTracks.vue \ + src/pages/PageMusicRecentlyAdded.vue \ + src/pages/PagePlaylistFolder.vue \ + src/pages/PagePlaylistTracksSpotify.vue \ + src/pages/PagePodcasts.vue \ + src/pages/PageQueue.vue \ + src/pages/PageSearchLibrary.vue \ + src/pages/PageSearchSpotify.vue \ + src/pages/PageSettingsOnlineServices.vue \ + src/pages/PageSettingsRemotesOutputs.vue \ + src/pages/PageAudiobooksAlbum.vue \ + src/pages/PageNowPlaying.vue \ + src/pages/PageSettingsArtwork.vue \ + src/pages/PageSettingsWebinterface.vue \ + src/router/index.js \ + src/stores/configuration.js \ + src/stores/library.js \ + src/stores/lyrics.js \ + src/stores/notifications.js \ + src/stores/outputs.js \ + src/stores/player.js \ + src/stores/queue.js \ + src/stores/remotes.js \ + src/stores/search.js \ + src/stores/services.js \ + src/stores/settings.js \ + src/stores/ui.js \ + src/templates/ContentWithHeading.vue \ + src/templates/ContentWithHero.vue \ + src/webapi/index.js \ + src/App.vue \ + src/icons.js \ + src/main.js \ + src/mystyles.scss \ + .prettierrc.json \ + eslint.config.js \ + index.html \ + jsconfig.json \ + package-lock.json \ + package.json \ + vite.config.js" +AC_SUBST([WEBSRC_SOURCE_FILES]) + +AC_CONFIG_COMMANDS([web-src], + [ + if test "x$enable_webinterface" = "xyes"; then + websrc_builddir="$ac_abs_builddir/web-src" + websrc_srcdir="$ac_abs_srcdir/web-src" + if test "$websrc_srcdir" != "$websrc_builddir"; then + echo "web-src: out-of-tree build, copy web-src to build dir ($websrc_srcdir = $websrc_builddir)" + for dir in $dirs; do + mkdir -p "$websrc_builddir/$dir" + echo "web-src: created dir $websrc_builddir/$dir" + done + for file in $files; do + cp "$websrc_srcdir/$file" "$websrc_builddir/$file" + echo "web-src: copied $file from '$websrc_srcdir' to '$websrc_builddir'" + done + else + echo "web-src: in-tree build, nothing to prepare ($websrc_srcdir = $websrc_builddir)" + fi + fi + ], [ + dirs="$WEBSRC_SUBDIRS" + files="$WEBSRC_SOURCE_FILES" + enable_webinterface="$enable_webinterface" + ]) + +HTDOCS_FILES="\ + index.html \ + android-chrome-192x192.png \ + android-chrome-512x512.png \ + apple-touch-icon.png \ + browserconfig.xml \ + favicon.ico \ + favicon-16x16.png \ + favicon-32x32.png \ + mstile-150x150.png \ + safari-pinned-tab.svg \ + site.webmanifest \ + assets/index.css \ + assets/index.js" +AC_SUBST([WEBSRC_BUILD_FILES]) + +AC_CONFIG_COMMANDS([htdocs], + [ + if test "x$enable_webinterface" = "xyes"; then + websrc_builddir="$ac_abs_builddir/web-src/htdocs" + websrc_srcdir="$ac_abs_srcdir/web-src/htdocs" + if test "$websrc_srcdir" != "$websrc_builddir"; then + echo "htdocs: out-of-tree build, copy prebuilt htdocs to build dir ($websrc_srcdir = $websrc_builddir)" + if test -d "$websrc_srcdir/htdocs"; then + mkdir -p "$websrc_builddir" + mkdir -p "$websrc_builddir/assets" + for file in $files; do + cp "$websrc_srcdir/$file" "$websrc_builddir/$file" + echo "htdocs: copied $file from '$websrc_srcdir' to '$websrc_builddir'" + done + echo "htdocs: copied prebuilt htdocs from '$websrc_srcdir' to '$websrc_builddir'" + else + echo "htdocs: no prebuilt htdocs found, nothing to prepare" + fi + else + echo "htdocs: in-tree build, nothing to prepare ($websrc_srcdir = $websrc_builddir)" + fi + fi + ], [ + files="$HTDOCS_FILES" + enable_webinterface="$enable_webinterface" + ]) + AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 9dd91b70..8e8d7c37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -155,7 +155,7 @@ EXTRA_DIST = \ # Rule for generating lexer headers. $@ is an automatic variable that is equal # to the particular target name, so a header file name. $(LEXER_SRC:.l=.h): $(LEXER_SRC) - $(LEX) --header-file=$@ --stdout $(@:.h=.l) > /dev/null + $(LEX) --header-file=$@ --stdout $(srcdir)/$(@:.h=.l) > /dev/null # Anything built by make should be cleaned by make clean, but when it comes to # flex/bison automake's support leaves something to be desired diff --git a/web-src/Makefile.am b/web-src/Makefile.am index 53ec5f9e..e5a1c077 100644 --- a/web-src/Makefile.am +++ b/web-src/Makefile.am @@ -3,166 +3,14 @@ WEB_BUILD_DIR = htdocs PACKAGE_JSON = package-lock.json \ package.json -WEB_DIRS = public \ - src \ - src/components \ - src/filter \ - src/i18n \ - src/lib \ - src/pages \ - src/router \ - src/stores \ - src/templates \ - src/webapi +WEB_DIRS = @WEBSRC_SUBDIRS@ -WEB_FILES = \ - public/android-chrome-512x512.png \ - public/mstile-150x150.png \ - public/browserconfig.xml \ - public/site.webmanifest \ - public/favicon.ico \ - public/android-chrome-192x192.png \ - public/safari-pinned-tab.svg \ - public/apple-touch-icon.png \ - public/favicon-16x16.png \ - public/logo.svg \ - public/favicon-32x32.png \ - src/components/ModalDialogAddRss.vue \ - src/components/ModalDialogPlaylistSpotify.vue \ - src/components/ListPlaylistsSpotify.vue \ - src/components/ListArtistsSpotify.vue \ - src/components/ModalDialogComposer.vue \ - src/components/ListArtists.vue \ - src/components/ControlSlider.vue \ - src/components/ModalDialogArtist.vue \ - src/components/ListPlaylists.vue \ - src/components/ModalDialogArtistSpotify.vue \ - src/components/ModalDialogPlaylistSave.vue \ - src/components/ModalDialogGenre.vue \ - src/components/ModalDialogTrackSpotify.vue \ - src/components/ListTracks.vue \ - src/components/ListGenres.vue \ - src/components/ModalDialogAlbumSpotify.vue \ - src/components/TabsAudiobooks.vue \ - src/components/IndexButtonList.vue \ - src/components/TabsSettings.vue \ - src/components/ModalDialogAddUrlStream.vue \ - src/components/ModalDialogDirectory.vue \ - src/components/ListComposers.vue \ - src/components/CoverArtwork.vue \ - src/components/NavbarItemOutput.vue \ - src/components/ModalDialogAlbum.vue \ - src/components/ControlDropdown.vue \ - src/components/ModalDialogPlaylist.vue \ - src/components/ListDirectories.vue \ - src/components/ModalDialog.vue \ - src/components/ListAlbums.vue \ - src/components/ListAlbumsSpotify.vue \ - src/components/ListItemQueueItem.vue \ - src/components/ListTracksSpotify.vue \ - src/components/LyricsPane.vue \ - src/components/ModalDialogQueueItem.vue \ - src/components/ModalDialogRemotePairing.vue \ - src/components/ModalDialogTrack.vue \ - src/components/ModalDialogUpdate.vue \ - src/components/NavbarBottom.vue \ - src/components/NavbarItemLink.vue \ - src/components/NavbarTop.vue \ - src/components/NotificationList.vue \ - src/components/PlayerButtonConsume.vue \ - src/components/PlayerButtonLyrics.vue \ - src/components/PlayerButtonNext.vue \ - src/components/PlayerButtonPlayPause.vue \ - src/components/PlayerButtonPrevious.vue \ - src/components/PlayerButtonRepeat.vue \ - src/components/PlayerButtonSeekBack.vue \ - src/components/PlayerButtonSeekForward.vue \ - src/components/PlayerButtonShuffle.vue \ - src/components/SettingsCheckbox.vue \ - src/components/SettingsIntfield.vue \ - src/components/SettingsTextfield.vue \ - src/components/TabsMusic.vue \ - src/components/TabsSearch.vue \ - src/filter/index.js \ - src/i18n/index.js \ - src/i18n/de.json \ - src/i18n/en.json \ - src/i18n/fr.json \ - src/i18n/zh-CN.json \ - src/i18n/zh-TW.json \ - src/lib/Audio.js \ - src/lib/SVGRenderer.js \ - src/lib/GroupedList.js \ - src/pages/PageMusicRecentlyPlayed.vue \ - src/pages/PageMusicSpotifyFeaturedPlaylists.vue \ - src/pages/PageAudiobooksArtists.vue \ - src/pages/PageAudiobooksGenres.vue \ - src/pages/PageAlbum.vue \ - src/pages/PageComposerAlbums.vue \ - src/pages/PageMusicSpotify.vue \ - src/pages/PagePlaylistTracks.vue \ - src/pages/PagePodcast.vue \ - src/pages/PageMusicSpotifyNewReleases.vue \ - src/pages/PageRadioStreams.vue \ - src/pages/PageAudiobooksAlbums.vue \ - src/pages/PageComposers.vue \ - src/pages/PageAudiobooksArtist.vue \ - src/pages/PageGenres.vue \ - src/pages/PageMusic.vue \ - src/pages/PageGenreAlbums.vue \ - src/pages/PageAbout.vue \ - src/pages/PageAlbumSpotify.vue \ - src/pages/PageAlbums.vue \ - src/pages/PageArtist.vue \ - src/pages/PageArtistSpotify.vue \ - src/pages/PageArtistTracks.vue \ - src/pages/PageArtists.vue \ - src/pages/PageComposerTracks.vue \ - src/pages/PageFiles.vue \ - src/pages/PageGenreTracks.vue \ - src/pages/PageMusicRecentlyAdded.vue \ - src/pages/PagePlaylistFolder.vue \ - src/pages/PagePlaylistTracksSpotify.vue \ - src/pages/PagePodcasts.vue \ - src/pages/PageQueue.vue \ - src/pages/PageSearchLibrary.vue \ - src/pages/PageSearchSpotify.vue \ - src/pages/PageSettingsOnlineServices.vue \ - src/pages/PageSettingsRemotesOutputs.vue \ - src/pages/PageAudiobooksAlbum.vue \ - src/pages/PageNowPlaying.vue \ - src/pages/PageSettingsArtwork.vue \ - src/pages/PageSettingsWebinterface.vue \ - src/router/index.js \ - src/stores/configuration.js \ - src/stores/library.js \ - src/stores/lyrics.js \ - src/stores/notifications.js \ - src/stores/outputs.js \ - src/stores/player.js \ - src/stores/queue.js \ - src/stores/remotes.js \ - src/stores/search.js \ - src/stores/services.js \ - src/stores/settings.js \ - src/stores/ui.js \ - src/templates/ContentWithHeading.vue \ - src/templates/ContentWithHero.vue \ - src/webapi/index.js \ - src/App.vue \ - src/icons.js \ - src/main.js \ - src/mystyles.scss \ - .prettierrc.json \ - eslint.config.js \ - index.html \ - jsconfig.json \ - $(PACKAGE_JSON) \ - vite.config.js +WEB_FILES = @WEBSRC_SOURCE_FILES@ EXTRA_DIST = $(WEB_FILES) htdocs -node_modules: $(PACKAGE_JSON) +# Build the Vue.js application +htdocs: $(WEB_FILES) @if [ "$(abs_srcdir)" = "$(abs_builddir)" ]; then \ echo "In-tree build detected"; \ else \ @@ -177,13 +25,36 @@ node_modules: $(PACKAGE_JSON) cp "$$src_path" "$$dest_path"; \ done; \ fi - $(if $(BUILD_WEBINTERFACE),$(NPM) clean-install) - -# Build the Vue.js application -htdocs: node_modules $(WEB_FILES) + $(if $(BUILD_WEBINTERFACE),$(NPM) clean-install --no-progress --no-audit) $(if $(BUILD_WEBINTERFACE),$(NPM) run build) -web: htdocs +all-local: htdocs + +install-data-local: + mkdir -p $(DESTDIR)$(datadir)/owntone/htdocs + cp -r $(WEB_BUILD_DIR)/* $(DESTDIR)$(datadir)/owntone/htdocs + +uninstall-local: + rm -rf $(DESTDIR)$(datadir)/owntone/htdocs + +# Clean up Vue.js build artifacts +clean-local: + $(if $(BUILD_WEBINTERFACE),rm -rf $(WEB_BUILD_DIR)) + +distclean-local: + @if [ "$(abs_srcdir)" != "$(abs_builddir)" ]; then \ + echo "Cleaning up copied files from out-of-tree build..."; \ + for file in $(WEB_FILES); do \ + rm -f "$(abs_builddir)/$$file"; \ + done; \ + fi + rm -rf node_modules + +node_modules: $(PACKAGE_JSON) + $(if $(BUILD_WEBINTERFACE),$(NPM) clean-install --no-progress --no-audit) + +web: node_modules $(WEB_FILES) + $(if $(BUILD_WEBINTERFACE),$(NPM) run build) web-serve: node_modules $(if $(BUILD_WEBINTERFACE),$(NPM) run serve) @@ -213,25 +84,3 @@ web-lint: node_modules web-format: node_modules $(if $(BUILD_WEBINTERFACE),$(NPM) run format) -all-local: htdocs - -install-data-local: - mkdir -p $(DESTDIR)$(datadir)/owntone/htdocs - cp -r $(WEB_BUILD_DIR)/* $(DESTDIR)$(datadir)/owntone/htdocs - -uninstall-local: - rm -rf $(DESTDIR)$(datadir)/owntone/htdocs - -# Clean up Vue.js build artifacts -clean-local: - rm -rf $(WEB_BUILD_DIR) - -distclean-local: - @if [ "$(abs_srcdir)" != "$(abs_builddir)" ]; then \ - echo "Cleaning up copied files from out-of-tree build..."; \ - for file in $(WEB_FILES); do \ - rm -f "$(abs_builddir)/$$file"; \ - done; \ - fi - rm -rf node_modules -