Re: Putting cross compilers into Fedora

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2010-09-01 at 21:50 +0300, Panu Matilainen wrote:
> On Wed, 1 Sep 2010, Ralf Corsepius wrote:
> >
> > b) To equippe the rpm/yum/mock etc. infrastructure with a mechanism to
> > pull-in "foreign binaries" into a sys-root (E.g. to install Fedora
> > *.ppc.rpm rpms into /usr/ppc-redhat/sys-root). So far, such mechanism
> > doesn't exist.
> 
> You should be able to force rpm to lay down the files, given enough 
> override-switches. Something like
> # rpm -Uvh --root /usr/ppc-redhat/sys-root --ignorearch --noscripts *.rpm
> 
> (or alternatively --relocate with --badrelocate instead of --root, if you 
> want the packages showing in system rpmdb instead of alternate root, and 
> then you'd /really/ need arch-specific buildrequires which in turn is 
> another can of worms etc)
> 
> ...but the resulting pile of files is likely to be fairly useless since 
> no scripts are executed. Having some way of executing scriptlets in an 
> emulator (eg qemu) might be an interesting experiment actually ;)
> 
>  	- Panu -

Speaking of crazy experiments, I came up with the attached rpm patch
last year when I was bootstrapping another arch. In short, to run
scripts without having to write a simulator, it bind mounts native
binary (/bin, /lib, etc) directories into the target sysroot before
running a script and unmounts them afterward. As crazy as that is, it
worked surprisingly well for a core set of F-10 rpms. Of course, it
doesn't work for scripts that try writing to the binary directories,
but it did help me compose a cross rootfs based on a kickstart file.
Something simulator based would definitely have been better.

--Mark

diff -rup a/lib/poptALL.c b/lib/poptALL.c
--- a/lib/poptALL.c	2009-03-03 01:51:52.000000000 -0500
+++ b/lib/poptALL.c	2009-08-03 16:01:23.295685376 -0400
@@ -68,6 +68,8 @@ const char * rpmcliRcfile = NULL;
 
 const char * rpmcliRootDir = "/";
 
+const char * rpmcliNativeRootDir = NULL;
+
 rpmQueryFlags rpmcliQueryFlags;
 
 extern int _rpmio_debug;
@@ -238,6 +240,10 @@ struct poptOption rpmcliAllPoptTable[] =
 	N_("use ROOT as top level directory"),
 	N_("ROOT") },
 
