Subject: pkg/23883: pkgsrc cannot change GCC_REQD after bsd.prefs.mk has been included; this might be serious in some cases; fix included
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <dotz@irc.pl>
List: netbsd-bugs
Date: 12/25/2003 18:47:20
>Number:         23883
>Category:       pkg
>Synopsis:       pkgsrc cannot change GCC_REQD after bsd.prefs.mk has been included; this might be serious in some cases; fix included
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 25 18:48:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Michal Pasternak
>Release:        N/A
>Organization:
>Environment:
N/A
>Description:

"compiler.mk", which detects compilers available and includes proper 
buildlink for such (in case compiler from pkgsrc is needed) is included 
from "bsd.prefs.mk"

"bsd.prefs.mk" setup many operating system preferences. They setup, 
among other, the variable ${OPSYS}, telling Makefile which operating system
is the build system. It is also commonly included file by other 
pkgsrc/mk/ files: ossaudio.buildlink2.mk, motif.buildlink2.mk, 
xaw.buildlink2.mk, java-vm.mk and other -- not to mention many pkgsrc
package Makefiles, which directly include it. This is quite important 
part of pkgsrc and changes there should be done with care, as they could
break many, many things.


Package "wine" -- on FreeBSD systems -- must be built with 

     GCC_REQD=3.3 

or

     GCC_REQD=3.2

Using gcc 2.95.4, which is included in FreeBSD-STABLE, makes wine build 
break with gcc: signal 10 received, core dumped (no, I have my RAM chips 
in perfect state, this is known bug). GCC 3 is also used to build WINE 
in FreeBSD Ports Collection - please see:

     http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/emulators/wine/Makefile?rev=1.158&content-type=text/plain

and check for USE_GCC line.

So, the task is easy: use GCC_REQD basing on the operating system 
setting! Include "bsd.prefs.mk" to get ${OPSYS}, then set compiler:

     .include "../../mk/bsd.prefs.mk"
     .if ${OPSYS} == "FreeBSD"
     GCC_REQD=     3.3
     .endif
     
And, with current pkgsrc, it is *IMPOSSIBLE* to do in a clean way.

Either I include "bsd.prefs.mk" (and have ${OPSYS} set, but I can't 
change USE_GCC compiler selection, as it was already parsed) -- 
or I declare "USE_GCC=3.3" even for cases, where GCC 3.x is not 
needed (or can't be built) -- which is very non-NetBSD .
>How-To-Repeat:

The need for such tasks (declare compiler basing on an OS) may be 
marginal, but it could be important in the future. 

Choosing compiler, based on operating system, can be useful and needed. Among gcc there is "Intel C++ Compiler for Linux", as the market is 
growing, there will be other compilers (eg. BSD licensed Tendra 
C Compiler). At some point pkgsrc could need this feature. This is
useful.

>Fix:

I have thought about many options to fix this and this one seems the
best:

     - make operating system detection a separate .mk file
     - include that .mk file from bsd.prefs.mk

It's the safest, does't break anything, and I can do things like 
this one below in my package's Makefiles:

     .include "../../mk/opsys.mk"
     .if ${OPSYS} == "FreeBSD"
     GCC_REQD=     3.3
     .endif
     .include "../../mk/bsd.prefs.mk"

This is consistent with mk's philosophy -- "compiler.mk" is included 
from "bsd.ports.mk" much like the same way and it is separate for the
same purpose. BTW to get my idea working we need also to include "opsys.mk"
from "compiler.mk", and not only from "bsd.prefs.mk"

To do that, here's the diff (trival diff, as usual):

Index: bsd.prefs.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/bsd.prefs.mk,v
retrieving revision 1.135
diff -u -r1.135 bsd.prefs.mk
--- bsd.prefs.mk        11 Dec 2003 22:35:50 -0000      1.135
+++ bsd.prefs.mk        25 Dec 2003 18:42:34 -0000
@@ -6,33 +6,22 @@
 # to make sure any variables defined in /etc/mk.conf, $MAKECONF, or
 # the system defaults (sys.mk and bsd.own.mk) are used.
 
-# Do not recursively include mk.conf, redefine OPSYS, include bsd.own.mk, etc.
+# Do not recursively include mk.conf, redefine OPSYS via including opsys.mk,
+# include bsd.own.mk, etc.
 .ifndef BSD_PKG_MK
 
 # Let mk.conf know that this is pkgsrc.
 BSD_PKG_MK=1
 __PREFIX_SET__:=${PREFIX}
 
-.if exists(/usr/bin/uname)
-UNAME=/usr/bin/uname
-.elif exists(/bin/uname)
-UNAME=/bin/uname
+.if exists(../../mk/opsys.mk)
+.include "../../mk/opsys.mk"
+.elif exists("../mk/opsys.mk)
+.include "../mk/opsys.mk"
 .else
-UNAME=echo Unknown
+.error "Cannot find opsys.mk in bsd.prefs.mk"
 .endif
 
-.ifndef OPSYS
-OPSYS!=                        ${UNAME} -s | tr -d /
-.endif
-MAKEFLAGS+=            OPSYS=${OPSYS}
-.ifndef OS_VERSION
-OS_VERSION!=           ${UNAME} -r
-.endif
-.ifndef LOWER_OS_VERSION
-LOWER_OS_VERSION!=     echo ${OS_VERSION} | tr 'A-Z' 'a-z'
-.endif
-MAKEFLAGS+=            OS_VERSION=${OS_VERSION}
-
 # Preload these for architectures not in all variations of bsd.own.mk.
 GNU_ARCH.alpha?=       alpha
 GNU_ARCH.arm26?=       arm
Index: compiler.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/compiler.mk,v
retrieving revision 1.24
diff -u -r1.24 compiler.mk
--- compiler.mk 10 Dec 2003 09:08:24 -0000      1.24
+++ compiler.mk 25 Dec 2003 18:42:35 -0000
@@ -60,6 +60,14 @@
 .if !defined(COMPILER_MK)
 COMPILER_MK=   # defined
 
+.if exists(../../mk/opsys.mk)
+.include "../../mk/opsys.mk"
+.elif exists("../mk/opsys.mk)
+.include "../mk/opsys.mk"
+.else
+.error "Cannot find opsys.mk in bsd.prefs.mk"
+.endif
+
 # Defaults for SunPro, work around sys.mk setting CC by default to
 # 'gcc'. These can be overriden by the user in /etc/mk.conf or on the
 # command line.
Index: opsys.mk
===================================================================
RCS file: opsys.mk
diff -N opsys.mk
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ opsys.mk    25 Dec 2003 18:42:35 -0000
@@ -0,0 +1,26 @@
+# $NetBSD$
+#
+
+.if !defined(OPSYS_MK)
+OPSYS_MK=              # defined
+
+.if exists(/usr/bin/uname)
+UNAME=/usr/bin/uname
+.elif exists(/bin/uname)
+UNAME=/bin/uname
+.else
+UNAME=echo Unknown
+.endif
+
+.ifndef OPSYS
+OPSYS!=                        ${UNAME} -s | tr -d /
+.endif
+MAKEFLAGS+=            OPSYS=${OPSYS}
+.ifndef OS_VERSION
+OS_VERSION!=           ${UNAME} -r
+.endif
+.ifndef LOWER_OS_VERSION
+LOWER_OS_VERSION!=     echo ${OS_VERSION} | tr 'A-Z' 'a-z'
+.endif
+MAKEFLAGS+=            OS_VERSION=${OS_VERSION}
+.endif

>Release-Note:
>Audit-Trail:
>Unformatted: