Compare commits

..

11 Commits

Author SHA1 Message Date
Xavier Roche
d0a1b957cd ci: let the deb job run debuild's test pass
The deb job set DEB_BUILD_OPTIONS=nocheck to skip a redundant second test run.
With mkdeb.sh no longer running its own pre-build check, debuild's is the only
test pass, so nocheck would suppress it entirely and CI would never exercise the
packaged build's tests. Drop nocheck; keep noautodbgsym and parallel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 22:15:51 +02:00
Xavier Roche
6c329744e7 mkdeb: drop the redundant pre-build test pass
mkdeb.sh built and tested the sources twice: once in its own export-tree
pre-build (make check, offline), then again under debuild, whose dh_auto_test
runs the suite with the online tests enabled (debian/rules configures with
--enable-online-unit-tests=auto). The first run was a slower, offline-only
subset of the second.

Drop mkdeb's own make check. The export-tree build stays, since regen-man needs
the compiled binaries, but the suite now runs once, under debuild, as the
superset. This is the same redundancy CI #352 removed via DEB_BUILD_OPTIONS=nocheck;
fixing it in mkdeb.sh applies it to release builds too instead of per-environment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 22:13:23 +02:00
Xavier Roche
1375ef97d7 Merge pull request #353 from xroche/ci/macos-i386
ci: add macOS and 32-bit (i386) build jobs
2026-06-14 22:09:11 +02:00
Xavier Roche
13207a92fc Make the cache and manpage tests POSIX-shell portable
Running the suite on macOS surfaced two GNU/Linux assumptions. The test
harness there resolves $(BASH) to /bin/sh (POSIX mode), and macOS ships
BSD userland, so:

- 01_engine-cache used "du -sb"; the -b (apparent bytes) flag is GNU-only
  and BSD/macOS du rejects it, leaving an empty size and an "integer
  expression expected" error. Switch to portable "du -sk" (1024-byte
  units); block-allocated size is an upper bound, fine for a ceiling.

- 02_manpage-regen used diff with process substitution, which a POSIX
  /bin/sh does not parse. Stage the stripped inputs in temp files instead.

Both now pass under dash as well as bash, on Linux and macOS.

Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 22:05:31 +02:00
Xavier Roche
d3eecbf211 Gate the GNU-ld libc-force flag behind a linker check
-Wl,--push-state,--no-as-needed,-lc,--pop-state forces libc back into
DT_NEEDED for libraries that reach it only through libhttrack: the
libhtsjava JNI wrapper and the libtest callback examples. The flag is
GNU-ld-specific; Apple's ld rejects it ("ld: unknown options:
--push-state --no-as-needed --pop-state"), breaking the macOS build, and
doesn't need it (every dylib links libSystem anyway).

Probe it once with AX_CHECK_LINK_FLAG and emit it via LIBC_FORCE_LINK
only where the linker accepts it. On GNU/Linux the flag is still applied
and libc.so.6 stays in DT_NEEDED, so behavior is unchanged there.

Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 21:57:56 +02:00
Xavier Roche
7ec77156d0 ci: add macOS and 32-bit (i386) build jobs
Two cheap portability targets that need no VM or second CI provider:

- macOS (Darwin/clang) on a native macos-14 runner. The tree has no
  __APPLE__ branches, so Darwin runs the generic-Unix path against a
  second libc and kernel. brew's openssl@3 is keg-only, so configure is
  pointed at it via CPPFLAGS/LDFLAGS.

- 32-bit i386 via multilib on the existing x86-64 runner. Exercises the
  32-bit size_t/pointer ABI, where size and bounds math can truncate or
  wrap in ways 64-bit never shows. --build (not --host) keeps configure
  out of cross mode so the i386 binary still runs the test suite.

Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 21:38:49 +02:00
Xavier Roche
3cd8197cc7 Merge pull request #352 from xroche/ci/deb-faster
ci: speed up the deb package job
2026-06-14 21:33:53 +02:00
Xavier Roche
37f50bb925 ci: speed up the deb package job
The deb job spent ~3m19s in the build step, half of it on work CI does not
need. The package build (via mkdeb.sh) ran the full test suite a second time
with online/network unit tests enabled (~54s), and compressed the large LTO
-dbgsym packages that CI throws away (~48s).