+ { "nativeroot", '\0', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmcliNativeRootDir, 0,
+	N_("use ROOT as top level directory of native binaries"),
+	N_("ROOT") },
+
  { "querytags", '\0', 0, 0, POPT_QUERYTAGS,
         N_("display known query tags"), NULL },
  { "showrc", '\0', 0, NULL, POPT_SHOWRC,
diff -rup a/lib/psm.c b/lib/psm.c
--- a/lib/psm.c	2009-04-03 07:04:46.000000000 -0400
+++ b/lib/psm.c	2009-08-04 16:39:57.944559570 -0400
@@ -4,6 +4,7 @@
  */
 
 #include "system.h"
+#include <sys/mount.h>
 
 #include <rpm/rpmlib.h>		/* rpmvercmp and others */
 #include <rpm/rpmmacro.h>
@@ -63,6 +64,69 @@ struct rpmpsm_s {
     int nrefs;			/*!< Reference count. */
 };
 
+static const char *nativeDirs[] = { 
+    "bin", 
+    "sbin",
+    "usr/bin",
+    "usr/sbin",
+    "lib",
+    "usr/lib",
+    "usr/libexec",
+    NULL
+};
+
+static int rpmMountNatives(rpmts ts)
+{
+    const char * rootDir = rpmtsRootDir(ts);
+    const char *nativeDir = rpmtsNativeDir(ts);
+
+    if (rootDir != NULL && nativeDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+	char **dirs;
+	if (rpmtsChrootDone(ts))
+		rootDir = "/";
+	    
+	for (dirs = nativeDirs; *dirs != NULL; ++dirs)  {
+	    struct stat st;
+	    char *srcDir = rpmGetPath(rootDir, "native/", *dirs, NULL);
+	    char *targetDir = rpmGetPath(rootDir, *dirs, NULL);
+
+	    if (stat(srcDir, &st) == 0) {
+		rpmioMkpath(targetDir, 0755, -1, -1);
+		mount(srcDir, targetDir, NULL, MS_BIND, NULL);
+	    }
+
+	    _free(srcDir);
+	    _free(targetDir);
+	}
+    }
+    return 0;
+}
+
+static int rpmUmountNatives(rpmts ts)
+{
+    const char * rootDir = rpmtsRootDir(ts);
+    char *nativeDir = rpmtsNativeDir(ts);
+
+    if (rootDir != NULL && nativeDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+	char **dirs;
+	if (rpmtsChrootDone(ts))
+	    rootDir = "/";
+
+	for (dirs = nativeDirs; *dirs != NULL; ++dirs)  {
+	    struct stat st;
+	    char *targetDir = rpmGetPath(rootDir, *dirs, NULL);
+
+	    if (stat(targetDir, &st) == 0) {
+		umount(targetDir);
+		unlink(targetDir);
+	    }
+
+	    _free(targetDir);
+	}
+    }
+    return 0;
+}
+
 int rpmVersionCompare(Header first, Header second)
 {
     struct rpmtd_s one, two;
@@ -482,11 +546,13 @@ static rpmRC runLuaScript(rpmpsm psm, He
     var = rpmluavFree(var);
     rpmluaPop(lua);
 
+    rpmMountNatives(ts);
     if (rpmluaRunScript(lua, script, sname) == 0) {
 	rc = RPMRC_OK;
     } else if ((stag != RPMTAG_PREIN && stag != RPMTAG_PREUN)) {
 	warn_only = 1;
     }
+    rpmUmountNatives(ts);
 
     rpmluaDelVar(lua, "arg");
 
@@ -744,6 +810,7 @@ static rpmRC runScript(rpmpsm psm, Heade
 	goto exit;
     }
 
+    rpmMountNatives(ts);
     xx = rpmsqFork(&psm->sq);
     if (psm->sq.child == 0) {
 	rpmlog(RPMLOG_DEBUG, "%s: %s\texecv(%s) pid %d\n",
@@ -778,6 +845,7 @@ static rpmRC runScript(rpmpsm psm, Heade
 	/* if we get this far we're clear */
 	rc = RPMRC_OK;
     }
+    rpmUmountNatives(ts);
 
 exit:
     rpmtdFreeData(&prefixes);
@@ -1556,17 +1624,41 @@ rpmRC rpmpsmStage(rpmpsm psm, pkgStage s
     case PSM_CHROOT_IN:
     {	const char * rootDir = rpmtsRootDir(ts);
 	/* Change root directory if requested and not already done. */
+	rpmlog(RPMLOG_DEBUG, "PSM_CHROOT_IN: rootDir: %s\n", rootDir ? rootDir : "NULL");
 	if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')
 	 && !rpmtsChrootDone(ts) && !psm->chrootDone)
 	{
+	    const char * nativeDir = rpmtsNativeDir(ts);
+	    char *chrootNative = NULL;
+	    rpmlog(RPMLOG_DEBUG, "PSM_CHROOT_IN: nativeDir: %s\n", nativeDir ? nativeDir : "NULL");
+	    if (nativeDir != NULL) {
+		chrootNative = rpmGetPath(rootDir, "native", NULL);
+		/* mount nativeDir somewhere we can get to from chroot */
+		if (mkdir(chrootNative, 0755)) {
+		    rpmlog(RPMLOG_ERR, _("Unable to make chroot native directory: %m\n"));
+		    return -1;
+		}
+		if (mount(nativeDir, chrootNative, NULL, MS_BIND, NULL)) {
+		    rpmlog(RPMLOG_ERR, _("Unable to mount chroot native directory: %m\n"));
+		    rmdir(chrootNative);
+		    _free(chrootNative);
+		    return -1;
+		}
+	    }
 	    xx = chdir("/");
 	    if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
 	        if (chroot(rootDir) == -1) {
 		    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
+		    if (chrootNative) {
+			umount(chrootNative);
+			rmdir(chrootNative);
+			_free(chrootNative);
+		    }
 		    return -1;
 		}
 	    psm->chrootDone = 1;
 	    (void) rpmtsSetChrootDone(ts, 1);
+	    _free(chrootNative);
 	}
     }	break;
     case PSM_CHROOT_OUT:
@@ -1574,8 +1666,16 @@ rpmRC rpmpsmStage(rpmpsm psm, pkgStage s
 	if (psm->chrootDone) {
 	    const char * rootDir = rpmtsRootDir(ts);
 	    const char * currDir = rpmtsCurrDir(ts);
-	    if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
+	    if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
+		const char * nativeDir = rpmtsNativeDir(ts);
 		rc = chroot(".");
+		if (nativeDir != NULL) {
+		    char *tmpDir = rpmGetPath(rootDir, "native", NULL);
+		    umount(tmpDir);
+		    rmdir(tmpDir);
+		    _free(tmpDir);
+		}
+	    }
 	    psm->chrootDone = 0;
 	    (void) rpmtsSetChrootDone(ts, 0);
 	    if (currDir != NULL)	/* XXX can't happen */
diff -rup a/lib/rpmcli.h b/lib/rpmcli.h
--- a/lib/rpmcli.h	2009-04-03 06:59:20.000000000 -0400
+++ b/lib/rpmcli.h	2009-08-04 15:43:51.432639428 -0400
@@ -40,6 +40,8 @@ extern const char * rpmcliRcfile;
 
 extern const char * rpmcliRootDir;
 
+extern const char * rpmcliNativeRootDir;
+
 /** \ingroup rpmcli
  * Initialize most everything needed by an rpm CLI executable context.
  * @param argc			no. of args
diff -rup a/lib/rpmts.c b/lib/rpmts.c
--- a/lib/rpmts.c	2009-04-03 07:36:48.000000000 -0400
+++ b/lib/rpmts.c	2009-08-04 11:40:51.269560123 -0400
@@ -594,6 +594,7 @@ rpmts rpmtsFree(rpmts ts)
 	ts->scriptFd = NULL;
     }
     ts->rootDir = _free(ts->rootDir);
+    ts->nativeDir = _free(ts->nativeDir);
     ts->currDir = _free(ts->currDir);
 
     ts->order = _free(ts->order);
@@ -681,6 +682,50 @@ int rpmtsSetRootDir(rpmts ts, const char
     return 0;
 }
 
+const char * rpmtsNativeDir(rpmts ts)
+{
+    const char * nativeDir = NULL;
+    
+    if (ts == NULL)
+	return NULL;
+
+    if (ts->nativeDir == NULL) {
+	char *x = getenv("RPM_NATIVEDIR");
+	if (x)
+	    ts->nativeDir = rpmGetPath(x, NULL);
+    }
+
+    if (ts->nativeDir != NULL) {
+	urltype ut = urlPath(ts->nativeDir, &nativeDir);
+	switch (ut) {
+	case URL_IS_UNKNOWN:
+	case URL_IS_PATH:
+	    break;
+	/* XXX these shouldn't be allowed as nativedir! */
+	case URL_IS_HTTPS:
+	case URL_IS_HTTP:
+	case URL_IS_HKP:
+	case URL_IS_FTP:
+	case URL_IS_DASH:
+	default:
+	    nativeDir = NULL;
+	    break;
+	}
+    }
+    return nativeDir;
+}
+
+int rpmtsSetNativeDir(rpmts ts, const char * nativeDir)
+{
+    if (ts == NULL || (nativeDir && nativeDir[0] != '/')) {
+	return -1;
+    }
+
+    ts->nativeDir = _free(ts->nativeDir);
+    ts->nativeDir = nativeDir ? rpmGetPath(nativeDir, NULL) : NULL ;
+    return 0;
+}
+
 const char * rpmtsCurrDir(rpmts ts)
 {
     const char * currDir = NULL;
@@ -1129,6 +1174,7 @@ rpmts rpmtsCreate(void)
 			sizeof(*ts->removedPackages));
 
     ts->rootDir = NULL;
+    ts->nativeDir = NULL;
     ts->currDir = NULL;
     ts->chrootDone = 0;
 
diff -rup a/lib/rpmts.h b/lib/rpmts.h
--- a/lib/rpmts.h	2009-04-03 06:59:20.000000000 -0400
+++ b/lib/rpmts.h	2009-08-04 13:11:36.436559980 -0400
@@ -394,6 +394,21 @@ const char * rpmtsRootDir(rpmts ts);
 int rpmtsSetRootDir(rpmts ts, const char * rootDir);
 
 /** \ingroup rpmts
+ * Get transaction nativeDir, i.e. path to native binaries.
+ * @param ts		transaction set
+ * @return		transaction nativeDir
+ */
+const char * rpmtsNativeDir(rpmts ts);
+
+/** \ingroup rpmts
+ * Set transaction nativeDir, i.e. path to native binaries.
+ * @param ts		transaction set
+ * @param nativeDir	new transaction nativeDir (or NULL)
+ * @return		0 on success, -1 on error (invalid rootDir)
+ */
+int rpmtsSetNativeDir(rpmts ts, const char * nativeDir);
+
+/** \ingroup rpmts
  * Get transaction currDir, i.e. current directory before chroot(2).
  * @param ts		transaction set
  * @return		transaction currDir
diff -rup a/lib/rpmts_internal.h b/lib/rpmts_internal.h
--- a/lib/rpmts_internal.h	2009-04-03 07:36:48.000000000 -0400
+++ b/lib/rpmts_internal.h	2009-08-03 21:20:18.112685343 -0400
@@ -73,6 +73,7 @@ struct rpmts_s {
     int selinuxEnabled;		/*!< Is SE linux enabled? */
     int chrootDone;		/*!< Has chroot(2) been been done? */
     char * rootDir;		/*!< Path to top of install tree. */
+    char * nativeDir;		/*!< Path to top of native install tree. */
     char * currDir;		/*!< Current working directory. */
     FD_t scriptFd;		/*!< Scriptlet stdout/stderr. */
     int delta;			/*!< Delta for reallocation. */
diff -rup a/python/rpmts-py.c b/python/rpmts-py.c
--- a/python/rpmts-py.c	2009-08-03 15:52:47.104684373 -0400
+++ b/python/rpmts-py.c	2009-09-14 15:28:49.281737146 -0400
@@ -790,6 +790,22 @@ fprintf(stderr, "*** rpmts_GetKeys(%p) t
     return tuple;
 }
 
+static PyObject *
+rpmts_SetNativeRoot(rpmtsObject * s, PyObject * args, PyObject * kwds)
+{
+    const char *nativeRoot;
+    char * kwlist[] = {"nativeRoot", NULL};
+
+if (_rpmts_debug)
+fprintf(stderr, "*** rpmts_SetNativeRoot(%p) ts %p\n", s, s->ts);
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:SetNativeRoot", kwlist,
+	    &nativeRoot))
+    	return NULL;
+
+    return Py_BuildValue("i", rpmtsSetNativeDir(s->ts, nativeRoot));
+}
+
 /** \ingroup py_c
  */
 static void *
@@ -1217,6 +1233,8 @@ static struct PyMethodDef rpmts_methods[
  {"next",		(PyCFunction)rpmts_Next,	METH_NOARGS,
 "ts.next() -> te\n\
 - Retrieve next transaction set element.\n" },
+ {"setNativeRoot",(PyCFunction) rpmts_SetNativeRoot,	METH_VARARGS|METH_KEYWORDS,
+	NULL },
     {NULL,		NULL}		/* sentinel */
 };
 
@@ -1310,19 +1328,21 @@ static PyObject * rpmts_new(PyTypeObject
     rpmtsObject * s = (void *) PyObject_New(rpmtsObject, subtype);
 
     char * rootDir = "/";
+    char * nativeDir = NULL;
     rpmVSFlags vsflags = rpmExpandNumeric("%{?__vsflags}");
-    char * kwlist[] = {"rootdir", "vsflags", 0};
+    char * kwlist[] = {"rootdir", "vsflags", "nativeRoot", 0};
 
     if (_rpmts_debug < 0)
 	fprintf(stderr, "*** rpmts_new(%p,%p,%p)\n", s, args, kwds);
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|si:rpmts_init", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sis:rpmts_init", kwlist,
 	    &rootDir, &vsflags))
 	return NULL;
 
     s->ts = rpmtsCreate();
     /* XXX: Why is there no rpmts_SetRootDir() ? */
     (void) rpmtsSetRootDir(s->ts, rootDir);
