Hi Bruno,

Hopefully this patch should be better. Feel free to let me know if
there is anything I didn't address.

On 3/10/24 5:07 AM, Bruno Haible wrote:
> 1) This form of conditional expression
> 
>        base = self.config['destdir'] if self.config['destdir'] else '.'
> 
>    mentions first a value, then a condition, then another value.
>    It would be good to mention the condition first, like in C, Lisp, Java, 
> etc.
>    - even if that means that this needs 4 lines of code instead of 1 line.

Sure, thanks for updating the coding style. I've changed it to a more
normal:

        if self.config['destdir']:
            base = self.config['destdir']
        else:
            base = '.'

>    automake_options = { x
>                         for y in automake_options
>                         for x in y.split() }
> 
>    It is more readable this way.

Oops, I forgot about this convention. Fixed.

> 3) Method GLConfig.setAutomakeSubdir claims that
>    "automake_subdir must be a string"
>    but it should be bool.

I think I see what you mean. I updated the type check but forgot to
update the comment and message below it. Should be fixed now.

> 4) In GLEmiter.initmacro_end, you translated the condition
> 
>    if $automake_subdir && ! "$2" && test -n "$sourcebase" && test 
> "$sourcebase" != '.'; then
> 
>    to
> 
>    if automake_subdir and not gentests and sourcebase != '.':
> 
>    What about the case sourcebase == '' ? We don't want subdir to be '/' in 
> this case.
>    (Or can this not happen?)

Oops, for some reason my brain must have ignored the
'test -n "$sourcebase"'. I am not 100% sure of all the paths that
sourcebase can enter this function with. In any case, I think it is
best to add the check. After a call to GLConfig.resetSourceBase() it
may be '', and that is probably likely to occur.

I'm not the best with shell and always have to look up the different
test flags. I believe that this condition should work according to my
interpretation of 'test -n' [1]:

    if automake_subdir and not gentests and sourcebase and sourcebase != '.':

In this case the condition will fail if sourcebase is a string with a
length of zero. Comparing to '' feels strange to me, but let me know if
you prefer it.

> 5) GLEmiter.shellvars_init has no function comment. How about
> 
>    def shellvars_init(self, gentests: bool, base: str) -> str:
>        '''emits some shell variable assignments'''

I've added this along with a description of each parameter, mostly
copied from the regular gnulib-tool.

>    Also please don't omit the comments that describe what gl_source_base and
>    gl_source_base_prefix. Because these are really hard to grasp without a
>    comment.

I agree. I assume that you mean the ones that are written in the shell
script? I forgot to copy and paste those. I am still learning how
gnulib-tool works so it is a bit hard for me to add original comments
for these, sorry. For example, I just learned how --local-dir worked
with Coreutils usage of it. That option seems very useful and I'm a
bit surprised I just noticed it...

