+2024-03-10 Collin Funk <collin.funk1@gmail.com>
+
+ gnulib-tool.py: Follow gnulib-tool changes, part 51.
+ Follow gnulib-tool change
+ 2021-12-15 Bruno Haible <bruno@clisp.org>
+ Accommodate non-recursive Automake in a less hacky way.
+ * pygnulib/GLConfig.py (GLConfig.__init__): Add 'automake_subdir' to the
+ parameter list.
+ (GLConfig.default): Set the default value of automake_subdir to a
+ boolean False.
+ (GLConfig.getAutomakeSubdir, GLConfig.setAutomakeSubdir)
+ (GLConfig.resetAutomakeSubdir): New functions to access and manipulate
+ the automake_subdir option.
+ * pygnulib/GLEmiter.py (GLEmiter.shellvars_init): New function.
+ (GLEmiter.initmacro_end): Add second parameter 'gentests'. Use it to prefix each
+ object file name in *_LIBOBJS and *_LTLIBOBJS.
+ * pygnulib/GLError.py (GLError.__init__, GLError.__repr__): Add new
+ error for if --automake-subdir is used without the 'subdir-objects'
+ Automake option.
+ * pygnulib/GLImport.py (GLImport.__init__): Check for 'subdir-objects'
+ in Makefile.am.
+ (GLImport.actioncmd): Emit --automake-subdir in actioncmd.
+ (GLImport.gnulib_cache): Add gl_AUTOMAKE_SUBDIR to gnulib-cache.m4 if
+ --automake-subdir is used.
+ (GLImport.gnulib_comp): Update calls to GLEmiter.initmacro_end. Call
+ GLEmiter.shellvars_init.
+ (GLImport.execute): Likewise. Use the build-aux/prefix-gnulib-mk script.
+ * pygnulib/GLInfo.py (GLInfo.usage): Add --automake-subdir to the usage
+ message.
+ * pygnulib/GLTestDir.py (GLTestDir.execute): Update calls to
+ GLEmiter.initmacro_end. Call GLEmiter.shellvars_init.
+ * pygnulib/main.py (main): Add support for --automake-subdir.
+
2024-03-10 Collin Funk <collin.funk1@gmail.com>
gnulib-tool: Don't remove comments referencing @NMD@, part 2.
Implement the options:
--extract-recursive-dependencies
--extract-recursive-link-directive
- --automake-subdir
-h | --hardlink
--local-hardlink
-S | --more-symlinks
--------------------------------------------------------------------------------
-commit b2bd0a9041ed7401fb69f59f7450abb8b3249ecb
-Author: Bruno Haible <bruno@clisp.org>
-Date: Wed Dec 15 19:18:31 2021 +0100
-
- Accommodate non-recursive Automake in a less hacky way.
-
- * gnulib-tool: New option --automake-subdir.
- (automake_subdir): New variable.
- (func_emit_initmacro_end): Add a second argument. Use it to prefix each
- object file name in *_LIBOBJS and *_LTLIBOBJS.
- (func_emit_shellvars_init): New function.
- (func_import): Add support for --automake-subdir. Invoke
- prefix-gnulib-mk. Update calls to func_emit_initmacro_end. Call
- func_emit_shellvars_init.
- (func_create_testdir): Update calls to func_emit_initmacro_end. Call
- func_emit_shellvars_init.
- * m4/gnulib-tool.m4 (gl_AUTOMAKE_SUBDIR): New macro.
- * m4/gnulib-common.m4 (gl_CONDITIONAL_HEADER): Use the value of the
- gl_source_base_prefix variable.
- * build-aux/prefix-gnulib-mk: New options --from-gnulib-tool, --prefix.
- (contents_of_file): Renamed from contents.
- (contents_of_stdin): New function.
- (process): Inline and remove function.
- * doc/gnulib-tool.texi (Non-recursive make): New section.
-
---------------------------------------------------------------------------------
-
commit 4b071c115309079528db7b60e8d2ffb22b129088
Author: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon Apr 26 23:31:29 2021 -0700
modules=None, avoids=None, files=None,
incl_test_categories=None, excl_test_categories=None, libname=None,
lgpl=None, gnu_make=None, makefile_name=None, tests_makefile_name=None,
- libtool=None, conddeps=None, macro_prefix=None,
+ automake_subdir=None, libtool=None, conddeps=None, macro_prefix=None,
podomain=None, witness_c_macro=None, vc_files=None, symbolic=None,
lsymbolic=None, configure_ac=None, ac_version=None,
libtests=None, single_configure=None, verbose=None, dryrun=None,
self.resetTestsMakefileName()
if tests_makefile_name != None:
self.setTestsMakefileName(tests_makefile_name)
+ # automake-subdir
+ self.resetAutomakeSubdir()
+ if automake_subdir != None:
+ self.setAutomakeSubdir(automake_subdir)
# libtool
self.resetLibtool()
if libtool != None:
return 0
elif key in ['modules', 'avoids', 'tests', 'incl_test_categories', 'excl_test_categories']:
return list()
- elif key in ['libtool', 'lgpl', 'gnu_make', 'conddeps', 'symbolic', 'lsymbolic',
- 'libtests', 'dryrun']:
+ elif key in ['libtool', 'lgpl', 'gnu_make', 'automake_subdir', 'conddeps', 'symbolic',
+ 'lsymbolic', 'libtests', 'dryrun']:
return False
elif key == 'vc_files':
return None
Default is the value of 'makefile_name'.'''
self.table['tests_makefile_name'] = ''
+ # Define automake_subdir methods.
+ def getAutomakeSubdir(self) -> bool:
+ '''Return a bool describing whether --automake-subdir is in use
+ or not.'''
+ return self.table['automake_subdir']
+
+ def setAutomakeSubdir(self, automake_subdir: bool) -> None:
+ '''Set the value describing whether --automake-subdir is in use.'''
+ if type(automake_subdir) is bool:
+ self.table['automake_subdir'] = automake_subdir
+ else: # if type of automake_subdir is not bool
+ raise TypeError('automake_subdir must be a bool, not %s'
+ % type(automake_subdir).__name__)
+
+ def resetAutomakeSubdir(self) -> None:
+ '''Set the value describing whether --automake-subdir is in use.
+ Default is False.'''
+ self.table['automake_subdir'] = False
+
# Define podomain methods.
def getPoDomain(self):
'''Return the prefix of the i18n domain. Usually use the package name.
# Generated by gnulib-tool.\n"""
return emit
+ def shellvars_init(self, gentests: bool, base: str) -> str:
+ '''Emits some shell variable assignments.
+
+ gentests is a bool that is True if a tests Makefile.am is being
+ generated, False otherwise.
+ base is a string representing the base directory relative to the
+ top-level directory.'''
+ if type(gentests) is not bool:
+ raise TypeError(f'gentests must be a bool, not {type(gentests).__name__}')
+ if type(base) is not str:
+ raise TypeError(f'base must be a str, not {type(base).__name__}')
+ automake_subdir = self.config['automake_subdir']
+ # Define the base directory, relative to the top-level directory.
+ emit = f' gl_source_base=\'{base}\'\n'
+ # Define the prefix for the file name of generated files.
+ if automake_subdir and not gentests:
+ emit += f' gl_source_base_prefix=\'$(top_build_prefix){base}/\'\n'
+ else:
+ emit += ' gl_source_base_prefix=\n'
+ return emit
+
def autoconfSnippet(self, module, toplevel,
disable_libtool, disable_gettext, replace_auxdir, indentation):
'''GLEmiter.autoconfSnippet(module, toplevel,
emit += ' AC_REQUIRE([gl_CXX_ALLOW_WARNINGS])\n'
return emit
- def initmacro_end(self, macro_prefix_arg):
+ def initmacro_end(self, macro_prefix_arg, gentests):
'''GLEmiter.initmacro_end(macro_prefix_arg) -> str
- Emit the last few statements of the gl_INIT macro.'''
+ Emit the last few statements of the gl_INIT macro.
+
+ macro_prefix_arg is the prefix of gl_EARLY, gl_INIT macros to use.
+ gentests is a bool that is True if a tests Makefile.am is being
+ generated, False otherwise.'''
if type(macro_prefix_arg) is not str:
raise TypeError('macro_prefix_arg must be a string, not %s'
% type(macro_prefix_arg).__name__)
+ if type(gentests) is not bool:
+ raise TypeError('gentests must be a bool, not %s'
+ % type(gentests).__name__)
+ sourcebase = self.config['sourcebase']
+ automake_subdir = self.config['automake_subdir']
emit = ''
# Check the presence of files that are mentioned as AC_LIBSOURCES
# arguments. The check is performed only when autoconf is run from the
# directory where the configure.ac resides; if it is run from a different
# directory, the check is skipped.
+ if automake_subdir and not gentests and sourcebase and sourcebase != '.':
+ subdir = f'{sourcebase}/'
+ else:
+ subdir = ''
emit += r'''
m4_ifval(%V1%_LIBSOURCES_LIST, [
m4_syscmd([test ! -d ]m4_defn([%V1%_LIBSOURCES_DIR])[ ||
# Remove the extension.
sed_drop_objext='s/\.o$//;s/\.obj$//'
for i in `for i in $%V1%_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
- %V1%_libobjs="$%V1%_libobjs $i.$ac_objext"
- %V1%_ltlibobjs="$%V1%_ltlibobjs $i.lo"
+ %V1%_libobjs="$%V1%_libobjs %V2%$i.$ac_objext"
+ %V1%_ltlibobjs="$%V1%_ltlibobjs %V2%$i.lo"
done
fi
AC_SUBST([%V1%_LIBOBJS], [$%V1%_libobjs])
])
'''
emit = emit.replace('%V1%', macro_prefix_arg)
+ emit = emit.replace('%V2%', subdir)
return emit
def initmacro_done(self, macro_prefix_arg, sourcebase_arg):
18: module lacks a license: <module>
19: could not create destination directory: <directory>
20: could not patch test-driver script
+ 21: Option --automake-subdir is only supported if the definition of AUTOMAKE_OPTIONS in Makefile.am contains 'subdir-objects'.
errinfo: additional information'''
self.errno = errno
self.errinfo = errinfo
message = "error when running subprocess: %s" % repr(errinfo)
elif errno == 20:
message = 'could not patch test-driver script'
+ elif errno == 21:
+ message = ('Option --automake-subdir is only supported if the definition of AUTOMAKE_OPTIONS '
+ 'in Makefile.am contains \'subdir-objects\'.')
self.message = '[Errno %d] %s' % (errno, message)
return self.message
#===============================================================================
# Define global constants
#===============================================================================
+APP = constants.APP
DIRS = constants.DIRS
MODES = constants.MODES
TESTS = constants.TESTS
if 'gl_WITH_ALL_TESTS' in data:
self.cache.enableInclTestCategory(TESTS['all-test'])
data = data.replace('gl_WITH_ALL_TESTS', '')
+ if 'gl_AUTOMAKE_SUBDIR' in data:
+ self.cache.setAutomakeSubdir(True)
+ data = data.replace('gl_AUTOMAKE_SUBDIR', '')
# Find string values
result = dict(pattern.findall(data))
values = cleaner([ result.get(key, '')
self.config.update_key(config, key)
self.config.setModules(modules)
+ if self.config['automake_subdir']:
+ found_subdir_objects = False
+ if self.config['destdir']:
+ base = self.config['destdir']
+ else:
+ base = '.'
+ if isfile(joinpath(base, 'Makefile.am')):
+ pattern = re.compile(r'^AUTOMAKE_OPTIONS[\t| ]*=(.*)$', re.MULTILINE)
+ with open(joinpath(base, 'Makefile.am'), encoding='utf-8') as file:
+ data = file.read()
+ automake_options = pattern.findall(data)
+ if automake_options:
+ automake_options = { x
+ for y in automake_options
+ for x in y.split() }
+ found_subdir_objects = 'subdir-objects' in automake_options
+ if not found_subdir_objects:
+ raise GLError(21, None)
+
# Define GLImport attributes.
self.emitter = GLEmiter(self.config)
self.filesystem = GLFileSystem(self.config)
gnu_make = self.config.getGnuMake()
makefile_name = self.config.getMakefileName()
tests_makefile_name = self.config.getTestsMakefileName()
+ automake_subdir = self.config.getAutomakeSubdir()
libtool = self.config.checkLibtool()
macro_prefix = self.config.getMacroPrefix()
witness_c_macro = self.config.getWitnessCMacro()
actioncmd += ' \\\n# --makefile-name=%s' % makefile_name
if tests_makefile_name:
actioncmd += ' \\\n# --tests-makefile-name=%s' % tests_makefile_name
+ if automake_subdir:
+ actioncmd += ' \\\n# --automake-subdir'
# FIXME: Add the following options in this order when implemented.
- # --automake-subdir
# --automake-subdir-tests
if conddeps:
actioncmd += ' \\\n# --conditional-dependencies'
libname = self.config['libname']
makefile_name = self.config['makefile_name']
tests_makefile_name = self.config['tests_makefile_name']
+ automake_subdir = self.config['automake_subdir']
conddeps = self.config['conddeps']
libtool = self.config['libtool']
macro_prefix = self.config['macro_prefix']
emit += 'gl_MAKEFILE_NAME([%s])\n' % makefile_name
if tests_makefile_name:
emit += 'gl_TESTS_MAKEFILE_NAME([%s])\n' % tests_makefile_name
+ if automake_subdir:
+ emit += 'gl_AUTOMAKE_SUBDIR\n'
if conddeps:
emit += 'gl_CONDITIONAL_DEPENDENCIES\n'
if libtool:
replace_auxdir = True
emit += ' gl_m4_base=\'%s\'\n' % m4base
emit += self.emitter.initmacro_start(macro_prefix, False)
+ emit += self.emitter.shellvars_init(False, sourcebase)
emit += ' gl_source_base=\'%s\'\n' % sourcebase
if witness_c_macro:
emit += ' m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [%s])\n' % witness_c_macro
if witness_c_macro:
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
emit += ' # End of code from modules\n'
- emit += self.emitter.initmacro_end(macro_prefix)
+ emit += self.emitter.initmacro_end(macro_prefix, False)
emit += ' gltests_libdeps=\n'
emit += ' gltests_ltlibdeps=\n'
emit += self.emitter.initmacro_start('%stests' % macro_prefix, gentests)
+ emit += self.emitter.shellvars_init(True, testsbase)
emit += ' gl_source_base=\'%s\'\n' % testsbase
# Define a tests witness macro that depends on the package.
# PACKAGE is defined by AM_INIT_AUTOMAKE, PACKAGE_TARNAME is defined by
emit += self.emitter.autoconfSnippets(moduletable['tests'], moduletable['main'] + moduletable['tests'],
moduletable, 0, True, True, True, replace_auxdir)
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
- emit += self.emitter.initmacro_end('%stests' % macro_prefix)
+ emit += self.emitter.initmacro_end('%stests' % macro_prefix, gentests)
# _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
# created using libtool, because libtool already handles the dependencies.
if not libtool:
libname = self.config['libname']
makefile_name = self.config['makefile_name']
tests_makefile_name = self.config['tests_makefile_name']
+ automake_subdir = self.config['automake_subdir']
conddeps = self.config['conddeps']
libtool = self.config['libtool']
macro_prefix = self.config['macro_prefix']
emit, uses_subdirs = self.emitter.lib_Makefile_am(basename,
self.moduletable['main'], self.moduletable, self.makefiletable,
actioncmd, for_test)
+ if automake_subdir:
+ emit = sp.run([joinpath(APP['root'], 'build-aux/prefix-gnulib-mk'), '--from-gnulib-tool',
+ f'--lib-name={libname}', f'--prefix={sourcebase}/'],
+ input=emit, text=True, capture_output=True).stdout
with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
file.write(emit)
filename, backup, flag = self.assistant.super_update(basename, tmpfile)
\"Makefile.in\" if --gnu-make).
--tests-makefile-name=NAME
Name of makefile in the tests-base directory
- (default as specified through --makefile-name)
+ (default as specified through --makefile-name).
+ --automake-subdir Specify that the makefile in the source-base
+ directory be generated in such a way that it can
+ be 'include'd from the toplevel Makefile.am.
--macro-prefix=PREFIX Specify the prefix of the macros 'gl_EARLY' and
'gl_INIT'. Default is 'gl'.
--po-domain=NAME Specify the prefix of the i18n domain. Usually use
# We don't have explicit ordering constraints between the various
# autoconf snippets. It's cleanest to put those of the library before
# those of the tests.
- emit += "gl_source_base='../%s'\n" % sourcebase
+ emit += self.emitter.shellvars_init(True, f'../{sourcebase}')
emit += self.emitter.autoconfSnippets(modules, modules,
moduletable, 1, False, False, False,
replace_auxdir)
- emit += "gl_source_base='.'"
+ emit += self.emitter.shellvars_init(True, '.')
emit += self.emitter.autoconfSnippets(modules, modules,
moduletable, 2, False, False, False,
replace_auxdir)
- emit += self.emitter.initmacro_end(macro_prefix)
+ emit += self.emitter.initmacro_end(macro_prefix, True)
# _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
# created using libtool, because libtool already handles the
# dependencies.
replace_auxdir = False
emit += 'gl_m4_base=\'%s\'\n' % m4base
emit += self.emitter.initmacro_start(macro_prefix, False)
- emit += 'gl_source_base=\'%s\'\n' % sourcebase
+ emit += self.emitter.shellvars_init(False, sourcebase)
if single_configure:
emit += self.emitter.autoconfSnippets(main_modules, main_modules, moduletable,
0, False, False, False, replace_auxdir)
else: # if not single_configure
emit += self.emitter.autoconfSnippets(modules, modules, moduletable,
1, False, False, False, replace_auxdir)
- emit += self.emitter.initmacro_end(macro_prefix)
+ emit += self.emitter.initmacro_end(macro_prefix, False)
if single_configure:
emit += ' gltests_libdeps=\n'
emit += ' gltests_ltlibdeps=\n'
emit += self.emitter.initmacro_start('%stests' % macro_prefix, True)
- emit += ' gl_source_base=\'%s\'\n' % testsbase
+ emit += self.emitter.shellvars_init(True, testsbase)
# Define a tests witness macro.
emit += ' %stests_WITNESS=IN_GNULIB_TESTS\n' % macro_prefix
emit += ' AC_SUBST([%stests_WITNESS])\n' % macro_prefix
moduletable, 1, True, False, False, replace_auxdir)
emit += snippets.strip()
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
- emit += self.emitter.initmacro_end('%stests' % macro_prefix)
+ emit += self.emitter.initmacro_end('%stests' % macro_prefix, True)
# _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
# created using libtool, because libtool already handles the dependencies.
if not libtool:
dest='tests_makefile_name',
default=None,
nargs=1)
+ # automake-subdir
+ parser.add_argument('--automake-subdir',
+ dest='automake_subdir',
+ default=None,
+ action='store_true')
# macro-prefix
parser.add_argument('--macro-prefix',
dest='macro_prefix',
or cmdargs.avoids != None or cmdargs.lgpl != None
or cmdargs.makefile_name != None
or cmdargs.tests_makefile_name != None
+ or cmdargs.automake_subdir != None
or cmdargs.macro_prefix != None or cmdargs.podomain != None
or cmdargs.witness_c_macro != None or cmdargs.vc_files != None))):
message = '%s: *** ' % constants.APP['name']
tests_makefile_name = cmdargs.tests_makefile_name
if tests_makefile_name != None:
tests_makefile_name = tests_makefile_name[0]
+ automake_subdir = cmdargs.automake_subdir == True
macro_prefix = cmdargs.macro_prefix
if macro_prefix != None:
macro_prefix = macro_prefix[0]
gnu_make=gnu_make,
makefile_name=makefile_name,
tests_makefile_name=tests_makefile_name,
+ automake_subdir=automake_subdir,
libtool=libtool,
conddeps=cond_dependencies,
macro_prefix=macro_prefix,
message += 'could not create destination directory: %s' % errinfo
elif errno == 20:
message += 'could not patch test-driver script'
+ elif errno == 21:
+ message = ('Option --automake-subdir is only supported if the definition of AUTOMAKE_OPTIONS '
+ 'in Makefile.am contains \'subdir-objects\'.')
message += '\n%s: *** Stop.\n' % constants.APP['name']
sys.stderr.write(message)
sys.exit(1)