From 3151180d4fe693a873ae979d44b10d7946f2e7e0 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 26 Apr 2019 13:19:11 +0300 Subject: [PATCH 1/2] Try to continue despite missing %include files on forced spec parse On forced spec parse (spec query or --force'd build) we already allow sources and patches to be missing. %include differs from sources and patches in that a missing include might make the spec unparseable, but then we lose nothing by trying, as quite often the spec is parseable enough to get at least some info out of it. Doesn't seem any worse than allowing build without sources present... Helps a bit in cases like RhBug:1658292 and RhBug:1547897. --- build/parseSpec.c | 20 ++++++++++++++------ tests/Makefile.am | 1 + tests/data/SPECS/inctest.spec | 11 +++++++++++ tests/rpmbuild.at | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 tests/data/SPECS/inctest.spec diff --git a/build/parseSpec.c b/build/parseSpec.c index 687c522148..70379115c1 100644 --- a/build/parseSpec.c +++ b/build/parseSpec.c @@ -34,6 +34,7 @@ typedef struct OpenFileInfo { char *readBuf; size_t readBufLen; const char * readPtr; + int missingok; struct OpenFileInfo * next; } OFI_t; @@ -127,7 +128,7 @@ int handleComments(char *s) } /* Push a file to spec's file stack, return the newly pushed entry */ -static OFI_t * pushOFI(rpmSpec spec, const char *fn) +static OFI_t * pushOFI(rpmSpec spec, const char *fn, int missingok) { OFI_t *ofi = xcalloc(1, sizeof(*ofi)); @@ -138,6 +139,7 @@ static OFI_t * pushOFI(rpmSpec spec, const char *fn) ofi->readBuf = xmalloc(ofi->readBufLen); ofi->readBuf[0] = '\0'; ofi->readPtr = NULL; + ofi->missingok = missingok; ofi->next = spec->fileStack; spec->fileStack = ofi; @@ -372,9 +374,15 @@ static int readLineFromOFI(rpmSpec spec, OFI_t *ofi) if (ofi->fp == NULL) { ofi->fp = fopen(ofi->fileName, "r"); if (ofi->fp == NULL) { - rpmlog(RPMLOG_ERR, _("Unable to open %s: %s\n"), - ofi->fileName, strerror(errno)); - return PART_ERROR; + /* Try to ignore missing includes on forced parse */ + rpmlog(ofi->missingok ? RPMLOG_WARNING : RPMLOG_ERR, + _("Unable to open %s: %s\n"), ofi->fileName, strerror(errno)); + if (ofi->missingok) { + ofi = popOFI(spec); + goto retry; + } else { + return PART_ERROR; + } } spec->lineNum = ofi->lineNum = 0; } @@ -525,7 +533,7 @@ int readLine(rpmSpec spec, int strip) } *endFileName = '\0'; - ofi = pushOFI(spec, fileName); + ofi = pushOFI(spec, fileName, (spec->flags & RPMSPEC_FORCE)); goto retry; } @@ -860,7 +868,7 @@ static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags, spec = newSpec(); spec->specFile = rpmGetPath(specFile, NULL); - pushOFI(spec, spec->specFile); + pushOFI(spec, spec->specFile, 0); /* If buildRoot not specified, use default %{buildroot} */ if (buildRoot) { spec->buildRoot = xstrdup(buildRoot); diff --git a/tests/Makefile.am b/tests/Makefile.am index ad9549a688..6126e51ceb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST += data/SPECS/filedep.spec EXTRA_DIST += data/SPECS/flangtest.spec EXTRA_DIST += data/SPECS/hlinktest.spec EXTRA_DIST += data/SPECS/iftest.spec +EXTRA_DIST += data/SPECS/inctest.spec EXTRA_DIST += data/SPECS/symlinktest.spec EXTRA_DIST += data/SPECS/deptest.spec EXTRA_DIST += data/SPECS/verifyscript.spec diff --git a/tests/data/SPECS/inctest.spec b/tests/data/SPECS/inctest.spec new file mode 100644 index 0000000000..277561daba --- /dev/null +++ b/tests/data/SPECS/inctest.spec @@ -0,0 +1,11 @@ +Name: inctest +Version: 1.0 +Release: 1 +Group: Testing +License: GPL +BuildArch: noarch +Summary: Testing include directive + +%description +%include %{incfile} + diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index 5379723f00..9d76725a3f 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -99,6 +99,29 @@ run rpmbuild \ [ignore]) AT_CLEANUP +AT_SETUP([rpmbuild include]) +AT_KEYWORDS([build]) +AT_CHECK([ +dsc="/tmp/description" +echo "Describe me" > "${RPMTEST}/${dsc}" +runroot rpmspec -q "/data/SPECS/notthere.spec" 2>&1; echo $? +runroot rpmspec -q --define "incfile /not/there" "/data/SPECS/inctest.spec" 2>&1; echo $? +runroot rpmspec -q --define "incfile ${dsc}" --qf "%{description}\n" "/data/SPECS/inctest.spec" 2>&1; echo $? +rm -f "${RPMTEST}/${dsc}" +], +[0], +[error: Unable to open /data/SPECS/notthere.spec: No such file or directory +error: query of specfile /data/SPECS/notthere.spec failed, can't parse +1 +warning: Unable to open /not/there: No such file or directory +inctest-1.0-1.noarch +0 +Describe me +0 +], +[]) +AT_CLEANUP + # ------------------------------ # %attr/%defattr tests AT_SETUP([rpmbuild %attr and %defattr]) From e42563e1a0395120890385b525b0b3c4d92f6a20 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Fri, 26 Apr 2019 14:05:20 +0300 Subject: [PATCH 2/2] Add support for special system-level %include path When %include argument is enclosed in <> (ie similar to C includes), look for the file in system-level %_rpmincludedir path instead %_sourcedir, and treat these as build-dependencies that get recorded in the src.rpm. --- Makefile.am | 2 ++ build/parseSpec.c | 11 +++++++++++ macros.in | 1 + tests/rpmbuild.at | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/Makefile.am b/Makefile.am index 057b7892c3..89ad770a80 100644 --- a/Makefile.am +++ b/Makefile.am @@ -250,6 +250,7 @@ install-data-local: @$(MKDIR_P) $(DESTDIR)$(localstatedir)/tmp @$(MKDIR_P) $(DESTDIR)$(rpmconfigdir)/macros.d @$(MKDIR_P) $(DESTDIR)$(rpmconfigdir)/lua + @$(MKDIR_P) $(DESTDIR)$(rpmconfigdir)/include # XXX to appease distcheck we need to remove "stuff" here... uninstall-local: @@ -259,6 +260,7 @@ uninstall-local: @rm -f $(DESTDIR)$(rpmconfigdir)/macros @rm -rf $(DESTDIR)$(rpmconfigdir)/macros.d @rm -rf $(DESTDIR)$(rpmconfigdir)/lua + @rm -rf $(DESTDIR)$(rpmconfigdir)/include MAINTAINERCLEANFILES = ChangeLog diff --git a/build/parseSpec.c b/build/parseSpec.c index 70379115c1..a16bcda857 100644 --- a/build/parseSpec.c +++ b/build/parseSpec.c @@ -516,6 +516,7 @@ int readLine(rpmSpec spec, int strip) spec->line[0] = '\0'; } else if (spec->readStack->reading && (lineType->id == LINE_INCLUDE)) { char *fileName, *endFileName, *p; + char *sysinc = NULL; fileName = s+8; SKIPSPACE(fileName); @@ -533,7 +534,17 @@ int readLine(rpmSpec spec, int strip) } *endFileName = '\0'; + /* System includes live in a special path and become buildrequires */ + if (*fileName == '<' && *(endFileName-1) == '>') { + *(endFileName-1) = '\0'; + sysinc = rpmGetPath("%{_rpmincludedir}/", fileName + 1, NULL); + addReqProv(spec->sourcePackage, RPMTAG_REQUIRENAME, + sysinc, NULL, 0, 0); + fileName = sysinc; + } + ofi = pushOFI(spec, fileName, (spec->flags & RPMSPEC_FORCE)); + free(sysinc); goto retry; } diff --git a/macros.in b/macros.in index a15e46f261..dd626ad942 100644 --- a/macros.in +++ b/macros.in @@ -604,6 +604,7 @@ package or when debugging this package.\ # %__myattr_exclude_path exclude by path regex # %_fileattrsdir %{_rpmconfigdir}/fileattrs +%_rpmincludedir %{_rpmconfigdir}/include # This macro defines how much space (in bytes) in package should be # reserved for gpg signatures during building of a package. If this space is diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index 9d76725a3f..6fb420a4d0 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -107,6 +107,7 @@ echo "Describe me" > "${RPMTEST}/${dsc}" runroot rpmspec -q "/data/SPECS/notthere.spec" 2>&1; echo $? runroot rpmspec -q --define "incfile /not/there" "/data/SPECS/inctest.spec" 2>&1; echo $? runroot rpmspec -q --define "incfile ${dsc}" --qf "%{description}\n" "/data/SPECS/inctest.spec" 2>&1; echo $? +runroot rpmspec -q --define "%_rpmincludedir /usr/lib/rpm/include" --define "incfile " --buildrequires "/data/SPECS/inctest.spec" 2>&1; echo $? rm -f "${RPMTEST}/${dsc}" ], [0], @@ -118,6 +119,9 @@ inctest-1.0-1.noarch 0 Describe me 0 +warning: Unable to open /usr/lib/rpm/include/system.inc: No such file or directory +/usr/lib/rpm/include/system.inc +0 ], []) AT_CLEANUP