Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Apr 1995 13:41:33 -0500 (CDT)
From:      Mike Pritchard <pritc003@maroon.tc.umn.edu>
To:        hackers@FreeBSD.org
Subject:   Kernel makefile changes to allow builds in different trees
Message-ID:  <199504071841.NAA19489@mpp.com>

next in thread | raw e-mail | index | archive | help
Here are some changes to the kernel makefile and related programs that will 
allow you to build kernels somewhere other than /usr/src/sys/compile/xxx.  
This will allow you to have local copies of source files and work on
them without having to worry about someone else/sup/whatever trashing
them and without having to copy the entire /usr/src/sys tree.  These changes 
should also let you compile off a read-only source tree (e.g. A CD-ROM), 
but I don't have any way to test that myself right now.  

The location of the sources is keyed off the "SRCROOT" environment
variable.  This defaults to "/usr/src" if SRCROOT is undefined.  If this 
variable is defined, then the kernel makefile will use that directory for 
the source files if they are not present relative to the current build 
directory.  

An example of how to config a kernel that you want to build somewhere
other than /usr/src/sys:

# cd /usr/src/i386/conf
# mkdir -p /usr/src/tmp/sys/compile/XXX
# ln -s /usr/src/tmp/sys compile/XXX ../../compile/XXX
# config -n XXX
# cd /usr/src/tmp/sys/compile/XXX
# mkdir ../../scsi
# cp /usr/src/sys/scsi/sd.c ../../scsi
# vi ../../scsi/sd.c
 [make your local changes to sd.c]
# make depend
# make

Since the makefile defaults to looking in /usr/src if it can't find
the sources relative to the current compile directory, SRCROOT doesn't need 
to be defined in this example.  If you are upgrading, say from 2.0 to 2.1 and
have your new 2.1 kernel sources in /usr/src2.1/sys and wanted to compile 
with those sources, simply set SRCROOT=/usr/src2.1 before doing your makes.
You would also use this to compile from sources on a CD-ROM.

Be sure to recompile "config" and "make" before attempting to use the 
new makefile.

You also need to do the following if you want to be able to build from
anywhere but /usr/src/sys/compile/XXX:
	cd /usr/src/sys/i386
	ln -s include machine

