How to build Thunderbird-ESR (and later patch it to become Betterbird)?

My aim is to build Betterbird, a soft fork of Thunderbird-ESR, for FreeBSD. My idea is to start with building mail/thunderbird-esr before applying all patches of Betterbird.

I read the Poudriere chapter in porters handbook and viewed/followed some tutorials like Setting up Poudriere on FreeBSD - Building Ports (youtube). I also read some Mozilla documentation like Linux Build Prerequisites and Betterbird build instructions.

I setup my jails and ports-tree:
Code:
~ # poudriere jail -l
JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
150build 15.0-RELEASE-p1 amd64 http   2026-01-02 20:59:41 /usr/local/poudriere/jails/150build

~ # poudriere ports -l
PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2026-01-04 19:21:33 /usr/local/poudriere/ports/default

I setup my distfile
Code:
~ # cat /usr/local/etc/poudriere.d/portlist
mail/thunderbird-esr

I started poudriere options -j 150build -f /usr/local/etc/poudriere.d/portlist. But now I have tons of dependencies like mercurial, binutils, cmake, bash, Tesseract OCR, SANE, ffmpeg, CUPS, etc., which I am supposed to build by mysely. First I think I do not need a specific configurations for most dependencies. It seems pointless to me to rebuild all packages when I could just install them directly with pkg into the jail. Somewhere I saw a make -D NO_DIALOG for ports but I do not know how to use it with poudriere.

Here are my questions:
  1. The hard way: I have to build all dependencies by myself ⇒ Is there a way to get a list of sane configuration settings for Thunderbird dependencies?
  2. The simpler approach: There is a way to avoid building the complete dependency tree by myself:
    1. How to set up poudriere jail / ports-tree so that available packages from FreeBSD 15.0-RELEASE are used?
    2. How to run Thunderbird configuration to build only parts of the dependencies like ffmpeg?
  3. "You are holding it wrong!" ⇒ I am a complete beginner. Did I misunderstood something, or is there a simpler approach to building a Betterbird?
 
How to set up poudriere jail / ports-tree so that available packages from FreeBSD 15.0-RELEASE are used?

Code:
     -b branch
              Fetch binary packages from a binary package repository instead
              of building them.  The branch argument can be one of the
              following: latest, quarterly, release_X (where X is the minor
              version of a release, e.g., “0”), or url.

              With this option poudriere will first try to fetch a binary
              package from the specified binary package repository.
poudriere-bulk(8)
 
Code:
     -b branch
              Fetch binary packages from a binary package repository instead
              of building them.  The branch argument can be one of the
              following: latest, quarterly, release_X (where X is the minor
              version of a release, e.g., “0”), or url.

              With this option poudriere will first try to fetch a binary
              package from the specified binary package repository.
poudriere-bulk(8)
I found this option really tricky cuz i could never made use of it for myself. I think they can go into thunderbird port and run a make install-missing-packages then figure out later steps. I don't know how you can do that in jail/poudriere though.
 
I tried -b with: poudriere bulk -f /usr/local/etc/poudriere.d/portlist -j 150build -b quarterly

But something is wrong:
Code:
[150build-default] [2026-01-06_22h10m35s] [parallel_build] Queued: 297 Built: 257 Failed: 0   Skipped: 0   Ignored: 0   Fetched: 0   Tobu
ild: 40   Time: 00:25:40
 ID  TOTAL                            ORIGIN   PKGNAME                               PHASE PHASE    TMPFS       CPU% MEM%
[01] 00:00:23                 print/harfbuzz | harfbuzz-12.3.0               build-depends 00:00:07 98.79 MiB   4.4% 0.1%
[02] 00:10:14                      lang/rust | rust-1.92.0                           build 00:08:29 5.90 GiB  222.7% 3.3%
[03] 00:10:52           devel/llvm19@default | llvm19-19.1.7_1                       build 00:08:21 2.28 GiB  304.4% 4.7%
[04] 00:00:22 graphics/gtk-update-icon-cache | gtk-update-icon-cache-3.24.42 build-depends 00:00:13 1.03 MiB      0%   0%
[05] 00:00:46               security/p11-kit | p11-kit-0.25.10                   configure 00:00:00 11.67 MiB            
[06] 00:01:35                      lang/vala | vala-0.56.18,1                    configure 00:00:51 58.32 MiB     0%   0%