Set DEB_BUILD_OPTIONS=nocheck,noautodbgsym,parallel=N on the CI step only.
nocheck skips debuild's make check, which is redundant here: the build matrix
already runs the suite on every config and mkdeb.sh's own pre-build runs the
offline tests. noautodbgsym drops the -dbgsym packages. parallel uses every
runner core. mkdeb.sh is unchanged, so release builds still build with LTO,
full tests, and debug symbols; only the CI environment differs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 21:31:03 +02:00
Xavier Roche
d8d1eafcd1 Merge pull request #351 from xroche/feature/appstream-metainfo
Ship AppStream MetaInfo for WebHTTrack
2026-06-14 21:30:28 +02:00
Xavier Roche
80d0e90819 Merge pull request #350 from xroche/fix/webhttrack-browser-deps
debian: refresh stale webhttrack browser dependency
2026-06-14 21:26:31 +02:00
Xavier Roche
8dde8dc03c Ship AppStream MetaInfo for WebHTTrack
The Debian AppStream generator flagged both webhttrack desktop entries as
no-metainfo: with no MetaInfo file, the catalog entry is synthesized from
the .desktop file and the package description, which is deprecated and risks
the app being dropped from the metadata catalog.

Add com.httrack.WebHTTrack.metainfo.xml (installed to share/metainfo) for the
main app, launching WebHTTrack.desktop. Mark the secondary "Browse Mirrored
Websites" launcher with X-AppStream-Ignore=true so it doesn't produce a
duplicate, metadata-less catalog entry.

Validated with appstreamcli validate and desktop-file-validate.

Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-14 21:24:45 +02:00
21 changed files with 300 additions and 50 deletions

View File

@@ -61,6 +61,78 @@ jobs:
if: failure()
run: cat tests/test-suite.log 2>/dev/null || true
# Portability: build and test on macOS (Darwin/clang) on a native runner --
# no VM. The tree has no __APPLE__ branches, so Darwin exercises the
# generic-Unix path on a second libc and kernel. brew's openssl@3 is keg-only,
# so point configure at it; everything else is in the SDK or default paths.
macos:
name: build (macOS arm64, clang)
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install build dependencies
run: |
set -euo pipefail
brew install autoconf automake libtool autoconf-archive
- name: Configure
run: |
set -euo pipefail
ssl="$(brew --prefix openssl@3)"
autoreconf -fi
./configure CPPFLAGS="-I${ssl}/include" LDFLAGS="-L${ssl}/lib"
- name: Build
run: make -j"$(sysctl -n hw.ncpu)"
- name: Test
run: make check
- name: Print the test log on failure
if: failure()
run: cat tests/test-suite.log 2>/dev/null || true
# Portability/hardening: 32-bit (i386) build on the x86-64 runner via multilib
# -- no extra hardware. Exercises the 32-bit size_t/pointer ABI, where size
# and bounds math can truncate or wrap in ways 64-bit never reveals (the axis
# the overflow-safe bounds work targets). --build (not --host) keeps configure
# out of cross mode, so the i386 binary still runs the test suite here.
linux-i386:
name: build (linux i386, gcc -m32)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install build dependencies (multilib + 32-bit libs)
run: |
set -euo pipefail
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential gcc-multilib autoconf automake libtool \
autoconf-archive zlib1g-dev:i386 libssl-dev:i386
- name: Configure
run: |
set -euo pipefail
autoreconf -fi
./configure --build=i686-pc-linux-gnu CC="gcc -m32"
- name: Build
run: make -j"$(nproc)"
- name: Test
run: make check
- name: Print the test log on failure
if: failure()
run: cat tests/test-suite.log 2>/dev/null || true
# Validate the Debian packaging via the same script maintainers release with.
# One amd64/gcc run is enough: packaging (control/rules/manifest/lintian/quilt
# source build) is arch- and compiler-independent, and the build matrix above
@@ -84,8 +156,16 @@ jobs:
# --unsigned: CI has no GPG key (also skips the release sig/checksums).
# debuild builds every package, then lintian gates on errors.
#
# DEB_BUILD_OPTIONS trims work CI does not need (release builds via
# mkdeb.sh are untouched): noautodbgsym drops the -dbgsym packages whose
# LTO payloads are slow to compress and that CI never ships; parallel uses
# every core. We let debuild run its test pass -- the only one now that
# mkdeb no longer runs its own -- so CI exercises the packaged tests.
- name: Build Debian packages
run: bash tools/mkdeb.sh --unsigned --no-release-artifacts
run: |
export DEB_BUILD_OPTIONS="noautodbgsym parallel=$(nproc)"
bash tools/mkdeb.sh --unsigned --no-release-artifacts
dco:
name: DCO sign-off

