Bug 215542

Summary: ports-mgmt/portmaster: (r428604) mishandles USE_GCC=any context when lang/gcc6-devel is already installed, for example
Product: Ports & Packages Reporter: Mark Millard <marklmi26-fbsd>
Component: Individual Port(s)Assignee: Stefan Eßer <se>
Status: Closed FIXED    
Severity: Affects Only Me CC: gerald, tz
Priority: --- Flags: vlad-fbsd: maintainer-feedback? (tz)
Version: Latest   
Hardware: Any   
OS: Any   

Description Mark Millard 2016-12-25 01:21:34 UTC
This note uses lang/gcc6-devel and lang/gcc6 vs. ports-mgmt/postmaster
as an example of a more general issue. Another port having USE_GCC=any
in use was involved and I had lang/gcc6-devel already installed (and
no other lang/gcc* ). lang/gcc6-devel has been installed via
portmaster.

The issue is tied to both of those lang/gcc6* 's install gcc6 . If one
is installed already the other should not be attempted: they conflict.

ports-mgmt/portmaster tried to install lang/gcc6 instead.

First I'll quote wha the gcc6 maintainer Gerald Pfeifer wrote about
the expected build environment behavior in a message-list exchange that
we had:

BEGIN QUOTE:
USE_GCC=any is the equivalent of USE_GCC=4.2+, and lang/gcc6 and
lang/gcc6-devel should both meet this requirement.
. . . (omitted interlaced material from me) . . .
That works as designed.  USE_GCC=yes defaults to lang/gcc.  USE_GCC=any 
tries to use an existing GCC system compiler and lang/gcc by default if 
none is present.
. . .
It means gcc6 from lang/gcc6-devel is found
and identified as a suitable version of GCC.
. . .
Then Mk/bsd.gcc.mk adds

BUILD_DEPENDS+= gcc6:lang/gcc6

when it resolves USE_GCC=any.

That should not trigger and pull in lang/gcc6, though, as long
as gcc6 is found.
END QUOTE.


But what I found for this context was that using postmaster
was that it checks via:

pkg query %n-%v lang/gcc6

and never via:

pkg query %n-%v gcc6

(or anything based on just gcc6 or on lang/gcc6-devel that had
been used for installation of gcc6 ).

In essence the USE_GCC=any lead to use of the wrong "origin" for
gcc6 despite prior portmaster use to install gcc6 via gcc6-devel.


From the "pkg query %n-%v lang/gcc6" test result portmaster is
programmed to try to install lang/gcc6 even if gcc6 is already
installed.

The attempt fails because of conflicts between lang/gcc6-devel and
lang/gcc6 . (The conflicts are expected/required.)

I temporarily edited portmaster to use "sh -x" so that its execution
could be observed in detail and logged. The relevant part was:

+ pm_cd /usr/ports/lang/gcc6
+ builtin cd /usr/ports/lang/gcc6
+ grep -ql ^CONFLICTS Makefile
+ origin=lang/gcc6
+ iport_from_origin lang/gcc6
+ local sn dir
+ [ -n yes ]
+ pkg query %n-%v lang/gcc6
+ return 1
+ iport=''
+ check_exclude lang/gcc6
+ [ -n '' ]
+ return 0
+ [ -n '' -a -n '' ]
+ [ -n '' -a -n '' ]
+ [ -n '' ]
+ check_interactive lang/gcc6
+ [ -n '' ]
+ return 0
+ update_port lang/gcc6
+ local deps
+ [ -n '' ]
+ [ -z '' ]
+ echo '===>>> Launching child to install lang/gcc6'
===>>> Launching child to install lang/gcc6
+ dep_of_deps=2
+ [ -n pm_first_pass ]
+ [ ! '(' -n '' -a -n '' ')' ]
+ num_of_deps=2
+ deps='(2/2)'
+ term_printf ' >> devel/kBuild >> lang/gcc6 (2/2)'
+ echo -e '\n===>>> emulators/virtualbox-ose-additions >> devel/kBuild >> lang/gcc6 (2/2)'

===>>> emulators/virtualbox-ose-additions >> devel/kBuild >> lang/gcc6 (2/2)
+ [ -n '' ]
+ printf '\033]0;portmaster: emulators/virtualbox-ose-additions >> devel/kBuild >> lang/gcc6 (2/2)\007'
ESC]0;portmaster: emulators/virtualbox-ose-additions >> devel/kBuild >> lang/gcc6 (2/2)^G+ [ -n doing_dep_check -o '(' -n '' -a -n pm_first_pass ')' ]
+ unset NO_DEP_UPDATES
+ [ -z '' -o -n pm_first_pass ]
+ sh -x /usr/local/sbin/portmaster -D -K lang/gcc6
+ trap trap_exit INT