[1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html

Collin
From ef34572ca72ad1bb825dcae17b1472db63c779d3 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Sun, 10 Mar 2024 14:07:35 -0700
Subject: [PATCH] gnulib-tool.py: Follow gnulib-tool changes, part 51.

Follow gnulib-tool change
2021-12-15  Bruno Haible  <br...@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.
---
 ChangeLog             | 33 +++++++++++++++++++++++++++++++++
 gnulib-tool.py.TODO   | 28 ----------------------------
 pygnulib/GLConfig.py  | 29 ++++++++++++++++++++++++++---
 pygnulib/GLEmiter.py  | 43 +++++++++++++++++++++++++++++++++++++++----
 pygnulib/GLError.py   |  4 ++++
 pygnulib/GLImport.py  | 41 ++++++++++++++++++++++++++++++++++++++---
 pygnulib/GLInfo.py    |  5 ++++-
 pygnulib/GLTestDir.py | 14 +++++++-------
 pygnulib/main.py      | 11 +++++++++++
 9 files changed, 162 insertions(+), 46 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1832598970..d38d67342c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2024-03-10  Collin Funk  <collin.fu...@gmail.com>
+
+	gnulib-tool.py: Follow gnulib-tool changes, part 51.
+	Follow gnulib-tool change
+	2021-12-15  Bruno Haible  <br...@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.fu...@gmail.com>
 
 	gnulib-tool: Don't remove comments referencing @NMD@, part 2.
diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO
index eedb916ca9..51e6cd9e18 100644
--- a/gnulib-tool.py.TODO
+++ b/gnulib-tool.py.TODO
@@ -18,7 +18,6 @@ The following commits to gnulib-tool have not yet been reflected in
 Implement the options:
   --extract-recursive-dependencies
   --extract-recursive-link-directive
-  --automake-subdir
   -h | --hardlink
   --local-hardlink
   -S | --more-symlinks
@@ -317,33 +316,6 @@ Date:   Wed Dec 15 21:49:41 2021 +0100
 
 --------------------------------------------------------------------------------
 
-commit b2bd0a9041ed7401fb69f59f7450abb8b3249ecb
-Author: Bruno Haible <br...@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 <egg...@cs.ucla.edu>
 Date:   Mon Apr 26 23:31:29 2021 -0700
diff --git a/pygnulib/GLConfig.py b/pygnulib/GLConfig.py
index b0b59624b9..fea65803d9 100644
--- a/pygnulib/GLConfig.py
+++ b/pygnulib/GLConfig.py
@@ -57,7 +57,7 @@ class GLConfig(object):
                  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,
@@ -143,6 +143,10 @@ class GLConfig(object):
         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:
@@ -280,8 +284,8 @@ class GLConfig(object):
                 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
@@ -883,6 +887,25 @@ class GLConfig(object):
         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.
diff --git a/pygnulib/GLEmiter.py b/pygnulib/GLEmiter.py
index d4499df258..9a889fde5a 100644
--- a/pygnulib/GLEmiter.py
+++ b/pygnulib/GLEmiter.py
@@ -114,6 +114,27 @@ class GLEmiter(object):
 # 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,
@@ -524,18 +545,31 @@ USE_MSGCTXT = no\n"""
             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])[ ||
@@ -562,8 +596,8 @@ USE_MSGCTXT = no\n"""
       # 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])
@@ -571,6 +605,7 @@ USE_MSGCTXT = no\n"""
   ])
 '''
         emit = emit.replace('%V1%', macro_prefix_arg)
+        emit = emit.replace('%V2%', subdir)
         return emit
 
     def initmacro_done(self, macro_prefix_arg, sourcebase_arg):
diff --git a/pygnulib/GLError.py b/pygnulib/GLError.py
index 0fd1fcf3a1..4f46fbc994 100644
--- a/pygnulib/GLError.py
+++ b/pygnulib/GLError.py
@@ -62,6 +62,7 @@ class GLError(Exception):
          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
@@ -112,5 +113,8 @@ class GLError(Exception):
                 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
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 9ba2775425..8864bfd7c0 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -42,6 +42,7 @@ __copyright__ = constants.__copyright__
 #===============================================================================
 # Define global constants
 #===============================================================================
+APP = constants.APP
 DIRS = constants.DIRS
 MODES = constants.MODES
 TESTS = constants.TESTS
@@ -162,6 +163,9 @@ class GLImport(object):
             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, '')
@@ -255,6 +259,25 @@ class GLImport(object):
                     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)
@@ -367,6 +390,7 @@ class GLImport(object):
         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()
@@ -418,8 +442,9 @@ class GLImport(object):
             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'
@@ -496,6 +521,7 @@ class GLImport(object):
         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']
@@ -551,6 +577,8 @@ class GLImport(object):
         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:
@@ -673,6 +701,7 @@ AC_DEFUN([%s_INIT],
             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
@@ -682,10 +711,11 @@ AC_DEFUN([%s_INIT],
         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
@@ -703,7 +733,7 @@ AC_DEFUN([%s_INIT],
         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:
@@ -1004,6 +1034,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         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']
@@ -1148,6 +1179,10 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % 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)
diff --git a/pygnulib/GLInfo.py b/pygnulib/GLInfo.py
index 4d5d621e91..11fdfa60e6 100644
--- a/pygnulib/GLInfo.py
+++ b/pygnulib/GLInfo.py
@@ -282,7 +282,10 @@ Options for --import, --add/remove-import:
                             \"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
diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py
index b294dbd58b..f747a480f5 100644
--- a/pygnulib/GLTestDir.py
+++ b/pygnulib/GLTestDir.py
@@ -489,15 +489,15 @@ class GLTestDir(object):
                 # 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.
@@ -606,19 +606,19 @@ class GLTestDir(object):
             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
@@ -629,7 +629,7 @@ class GLTestDir(object):
                                                      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:
diff --git a/pygnulib/main.py b/pygnulib/main.py
index 97ff76957a..7f710a2079 100644
--- a/pygnulib/main.py
+++ b/pygnulib/main.py
@@ -393,6 +393,11 @@ def main():
                         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',
@@ -615,6 +620,7 @@ def main():
                  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']
@@ -712,6 +718,7 @@ def main():
     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]
@@ -751,6 +758,7 @@ def main():
         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,
@@ -1277,6 +1285,9 @@ if __name__ == '__main__':
                 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)
-- 
2.44.0

Reply via email to