+    (void) rpmtsSetNativeDir(s->ts, nativeDir);
     /* XXX: make this use common code with rpmts_SetVSFlags() to check the
      *      python objects */
     (void) rpmtsSetVSFlags(s->ts, vsflags);
diff -rup a/rpmqv.c b/rpmqv.c
--- a/rpmqv.c	2009-04-03 07:05:52.000000000 -0400
+++ b/rpmqv.c	2009-08-04 15:44:01.539559986 -0400
@@ -597,6 +597,7 @@ int main(int argc, char *argv[])
 	
     ts = rpmtsCreate();
     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
+    (void) rpmtsSetNativeDir(ts, rpmcliNativeRootDir);
     switch (bigMode) {
 #ifdef	IAM_RPMDB
     case MODE_INITDB:
diff --git a/tools/debugedit.c b/tools/debugedit.c
index f42b34a..5d150e8 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -1247,6 +1247,56 @@ edit_dwarf2 (DSO *dso)
   return 0;
 }
 
+/* The .GCC-command-line section will likely have the RPM_BUILD_ROOT string
+   in it. This causes check-buildroot to abort the build. Since this section
+   is informational, just change the string slightly to avoid problems with
+   check-buildroot. */
+static int
+edit_commandline (DSO *dso)
+{
+  Elf_Data *data;
+  Elf_Scn *scn;
+  char *p, *end;
+  int i, changed;
+
+  for (i = 1; i < dso->ehdr.e_shnum; ++i)
+    if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR))
+	&& dso->shdr[i].sh_size)
+      {
+        const char *name = strptr (dso, dso->ehdr.e_shstrndx,
+				   dso->shdr[i].sh_name);
+	if (strcmp (name, ".GCC-command-line") == 0)
+	  {
+	    scn = dso->scn[i]; 
+	    data = elf_rawdata (scn, NULL);
+	    assert (data != NULL && data->d_buf != NULL);
+	    assert (elf_rawdata (scn, data) == NULL);
+	    assert (data->d_off == 0);
+	    assert (data->d_size == dso->shdr[i].sh_size);
+
+	    changed = 0;
+	    p = data->d_buf;
+	    end = p + data->d_size - strlen("BUILDR00T");
+	    while (p < end)
+	      {
+		/* just change "BUILDROOT" to "BUILDR00T" */
+		if (*p == 'B' && strncmp(p, "BUILDROOT", 9) == 0)
+		  {
+		    p[6] = p[7] = '0';
+		    changed = 1;
+		    p += 9;
+		  }
+		else
+		  ++p;
+	      }
+	    if (changed)
+	      elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+	  }
+      }
+  return 0;
+}
+
+
 static struct poptOption optionsTable[] = {
     { "base-dir",  'b', POPT_ARG_STRING, &base_dir, 0,
       "base build directory of objects", NULL },
@@ -1530,7 +1580,7 @@ main (int argc, char *argv[])
 
   if (stat(file, &stat_buf) < 0)
     {
-      fprintf (stderr, "Failed to open input file '%s': %s\n", file, strerror(errno));
+      fprintf (stderr, "Failed to stat input file '%s': %s\n", file, strerror(errno));
       exit (1);
     }
 
@@ -1564,6 +1614,10 @@ main (int argc, char *argv[])
 	  if (strcmp (name, ".debug_info") == 0)
 	    edit_dwarf2 (dso);
 
+	  /* Handle gcc command-line section */
+	  if (strcmp (name, ".GCC-command-line") == 0)
+	    edit_commandline (dso);
+
 	  break;
 	case SHT_NOTE:
 	  if (do_build_id
-- 
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxxx
https://admin.fedoraproject.org/mailman/listinfo/devel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Fedora Announce]     [Fedora Kernel]     [Fedora Testing]     [Fedora Formulas]     [Fedora PHP Devel]     [Kernel Development]     [Fedora Legacy]     [Fedora Maintainers]     [Fedora Desktop]     [PAM]     [Red Hat Development]     [Gimp]     [Yosemite News]
  Powered by Linux