Paul Eggert wrote: > > What was the immediate problem that you had with this module? > > I was testing all modules that depend on c99, this way: > > ./gnulib-tool -h --create-testdir --dir foo $(cd modules && grep -lx > 'c99' $(git ls-files)) > cd foo > ./configure > make > > The last command fails as follows on Fedora 40 x86-64 when building > Gnullib commit 56a8b46608f60d33cc4026875e8a52b1bf8a2e16: > > ... > gcc -DHAVE_CONFIG_H -I. -I.. -DGNULIB_STRICT_CHECKING=1 -g -O2 -MT > timevar.o -MD -MP -MF $depbase.Tpo -c -o timevar.o timevar.c && mv -f > $depbase.Tpo $depbase.Po > In file included from timevar.c:24: > timevar.h:80:10: fatal error: timevar.def: No such file or directory > 80 | #include "timevar.def" > | ^~~~~~~~~~~~~ > compilation terminated. > make[4]: *** [Makefile:4705: timevar.o] Error 1
Collin Funk wrote: > Perhaps there should be an extra status for test modules that should > generally be excluded. I was thinking in the same direction. The 'Status' is already taken (it is 'deprecated' for some of the relevant modules). Therefore, I'm adding a new piece of meta-information. With it, Paul's --create-testdir command will filter out the 'timevar' module and give a warning: gnulib-tool: warning: module timevar cannot be used in a testdir With that in place, let's go back to the timevar module without a stub timevar.def file, so that it can be used in packages, like before. 2024-07-28 Bruno Haible <br...@clisp.org> gnulib-tool.py: Avoid adding specific modules to a testdir. Reported by Paul Eggert in <https://lists.gnu.org/archive/html/bug-gnulib/2024-07/msg00292.html>. * pygnulib/GLInfo.py (GLInfo.usage): Document --extract-usability-in-testdir option. * pygnulib/GLModuleSystem.py (GLModule.section_label_pattern): Recognize Usable-in-testdir section. (GLModule.getUsabilityInTestdir): New function. * pygnulib/GLTestDir.py (GLTestDir.execute): Invoke it to filter out modules to avoid. Warn if such a module was specified. * pygnulib/main.py (main): Add support for --extract-usability-in-testdir. Provide an error message for error 24. * pygnulib/GLError.py: Likewise. * modules/config-h (Usable-in-testdir): New section. * modules/lib-ignore (Usable-in-testdir): New section. * modules/mountlist (Usable-in-testdir): New section. * modules/non-recursive-gnulib-prefix-hack (Usable-in-testdir): New section. * modules/timevar (Usable-in-testdir): New section. (Files): Remove lib/timevar.def. diff --git a/modules/config-h b/modules/config-h index 0af7c3e2bb..0d21277525 100644 --- a/modules/config-h +++ b/modules/config-h @@ -1,6 +1,10 @@ Description: Assume config.h exists, to avoid -DHAVE_CONFIG_H clutter in 'make' output. +Usable-in-testdir: +# This module breaks all modules which use HAVE_CONFIG_H. +no + Files: m4/config-h.m4 diff --git a/modules/lib-ignore b/modules/lib-ignore index 8fe1c328c1..0c3d5e6922 100644 --- a/modules/lib-ignore +++ b/modules/lib-ignore @@ -1,6 +1,10 @@ Description: If possible, ignore libraries that are not depended on. +Usable-in-testdir: +# This module leads to link errors when Sun C++ is used. FIXME +no + Files: m4/lib-ignore.m4 diff --git a/modules/mountlist b/modules/mountlist index f61038ec15..99d9073151 100644 --- a/modules/mountlist +++ b/modules/mountlist @@ -1,6 +1,10 @@ Description: Return list of mounted file systems. +Usable-in-testdir: +# This module aborts the configuration on mingw. FIXME +no + Files: lib/mountlist.h lib/mountlist.c diff --git a/modules/non-recursive-gnulib-prefix-hack b/modules/non-recursive-gnulib-prefix-hack index c188e93f4e..4925bb99ad 100644 --- a/modules/non-recursive-gnulib-prefix-hack +++ b/modules/non-recursive-gnulib-prefix-hack @@ -11,6 +11,10 @@ This module is deprecated. Instead, - remove the explicit invocation of build-aux/prefix-gnulib-mk from your build system. +Usable-in-testdir: +# This module represents a nonstandard way of using Automake. +no + Files: build-aux/prefix-gnulib-mk m4/non-recursive-gnulib-prefix-hack.m4 diff --git a/modules/timevar b/modules/timevar index a460a08de8..5f911cd27b 100644 --- a/modules/timevar +++ b/modules/timevar @@ -1,10 +1,13 @@ Description: A simple self-profiling module based on timers. +Usable-in-testdir: +# This module lacks the required file timevar.def. +no + Files: lib/timevar.h lib/timevar.c -lib/timevar.def Depends-on: c99 diff --git a/pygnulib/GLError.py b/pygnulib/GLError.py index 15e24a8bf2..e57a50301f 100644 --- a/pygnulib/GLError.py +++ b/pygnulib/GLError.py @@ -57,6 +57,7 @@ def __init__(self, errno: int, errinfo: Any = None) -> None: 21: Option --automake-subdir is only supported if the definition of AUTOMAKE_OPTIONS in Makefile.am contains 'subdir-objects'. 22: not overwriting destination directory: <directory> 23: module <module> doesn't exist + 24: module <module> cannot be used in a testdir errinfo: additional information''' self.errno = errno self.errinfo = errinfo @@ -113,5 +114,7 @@ def __repr__(self) -> str: message = 'not overwriting destination directory: %s' % repr(errinfo) elif errno == 23: message = "module %s doesn't exist" % repr(errinfo) + elif errno == 24: + message = 'module %s cannot be used in a testdir' % repr(errinfo) self.message = '[Errno %d] %s' % (errno, message) return self.message diff --git a/pygnulib/GLInfo.py b/pygnulib/GLInfo.py index eac4c65071..9ed3ea61d4 100644 --- a/pygnulib/GLInfo.py +++ b/pygnulib/GLInfo.py @@ -130,6 +130,7 @@ def usage(self) -> str: gnulib-tool --extract-status module gnulib-tool --extract-notice module gnulib-tool --extract-applicability module + gnulib-tool --extract-usability-in-testdir module gnulib-tool --extract-filelist module gnulib-tool --extract-dependencies module gnulib-tool --extract-recursive-dependencies module @@ -168,6 +169,7 @@ def usage(self) -> str: --extract-status extract the status (obsolete etc.) --extract-notice extract the notice or banner --extract-applicability extract the applicability + --extract-usability-in-testdir extract the usability in testdirs --extract-filelist extract the list of files --extract-dependencies extract the dependencies --extract-recursive-dependencies extract the dependencies of the module diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py index 0eb875a499..248d9ec800 100644 --- a/pygnulib/GLModuleSystem.py +++ b/pygnulib/GLModuleSystem.py @@ -176,7 +176,7 @@ class GLModule: # Regular expression matching the start of a section in the module description. section_label_pattern: ClassVar[re.Pattern] = \ - re.compile(r'^(Description|Comment|Status|Notice|Applicability|' + re.compile(r'^(Description|Comment|Status|Notice|Applicability|Usable-in-testdir|' + r'Files|Depends-on|configure\.ac-early|configure\.ac|' + r'Makefile\.am|Include|Link|License|Maintainer):$', re.M) @@ -459,6 +459,17 @@ def getApplicability(self) -> str: self.cache['applicability'] = result return self.cache['applicability'] + def getUsabilityInTestdir(self) -> str: + '''Return the usability-in-testdir of module.''' + if 'usability-in-testdir' not in self.cache: + snippet = self.sections.get('Usable-in-testdir', '') + result = [ line.strip() + for line in snippet.split('\n') + if not line.startswith('#') and line.strip() ] + result = lines_to_multiline(result).strip() + self.cache['usability-in-testdir'] = result + return self.cache['usability-in-testdir'] + def getFiles_Raw(self) -> str: '''Return the unmodified list of files as a string.''' return self.sections.get('Files', '') diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py index ad4549f734..ecedf992c6 100644 --- a/pygnulib/GLTestDir.py +++ b/pygnulib/GLTestDir.py @@ -145,25 +145,26 @@ def execute(self) -> None: specified_modules = self.config['modules'] if len(specified_modules) == 0: - # All modules together. - # Except config-h, which breaks all modules which use HAVE_CONFIG_H. - # Except non-recursive-gnulib-prefix-hack, which represents a nonstandard - # way of using Automake. - # Except timevar, which lacks the required file timevar.def. - # Except mountlist, which aborts the configuration on mingw. FIXME. - # Except lib-ignore, which leads to link errors when Sun C++ is used. FIXME. + # All modules together, except those that are not usable in a testdir. specified_modules = self.modulesystem.list() - specified_modules = [module - for module in specified_modules - if module not in ['config-h', 'non-recursive-gnulib-prefix-hack', 'timevar', - 'mountlist', 'lib-ignore']] + specified_modules = [ module_name + for module_name in specified_modules + if self.modulesystem.find(module_name) is not None \ + and self.modulesystem.find(module_name).getUsabilityInTestdir() != 'no' ] # Canonicalize the list of specified modules. modules = set() - for name in specified_modules: - module = self.modulesystem.find(name) + for module_name in specified_modules: + module = self.modulesystem.find(module_name) if module is not None: - modules.add(module) + if module.getUsabilityInTestdir() == 'no': + if self.config['errors']: + raise GLError(24, module_name) + else: # if not self.config['errors'] + sys.stderr.write('gnulib-tool: warning: ') + sys.stderr.write('module %s cannot be used in a testdir\n' % module_name) + else: + modules.add(module) specified_modules = sorted(modules) # Test modules which invoke AC_CONFIG_FILES cannot be used with diff --git a/pygnulib/main.py b/pygnulib/main.py index 9767f38676..6953a84917 100644 --- a/pygnulib/main.py +++ b/pygnulib/main.py @@ -197,6 +197,10 @@ def main(temp_directory: str) -> None: dest='mode_xapplicability', default=None, action='store_true') + parser.add_argument('--extract-usability-in-testdir', + dest='mode_xusability_in_testdir', + default=None, + action='store_true') parser.add_argument('--extract-filelist', dest='mode_xfilelist', default=None, @@ -551,6 +555,7 @@ def main(temp_directory: str) -> None: cmdargs.mode_xstatus, cmdargs.mode_xnotice, cmdargs.mode_xapplicability, + cmdargs.mode_xusability_in_testdir, cmdargs.mode_xfilelist, cmdargs.mode_xdependencies, cmdargs.mode_xautoconf, @@ -625,6 +630,9 @@ def main(temp_directory: str) -> None: if cmdargs.mode_xapplicability != None: mode = 'extract-applicability' modules = list(cmdargs.non_option_arguments) + if cmdargs.mode_xusability_in_testdir != None: + mode = 'extract-usability-in-testdir' + modules = list(cmdargs.non_option_arguments) if cmdargs.mode_xfilelist != None: mode = 'extract-filelist' modules = list(cmdargs.non_option_arguments) @@ -1189,6 +1197,13 @@ def main(temp_directory: str) -> None: if module: print(module.getApplicability()) + elif mode == 'extract-usability-in-testdir': + modulesystem = GLModuleSystem(config) + for name in modules: + module = modulesystem.find(name) + if module: + print(module.getUsabilityInTestdir()) + elif mode == 'extract-filelist': modulesystem = GLModuleSystem(config) for name in modules: @@ -1459,6 +1474,8 @@ def main_with_exception_handling() -> None: message += 'not overwriting destination directory: %s' % errinfo elif errno == 23: message += "module %s doesn't exist" % errinfo + elif errno == 24: + message += 'module %s cannot be used in a testdir' % errinfo message += '\n%s: *** Stop.\n' % APP['name'] sys.stderr.write(message) sys.exit(1)