cross platform building under emulation

Doug Ambrisko ambrisko at ambrisko.com
Fri Oct 14 19:27:01 PDT 2005


Dan Langille writes:
| Daris has got me thinking about unpacking 4.9-release/bin into a 
| directory, and then doing a chroot.

That sort-of works.  I've done some setups for companies and get
iteratively better solutions.  I copy over some host bins & libs
into special directories so mount, ps etc can be run from inside.
I also have mods to libc so that uname & getosreldate so it can
be set via env. variables so pkg_add, autoconf etc picks up the
right stuff.  Now this is a little trickier for old version of
libc that I haven't modified locally yet so I build a stub lib.
of these in the chroot then load this then LD_PRELOAD.  If you don't
then some things get messed up.

This lets me build on a FreeBSD 6.X/amd64 host for FreeBSD 4.X/386, 
FreeBSD amd64 etc.  I've also at times loaded in the Linux tools and
made that work so I could build Linux bins in chroots.

I hope to commit my changes to getosreldate(3) and uname(3).
This mirrors the env. variables in /usr/bin/uname.

Index: __xuname.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/__xuname.c,v
retrieving revision 1.9
diff -u -p -r1.9 __xuname.c
--- __xuname.c	1 Feb 2002 00:57:29 -0000	1.9
+++ __xuname.c	15 Oct 2005 02:24:05 -0000
@@ -41,13 +41,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/utsname.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 int
 __xuname(int namesize, void *namebuf)
 {
 	int mib[2], rval;
 	size_t len;
-	char *p;
+	char *p, *u_s, *u_r, *u_v, *u_m;
 	int oerrno;
 	struct xutsname {
 		char	sysname[namesize];	/* Name of this OS. */
@@ -57,18 +59,27 @@ __xuname(int namesize, void *namebuf)
 		char	machine[namesize];	/* Hardware type. */
 	} *name;
 
+	u_s = getenv("UNAME_s");
+	u_r = getenv("UNAME_r");
+	u_v = getenv("UNAME_v");
+	u_m = getenv("UNAME_m");
+
 	name = (struct xutsname *)namebuf;
 	rval = 0;
 
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_OSTYPE;
-	len = sizeof(name->sysname);
-	oerrno = errno;
-	if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
-		if(errno == ENOMEM)
-			errno = oerrno;
-		else
-			rval = -1;
+	if (u_s)
+		strncpy(name->sysname, u_s, sizeof(name->sysname));
+	else {
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_OSTYPE;
+		len = sizeof(name->sysname);
+		oerrno = errno;
+		if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
+			if(errno == ENOMEM)
+				errno = oerrno;
+			else
+				rval = -1;
+		}
 	}
 	name->sysname[sizeof(name->sysname) - 1] = '\0';
 
@@ -84,28 +95,36 @@ __xuname(int namesize, void *namebuf)
 	}
 	name->nodename[sizeof(name->nodename) - 1] = '\0';
 
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_OSRELEASE;
-	len = sizeof(name->release);
-	oerrno = errno;
-	if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
-		if(errno == ENOMEM)
-			errno = oerrno;
-		else
-			rval = -1;
+	if (u_r)
+		strncpy(name->sysname, u_r, sizeof(name->sysname));
+	else {
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_OSRELEASE;
+		len = sizeof(name->release);
+		oerrno = errno;
+		if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
+			if(errno == ENOMEM)
+				errno = oerrno;
+			else
+				rval = -1;
+		}
 	}
 	name->release[sizeof(name->release) - 1] = '\0';
 
 	/* The version may have newlines in it, turn them into spaces. */
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_VERSION;
-	len = sizeof(name->version);
-	oerrno = errno;
-	if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
-		if (errno == ENOMEM)
-			errno = oerrno;
-		else
-			rval = -1;
+	if (u_v)
+		strncpy(name->sysname, u_v, sizeof(name->sysname));
+	else {
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_VERSION;
+		len = sizeof(name->version);
+		oerrno = errno;
+		if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
+			if (errno == ENOMEM)
+				errno = oerrno;
+			else
+				rval = -1;
+		}
 	}
 	name->version[sizeof(name->version) - 1] = '\0';
 	for (p = name->version; len--; ++p) {
@@ -117,15 +136,19 @@ __xuname(int namesize, void *namebuf)
 		}
 	}
 
-	mib[0] = CTL_HW;
-	mib[1] = HW_MACHINE;
-	len = sizeof(name->machine);
-	oerrno = errno;
-	if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
-		if (errno == ENOMEM)
-			errno = oerrno;
-		else
-			rval = -1;
+	if (u_m)
+		strncpy(name->sysname, u_m, sizeof(name->sysname));
+	else {
+		mib[0] = CTL_HW;
+		mib[1] = HW_MACHINE;
+		len = sizeof(name->machine);
+		oerrno = errno;
+		if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
+			if (errno == ENOMEM)
+				errno = oerrno;
+			else
+				rval = -1;
+		}
 	}
 	name->machine[sizeof(name->machine) - 1] = '\0';
 	return (rval);
Index: getosreldate.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/getosreldate.c,v
retrieving revision 1.7
diff -u -p -r1.7 getosreldate.c
--- getosreldate.c	12 Sep 2005 19:52:41 -0000	1.7
+++ getosreldate.c	15 Oct 2005 02:24:05 -0000
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
+#include <stdlib.h>
 
 #include <osreldate.h>
 
@@ -49,10 +50,16 @@ getosreldate(void)
 	size_t size;
 	int value;
 
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_OSRELDATE;
-	size = sizeof value;
-	if (sysctl(mib, 2, &value, &size, NULL, 0) == -1)
-		return (-1);
+	char *temp;
+
+	if ((temp = getenv("OSVERSION")))
+		value = atoi(temp);
+	else {
+		mib[0] = CTL_KERN;
+		mib[1] = KERN_OSRELDATE;
+		size = sizeof value;
+		if (sysctl(mib, 2, &value, &size, NULL, 0) == -1)
+			return (-1);
+	}
 	return (value);
 }

Does anyone have any objections?

Thanks,

Doug A.


More information about the freebsd-emulation mailing list