Re: What is a FLAVOR and how to unbreak ports?

"Edward Sanford Sutton, III" <[email protected]> Sun, 26 Jul 2026 18:41:53 -0700
Newsgroups gmane.os.freebsd.devel.ports
Message-ID <SA1PR11MB88113E9A84985B293F61293BE6CC2@SA1PR11MB8811.namprd11.prod.outlook.com>
   Flavors are a way to have separate packages created for different 
configurations of a port. That way users of pkg do not need to go 
manually build software for relatively common software variation 
possibilities that they may want or need in place of a single default 
set of options.

On 7/26/26 13:18, Steve Kargl wrote:
> On 7/26/26 12:51, Gleb Popov wrote:
>> On Sun, Jul 26, 2026 at 10:43 PM Steve Kargl <[email protected]> wrote:
>>>
>>> Hi,
>>>
>>> Updating a laptop that had a year old FreeBSD on it
>>> to top-of-tree.
>>>
>>> % portmaster -Byd --force-config sqlite3 |& tee sgk.log
>>
>> Try updating libclc first using portmaster or plain make.
> 
> I did try plain make in libclc.  See the end of original email.
> make dies with an error about llvm15 no longer being supported.
> If llvm15 is no longer supported on fbsd 16, then the libclc
> Makefile should simply skip trying to build for llvm15.
> 
>> Figure out what flavor you need by looking at the installed package's 
>> name
> 
> That's the question.  What is a FLAVOR and how do I determine what
> FLAVOR is the right flavor?
> 
>> pkg info -x libclc
>>
>> If going the plain make route, append FLAVOR=llvmXY to make invocation.
> 
> Is there a comprehensive list of FLAVORs?  'man make.conf' does not
> mention FLAVOR.  Is it possible to set FLAVORS there?

   Flavors are a property of each port individually and not an 
externally defined property; some different ports use common flavors 
like 'nox11' but there is no hard rule to it. In the ports tree you can 
list flavors with `make -C /usr/ports/devel/libclc -VFLAVORS` and drop 
-C if you run it in the port's folder.
   The problem with setting FLAVOR in make.conf is make.conf will be 
applied to everything you build (kernel, base system, and 'every' port. 
You would need to write it within a conditional test such as what port 
is being built or what directory it is in and that test will then run 
during every build instead of just for that one port.
   portmaster supports a format such as `portmaster devel/libclc@llvm21` 
but if a port requests libclc as a dependency then it could also request 
a particular flavor (not usually the case, but doable). This seems to be 
a syntax similar to or the same to how you can do it with other tools 
like pkg and poudriere.
   For manually running make, `make -C /usr/ports/devel/libclc 
FLAVOR=llvm17` would be an example of overriding it. Not sure if there 
are other ways to express it.
   Some changes I assume should happen:
   1. The default of libclc should be reconsidered if it is broken on a 
platform unless it is being actively worked on. Why are we defaulting to 
the oldest compiler, a compiler not included as a base compiler on any 
supported FreeBSD version, and not even having a comment as to why?
   2. That flavor should be removed from the list at least in the case 
of the incompatible system. Broken may be appropriate if the default 
flavor is the only one that works on most supported systems and with 
most programs.
   3. If the libclc message is accurate, then devel/llvm15 should 
probably be altered to request it be built with a compatible port of 
llvm when the base version is known to be incompatible.

> In the old days, one could cd into any directory under /usr/port
> and simply type 'make'.

   Unless things are broken. Having been building things since 2004, you 
can usually find broken things when you look. at over 30,000 port 
folders, its hard to have the tree in a state where 'nothing' fails.
   This port self declared the build conditions are known to be broken. 
In this case it is the OS version (a non-RELEASE one) and the requested 
port flavor. Defining a BROKEN condition is better than some ports that 
are known to be broken but don't say so and that results in users and 
the build system spending time to reach a known failure. BROKEN and 
IGNORE are preferable to the ports tree trying when it is known to fail.

> My actual problem is building devel/node24, which dies with an
> error:
> ld.lld: error: undefined symbol: sqlite3session_patchset.

   I'd have to see a more complete error log to guess properly. If 
devel/note24 completed all dependency steps then I'd assume it may have 
an issue with bundling its own copy of sqlite3 and the build system 
messed up and used some stuff from its bundled copy and other stuff from 
the copy that databases/sqlite3 installed. Otherwise, maybe there is a 
real incompatibility with our sqlite3 port vs what node24 needs. If you 
somehow reached a point where you had additional older versions of 
sqlite3 files on your system then it too could cause mismatches. I never 
was a big portmaster user as it was incapable of completing a run when I 
tried it and any error caused a complete abort in the middle of 
rebuilding; portupgrade could be forced to proceed anyway with other 
ports and I thought I recalled an ability to keep older libraries around 
so less would break during the transition from old to new.
   A quick skim I see that sqlite3 runs a series of "@${RM}" (wrong way 
to do it, but better than nothing) steps including to remove a bundled 
sqlite3 so I would have thought that build/link steps would not see it.
   When a port messes up due to things that are installed onto the 
system (other versions, things not listed as a dependency/option, etc.) 
it is still a bug and should be reported and fixed appropriately. Think 
it was about 15 years ago now but I looked and found there were quite a 
few ports that would refer to installed files before they referred to 
build directory files which without a fix means the port should register 
as conflicting with itself and require uninstall to guarantee some build 
failures are avoided. I'd love to learn how to properly fix such issues 
but never have found how to understand+fix.
   To avoid any "contamination" of a build by an existing version of the 
port already being installed or any other non-dependency data on the 
system influencing how it is built, many maintainers and committers 
build packages from ports inside of a clean environment using poudriere 
or synth and then when complete they use the created collection of 
packages to upgrade/install as needed. Beyond less build failures from 
contamination, it also minimizes downtime caused by an installed program 
breaking because a dependency was built+installed but is not compatible 
until the program is rebuild+reinstalled too. At over 5 days for a 
non-ccache build of everything I have installed + a few other things to 
complete, I upgraded to such a workflow before poudriere existed for 
both of those reasons.