Page MenuHomeFreeBSD

Allow category_port_VARS= in make.conf for arbitrary per-port overrides.
Needs ReviewPublic

Authored by andrew_tao173.riddles.org.uk on Apr 7 2020, 6:28 AM.

Details

Reviewers
koobs
Group Reviewers
portmgr
Summary

(Per a request from koobs on irc)

Currently the only way to specify make.conf variables (other than port options which have their own mechanism) in a per-port fashion is to use conditionals on .CURDIR, which is fragile since it tends to involve assumptions about where the ports tree is mounted.

Instead, allow category_portname_VARS= to be set in make.conf to provide arbitrary assignments when building a specified port. For example one might use

devel_llvm10_VARS= make_jobs_number=2

or

converters_lua-iconv_VARS= trybroken=yes

This is intended to be consistent with the existing category_portname_SET= variables for port options, and uses the same syntax for values as option_VARS= in port makefiles.

Diff Detail

Repository
rP FreeBSD ports repository
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

Background on request/motivation:

Was looking for a way to enable MAKE_JOBS globally in poudriere, but disable MAKE_JOBS for specific ports (like llvm, ghc, etc)

Poudriere provides a global make jobs toggle, and a per-port specific 'opt-in' variable ALLOW_MAKE_JOBS_PACKAGES. It doesn't provide the converse to 'opt-out' of make jobs on a per port basis

Adding this to the ports framework, as an extension of existing category_portname_{UN}SET functionality for OPTIONS, would as a bonus allow poudriere to be simplified too

Thanks for this @andrew_tao173.riddles.org.uk

Only a minor review comment to add basic inline feature description/usage comment

Will test this locally

Mk/bsd.port.mk
1326

Add brief comment block for feature description and usage/syntax line (in the absence of additional documentation added elsewhere). Something like:

# Per-port variable setting, like category_portname_{UN}SET from bsd.options.mk
# usage: /etc/make.conf: category_portname_VARS=<variable>=<value>

What difference is there from having either a Makefile.local with whatever you need in the port's directory, or using what everyone has been using for decades:

.if ${.CURDIR:M*/lang/rust*}
DISABLE_MAKE_JOBS=yes
.endif
Mk/bsd.port.mk
1323–1325

This is a very bad idea.

The default version of something is global and unique, it absolutely MUIST NOT be changed.

In D24324#543789, @mat wrote:

What difference is there from having either a Makefile.local with whatever you need in the port's directory, or using what everyone has been using for decades:

.if ${.CURDIR:M*/lang/rust*}
DISABLE_MAKE_JOBS=yes
.endif

Makefile.local means putting a file in the tree, which is probably not what you want if the same ports tree is being used for several package sets with different options.

The .if ${.CURDIR...} thing is error-prone (if you make it too general, it matches outside the ports tree; too specific, and it'll fail to match depending on where the ports tree got mounted).

I really like the idea of being able to simply and cleanly set vars for specific ports from /etc/make.conf. I think the choice of variable naming is exactly right here, and the implementation is clean and simple.

However, I am 100% with @mat here that bsd.default-versions.mk is the wrong place for this. The idea is that the things defined in there choose one from a list of conflicting options. If every port is built with ssl=openssl and one port is overridden with ssl=libressl, then it will be impossible to install that port without uninstalling everything else. I can't think of a scenario where any default version should be overridden.

Can you implement this somewhere else, so that default versions are preserved?

I really like the idea of being able to simply and cleanly set vars for specific ports from /etc/make.conf. I think the choice of variable naming is exactly right here, and the implementation is clean and simple.

However, I am 100% with @mat here that bsd.default-versions.mk is the wrong place for this. The idea is that the things defined in there choose one from a list of conflicting options. If every port is built with ssl=openssl and one port is overridden with ssl=libressl, then it will be impossible to install that port without uninstalling everything else. I can't think of a scenario where any default version should be overridden.

Can you implement this somewhere else, so that default versions are preserved?

I put it there specifically because, prior to getting the lua flavors work in, I was having to override versions all the time to deal with conflicts over what lua version was needed for a given dependency. (e.g. Port X needs port Y built for lua52, even when the default is 5.3, or I could keep the default on 5.2 and then have to override it again via DEFAULT_VERSIONS for port Z required for my own development work under 5.3).

That specific issue may be solved now, but it's an example of why "I can't think of a scenario..." cuts no ice with me.

Incidentally, in case it's not obvious, if my addition is moved to before the inclusion of bsd.default-versions.mk then it remains entirely possible to do

category_port_VARS= default_versions+=foo=123

which would have the same effect as category_port_VARS= foo_version=123 with the current placement.

Maybe that's better style, but it's not any different functionally.

Move to an earlier place in processing (in fact the earliest possible place, just after PKGORIGIN is set).

Change the comments a bit to include usage and example.

Discussion point: this implementation converts the variable name to upper case for consistency with the way that port option_VARS works. But there are some cases where one might want to set a mixed-case name (such as CFLAGS.arch), so maybe it shouldn't do that and just use the case as written?

Also, it looks like a way to undefine a variable would also be useful, since sometimes setting an empty value isn't enough.