/* * Parses RPM spec file into Makefile fragment. See * * http://fedora.redhat.com/docs/drafts/rpm-guide-en/ch-programming-c.html * * Mark Huang * Copyright (C) 2006 The Trustees of Princeton University * * $Id$ */ #include #include #include #include #include #include #include #include #include #include extern size_t strnlen(const char *s, size_t maxlen); /* the structure describing the options we take and the defaults */ static struct poptOption optionsTable[] = { { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0, "Common options for all rpm modes and executables:", NULL }, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; /* Stolen from rpm/build/spec.c:rpmspecQuery() */ Spec rpmspecGet(rpmts ts, const char * arg) { char * buildRoot = NULL; int recursing = 0; char * passPhrase = ""; char *cookie = NULL; int anyarch = 1; int force = 1; if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase, cookie, anyarch, force)) { fprintf(stderr, "query of specfile %s failed, can't parse\n", arg); return NULL; } return rpmtsSpec(ts); } int main(int argc, char *argv[]) { poptContext context; rpmts ts = NULL; int ec = 0; Spec spec; struct Source *source; Package pkg; const char *name, *version, *release, *arch, *unused; const char *package_name; /* BEGIN: support to pull out --target from the args list */ int alen, i; char *target = NULL; int args = 1; int tlen = strlen("--target"); /* walk argv list looking for --target */ while ((args+1)sources; source; source = source->next) { char fullSource[PATH_MAX]; strncpy(fullSource, source->fullSource, sizeof(fullSource)); printf("%s-TARBALL += SOURCES/%s\n", package_name, basename(fullSource)); /* computes the SOURCEDIR variable by removing .tar.gz or .tar.bz2 */ { char *suffixes[] = {".tar.gz",".tgz",".tar.bz2", NULL}; char **suffix; char *suffix_index; for (suffix=suffixes ; *suffix ; suffix++) { printf("# trying %s\n",*suffix); suffix_index=strstr(fullSource,*suffix); if (suffix_index) { char sourcename[PATH_MAX]; size_t len = (size_t)(suffix_index-fullSource); strncpy(sourcename,fullSource,len); sourcename[len]='\0'; printf ("%s-SOURCE := SOURCES/%s\n",package_name,basename(sourcename)); printf ("%s-CODEBASE := CODEBASES/%s\n",package_name,package_name); break; } } } } /* Get SRPM name from name of first package */ pkg = spec->packages; name = version = release = NULL; (void) headerNVR(pkg->header, &name, &version, &release); if (name && version && release) printf("%s-SRPM := SRPMS/%s-%s-%s.src.rpm\n", package_name, name, version, release); /* Print non-empty packages */ for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { name = version = release = arch = NULL; (void) headerNEVRA(pkg->header, &name, &unused, &version, &release, &arch); if (name && version && release && arch) { if (!pkg->fileList) printf("# Empty\n# "); if (target != NULL) { if (strcmp(arch,target)!=0) { arch=target; } } printf("%s-RPM += RPMS/%s/%s-%s-%s.%s.rpm\n", package_name, arch, name, version, release, arch); } } /* export some macros to make */ { char *macros[] = { "release" , "name" , "version" , "subversion" , NULL } ; char **nav; char *macro=malloc(32); for (nav=macros; *nav; nav++) { sprintf(macro,"%%{%s}",*nav); char *value = rpmExpand(macro,NULL); printf ("%s-rpm-%s := %s\n",package_name,*nav,value); } } spec = freeSpec(spec); done: ts = rpmtsFree(ts); context = rpmcliFini(context); return ec; }