View File

@@ -257,6 +257,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

48
configure vendored
View File

@@ -695,6 +695,7 @@ HAVE_VISIBILITY
CFLAG_VISIBILITY
LDFLAGS_PIE
CFLAGS_PIE
LIBC_FORCE_LINK
DEFAULT_LDFLAGS
DEFAULT_CFLAGS
VERSION_INFO
@@ -15871,6 +15872,53 @@ esac
fi
# Force libc back into DT_NEEDED for libraries that reach it only through
# libhttrack (libhtsjava, the libtest callbacks), but only with a GNU-style
# linker; Apple ld rejects these flags and links libSystem unconditionally.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--push-state,--no-as-needed,-lc,--pop-state" >&5
printf %s "checking whether the linker accepts -Wl,--push-state,--no-as-needed,-lc,--pop-state... " >&6; }
if test ${ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ax_check_save_flags=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--push-state,--no-as-needed,-lc,--pop-state"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state=yes
else case e in #(
e) ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LDFLAGS=$ax_check_save_flags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state" >&5
printf "%s\n" "$ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state" >&6; }
if test "x$ax_cv_check_ldflags___Wl___push_state___no_as_needed__lc___pop_state" = xyes
then :
LIBC_FORCE_LINK="-Wl,--push-state,--no-as-needed,-lc,--pop-state"
else case e in #(
e) : ;;
esac
fi
### PIE
CFLAGS_PIE=""
LDFLAGS_PIE=""

View File

