Esempio n. 1
0
/*
 * Builds the spec file
 * @param [Number] flags bits to enable stages of build
 * @param [Boolean] test When true, don't execute scripts or package
 * @return [Number] exit code
 *
 * @example
 *   spec = RPM::Spec.open("foo.spec")
 *   spec.build(RPM::BUILD__UNTIL_BUILD)
 */
VALUE
rpm_spec_build(int argc, VALUE* argv, VALUE spec)
{
	int flags, test;
	rpmRC rc;

	switch (argc) {
	case 0:
		rb_raise(rb_eArgError, "argument too few(1..2)");

	case 1:
		flags = NUM2INT(argv[0]);
		test = 0;
		break;

	case 2:
		flags = NUM2INT(argv[0]);
		test = RTEST(argv[1]);
		break;

	default:
		rb_raise(rb_eArgError, "argument too many(0..1)");
	}

#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
	rc = buildSpec(RPM_SPEC(spec), flags,test);
#else
	rpmts ts = NULL;
	ts = rpmtsCreate();
	rc = buildSpec(ts, RPM_SPEC(spec), flags,test);
	ts_free(ts);
#endif

	return INT2NUM(rc);
}
Esempio n. 2
0
rpmRC buildSpec(rpmts ts, Spec spec, int what, int test)
{
    rpmRC rc = RPMRC_OK;

    /* Generate a keypair lazily. */
    if (spec->dig == NULL)
	spec->dig = pgpDigNew(RPMVSF_DEFAULT, PGPPUBKEYALGO_DSA);

    if (!spec->recursing && spec->BACount) {
	int x;
	/* When iterating over BANames, do the source    */
	/* packaging on the first run, and skip RMSOURCE altogether */
	if (spec->BASpecs != NULL)
	for (x = 0; x < spec->BACount; x++) {
	    if ((rc = buildSpec(ts, spec->BASpecs[x],
				(what & ~RPMBUILD_RMSOURCE) |
				(x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
				test))) {
		goto exit;
	    }
	}
    } else {
	/* support "%track" script/section */
	if ((what & RPMBUILD_TRACK) &&
	    (rc = doScript(spec, RPMBUILD_TRACK, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_PREP) &&
	    (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_BUILD) &&
	    (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_INSTALL) &&
	    (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_CHECK) &&
	    (rc = doScript(spec, RPMBUILD_CHECK, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_PACKAGESOURCE) &&
	    (rc = processSourceFiles(spec)))
		goto exit;

	if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
	    (what & RPMBUILD_FILECHECK)) &&
	    (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
		goto exit;

	if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
	    (rc = packageSources(spec)))
		return rc;

	if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
	    (rc = packageBinaries(spec)))
		goto exit;
	
	if ((what & RPMBUILD_CLEAN) &&
	    (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
		goto exit;

	if ((what & RPMBUILD_RMBUILD) &&
	    (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
		goto exit;
    }

    if (what & RPMBUILD_RMSOURCE)
	doRmSource(spec);

    if (what & RPMBUILD_RMSPEC)
	(void) Unlink(spec->specFile);

#if defined(RPM_VENDOR_OPENPKG) /* auto-remove-source-directories */
    /* In OpenPKG we use per-package %{_sourcedir} and %{_specdir}
       definitions (macros have trailing ".../%{name}"). On removal of
       source(s) and .spec file, this per-package directory would be kept
       (usually <prefix>/RPM/SRC/<name>/), because RPM does not know about
       this OpenPKG convention. So, let RPM try(!) to remove the two
       directories (if they are empty) and just ignore removal failures
       (if they are still not empty). */
    if (what & RPMBUILD_RMSOURCE) {
	const char *pn;
	pn = rpmGetPath("%{_sourcedir}", NULL);
	Rmdir(pn); /* ignore error, it is ok if it fails (usually with ENOTEMPTY) */
	pn = _free(pn);
    }
    if (what & RPMBUILD_RMSPEC) {
	const char *pn;
	pn = rpmGetPath("%{_specdir}", NULL);
	Rmdir(pn); /* ignore error, it is ok if it fails (usually with ENOTEMPTY) */
	pn = _free(pn);
    }
#endif

exit:
    if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
	rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
	rpmlogPrint(NULL);
    }

    return rc;
}
Esempio n. 3
0
/*@-boundswrite@*/
static int buildForTarget(rpmts ts, BTA_t ba)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies ts, rpmGlobalMacroContext, fileSystem, internalState @*/
{
    const char * passPhrase = ba->passPhrase;
    const char * cookie = ba->cookie;
    int buildAmount = ba->buildAmount;
    const char * specFile = NULL;
    const char * specURL = NULL;
    int specut;
    const char * s;
    char * se;
    const char * arg = ba->specFile;
    size_t nb = strlen(arg) + BUFSIZ;
    char * buf = alloca(nb);
    Spec spec = NULL;
    int verify = ((ba->buildAmount & RPMBUILD_TRACK) ? 0 : 1);
    int xx;
    int rc;

    if (ba->buildMode == 't') {
	static const char * sfpats[] = { "Specfile", "\\*.spec", NULL };
	static const char _specfn[] = "%{mkstemp:%{_specdir}/rpm-spec.XXXXXX}";
	char * tmpSpecFile = (char *) rpmGetPath(_specfn, NULL);
	FILE *fp;
	int bingo = 0;
	int i;

	for (i = 0; sfpats[i]; i++) {
	    se = rpmExpand("%{uncompress: %{u2p:", arg, "}}",
		" | %{__tar} -xOvf - %{?__tar_wildcards} ", sfpats[i],
		" 2>&1 > '", tmpSpecFile, "'", NULL);
	    fp = popen(se, "r");
	    se = _free(se);
	    if (fp== NULL)
		continue;
	    s = fgets(buf, nb - 1, fp);
	    xx = pclose(fp);
	    if (!s || !*s || strstr(s, ": Not found in archive"))
		continue;
	    bingo = 1;
	    break;
	}
	if (!bingo) {
	    rpmlog(RPMLOG_ERR, _("Failed to read spec file from %s\n"), arg);
	    xx = Unlink(tmpSpecFile);
	    tmpSpecFile = _free(tmpSpecFile);
	    return 1;
	}

	s = se = basename(buf);
	se += strlen(se);
	while (--se > s && strchr("\r\n", *se) != NULL)
	    *se = '\0';
	specURL = rpmGetPath("%{_specdir}/", s, NULL);
	specut = urlPath(specURL, &specFile);
	xx = Rename(tmpSpecFile, specFile);
	if (xx) {
	    rpmlog(RPMLOG_ERR, _("Failed to rename %s to %s: %m\n"),
			tmpSpecFile, s);
	    (void) Unlink(tmpSpecFile);
	}
	tmpSpecFile = _free(tmpSpecFile);
	if (xx)
	    return 1;

	se = buf; *se = '\0';
	se = stpcpy(se, "_sourcedir ");
	(void) urlPath(arg, &s);
	if (*s != '/') {
	    if (getcwd(se, nb - sizeof("_sourcedir ")) != NULL)
		se += strlen(se);
	    else
		se = stpcpy(se, ".");
	} else
	    se = stpcpy(se, dirname(strcpy(se, s)));
	while (se > buf && se[-1] == '/')
	    *se-- = '0';
	rpmCleanPath(buf + sizeof("_sourcedir ") - 1);
	rpmDefineMacro(NULL, buf, RMIL_TARBALL);
    } else {
	specut = urlPath(arg, &s);
	se = buf; *se = '\0';
	if (*s != '/') {
	    if (getcwd(se, nb - sizeof("_sourcedir ")) != NULL)
		se += strlen(se);
	    else
		se = stpcpy(se, ".");
	    *se++ = '/';
	    se += strlen(strcpy(se,strcpy(se, s)));
	} else
	    se = stpcpy(se, s);
	specURL = rpmGetPath(buf, NULL);
	specut = urlPath(specURL, &specFile);
    }

    if (specut != URL_IS_DASH) {
	struct stat sb;
	if (Stat(specURL, &sb) < 0) {
	    rpmlog(RPMLOG_ERR, _("failed to stat %s: %m\n"), specURL);
	    rc = 1;
	    goto exit;
	}
	if (! S_ISREG(sb.st_mode)) {
	    rpmlog(RPMLOG_ERR, _("File %s is not a regular file.\n"),
		specURL);
	    rc = 1;
	    goto exit;
	}

	/* Try to verify that the file is actually a specfile */
	if (!isSpecFile(specURL)) {
	    rpmlog(RPMLOG_ERR,
		_("File %s does not appear to be a specfile.\n"), specURL);
	    rc = 1;
	    goto exit;
	}
    }
    
    /* Parse the spec file */
#define	_anyarch(_f)	\
(((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
    if (parseSpec(ts, specURL, ba->rootdir, 0, passPhrase,
		cookie, _anyarch(buildAmount), 0, verify))
    {
	rc = 1;
	goto exit;
    }
#undef	_anyarch
    if ((spec = rpmtsSetSpec(ts, NULL)) == NULL) {
	rc = 1;
	goto exit;
    }

    /* Assemble source header from parsed components */
    xx = initSourceHeader(spec, NULL);

    /* Check build prerequisites */
    if (!ba->noDeps && checkSpec(ts, spec->sourceHeader)) {
	rc = 1;
	goto exit;
    }

    if (buildSpec(ts, spec, buildAmount, ba->noBuild)) {
	rc = 1;
	goto exit;
    }
    
    if (ba->buildMode == 't')
	(void) Unlink(specURL);
    rc = 0;

exit:
    spec = freeSpec(spec);
    specURL = _free(specURL);
    return rc;
}
Esempio n. 4
0
File: build.c Progetto: kaltsi/rpm
rpmRC rpmSpecBuild(rpmSpec spec, BTA_t buildArgs)
{
    /* buildSpec() can recurse with different buildAmount, pass it separately */
    return buildSpec(buildArgs, spec, buildArgs->buildAmount);
}
Esempio n. 5
0
File: build.c Progetto: kaltsi/rpm
static rpmRC buildSpec(BTA_t buildArgs, rpmSpec spec, int what)
{
    rpmRC rc = RPMRC_OK;
    int test = (what & RPMBUILD_NOBUILD);
    char *cookie = buildArgs->cookie ? xstrdup(buildArgs->cookie) : NULL;

    /* XXX TODO: rootDir is only relevant during build, eliminate from spec */
    spec->rootDir = buildArgs->rootdir;
    if (!spec->recursing && spec->BACount) {
	int x;
	/* When iterating over BANames, do the source    */
	/* packaging on the first run, and skip RMSOURCE altogether */
	if (spec->BASpecs != NULL)
	for (x = 0; x < spec->BACount; x++) {
	    if ((rc = buildSpec(buildArgs, spec->BASpecs[x],
				(what & ~RPMBUILD_RMSOURCE) |
				(x ? 0 : (what & RPMBUILD_PACKAGESOURCE))))) {
		goto exit;
	    }
	}
    } else {
	int didBuild = (what & (RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL));

	if ((what & RPMBUILD_PREP) &&
	    (rc = doScript(spec, RPMBUILD_PREP, "%prep",
			   getStringBuf(spec->prep), test)))
		goto exit;

	if ((what & RPMBUILD_BUILD) &&
	    (rc = doScript(spec, RPMBUILD_BUILD, "%build",
			   getStringBuf(spec->build), test)))
		goto exit;

	if ((what & RPMBUILD_INSTALL) &&
	    (rc = doScript(spec, RPMBUILD_INSTALL, "%install",
			   getStringBuf(spec->install), test)))
		goto exit;

	if ((what & RPMBUILD_CHECK) &&
	    (rc = doScript(spec, RPMBUILD_CHECK, "%check",
			   getStringBuf(spec->check), test)))
		goto exit;

	if ((what & RPMBUILD_PACKAGESOURCE) &&
	    (rc = processSourceFiles(spec, buildArgs->pkgFlags)))
		goto exit;

	if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
	    (what & RPMBUILD_FILECHECK)) &&
	    (rc = processBinaryFiles(spec, buildArgs->pkgFlags,
				     what & RPMBUILD_INSTALL, test)))
		goto exit;

	if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY)) &&
	    (rc = processBinaryPolicies(spec, test)))
		goto exit;

	if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
	    (rc = packageSources(spec, &cookie)))
		return rc;

	if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
	    (rc = packageBinaries(spec, cookie, (didBuild == 0))))
		goto exit;
	
	if ((what & RPMBUILD_CLEAN) &&
	    (rc = doScript(spec, RPMBUILD_CLEAN, "%clean",
			   getStringBuf(spec->clean), test)))
		goto exit;

	if ((what & RPMBUILD_RMBUILD) &&
	    (rc = doScript(spec, RPMBUILD_RMBUILD, "--clean", NULL, test)))
		goto exit;
    }

    if (what & RPMBUILD_RMSOURCE)
	doRmSource(spec);

    if (what & RPMBUILD_RMSPEC)
	(void) unlink(spec->specFile);

exit:
    free(cookie);
    spec->rootDir = NULL;
    if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
	rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
	rpmlogPrint(NULL);
    }
    rpmugFree();

    return rc;
}
Esempio n. 6
0
/* Building a spec file */
int _specbuild(rpmts ts, Spec spec, SV * sv_buildflags) {
    rpmBuildFlags buildflags = sv2constant(sv_buildflags, "rpmbuildflags");
    if (buildflags == RPMBUILD_NONE) croak("No action given for build");
    return buildSpec(ts, spec, buildflags, 0);
}