or if you are not changing any of the files in i386/include/*, you
could do the following in your local compile/source tree:
	cd /usr/src/tmp/sys/i386
	ln -s /usr/src/sys/i386/include machine


To the core team:  Is there some reason why /usr/src/sys/i386/include 
shouldn't be renamed to /usr/src/sys/i386/machine?  That would eliminate 
the symbolic link junk, and it is more in line with the way every other 
include directory is named.  

I also had to fix make to not do some of the directory caching it has
been doing.  This looks like it is really only a problem when you are
using .PATH to setup a list of directories for make to search.  What would 
happen is that if I had ../../kern/kern_tty.c in my local build directory, 
and no other files in ../../kern, when make looked for the first file in
kern (imgact_aout.c), it would find it in /usr/src/sys/kern/imgact_aout.c.
Thinking that it is doing you a favor, it would add /usr/src/sys/kern 
to the list of directories to search.  Due to this and the way make 
works, when it finally tries to compile kern_tty.c, it finds it in 
/usr/src/sys/kern/kern_tty.c, instead of ../../kern/kern_tty.c.

I removed the code from make that was adding directories to the directory
list and that fixed the problem.  However, I'm worried that this may
reveal problems in other makefiles.  I've done a "make world" in /usr/src 
with my new make and everything seems to be working fine, but if someone has 
some heavy duty makefiles, I would like them to test the changes out and make 
sure I didn't break anything.  The funny thing is, even though the comments 
in make claim that it is adding those directories in the hope that it will 
help speed things up, with my change in, a full kernel "make depend; make all" 
winds up taking the same amount of time.


Here are the patches.  In order they are to the following programs/files:
usr.bin/make/dir.c, usr.sbin/config/mkmakefile.c, sys/i386/conf/files.i386.
I've included the entire sys/i386/conf/Makefile.i386, since the patch
was bigger than the makefile.  Each patch/file is separated by "--cut here--"
lines:

----cut here----
*** make/orig/dir.c	Fri Apr  7 04:03:12 1995
--- make/dir.c	Fri Apr  7 09:29:58 1995
***************
*** 604,610 ****
  			if (*dp == '/')
  			    *dp = '\0';
  			path = Lst_Init(FALSE);
- 			Dir_AddDir(path, dirpath);
  			DirExpandInt(cp+1, path, expansions);
  			Lst_Destroy(path, NOFREE);
  		    }
--- 604,609 ----
***************
*** 825,845 ****
  		}
  		
  		Lst_Close (path);
- 		
- 		/*
- 		 * We've found another directory to search. We know there's
- 		 * a slash in 'file' because we put one there. We nuke it after
- 		 * finding it and call Dir_AddDir to add this new directory
- 		 * onto the existing search path. Once that's done, we restore
- 		 * the slash and triumphantly return the file name, knowing
- 		 * that should a file in this directory every be referenced
- 		 * again in such a manner, we will find it without having to do
- 		 * numerous numbers of access calls. Hurrah!
- 		 */
- 		cp = strrchr (file, '/');
- 		*cp = '\0';
- 		Dir_AddDir (path, file);
- 		*cp = '/';
  		
  		/*
  		 * Save the modification time so if it's needed, we don't have
--- 824,829 ----
----cut here-----
*** /usr/src/usr.sbin/config/mkmakefile.c	Wed Mar  1 09:22:09 1995
--- config/mkmakefile.c	Fri Apr  7 09:47:13 1995
***************
*** 497,506 ****
  				lpos = 8;
  				fputs("\\\n\t", fp);
  			}
! 			if (tp->f_flags & NO_IMPLCT_RULE)
! 				fprintf(fp, "%s ", tp->f_fn);
! 			else
! 				fprintf(fp, "$S/%s ", tp->f_fn);
  			lpos += len + 1;
  		}
  	if (lpos != 8)
--- 497,503 ----
  				lpos = 8;
  				fputs("\\\n\t", fp);
  			}
! 			fprintf(fp, "%s ", tp->f_fn);
  			lpos += len + 1;
  		}
  	if (lpos != 8)
***************
*** 563,569 ****
  				lpos = 8;
  				fputs("\\\n\t", fp);
  			}
! 			fprintf(fp, "$S/%s ", tp->f_fn);
  			lpos += len + 1;
  		}
  	for (fl = conf_list; fl; fl = fl->f_next)
--- 560,566 ----
  				lpos = 8;
  				fputs("\\\n\t", fp);
  			}
! 			fprintf(fp, "%s ", tp->f_fn);
  			lpos += len + 1;
  		}
  	for (fl = conf_list; fl; fl = fl->f_next)
***************
*** 574,580 ****
  				fputs("\\\n\t", fp);
  			}
  			if (eq(fl->f_fn, "generic"))
! 				fprintf(fp, "$S/%s/%s/%s ",
  				    machinename, machinename, swapname);
  			else
  				fprintf(fp, "%s ", swapname);
--- 571,577 ----
  				fputs("\\\n\t", fp);
  			}
  			if (eq(fl->f_fn, "generic"))
! 				fprintf(fp, "%s/%s/%s ",
  				    machinename, machinename, swapname);
  			else
  				fprintf(fp, "%s ", swapname);
***************
*** 624,638 ****
  		else {
  			*cp = '\0';
  			if (och == 'o') {
! 				fprintf(f, "%so:\n\t-cp $S/%so .\n\n", 
  					tail(np), np);
  				continue;
  			}
  			if (ftp->f_depends)
! 				fprintf(f, "%so: $S/%s%c %s\n", tail(np), 
  					np, och, ftp->f_depends);
  			else
! 				fprintf(f, "%so: $S/%s%c\n", tail(np), 
  					np, och);
  		}
  		tp = tail(np);
--- 621,635 ----
  		else {
  			*cp = '\0';
  			if (och == 'o') {
! 				fprintf(f, "%so:\n\t-cp %so .\n\n", 
  					tail(np), np);
  				continue;
  			}
  			if (ftp->f_depends)
! 				fprintf(f, "%so: %s%c %s\n", tail(np), 
  					np, och, ftp->f_depends);
  			else
! 				fprintf(f, "%so: %s%c\n", tail(np), 
  					np, och);
  		}
  		tp = tail(np);
***************
*** 741,747 ****
  	if (!eq(name, "generic"))
  		fprintf(f, "swap%s.o: swap%s.c\n", name, name);
  	else
! 		fprintf(f, "swapgeneric.o: $S/%s/%s/swapgeneric.c\n",
  			machinename, machinename);
  	fprintf(f, "\t${NORMAL_C}\n\n");
  }
--- 738,744 ----
  	if (!eq(name, "generic"))
  		fprintf(f, "swap%s.o: swap%s.c\n", name, name);
  	else
! 		fprintf(f, "swapgeneric.o: %s/%s/swapgeneric.c\n",
  			machinename, machinename);
  	fprintf(f, "\t${NORMAL_C}\n\n");
  }
----cut here----
*** /usr/src/sys/i386/conf/files.i386	Mon Mar 27 15:23:03 1995
--- i386/conf/files.i386	Fri Apr  7 03:05:09 1995
***************
*** 4,16 ****
  #	$Id: files.i386,v 1.92 1995/03/27 19:39:45 ache Exp $
  #
  aic7xxx				optional	ahc	device-driver	   \
! 	dependency 	"$S/gnu/misc/aic7xxx/aic7xxx.c"			   \
  	compile-with	"${CC} -o $@ $>"				   \
  	no-obj no-implicit-rule						   \
  	clean		"aic7xxx"
  aic7xxx_seq.h			optional	ahc	device-driver	   \
! 	dependency	"$S/gnu/misc/aic7xxx/aic7xxx.seq aic7xxx"	   \
! 	compile-with	"./aic7xxx -o $@ $S/gnu/misc/aic7xxx/aic7xxx.seq"  \
  	no-obj no-implicit-rule before-depend				   \
  	clean		"aic7xxx_seq.h"
  i386/apm/apm.c			optional	apm	device-driver
--- 4,16 ----
  #	$Id: files.i386,v 1.92 1995/03/27 19:39:45 ache Exp $
  #
  aic7xxx				optional	ahc	device-driver	   \
! 	dependency 	"gnu/misc/aic7xxx/aic7xxx.c"			   \
  	compile-with	"${CC} -o $@ $>"				   \
  	no-obj no-implicit-rule						   \
  	clean		"aic7xxx"
  aic7xxx_seq.h			optional	ahc	device-driver	   \
! 	dependency	"aic7xxx gnu/misc/aic7xxx/aic7xxx.seq"  	   \
! 	compile-with	"./aic7xxx -o $@ `echo $> | sed 's;^aic7xxx ;;'`"   \
  	no-obj no-implicit-rule before-depend				   \
  	clean		"aic7xxx_seq.h"
  i386/apm/apm.c			optional	apm	device-driver
----cut here----(sys/i386/conf/Makefile.i386 follows)
# Copyright 1990 W. Jolitz
#	from: @(#)Makefile.i386	7.1 5/10/91
#	$Id: Makefile.i386,v 1.62 1995/04/05 04:10:58 nate Exp $
#
# Makefile for FreeBSD
#
# This makefile is constructed from a machine description:
#	config machineid
# Most changes should be made in the machine description
#	/sys/i386/conf/``machineid''
# after which you should do
#	 config machineid
# Generic makefile changes should be made in
#	/sys/i386/conf/Makefile.i386
# after which config should be rerun for all machines.
#
CC?=	cc 
CPP?=	cpp
LD?=	/usr/bin/ld

.if ! defined(SRCROOT)
SRCROOT=	/usr/src
.endif
.if exists(./@/.)
S=	./@
.else
S=	${SRCROOT}/sys
.endif
I386=	i386

# This hack is to allow kernel compiles to succeed on machines w/out srcdist
# and must be done before .PATH is set below, otherwise make will check
# if the directory exists relative to the .PATH directories.
.if exists(../../../include)
INCS= -I../../../include
.elif exists(${SRCROOT}/include)
INCS= -I${SRCROOT}/include
.else
INCS= -I/usr/include
.endif

.PATH:	../.. $S
.SUFFIXES:	.c .h .s .raw .sh .src .seq

CWARNFLAGS?=-W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit
#
# The following flags are next up for working on:
#	-Wnested-externs (almost works)
#	-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
#
# When working on removing warnings from code, the `-Werror' flag should be
# of material assistance.
#
COPTFLAGS?=-O
# Not ready for -I- yet.  #include "foo.h" where foo.h is in the srcdir fails.
INCLUDES= -nostdinc -I. -I../.. -I../../sys -I$S -I$S/sys -I$S/${I386} \
	${INCS}
COPTS=	${INCLUDES} ${IDENT} -DKERNEL -Di386 -DLOAD_ADDRESS=0x${LOAD_ADDRESS}
ASFLAGS=
CFLAGS=	${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS}
LOAD_ADDRESS?=	F0100000

NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} $<
NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
# XXX errors leak out of all the pipes.  Should use cc *.S.
# XXX LOCORE means "don't declare C stuff" not "for locore.s".
NORMAL_S= ${CPP} -DLOCORE ${COPTS} $< | ${AS} ${ASFLAGS} -o $*.o
DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
PROFILE_C= ${CC} -c ${CFLAGS} ${PARAM} $<

SFILES=	${I386}/i386/exception.s ${I386}/i386/microtime.s \
	${I386}/i386/support.s ${I386}/i386/swtch.s ${I386}/apm/apm_setup.s
SYSTEM_CFILES= ioconf.c param.c vnode_if.c
SYSTEM_SFILES= ${I386}/i386/locore.s
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o 
SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS} libkern.a
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
SYSTEM_LD= @${LD} -Bstatic -Z -T ${LOAD_ADDRESS} -o $@ -X ${SYSTEM_OBJS} vers.o libkern.a
.if ${CFLAGS:M-g} == ""
SYMORDER_EXCLUDE=-x symbols.exclude
.endif
SYSTEM_LD_TAIL= @echo rearranging symbols; \
	symorder -m ${SYMORDER_EXCLUDE} symbols.sort $@; \
	size $@; chmod 755 $@

%BEFORE_DEPEND

%OBJS

%CFILES

%LOAD

%CLEAN

# This is slightly different from before in that if you define PROF
# to anything, it will assume profiling.  Don't do "PROF=" to turn
# profiling off!
.if exists(../../libkern)
LIBKERNDIR=../../libkern
.else
LIBKERNDIR=$S/libkern
.endif

.if exists(${LIBKERNDIR}/obj)
LIBKERNP=${LIBKERNDIR}/obj
.else
LIBKERNP=${LIBKERNDIR}
.endif

.if defined(PROF)
LIBKERN=${LIBKERNP}/libkern_p.a
.else
LIBKERN=${LIBKERNP}/libkern.a
.endif

libkern.a: ${LIBKERN}
	@rm -f libkern.a
	ln -s ${LIBKERN} libkern.a

${LIBKERN}:
	@(cd ${LIBKERNDIR}; make)

clean:
	rm -f eddep kernel tags *.o *.s errs linterrs makelinks genassym \
	      symbols.exclude symbols.sort ${CLEAN}

#lint: /tmp param.c
#	@lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} \
#	  ${I386}/i386/Locore.c ${CFILES} ioconf.c param.c | \
#	    grep -v 'struct/union .* never defined' | \
#	    grep -v 'possible pointer alignment problem'

symbols.exclude: Makefile
	echo "gcc2_compiled." >symbols.exclude
	echo "___gnu_compiled_c" >>symbols.exclude

symbols.sort: ${I386}/i386/symbols.raw
	grep -v '^#' $> | sed 's/^	//' | sort -u > symbols.sort

locore.o: ${I386}/i386/locore.s assym.s
	${NORMAL_S}

# everything potentially depends on the Makefile since everything potentially
# depends on the options.  Some things are more dependent on the Makefile for
# historical reasons.
machdep.o: Makefile

# the following is necessary because autoconf.o depends on #if GENERIC
autoconf.o: Makefile

# depend on network configuration
af.o uipc_proto.o locore.o: Makefile

# depends on KDB (cons.o also depends on GENERIC)
trap.o cons.o: Makefile

# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s

assym.s: genassym
	./genassym >assym.s

# Some of the defines that genassym outputs may well depend on the 
# value of kernel options.
genassym.o: ${I386}/i386/genassym.c Makefile
	${CC} -c ${CFLAGS} ${PARAM} -UKERNEL $<

genassym: genassym.o
	${CC} -static ${CFLAGS} ${PARAM} genassym.o -o $@

# XXX this assumes that the options for NORMAL_C* and DRIVER_C* are identical.
depend: ${BEFORE_DEPEND} assym.s param.c vnode_if.h depend_cfiles \
	depend_genassym depend_sfiles ${BEFORE_DEPEND}

depend_cfiles: ${CFILES} ${SYSTEM_CFILES}
	mkdep ${COPTS} $>

depend_genassym: ${I386}/i386/genassym.c
	mkdep -a ${COPTS} ${PARAM} -UKERNEL $>

depend_sfiles: ${SFILES} ${SYSTEM_SFILES}
	MKDEP_CPP=${CPP} ; export MKDEP_CPP ; \
	mkdep -a -DLOCORE ${COPTS} $>

links: ${CFILES}
	egrep '#if' $> | sed -f ../../conf/defines | \
	  sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
	echo $> | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
	  sort -u | comm -23 - dontlink | \
	  sed 's,.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks
	sh makelinks && rm -f dontlink

tags:
	@echo "see ../../kern/Makefile for tags"

install:
	chflags noschg /kernel
	mv /kernel /kernel.old
	install -c -m 555 -o root -g wheel -fschg kernel /

ioconf.o: ioconf.c sys/param.h ${I386}/include/pte.h sys/buf.h \
    ${I386}/isa/isa_device.h ${I386}/isa/isa.h \
    ${I386}/isa/icu.h
	${CC} -c ${CFLAGS} ioconf.c

param.c: conf/param.c
	-rm -f param.c
	cp $> .

param.o: param.c Makefile
	${CC} -c ${CFLAGS} ${PARAM} param.c

vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP} ver_sh

ver_sh:	conf/newvers.sh
	sh $> ${KERN_IDENT} ${IDENT}
	${CC} ${CFLAGS} -c vers.c

vnode_if.c: kern/vnode_if.sh kern/vnode_if.src
	sh $>
vnode_if.h: kern/vnode_if.sh kern/vnode_if.src
	sh $>

%RULES

# DO NOT DELETE THIS LINE -- make depend uses it
----cut here----
-- 
Mike Pritchard
pritc003@maroon.tc.umn.edu
"Go that way.  Really fast.  If something gets in your way, turn"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199504071841.NAA19489>