bsd.obj.mk does not set CANONICALOBJDIR correctly when TARGET_ARCH and MAKEOBJDIRPREFIX are set

Ruslan Ermilov ru at freebsd.org
Sun Jan 4 20:56:58 UTC 2009


Hi,

On Thu, Jan 01, 2009 at 11:42:12PM -0800, Doug Barton wrote:
> In working on cross-platform support for mergemaster I came across the
> following problem. I set MAKEOBJDIRPREFIX to be that of the temproot
> environment, which works fine when you do not specify a TARGET_ARCH.
> When you do specify TARGET_ARCH there is a conflict between
> src/Makefile.inc1 and share/mk/bsd.obj.mk.

> The former does this:
> 
> .if ${MACHINE} == ${TARGET} && !defined(CROSS_BUILD_TESTING)
> OBJTREE=        ${MAKEOBJDIRPREFIX}
> .else
> OBJTREE=        ${MAKEOBJDIRPREFIX}/${TARGET}
> .endif

OBJTREE is a variable internal to Makefile.inc1; it's then assigned to
a MAKEOBJDIRPREFIX environment variable which make(1) understands and
uses to find the actual object directory.

> however the latter does this:
> 
> .if defined(MAKEOBJDIRPREFIX)
> CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR}
> .else
> CANONICALOBJDIR:=/usr/obj${.CURDIR}
> .endif

CANONICALOBJDIR is what we (BSD, FreeBSD) choose to be a canonical
object directory out of the list of possible object directories
make(1) understands; the list is documented in the manpage:

: 1.   ${MAKEOBJDIRPREFIX}/`pwd`
: 2.   ${MAKEOBJDIR}
: 3.   obj.${MACHINE}
: 4.   obj
: 5.   /usr/obj/`pwd`

That is, 1 and 5.

There's no conflict between bsd.obj.mk and Makefile.inc1; the former
creates a canonical object directory with the default "obj" target,
${MAKEOBJDIRPREFIX}/`pwd` or /usr/obj/`pwd`, and Makefile.inc1 only
changes the value of MAKEOBJDIRPREFIX environment variable.

bsd.obj.mk doesn't (and shouldn't) know anything about OBJTREE which
is internal to Makefile.inc1.

> When trying to install the stuff in src/etc/sendmail install(1) cannot
> find the file because it is built in <foo>/obj but it's looking for it
> in <foo>/obj/$target

You should set MAKEOBJDIRPREFIX to the same value for "build" and
"install" targets.  If you set it only for the "install" target,
you'll get what you describe; let's see...

> The simplest fix I found was to do the following in bsd.obj.mk:
> 
> Index: bsd.obj.mk
> ===================================================================
> --- bsd.obj.mk	(revision 186676)
> +++ bsd.obj.mk	(working copy)
> @@ -43,7 +43,7 @@
>  .include <bsd.own.mk>
> 
>  .if defined(MAKEOBJDIRPREFIX)
> -CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR}
> +CANONICALOBJDIR:=${OBJTREE}${.CURDIR}
>  .else
>  CANONICALOBJDIR:=/usr/obj${.CURDIR}
>  .endif

This change is plain wrong and shouldn't be committed.

> However I would be happy with any solution that makes it work. It's
> trivial to test with 'mergemaster -i -D</temp/dir/for/root> -A arm'

The problem is that Makefile.inc1 sets MAKEOBJDIRPREFIX for world-
related targets specially, taking into account the value of ${TARGET},
to be able to use a single directory to build worlds for different
architectures.

mergemaster.sh uses "obj" and "all" targets which aren't cross-build
aware (don't take ${TARGET} into account) to build etc/ bits, and then
"distribution" target (which is cross-build aware) to install then.
The effect of this is that you end up with "build" and "install" targets
having different ideas of MAKEOBJDIRPREFIX.  The fix is to use cross-aware
versions of "obj" and "all" targets:

%%%
Index: mergemaster.sh
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mergemaster/mergemaster.sh,v
retrieving revision 1.63
diff -u -p -r1.63 mergemaster.sh
--- mergemaster.sh	2 Jan 2009 00:37:59 -0000	1.63
+++ mergemaster.sh	4 Jan 2009 20:18:40 -0000
@@ -588,8 +588,8 @@ case "${RERUN}" in
         ;;
       esac
       ${MM_MAKE} DESTDIR=${TEMPROOT} ${ARCHSTRING} distrib-dirs &&
-      MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj ${MM_MAKE} ${ARCHSTRING} obj SUBDIR_OVERRIDE=etc &&
-      MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj ${MM_MAKE} ${ARCHSTRING} all SUBDIR_OVERRIDE=etc &&
+      MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj ${MM_MAKE} ${ARCHSTRING} _obj SUBDIR_OVERRIDE=etc &&
+      MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj ${MM_MAKE} ${ARCHSTRING} everything SUBDIR_OVERRIDE=etc &&
       MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj ${MM_MAKE} ${ARCHSTRING} \
 	  DESTDIR=${TEMPROOT} distribution;} ||
     { echo '';
%%%


Cheers,
-- 
Ruslan Ermilov
ru at FreeBSD.org
FreeBSD committer


More information about the freebsd-hackers mailing list