From d0ab4a8eabcf9d8b2fb96e2b77ee1266b707f99f Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 27 Mar 2014 11:13:36 +0100 Subject: [PATCH] reinstate spec2make.c, this is still needed for f14 builds unfortunately --- Makefile | 4 +- spec2make.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 spec2make.c diff --git a/Makefile b/Makefile index c2d237b1..1c9e81f4 100644 --- a/Makefile +++ b/Makefile @@ -439,8 +439,8 @@ endif ### this utility allows to extract various info from a spec file ### and to define them in makefiles # use the C code where it works as it's the original one, use the python code otherwise -spec2make: spec2make.py - ln -s spec2make.py $@ +spec2make: spec2make.c + $(CC) -g -Wall $< -o $@ -lrpm -lrpmbuild -lrpmio -lpopt || ln -s spec2make.py $@ ### run spec2make on the spec file and include the result # usage: spec2make package diff --git a/spec2make.c b/spec2make.c new file mode 100644 index 00000000..60004ef6 --- /dev/null +++ b/spec2make.c @@ -0,0 +1,258 @@ +/* + * 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 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* from f10 and up, Spec is renamed rpmSpec */ +#ifndef _RPMTYPES_H +#define rpmSpec Spec +#endif + +#define MAX_WHITELIST_SIZE 16 + +#ifndef PATH_MAX +#include +#endif +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, rpmBuildPoptTable, 0, + "Build options with [ | | ]:", + NULL }, + + { 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() */ +rpmSpec +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; + rpmSpec spec; + struct Source *source; + Package pkg; + const char *name, *version, *release, *arch, *unused; + const char *package_name; + + char **package_whitelist; + + /* BEGIN: support to pull out --target from the args list */ + int alen, i; + char *target = NULL; + int args = 1; + int whitelist_size=0; + package_whitelist = (char **) malloc(MAX_WHITELIST_SIZE * sizeof(char *)); + + if (!package_whitelist) { + perror("Could not allocate package whitelist\n"); + exit(1); + } + + /* walk argv list looking for options */ + while ((args+1) from argv */ + + int option_offset = 1; + char *whitelist_str = argv[args+1]; + if (whitelist_str != NULL) { + char *saveptr = NULL, *str; + option_offset = 2; + for (str = whitelist_str; ; str = NULL) { + char *token; + token = strtok_r(str, "," , &saveptr); + if (token == NULL) break; + package_whitelist[whitelist_size++] = token; + } + } + for (i=args;isources; source; source = source->next) { + char fullSource[PATH_MAX]; + + strncpy(fullSource, source->fullSource, sizeof(fullSource)); + printf("%s.tarballs += 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)); + 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) { + int force = 0; + name = version = release = arch = NULL; + (void) headerNEVRA(pkg->header, &name, &unused, &version, &release, &arch); + if (name && version && release && arch) { + if (target != NULL) { + if (strcmp(arch,target)!=0) { + arch=target; + } + } + /* skip empty packages + * + * Unfortunately, f8 + the RHEL kernel break this bit of cleverness. The following + * line returns false for the kernel-devel package even though it is not empty thereby breaking the build. + * Rather than unfolding the kernel package macros in the current specfile, + * this hack should work till f8 dies its natural death. + * To add rpms that are exempted in this way, add a "-WHITELIST-RPMS" tag in the tags file. + */ + + for (i=0;ifileList || force) { + /* attach (add) rpm path to package */ + printf("%s.rpms += RPMS/%s/%s-%s-%s.%s.rpm\n", + package_name, arch, name, version, release, arch); + /* convenience */ + printf("%s.rpmnames += %s\n", + package_name, name); + /* attach path to rpm name */ + printf("%s.rpm-path := RPMS/%s/%s-%s-%s.%s.rpm\n", + name,arch, name, version, release, arch); + /* attach package to rpm name for backward resolution - should be unique */ + printf("%s.package := %s\n", + name,package_name); + } + } + } + + /* export some macros to make */ + /* note : this relies on pl-specific conventions and might be wrong */ + { + char *macros[] = { "release" , "name" , "version" , "taglevel" , 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); + } + } + + /* export arch */ + printf ("%s.rpm-arch := %s\n",package_name,target); + + spec = freeSpec(spec); + + done: + ts = rpmtsFree(ts); + context = rpmcliFini(context); + return ec; +} -- 2.43.0