Hi Bruno,
On 3/19/24 2:23 AM, Bruno Haible wrote:
> One point needs attention, still: In gnulib-tool.sh the code looks at
> configure.ac and, if that does not exist, at configure.in:
>
> # Prefer configure.ac to configure.in.
> if test -f "$destdir"/configure.ac; then
> configure_ac="$destdir/configure.ac"
> else
> if test -f "$destdir"/configure.in; then
> configure_ac="$destdir/configure.in"
> else
> func_fatal_error "cannot find $destdir/configure.ac - make sure you
> run gnulib-tool from within your package's directory"
> fi
> fi
>
> Whereas in main.py configure.in is not looked at:
>
> # Analyze configure.ac.
> with open(joinpath(destdir, 'configure.ac'), 'r', encoding='utf-8')
> as file:
> configure_ac_data = file.read()
Sorry it took me a while to get around to doing this. I got caught up
fixing the other issues. In many of the test cases:
$ diff -u ./test-oath-toolkit-5.result/pskctool/gl/m4/gnulib-comp.m4
tmp101056-result/pskctool/gl/m4/gnulib-comp.m4
--- ./test-oath-toolkit-5.result/pskctool/gl/m4/gnulib-comp.m4 2024-03-24
03:30:48.602074864 -0700
+++ tmp101056-result/pskctool/gl/m4/gnulib-comp.m4 2024-03-25
18:21:57.480903863 -0700
@@ -28,7 +28,7 @@
# other built files.
-# This macro should be invoked from ./configure.ac, in the section
+# This macro should be invoked from configure.ac, in the section
# "Checks for programs", right after AC_PROG_CC, and certainly before
# any checks for libraries, header files, types and library functions.
AC_DEFUN([gl_EARLY],
@@ -122,7 +122,7 @@
# Code from module xalloc-oversized:
])
-# This macro should be invoked from ./configure.ac, in the section
+# This macro should be invoked from configure.ac, in the section
# "Check for header files, types and library functions".
AC_DEFUN([gl_INIT],
[
This could be solved by joinpath -> os.path.join, but I felt it was a
good time to fix the configure.ac/configure.in issue. Kill two birds
with one stone.
I've also moved the AC_CONFIG_AUX_DIR, A[CM]_PROG_LIBTOOL,
AC_CONFIG_MACRO_DIR, and AC_CONFIG_MACRO_DIRS to main.py, with some
necessary renaming/reordering.
For testing I just created a testdir and put the 'subdir-objects' in
configure.ac and then moved it to Makefile.am. That should be enough
to make sure I didn't accidentally add any unbound variables or
anything.
I'm not sure if you want to add a test case which uses configure.in.
Maybe just checking on clisp or something would be enough?
Collin
From ee1f493fb1c364c232b8d1e0aab194c1cf5dc347 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Mon, 25 Mar 2024 16:49:58 -0700
Subject: [PATCH] gnulib-tool.py: Only process configure.ac once.
* pygnulib/GLConfig.py (GLConfig.setAutoconfFile): Don't combine the
path with destdir, accept it as given.
* pygnulib/GLImport.py (GLImport.__init__): Don't check
AC_CONFIG_AUX_DIR, A[CM]_PROG_LIBTOOL, AC_PREREQ, and for Automake
'subdir-objects' here since it can happen multiple times.
* pygnulib/main.py (main): Perform the checks here once. Check for both
configure.ac and configure.in, preferring configure.ac. Fix spacing in
error message.
---
ChangeLog | 12 +++++
pygnulib/GLConfig.py | 3 +-
pygnulib/GLImport.py | 61 -------------------------
pygnulib/main.py | 104 +++++++++++++++++++++++++++++++++++++++++--
4 files changed, 113 insertions(+), 67 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 39d8dd5d60..d72b1ebb82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2024-03-25 Collin Funk <collin.fu...@gmail.com>
+
+ gnulib-tool.py: Only process configure.ac once.
+ * pygnulib/GLConfig.py (GLConfig.setAutoconfFile): Don't combine the
+ path with destdir, accept it as given.
+ * pygnulib/GLImport.py (GLImport.__init__): Don't check
+ AC_CONFIG_AUX_DIR, A[CM]_PROG_LIBTOOL, AC_PREREQ, and for Automake
+ 'subdir-objects' here since it can happen multiple times.
+ * pygnulib/main.py (main): Perform the checks here once. Check for both
+ configure.ac and configure.in, preferring configure.ac. Fix spacing in
+ error message.
+
2024-03-25 Bruno Haible <br...@clisp.org>
gnulib-tool.py: Print "executing mkdir ..." messages.
diff --git a/pygnulib/GLConfig.py b/pygnulib/GLConfig.py
index b95d2dd613..6d67efea08 100644
--- a/pygnulib/GLConfig.py
+++ b/pygnulib/GLConfig.py
@@ -1006,8 +1006,7 @@ class GLConfig(object):
'''Specify path of autoconf file relative to destdir.'''
if type(configure_ac) is str:
if configure_ac:
- self.table['configure_ac'] = \
- os.path.join(self.table['destdir'], configure_ac)
+ self.table['configure_ac'] = configure_ac
else: # if type of configure_ac is not str
raise TypeError('configure_ac must be a string, not %s'
% type(configure_ac).__name__)
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 1a45776f4f..ad458171ec 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -87,36 +87,6 @@ class GLImport(object):
self.config = config.copy()
os.rmdir(self.cache['tempdir'])
- # Get cached auxdir and libtool from configure.ac/in.
- self.cache.setAuxDir('.')
- path = joinpath(self.config['destdir'], 'configure.ac')
- if not isfile(path):
- path = joinpath(self.config['destdir'], 'configure.in')
- if not isfile(path):
- raise GLError(3, path)
- self.config.setAutoconfFile(path)
- with codecs.open(path, 'rb', 'UTF-8') as file:
- data = file.read()
- pattern = re.compile(r'^AC_CONFIG_AUX_DIR\((.*)\)$', re.M)
- match = pattern.findall(data)
- if match:
- result = cleaner(match)[0]
- self.cache.setAuxDir(joinpath(self.config['destdir'], result))
- pattern = re.compile(r'A[CM]_PROG_LIBTOOL', re.M)
- guessed_libtool = bool(pattern.findall(data))
- if self.config['auxdir'] == None:
- self.config.setAuxDir(self.cache['auxdir'])
-
- # Guess autoconf version.
- pattern = re.compile(r'.*AC_PREREQ\((.*)\)', re.M)
- versions = cleaner(pattern.findall(data))
- if versions:
- version = sorted(set([ float(version)
- for version in versions ]))[-1]
- self.config.setAutoconfVersion(version)
- if version < 2.64:
- raise GLError(4, version)
-
# Get other cached variables.
path = joinpath(self.config['m4base'], 'gnulib-cache.m4')
if isfile(joinpath(self.config['m4base'], 'gnulib-cache.m4')):
@@ -260,37 +230,6 @@ class GLImport(object):
self.config.update_key(config, key)
self.config.setModules(modules)
- # Determine whether --automake-subdir/--automake-subdir-tests are supported.
- if self.config['automake_subdir'] or self.config['automake_subdir_tests']:
- found_subdir_objects = False
- if self.config['destdir']:
- with open(self.config['configure_ac'], encoding='utf-8') as file:
- data = file.read()
- pattern = re.compile(r'^.*AM_INIT_AUTOMAKE\([\[ ]*([^\]\)]*).*$', re.MULTILINE)
- configure_ac_automake_options = pattern.findall(data)
- if configure_ac_automake_options:
- automake_options = { x
- for y in configure_ac_automake_options
- for x in y.split() }
- found_subdir_objects = 'subdir-objects' in automake_options
- if not found_subdir_objects:
- if self.config['destdir']:
- base = self.config['destdir']
- else:
- base = '.'
- if isfile(joinpath(base, 'Makefile.am')):
- with open(joinpath(base, 'Makefile.am'), encoding='utf-8') as file:
- data = file.read()
- pattern = re.compile(r'^AUTOMAKE_OPTIONS[\t ]*=(.*)$', re.MULTILINE)
- 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)
diff --git a/pygnulib/main.py b/pygnulib/main.py
index c83612d91f..a697c27f2d 100644
--- a/pygnulib/main.py
+++ b/pygnulib/main.py
@@ -722,6 +722,8 @@ def main():
testsbase = cmdargs.testsbase
if testsbase != None:
testsbase = cmdargs.testsbase[0]
+ automake_subdir = cmdargs.automake_subdir == True
+ automake_subdir_tests = cmdargs.automake_subdir_tests == True
dryrun = cmdargs.dryrun
verbose = -cmdargs.quiet + cmdargs.verbose
inctests = cmdargs.inctests
@@ -731,6 +733,71 @@ def main():
inctests = False
elif mode in ['create-testdir', 'create-megatestdir', 'test', 'megatest']:
inctests = True
+ # Now the only possible values of "$inctests" are true and false
+ # (or blank but then it is irrelevant).
+
+ # Determine the minimum supported autoconf version from the project's
+ # configure.ac.
+ configure_ac = ''
+ autoconf_minversion = None
+ if mode in ['import', 'add-import', 'remove-import', 'update'] and destdir != None:
+ if isfile(os.path.join(destdir, 'configure.ac')):
+ configure_ac = os.path.join(destdir, 'configure.ac')
+ elif isfile(os.path.join(destdir, 'configure.in')):
+ configure_ac = os.path.join(destdir, 'configure.in')
+ else:
+ if isfile('configure.ac'):
+ configure_ac = 'configure.ac'
+ elif isfile('configure.in'):
+ configure_ac = 'configure.in'
+ if configure_ac != '':
+ # Use sed, not autoconf --trace, to look for the AC_PREREQ invocation,
+ # because when some m4 files are omitted from a version control repository,
+ # "autoconf --trace=AC_PREREQ" fails with an error message like this:
+ # m4: aclocal.m4:851: Cannot open m4/absolute-header.m4: No such file or directory
+ # autom4te: m4 failed with exit status: 1
+ with open(configure_ac, 'r', encoding='utf-8') as file:
+ configure_ac_data = file.read()
+ pattern = re.compile(r'^.*AC_PREREQ\([\[ ]*([^\]\)]*).*$', re.MULTILINE)
+ autoconf_minversion = pattern.search(configure_ac_data)
+ if autoconf_minversion:
+ autoconf_minversion = float(autoconf_minversion.group(1))
+ if autoconf_minversion == None:
+ autoconf_minversion = constants.DEFAULT_AUTOCONF_MINVERSION
+ if autoconf_minversion < 2.64:
+ raise classes.GLError(4, autoconf_minversion)
+
+ # Determine whether --automake-subdir/--automake-subdir-tests are supported.
+ if automake_subdir or automake_subdir_tests:
+ found_subdir_objects = False
+ if configure_ac != '':
+ with open(configure_ac, 'r', encoding='utf-8') as file:
+ data = file.read()
+ pattern = re.compile(r'^.*AM_INIT_AUTOMAKE\([\[ ]*([^\]\)]*).*$', re.MULTILINE)
+ configure_ac_automake_options = pattern.findall(data)
+ if configure_ac_automake_options:
+ automake_options = { x
+ for y in configure_ac_automake_options
+ for x in y.split() }
+ found_subdir_objects = 'subdir-objects' in automake_options
+ if not found_subdir_objects:
+ if destdir == None:
+ makefile_am = 'Makefile.am'
+ else:
+ makefile_am = os.path.join(destdir, 'Makefile.am')
+ if isfile(makefile_am):
+ with open(makefile_am, 'r', encoding='utf-8') as file:
+ data = file.read()
+ pattern = re.compile(r'^AUTOMAKE_OPTIONS[\t ]*=(.*)$', re.MULTILINE)
+ 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 classes.GLError(21, None)
+
incl_test_categories = []
if inctests:
incl_test_categories += [constants.TESTS['tests']]
@@ -769,8 +836,6 @@ 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
- automake_subdir_tests = cmdargs.automake_subdir_tests == True
macro_prefix = cmdargs.macro_prefix
if macro_prefix != None:
macro_prefix = macro_prefix[0]
@@ -886,10 +951,41 @@ def main():
destdir = '.'
config.setDestDir(destdir)
+ # Prefer configure.ac to configure.in.
+ # Use os.path.join instead of joinpath to preserve './' printed in gnulib-comp.m4.
+ if isfile(os.path.join(destdir, 'configure.ac')):
+ configure_ac = os.path.join(destdir, 'configure.ac')
+ elif isfile(os.path.join(destdir, 'configure.in')):
+ configure_ac = os.path.join(destdir, 'configure.in')
+ else:
+ raise classes.GLError(3, os.path.join(destdir, 'configure.ac'))
+
+ # Set the configure.ac file for each GLImport.
+ config.setAutoconfFile(configure_ac)
+
# Analyze configure.ac.
- with open(joinpath(destdir, 'configure.ac'), 'r', encoding='utf-8') as file:
+ with open(configure_ac, 'r', encoding='utf-8') as file:
configure_ac_data = file.read()
+ # Guess the auxdir.
+ pattern = re.compile(r'^.*AC_CONFIG_AUX_DIR\([\[ ]*([^\]"\$`\\\)]*).*$', re.MULTILINE)
+ guessed_auxdir = pattern.search(configure_ac_data)
+ if guessed_auxdir:
+ auxdir = guessed_auxdir.group(1)
+ else:
+ auxdir = '.'
+
+ # # Set the build-aux directory for each GLImport.
+ config.setAuxDir(auxdir)
+
+ # Guess if libtool is used.
+ pattern = re.compile(r'A[CM]_PROG_LIBTOOL', re.MULTILINE)
+ guessed_libtool = bool(pattern.search(configure_ac))
+
+ # Set whether we use libtool for each GLImport.
+ config.setLibtool(guessed_libtool)
+
+ # Guess the m4dirs.
guessed_m4dirs = []
pattern = re.compile(r'^.*AC_CONFIG_MACRO_DIRS?\([\[ ]*([^\]"\$`\\\)]*).*$', re.MULTILINE)
match = pattern.findall(configure_ac_data)
@@ -1363,7 +1459,7 @@ if __name__ == '__main__':
message += 'cannot find %s - make sure you run gnulib-tool from within your package\'s directory' % errinfo
elif errno == 4:
message += 'minimum supported autoconf version is 2.64. Try adding'
- message += 'AC_PREREQ([%s])' % constants.DEFAULT_AUTOCONF_MINVERSION
+ message += ' AC_PREREQ([%s])' % constants.DEFAULT_AUTOCONF_MINVERSION
message += ' to your configure.ac.'
elif errno == 5:
message += '%s is expected to contain gl_M4_BASE([%s])' % (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo))
--
2.44.0