For example I build rust and llvm19. But they shall be downloaded/used as pkg binary.
 
I restarted from scratch and reduced my setup to build sudo instead of tunderbird to find the error. But I think I failed again. Perhaps someone can point out my mistake.
  1. old jail
    1. stop: poudriere jail -k -j 150build
    2. delete: poudriere jail -d -j 150build
  2. poudriere ports
    1. clean all ports trees: poudriere distclean -a -J 12 -y
    2. remove port options: poudriere options -j 150build -r -f /usr/local/etc/poudriere.d/portlist
    3. delete ports tree: poudriere ports -d -p default
    4. remove old distfiles: rm -r /usr/ports/distfiles/*
  3. remove old packages: rm -r /usr/local/poudriere/data/packages/*
  4. setup configuration:
    1. :~ # egrep -v '^$|^#' /usr/local/etc/poudriere.conf
      Code:
      ZPOOL=zroot
      ZROOTFS=/poudriere
      FREEBSD_HOST=ftp://ftp.freebsd.org
      RESOLV_CONF=/etc/resolv.conf
      BASEFS=/usr/local/poudriere
      POUDRIERE_DATA=${BASEFS}/data
      USE_PORTLINT=no
      USE_TMPFS=yes
      TMPFS_LIMIT=10
      MAX_MEMORY=10
      DISTFILES_CACHE=/usr/ports/distfiles
      CHECK_CHANGED_OPTIONS=verbose
      CHECK_CHANGED_DEPS=yes
      CCACHE_DIR=/var/cache/ccache
      PARALLEL_JOBS=6
      PREPARE_PARALLEL_JOBS=3
      ALLOW_MAKE_JOBS=yes
      KEEP_OLD_PACKAGES=no
      USE_COLORS=yes
      PACKAGE_FETCH_BRANCH=2025Q4
      PACKAGE_FETCH_URL=pkg+http://pkg.FreeBSD.org/\${ABI}
    2. :~ # cat /usr/local/etc/poudriere.d/make.conf
      Makefile:
      # general
      ALLOW_UNSUPPORTED_SYSTEM= YES
      DISABLE_LICENSES=         YES
      WITHOUT_DEBUG=            YES
      NO_PROFILE=               YES
      BUILD_STATIC=             YES
      OPTIONS_UNSET+=           DOCS INFO MANPAGES EXAMPLES PROFILE SOURCES WAYLAND
      # National Language Support and Link Time Opimization
      OPTIONS_SET+=             NLS LTO CPU_OPTS OPTIMIZED_CFLAGS STATIC
      ENABLE_LICENSES=          YES
      
      # ccache(1)
      WITH_CCACHE_BUILD=        YES
      
      # ports build options (defined in poutriere.conf)
      # FORCE_MAKE_JOBS=        YES
      # MAKE_JOBS_UNSAFE=       YES
      # MAKE_JOBS_NUMBER=       8
      
      CPUTYPE?=                 native
      OPTIMIZED_CFLAGS=         YES
      BUILD_OPTIMIZED=          YES
      WITH_CPUFLAGS=            YES
      WITH_OPTIMIZED_CFLAGS=    YES
    3. :~ # zfs list
      Code:
      NAME                                        USED  AVAIL  REFER  MOUNTPOINT
      zroot                                      28.7G  3.49T  30.6K  /zroot
      zroot/ROOT                                 18.1G  3.49T  30.6K  none
      zroot/ROOT/15.0-RELEASE_2025-12-17_231732  1.33K  3.49T  15.5G  /
      zroot/ROOT/default                         18.1G  3.49T  17.5G  /
      ...
      zroot/poudriere                            1.62G  3.49T  33.3K  /usr/local/poudriere
      zroot/poudriere/data                       91.8M  3.49T  38.6K  /usr/local/poudriere/data
      zroot/poudriere/data/.m                    32.0K  3.49T  32.0K  /usr/local/poudriere/data/.m
      zroot/poudriere/data/cache                  167K  3.49T   167K  /usr/local/poudriere/data/cache
      zroot/poudriere/data/images                30.6K  3.49T  30.6K  /usr/local/poudriere/data/images
      zroot/poudriere/data/logs                  26.0M  3.49T  26.0M  /usr/local/poudriere/data/logs
      zroot/poudriere/data/packages              65.5M  3.49T  65.5M  /usr/local/poudriere/data/packages
      zroot/poudriere/data/wrkdirs               30.6K  3.49T  30.6K  /usr/local/poudriere/data/wrkdirs
      zroot/poudriere/jails                      1.14G  3.49T  30.6K  /usr/local/poudriere/jails
      zroot/poudriere/jails/150rel               1.14G  3.49T  1.14G  /usr/local/poudriere/jails/150rel
      zroot/poudriere/ports                       400M  3.49T  30.6K  /usr/local/poudriere/ports
      zroot/poudriere/ports/2025Q4                400M  3.49T   400M  /usr/local/poudriere/ports/2025Q4
      zroot/test                                 30.6K  3.49T  30.6K  /zroot/test
      zroot/tmp                                  1.44M  3.49T  1.44M  /tmp
      zroot/usr                                   489M  3.49T  30.6K  /usr
      zroot/usr/ports                             489M  3.49T   489M  /usr/ports
      zroot/usr/src                              30.6K  3.49T  30.6K  /usr/src
      zroot/var                                  1008K  3.49T  30.6K  /var
      zroot/var/audit                            30.6K  3.49T  30.6K  /var/audit
      zroot/var/crash                            30.6K  3.49T  30.6K  /var/crash
      zroot/var/log                               835K  3.49T   835K  /var/log
      zroot/var/mail                             50.6K  3.49T  50.6K  /var/mail
      zroot/var/tmp                              30.6K  3.49T  30.6K  /var/tmp
  5. check ccache configuration: ccache -p vs. CCACHE_DIR=/var/cache/ccache using egrep -v '^$|^#' /usr/local/etc/poudriere.conf | sort
  6. generate new jail: poudriere jail -c -j 150rel -v 15.0-RELEASE -a amd64
  7. generate new ports tree: poudriere ports -c -p 2025Q4 -B 2025Q4 -v
  8. add sudo to portlist (the package to build): echo "security/sudo" > /usr/local/etc/poudriere.d/portlist
  9. configure build: poudriere options -j 150rel -p 2025Q4 -n -c -f /usr/local/etc/poudriere.d/portlist
  10. build: poudriere bulk -f /usr/local/etc/poudriere.d/portlist -j 150rel -b quarterly -p 2025Q4

Results:
1. I only see 2 parallel builds at the same time out of possible 6 as configured in poudriere.conf.
2. I see no llvm, rust or whatever is inside 15.0-Release base. Perfekt.
3. I see building messages of all those files when Ctrl+t. All packages seems to be downloaded and also rebuild from source:
Code:
:~ # ls -l /usr/local/poudriere/data/packages/150rel-2025Q4/.latest/All
total 66976
-rw-r--r--  1 root wheel   334718 Jan  7 15:29 autoconf-2.72.pkg
-rw-r--r--  1 root wheel     1002 Jan  7 15:27 autoconf-switch-20220527.pkg
-rw-r--r--  1 root wheel   559261 Jan  7 15:27 ccache-3.7.12_8.pkg
-rw-r--r--  1 root wheel   289619 Jan  7 15:29 cyrus-sasl-2.1.28_5.pkg
-rw-r--r--  1 root wheel   209074 Jan  7 13:14 gettext-runtime-0.23.1.pkg
-rw-r--r--  1 root wheel  3018117 Jan  7 13:15 gettext-tools-0.23.1_1.pkg
-rw-r--r--  1 root wheel   491313 Jan  7 15:27 gmake-4.4.1.pkg
-rw-r--r--  1 root wheel     4620 Jan  7 13:13 indexinfo-0.3.1_1.pkg
-rw-r--r--  1 root wheel    49735 Jan  7 15:27 libffi-3.5.1.pkg
-rw-r--r--  1 root wheel   462490 Jan  7 13:14 libtextstyle-0.23.1.pkg
-rw-r--r--  1 root wheel   181159 Jan  7 15:28 m4-1.4.19_1,1.pkg
-rw-r--r--  1 root wheel   166587 Jan  7 15:27 mpdecimal-4.0.1.pkg
-rw-r--r--  1 root wheel   572580 Jan  7 15:29 openldap26-client-2.6.10.pkg
-rw-r--r--  1 root wheel 16691129 Jan  7 15:29 perl5-5.42.0_1.pkg
-rw-r--r--  1 root wheel 14352843 Jan  7 13:13 pkg-2.4.2.pkg
-rw-r--r--  1 root wheel    84114 Jan  7 13:13 pkgconf-2.4.3,1.pkg
-rw-r--r--  1 root wheel 28308132 Jan  7 15:30 python311-3.11.14.pkg
-rw-r--r--  1 root wheel   388621 Jan  7 15:27 readline-8.2.13_2.pkg
-rw-r--r--  1 root wheel  1359414 Jan  7 15:30 sudo-1.9.17p2_1.pkg

:~ # ls -l /usr/ports/distfiles/*
total 25533
-rw-r--r--  1 root wheel 1389680 Dec 22  2023 autoconf-2.72.tar.xz
-rw-r--r--  1 root wheel  506948 Dec  8  2021 ccache-3.7.12.tar.gz
-rw-r--r--  1 root wheel 4034803 Feb 22  2022 cyrus-sasl-2.1.28.tar.gz
-rw-r--r--  1 root wheel 1419757 Jun 10  2025 libffi-3.5.1.tar.gz
-rw-r--r--  1 root wheel 1654908 May 28  2021 m4-1.4.19.tar.xz
-rw-r--r--  1 root wheel 1305648 Feb 26  2023 make-4.4.1.tar.lz
-rw-r--r--  1 root wheel  316268 May  6  2025 mpdecimal-4.0.1.tar.gz
-rw-r--r--  1 root wheel 6517089 May 23  2025 openldap-2.6.10.tgz
drwxr-xr-x  2 root wheel       3 Jan  7 15:27 perl
drwxr-xr-x  2 root wheel       3 Jan  7 15:28 python
-rw-r--r--  1 root wheel 3043952 Sep 26  2022 readline-8.2.tar.gz
-rw-r--r--  1 root wheel    1198 Oct  5  2022 readline82-001
-rw-r--r--  1 root wheel    1134 Nov 17  2023 readline82-002
-rw-r--r--  1 root wheel    1201 Nov 17  2023 readline82-003
-rw-r--r--  1 root wheel    1708 Nov 17  2023 readline82-004
-rw-r--r--  1 root wheel    1501 Nov 17  2023 readline82-005
-rw-r--r--  1 root wheel    3031 Nov 17  2023 readline82-006
-rw-r--r--  1 root wheel    1422 Nov 17  2023 readline82-007
-rw-r--r--  1 root wheel    1697 Jan 14  2024 readline82-008
-rw-r--r--  1 root wheel    2270 Jan 14  2024 readline82-009
-rw-r--r--  1 root wheel    2653 Jan 14  2024 readline82-010
-rw-r--r--  1 root wheel    1865 Aug  2  2024 readline82-011
-rw-r--r--  1 root wheel    2824 Aug  2  2024 readline82-012
-rw-r--r--  1 root wheel    5757 Aug  2  2024 readline82-013
-rw-r--r--  1 root wheel 5451682 Jul 26 17:16 sudo-1.9.17p2.tar.gz

/usr/ports/distfiles/perl:
total 14079
-rw-r--r--  1 root wheel 14400988 Jul  3  2025 perl-5.42.0.tar.xz

/usr/ports/distfiles/python:
total 19964
-rw-r--r--  1 root wheel 20326860 Oct  9 19:07 Python-3.11.14.tar.xz

What's the problem? Or am I misinterpreting something?
 
2.1) that command ferrets out the 'distfiles', i.e. all the source files from which the ports are built (usually saved to /usr/ports/distfiles or wherever you have set DISTFILES_CACHE to) . It doesn't 'clean' the ports tree itself. There's nothing to 'clean' in those ports trees. You might thinking of the work/ directories you see when you build from ports yourself. But poudriere saves those elsewhere (a tmpfs(4) filesystem, by default; USE_TMPFS=yes).

2.4) You already cleaned it out in step 2.1.

I only see 2 parallel builds at the same time out of possible 6 as configured in poudriere.conf.
More jobs can only run if their dependencies can be satisfied. And if there's more than 2 to build of course.

What's the problem?
You have a whole bunch of global options in your make.conf, turning various options on. Deviating everything from the defaults the FreeBSD repository builders use.

Code:
              poudriere will only use packages that:
              •   come from a repository having the same or older version of
                  pkg.
              •   do not have a locally fetched package already.
              •   are not IGNORED.
              •   match the expected local version.
              •   match the expected ABI.
              •   match the expected runtime and library dependencies.
              •   match the expected OPTIONS when CHECK_CHANGED_OPTIONS is                    <--------- !!!! 
                  enabled (default: on).
              •   is NOT listed in PACKAGE_FETCH_BLACKLIST.
              •   is NOT listed with -C, or -c, when -t is used.
              The -v flag can be used to show these decisions during build.
              Specifing twice will show more details on why some are skipped.

rm -rf /usr/local/etc/poudriere.d/make.conf
rm -rf /usr/local/etc/poudriere.d/*-options
 
Thanks for the feedback.


SirDice said:
Code:
              poudriere will only use packages that:
              •   come from a repository having the same or older version of
                  pkg.
I possibly see my mistake. I mixed a jail of 15.0-RELESE with port of origin/main. So if I want to build something like thunderbird which needs rust it cannot use rust from 15.0-RELESE but has to build it from origin/main port. Is this correct?

SirDice said:
2.1) ... the source files from which the ports are built (usually saved to /usr/ports/distfiles ...). ... There's nothing to 'clean' in those ports trees. ... But poudriere saves those elsewhere ...).

2.4) You already cleaned it out in step 2.1.
In my case :~ # poudriere distclean -a -J 12 -p 2025Q4 -y does not wipe neither /usr/ports/distfiles/ nor /usr/local/poudriere/data/packages/150rel-2025Q4/.latest/All. I think the last sentense of your first paragraph describes the meaning of the command.

I will adjust my setup and try again.
 
does not wipe neithe
Oh yea. That part don't work well either. Deleting built works. You need to properly delete jails then sweep up leftover files. If not chflag hell.
/usr/obj/ is the root build directory for poudriere and there is stuff scattered elsewhere like /poudriere.d/. I move my /usr/local/poudriere/ to /poudriere for convenience. Change conf.
Ports end up under that directory with default setting. /dev/null is probably better. Less diskspace used.
 
Some progress...

To be able to use poudriere-bulk -b option, I setup on a trial base:
Code:
root@mybsd:~ # poudriere jail -l
JAILNAME VERSION      ARCH  METHOD TIMESTAMP           PATH
160c     16.0-CURRENT amd64 http   2026-01-09 12:09:28 /usr/local/poudriere/jails/160c

root@mybsd:~ # poudriere ports -l
PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2026-01-09 12:13:49 /usr/local/poudriere/ports/default

root@mybsd:~ # git -C /usr/local/poudriere/ports/default/ status | head -2
On branch main
Your branch is up to date with 'origin/main'.

And I got:
Code:
root@mybsd:~ # poudriere bulk -f /usr/local/etc/poudriere.d/portlist -j 160c -b latest
[00:00:00] Creating the reference jail... done
[00:00:00] Warning: !!! Jail is newer than host. (Jail: 1600007, Host: 1500068) !!!
[00:00:00] Warning: This is not supported.
[00:00:00] Warning: Host kernel must be same or newer than jail.
[00:00:00] Warning: Expect build failures.
Same result when using 15.0-STABLE. Great!

Seems for "poudiere bulk ... -b" a 15.0-RELEASE jail is bound to a 2025Q4 port. If I want to benefit from -b option and latest ports I have to change my host at least to 15.0-STABLE.

Is my assumption correct?
 
Back
Top