@@ -91,6 +91,13 @@ AX_CHECK_LINK_FLAG([-Wl,--no-undefined], [DEFAULT_LDFLAGS="$DEFAULT_LDFLAGS -Wl,
AX_CHECK_LINK_FLAG([-Wl,-z,relro,-z,now], [DEFAULT_LDFLAGS="$DEFAULT_LDFLAGS -Wl,-z,relro,-z,now"])
AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [DEFAULT_LDFLAGS="$DEFAULT_LDFLAGS -Wl,-z,noexecstack"])
# Force libc back into DT_NEEDED for libraries that reach it only through
# libhttrack (libhtsjava, the libtest callbacks), but only with a GNU-style
# linker; Apple ld rejects these flags and links libSystem unconditionally.
AX_CHECK_LINK_FLAG([-Wl,--push-state,--no-as-needed,-lc,--pop-state],
[LIBC_FORCE_LINK="-Wl,--push-state,--no-as-needed,-lc,--pop-state"])
AC_SUBST([LIBC_FORCE_LINK])
### PIE
CFLAGS_PIE=""
LDFLAGS_PIE=""

View File

@@ -4,3 +4,4 @@ usr/share/man/man1/webhttrack.1
usr/share/man/man1/htsserver.1
usr/share/applications/WebHTTrack-Websites.desktop
usr/share/applications/WebHTTrack.desktop
usr/share/metainfo/com.httrack.WebHTTrack.metainfo.xml

View File

@@ -12,6 +12,7 @@ WebIcon16x16dir = $(datadir)/icons/hicolor/16x16/apps
WebIcon32x32dir = $(datadir)/icons/hicolor/32x32/apps
WebIcon48x48dir = $(datadir)/icons/hicolor/48x48/apps
VFolderEntrydir = $(prefix)/share/applications
MetaInfodir = $(datadir)/metainfo
# Wildcards are globbed against $(srcdir): a bare "*.html" is resolved against
# the build dir and stays unexpanded (breaking "make") in an out-of-tree build.
@@ -33,11 +34,12 @@ WebIcon16x16_DATA = $(srcdir)/server/div/16x16/*.png
WebIcon32x32_DATA = $(srcdir)/server/div/32x32/*.png
WebIcon48x48_DATA = $(srcdir)/server/div/48x48/*.png
VFolderEntry_DATA = $(srcdir)/server/div/*.desktop
MetaInfo_DATA = $(srcdir)/server/div/*.metainfo.xml
EXTRA_DIST = $(HelpHtml_DATA) $(HelpHtmlimg_DATA) $(HelpHtmlimages_DATA) \
$(HelpHtmldiv_DATA) $(WebHtml_DATA) $(WebHtmlimages_DATA) \
$(WebPixmap_DATA) $(WebIcon16x16_DATA) $(WebIcon32x32_DATA) $(WebIcon48x48_DATA) \
$(VFolderEntry_DATA) \
$(VFolderEntry_DATA) $(MetaInfo_DATA) \
httrack.css
install-data-hook:

View File

@@ -152,14 +152,15 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(HelpHtmldir)" \
"$(DESTDIR)$(HelpHtmlTxtdir)" "$(DESTDIR)$(HelpHtmldivdir)" \
"$(DESTDIR)$(HelpHtmlimagesdir)" "$(DESTDIR)$(HelpHtmlimgdir)" \
"$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(VFolderEntrydir)" \
"$(DESTDIR)$(WebHtmldir)" "$(DESTDIR)$(WebHtmlimagesdir)" \
"$(DESTDIR)$(WebIcon16x16dir)" "$(DESTDIR)$(WebIcon32x32dir)" \
"$(DESTDIR)$(WebIcon48x48dir)" "$(DESTDIR)$(WebPixmapdir)"
"$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(MetaInfodir)" \
"$(DESTDIR)$(VFolderEntrydir)" "$(DESTDIR)$(WebHtmldir)" \
"$(DESTDIR)$(WebHtmlimagesdir)" "$(DESTDIR)$(WebIcon16x16dir)" \
"$(DESTDIR)$(WebIcon32x32dir)" "$(DESTDIR)$(WebIcon48x48dir)" \
"$(DESTDIR)$(WebPixmapdir)"
DATA = $(HelpHtml_DATA) $(HelpHtmlTxt_DATA) $(HelpHtmldiv_DATA) \
$(HelpHtmlimages_DATA) $(HelpHtmlimg_DATA) \
$(HelpHtmlroot_DATA) $(VFolderEntry_DATA) $(WebHtml_DATA) \
$(WebHtmlimages_DATA) $(WebIcon16x16_DATA) \
$(HelpHtmlroot_DATA) $(MetaInfo_DATA) $(VFolderEntry_DATA) \
$(WebHtml_DATA) $(WebHtmlimages_DATA) $(WebIcon16x16_DATA) \
$(WebIcon32x32_DATA) $(WebIcon48x48_DATA) $(WebPixmap_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
@@ -212,6 +213,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -320,6 +322,7 @@ WebIcon16x16dir = $(datadir)/icons/hicolor/16x16/apps
WebIcon32x32dir = $(datadir)/icons/hicolor/32x32/apps
WebIcon48x48dir = $(datadir)/icons/hicolor/48x48/apps
VFolderEntrydir = $(prefix)/share/applications
MetaInfodir = $(datadir)/metainfo
# Wildcards are globbed against $(srcdir): a bare "*.html" is resolved against
# the build dir and stays unexpanded (breaking "make") in an out-of-tree build.
@@ -341,10 +344,11 @@ WebIcon16x16_DATA = $(srcdir)/server/div/16x16/*.png
WebIcon32x32_DATA = $(srcdir)/server/div/32x32/*.png
WebIcon48x48_DATA = $(srcdir)/server/div/48x48/*.png
VFolderEntry_DATA = $(srcdir)/server/div/*.desktop
MetaInfo_DATA = $(srcdir)/server/div/*.metainfo.xml
EXTRA_DIST = $(HelpHtml_DATA) $(HelpHtmlimg_DATA) $(HelpHtmlimages_DATA) \
$(HelpHtmldiv_DATA) $(WebHtml_DATA) $(WebHtmlimages_DATA) \
$(WebPixmap_DATA) $(WebIcon16x16_DATA) $(WebIcon32x32_DATA) $(WebIcon48x48_DATA) \
$(VFolderEntry_DATA) \
$(VFolderEntry_DATA) $(MetaInfo_DATA) \
httrack.css
all: all-am
@@ -511,6 +515,27 @@ uninstall-HelpHtmlrootDATA:
@list='$(HelpHtmlroot_DATA)'; test -n "$(HelpHtmlrootdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(HelpHtmlrootdir)'; $(am__uninstall_files_from_dir)
install-MetaInfoDATA: $(MetaInfo_DATA)
@$(NORMAL_INSTALL)
@list='$(MetaInfo_DATA)'; test -n "$(MetaInfodir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(MetaInfodir)'"; \
$(MKDIR_P) "$(DESTDIR)$(MetaInfodir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(MetaInfodir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(MetaInfodir)" || exit $$?; \
done
uninstall-MetaInfoDATA:
@$(NORMAL_UNINSTALL)
@list='$(MetaInfo_DATA)'; test -n "$(MetaInfodir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(MetaInfodir)'; $(am__uninstall_files_from_dir)
install-VFolderEntryDATA: $(VFolderEntry_DATA)
@$(NORMAL_INSTALL)
@list='$(VFolderEntry_DATA)'; test -n "$(VFolderEntrydir)" || list=; \
@@ -701,7 +726,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(HelpHtmldir)" "$(DESTDIR)$(HelpHtmlTxtdir)" "$(DESTDIR)$(HelpHtmldivdir)" "$(DESTDIR)$(HelpHtmlimagesdir)" "$(DESTDIR)$(HelpHtmlimgdir)" "$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(VFolderEntrydir)" "$(DESTDIR)$(WebHtmldir)" "$(DESTDIR)$(WebHtmlimagesdir)" "$(DESTDIR)$(WebIcon16x16dir)" "$(DESTDIR)$(WebIcon32x32dir)" "$(DESTDIR)$(WebIcon48x48dir)" "$(DESTDIR)$(WebPixmapdir)"; do \
for dir in "$(DESTDIR)$(HelpHtmldir)" "$(DESTDIR)$(HelpHtmlTxtdir)" "$(DESTDIR)$(HelpHtmldivdir)" "$(DESTDIR)$(HelpHtmlimagesdir)" "$(DESTDIR)$(HelpHtmlimgdir)" "$(DESTDIR)$(HelpHtmlrootdir)" "$(DESTDIR)$(MetaInfodir)" "$(DESTDIR)$(VFolderEntrydir)" "$(DESTDIR)$(WebHtmldir)" "$(DESTDIR)$(WebHtmlimagesdir)" "$(DESTDIR)$(WebIcon16x16dir)" "$(DESTDIR)$(WebIcon32x32dir)" "$(DESTDIR)$(WebIcon48x48dir)" "$(DESTDIR)$(WebPixmapdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -757,10 +782,10 @@ info-am:
install-data-am: install-HelpHtmlDATA install-HelpHtmlTxtDATA \
install-HelpHtmldivDATA install-HelpHtmlimagesDATA \
install-HelpHtmlimgDATA install-HelpHtmlrootDATA \
install-VFolderEntryDATA install-WebHtmlDATA \
install-WebHtmlimagesDATA install-WebIcon16x16DATA \
install-WebIcon32x32DATA install-WebIcon48x48DATA \
install-WebPixmapDATA
install-MetaInfoDATA install-VFolderEntryDATA \
install-WebHtmlDATA install-WebHtmlimagesDATA \
install-WebIcon16x16DATA install-WebIcon32x32DATA \
install-WebIcon48x48DATA install-WebPixmapDATA
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-am
@@ -808,10 +833,10 @@ ps-am:
uninstall-am: uninstall-HelpHtmlDATA uninstall-HelpHtmlTxtDATA \
uninstall-HelpHtmldivDATA uninstall-HelpHtmlimagesDATA \
uninstall-HelpHtmlimgDATA uninstall-HelpHtmlrootDATA \
uninstall-VFolderEntryDATA uninstall-WebHtmlDATA \
uninstall-WebHtmlimagesDATA uninstall-WebIcon16x16DATA \
uninstall-WebIcon32x32DATA uninstall-WebIcon48x48DATA \
uninstall-WebPixmapDATA
uninstall-MetaInfoDATA uninstall-VFolderEntryDATA \
uninstall-WebHtmlDATA uninstall-WebHtmlimagesDATA \
uninstall-WebIcon16x16DATA uninstall-WebIcon32x32DATA \
uninstall-WebIcon48x48DATA uninstall-WebPixmapDATA
.MAKE: install-am install-data-am install-strip
@@ -821,20 +846,21 @@ uninstall-am: uninstall-HelpHtmlDATA uninstall-HelpHtmlTxtDATA \
install install-HelpHtmlDATA install-HelpHtmlTxtDATA \
install-HelpHtmldivDATA install-HelpHtmlimagesDATA \
install-HelpHtmlimgDATA install-HelpHtmlrootDATA \
install-VFolderEntryDATA install-WebHtmlDATA \
install-WebHtmlimagesDATA install-WebIcon16x16DATA \
install-WebIcon32x32DATA install-WebIcon48x48DATA \
install-WebPixmapDATA install-am install-data install-data-am \
install-data-hook install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
uninstall-HelpHtmlDATA uninstall-HelpHtmlTxtDATA \
uninstall-HelpHtmldivDATA uninstall-HelpHtmlimagesDATA \
uninstall-HelpHtmlimgDATA uninstall-HelpHtmlrootDATA \
install-MetaInfoDATA install-VFolderEntryDATA \
install-WebHtmlDATA install-WebHtmlimagesDATA \
install-WebIcon16x16DATA install-WebIcon32x32DATA \
install-WebIcon48x48DATA install-WebPixmapDATA install-am \
install-data install-data-am install-data-hook install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-HelpHtmlDATA \
uninstall-HelpHtmlTxtDATA uninstall-HelpHtmldivDATA \
uninstall-HelpHtmlimagesDATA uninstall-HelpHtmlimgDATA \
uninstall-HelpHtmlrootDATA uninstall-MetaInfoDATA \
uninstall-VFolderEntryDATA uninstall-WebHtmlDATA \
uninstall-WebHtmlimagesDATA uninstall-WebIcon16x16DATA \
uninstall-WebIcon32x32DATA uninstall-WebIcon48x48DATA \

View File

@@ -8,3 +8,6 @@ Comment=Browse Websites Mirrored by WebHTTrack
Keywords=browse mirrored;
Exec=webhttrack browse
Icon=httrack
# Helper launcher for WebHTTrack's browse mode, not a standalone app: keep it
# out of software-center catalogs so it doesn't duplicate the main entry.
X-AppStream-Ignore=true

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2026 Xavier Roche <roche@httrack.com> -->
<component type="desktop-application">
<id>com.httrack.WebHTTrack</id>
<metadata_license>FSFAP</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<name>WebHTTrack Website Copier</name>
<summary>Copy websites to your computer for offline browsing</summary>
<description>
<p>
WebHTTrack is the web interface to HTTrack, an offline browser utility.
It downloads a website from the Internet to a local directory, fetching
the HTML, images, and other files and rebuilding the site's link
structure so you can browse it offline.
</p>
<p>
A step-by-step web interface guides you through choosing the addresses
to mirror and the options to apply. Mirrors can be updated in place and
interrupted downloads resumed.
</p>
<p>Typical uses include:</p>
<ul>
<li>Keeping an offline copy of a website for reading without a connection</li>
<li>Archiving or preserving sites and capturing them for later reference</li>
<li>Updating an existing local mirror without downloading it again</li>
</ul>
</description>
<launchable type="desktop-id">WebHTTrack.desktop</launchable>
<icon type="stock">httrack</icon>
<categories>
<category>Network</category>
</categories>
<keywords>
<keyword>offline browser</keyword>
<keyword>website copier</keyword>
<keyword>mirror</keyword>
<keyword>crawl</keyword>
<keyword>archiving</keyword>
</keywords>
<url type="homepage">https://www.httrack.com/</url>
<url type="bugtracker">https://github.com/xroche/httrack/issues</url>
<developer id="com.httrack">
<name>Xavier Roche</name>
</developer>
<screenshots>
<screenshot type="default">
<caption>Choosing the addresses and options for a new mirror</caption>
<image>https://www.httrack.com/html/images/screenshot_01b.jpg</image>
</screenshot>
</screenshots>
<content_rating type="oars-1.1"/>
<releases>
<release version="3.49.8" date="2026-06-07"/>
</releases>
</component>

View File

@@ -202,6 +202,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

View File

@@ -20,11 +20,12 @@ AM_CPPFLAGS += -I$(top_srcdir)/src
# The callback examples reference libc only through libhttrack, so the direct
# libc edge gets dropped from DT_NEEDED (library-not-linked-against-libc).
# Force libc to be recorded as a dependency.
# Force libc back; configure gates the flag since only a GNU-style linker
# accepts it (LIBC_FORCE_LINK is empty on e.g. macOS).
AM_LDFLAGS = \
@DEFAULT_LDFLAGS@ \
-L../src \
-Wl,--push-state,--no-as-needed,-lc,--pop-state
@LIBC_FORCE_LINK@
# Examples
libbaselinks_la_SOURCES = callbacks-example-baselinks.c

View File

@@ -344,6 +344,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -453,11 +454,12 @@ AM_CPPFLAGS = @DEFAULT_CFLAGS@ @THREADS_CFLAGS@ @V6_FLAG@ @LFS_FLAG@ \
# The callback examples reference libc only through libhttrack, so the direct
# libc edge gets dropped from DT_NEEDED (library-not-linked-against-libc).
# Force libc to be recorded as a dependency.
# Force libc back; configure gates the flag since only a GNU-style linker
# accepts it (LIBC_FORCE_LINK is empty on e.g. macOS).
AM_LDFLAGS = \
@DEFAULT_LDFLAGS@ \
-L../src \
-Wl,--push-state,--no-as-needed,-lc,--pop-state
@LIBC_FORCE_LINK@
# Examples

View File

@@ -173,6 +173,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

View File

@@ -203,6 +203,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

View File

@@ -86,8 +86,9 @@ libhtsjava_la_SOURCES = htsjava.c htsjava.h
libhtsjava_la_LIBADD = $(THREADS_LIBS) $(DL_LIBS) libhttrack.la
# This thin JNI wrapper reaches libc only through libhttrack, so the direct
# libc edge is dropped from DT_NEEDED (library-not-linked-against-libc). Force
# libc to be recorded as a dependency.
libhtsjava_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(VERSION_INFO) -Wl,--push-state,--no-as-needed,-lc,--pop-state
# libc back as a dependency; configure gates the flag since only a GNU-style
# linker accepts it (LIBC_FORCE_LINK is empty on e.g. macOS).
libhtsjava_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(VERSION_INFO) $(LIBC_FORCE_LINK)
EXTRA_DIST = httrack.h webhttrack \
coucal/murmurhash3.h.diff \

View File

@@ -361,6 +361,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -537,8 +538,9 @@ libhtsjava_la_SOURCES = htsjava.c htsjava.h
libhtsjava_la_LIBADD = $(THREADS_LIBS) $(DL_LIBS) libhttrack.la
# This thin JNI wrapper reaches libc only through libhttrack, so the direct
# libc edge is dropped from DT_NEEDED (library-not-linked-against-libc). Force
# libc to be recorded as a dependency.
libhtsjava_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(VERSION_INFO) -Wl,--push-state,--no-as-needed,-lc,--pop-state
# libc back as a dependency; configure gates the flag since only a GNU-style
# linker accepts it (LIBC_FORCE_LINK is empty on e.g. macOS).
libhtsjava_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(VERSION_INFO) $(LIBC_FORCE_LINK)
EXTRA_DIST = httrack.h webhttrack \
coucal/murmurhash3.h.diff \
coucal/murmurhash3.h.orig \

View File

@@ -202,6 +202,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

View File

@@ -1,5 +1,8 @@
#!/bin/bash
#
# Keep this POSIX-portable: the harness runs it via $(BASH), which is a plain
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms and GNU-only
# tool flags despite the #!/bin/bash above.
# Cache create/read/update logic (driven by 'httrack -#A <dir>').
#
@@ -38,9 +41,12 @@ test -e "$dir/hts-cache/new.zip" || {
# Sanity-check the cache footprint: the few-thousand-entry pass is expected to
# weigh ~1-2 MB. Fail if it balloons well past that (e.g. a per-entry overhead
# regression or runaway growth), so the cache size stays bounded.
ceiling=$((4 * 1024 * 1024))
bytes=$(du -sb "$dir/hts-cache" | cut -f1)
test "$bytes" -le "$ceiling" || {
echo "cache footprint $bytes bytes exceeds ${ceiling} ceiling" >&2
# du -sk (1024-byte units) is portable; GNU's -b (apparent bytes) is rejected
# by BSD/macOS du. Block-allocated size is an upper bound on apparent size,
# which is all a ceiling check needs.
ceiling=$((4 * 1024)) # KiB
kbytes=$(du -sk "$dir/hts-cache" | cut -f1)
test "$kbytes" -le "$ceiling" || {
echo "cache footprint ${kbytes} KiB exceeds ${ceiling} KiB ceiling" >&2
exit 1
}

View File

@@ -3,6 +3,10 @@
# The committed man/httrack.1 must match what man/makeman.sh produces from the
# current "httrack --help" output. This catches a --help change that was not
# followed by "make -C man regen-man".
#
# Keep this POSIX-portable: the harness runs it via $(BASH), which is a plain
# POSIX /bin/sh on some platforms (e.g. macOS), so avoid bashisms (such as
# process substitution) despite the #!/bin/bash above.
: "${top_srcdir:=..}"
@@ -20,7 +24,9 @@ command -v httrack >/dev/null 2>&1 || {
}
tmp=$(mktemp) || exit 1
trap 'rm -f "$tmp"' EXIT
committed_clean=$(mktemp) || exit 1
generated_clean=$(mktemp) || exit 1
trap 'rm -f "$tmp" "$committed_clean" "$generated_clean"' EXIT
README="$top_srcdir/README" bash "$gen" httrack >"$tmp" 2>/dev/null || {
echo "makeman.sh failed" >&2
@@ -28,12 +34,15 @@ README="$top_srcdir/README" bash "$gen" httrack >"$tmp" 2>/dev/null || {
}
# Ignore the two intentionally date-dependent lines (page date, copyright year).
# Temp files, not process substitution, so this works under a POSIX /bin/sh.
strip_volatile() { grep -vE '^\.TH httrack |^Copyright \(C\) 1998-'; }
strip_volatile <"$committed" >"$committed_clean"
strip_volatile <"$tmp" >"$generated_clean"
if diff <(strip_volatile <"$committed") <(strip_volatile <"$tmp") >/dev/null; then
if diff "$committed_clean" "$generated_clean" >/dev/null; then
exit 0
fi
echo "man/httrack.1 is out of date. Regenerate with: make -C man regen-man" >&2
diff <(strip_volatile <"$committed") <(strip_volatile <"$tmp") | head -40 >&2
diff "$committed_clean" "$generated_clean" | head -40 >&2
exit 1

View File

@@ -380,6 +380,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_PIE = @LDFLAGS_PIE@
LFS_FLAG = @LFS_FLAG@
LIBC_FORCE_LINK = @LIBC_FORCE_LINK@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@

View File

@@ -118,7 +118,10 @@ main() {
git -C "$repo/src/coucal" archive --format=tar --prefix=src/coucal/ HEAD |
tar -x -C "$export_dir"
# Refresh build system and man page, then build and validate the tarball.
# Refresh build system and man page, then build the tarball. We build here
# only because regen-man needs the compiled binaries; the test suite is not
# run in this pass. debuild (below) runs the full suite once, with the online
# tests enabled, so a check here would just be a slower, offline-only repeat.
info "regenerating build system and man page"
(
cd "$export_dir"
@@ -126,8 +129,6 @@ main() {
./configure --quiet
make -s -j"$(nproc)"
make -s -C man regen-man
info "running test suite"
make -s check
# Build the tarball from a clean tree so no object files leak into it.
make -s clean
make -s dist