(So devel/kBuild was what was using USE_GCC=any in my specific example.)
Comment 1 Torsten Zuehlsdorff freebsd_committer 2017-12-08 14:09:23 UTC
Hand over PR to new Maintainer of portmaster :)
Comment 2 Stefan Eßer freebsd_committer 2017-12-18 19:02:15 UTC
I plan to completely rewrite the upgrade strategy routine to use explicit state instead of the state implicitly encoded in a large number of global variables.

Dependency tracking will also need to be re-implemented, and I'll keep this special case in mind.
Comment 3 Rene Ladan freebsd_committer 2020-03-07 12:26:54 UTC
FYI, both lang/gcc6-devel and lang/gcc6 have expired and are being removed.
Comment 4 Gerald Pfeifer freebsd_committer 2020-03-07 14:13:56 UTC
(In reply to Rene Ladan from comment #3)
> FYI, both lang/gcc6-devel and lang/gcc6 have expired and are being removed.

I believe these days using lang/gcc9-devel and lang/gcc9 will be equivalent
to what Mark originally described.

Note that since recent changes to Mk/bsd.gcc.mk (revision r526751) USE_GCC=any
no longer considers versions between GCC 4.2 and GCC_DEFAULT, so reproducing
this will require lang/gcc9-devel installed (or whatever GCC_DEFAULT is at
that point).
Comment 5 Mark Millard 2020-03-07 20:57:35 UTC
(In reply to Rene Ladan from comment #3)
and:
(In reply to Gerald Pfeifer from comment #4)

Summary of the below: Retesting with a more modern
environment did not have the problem. May be
portmaster was adjusted to not implicitly use the
potentially wrong origin.

Note: My /usr/ports/ was at -r526539 during this
test. amd64 FreeBSD head -r358510 as well.


I've done the following to test the current status
for this (in a context with gcc9 as the default version
and using a full bootstrap on amd64):

pkg delete gcc9
portmaster -DK lang/gcc9-devel
portmaster -DK devel/kBuild

(Note: I normally use poudriere. This is just for
testing.)

Looking at devel/kBuild looks like it still
indicates to use a default but that now looks
like:

OPTIONS_DEFINE= DOCS GCC
OPTIONS_DEFAULT=GCC
GCC_DESC=       Build with GCC (should almost always be enabled)
GCC_USE=        GCC=yes

(No "any".)

The build of devel/kBuild completed and did not
try to build lang/gcc9 when lang/gcc9-devel was
already installed: it used the gcc9-devel materials.
Comment 6 Gerald Pfeifer freebsd_committer 2020-03-07 22:25:46 UTC
Looking at history, I believe this may have been addressed by my
restructuring of the lang/gcc* ports with

  r441883 | gerald | 2017-05-27 23:27:21 +0000 (Sa., 27 Mai 2017) | 17 lines

  Essentially replace (or rather reinvent) the lang/gcc port, which more
  or less ended up identical to lang/gcc5 now that we differentiate between
  lang/gccX-devel and lang/gccX ports, by (or as) a meta-port that pulls in
  the respective lang/gccX port (based on the setting of $GCC_DEFAULT) and
  defines gcc, g++, and gfortran as symlinks to the respective versioned
  binaries.

  This is the end of a long journey establishing this infrastructure
  which is now similar to the one of the python ports, for example,
  and makes upgrading the default as well as adjusting the default
  locally a lot easier.
Comment 7 Mark Millard 2020-03-08 01:26:15 UTC
(In reply to Gerald Pfeifer from comment #6)

I just looked back at portmaster and gcc6 v s. gcc9.
portmaster now and then had logic for following
a conflcting port having been available instead
but gcc6 of the time had nothing analogous to
gcc9's:

CONFLICTS=      gcc9-devel-9.*

in gcc6's Makefile .

And, in fact, for the gcc9 context, the devel/kBuild
build even has a log message that I did not know to
look for before seeing what generates it in
portmaster's code:

===>>> The dependency for lang/gcc9
       seems to be handled by gcc9-devel-9.2.1.s20200215

( So it avoided trying to install lang/gcc9 .)

It appears to me that the old gcc6 problem was
probably just the lack of a CONFLICTS assignment
vs. gcc6-devel . portmaster allows (and at least
tried to allow back then) use of the conflicting
port when it finds such declared in the Makefile
involved.

Too bad I did not notice such back then. Then
lack of the message would have pointed to the
missing CONFLICTS assignment.

Despite the switch to later gcc*'s, I'll leave
the submittal listed as fixed, meaning some
lang/gcc* having CONFLICTS now listed explicitly
with respect to the matching *-devel variant.