Skip to content

Commit

Permalink
Update to waf 2.0.26
Browse files Browse the repository at this point in the history
This makes waf compatible with Python 3.12 again.

Also, apply modifications needed for MacOS and add as a patch file (see
commits 0f2e3b2 and dc6c995).

Signed-off-by: Nils Philippsen <nils@tiptoe.de>
  • Loading branch information
nphilipp committed Aug 29, 2023
1 parent 4f58969 commit 553ca1e
Show file tree
Hide file tree
Showing 40 changed files with 2,114 additions and 195 deletions.
7 changes: 5 additions & 2 deletions waf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python
# encoding: latin-1
# Thomas Nagy, 2005-2018
#
Expand Down Expand Up @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.

import os, sys, inspect

VERSION="2.0.12"
VERSION="2.0.26"
REVISION="x"
GIT="x"
INSTALL="x"
Expand Down Expand Up @@ -142,6 +142,9 @@ def find_lib():
if name.endswith('waf-light'):
w = test(base)
if w: return w
for dir in sys.path:
if test(dir):
return dir
err('waf-light requires waflib -> export WAFDIR=/folder')

dirname = '%s-%s-%s' % (WAF, VERSION, REVISION)
Expand Down
18 changes: 18 additions & 0 deletions waflib-macos-mods.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py
index cfef8bf5..484846f5 100644
--- a/waflib/Tools/ccroot.py
+++ b/waflib/Tools/ccroot.py
@@ -575,12 +575,10 @@ def apply_vnum(self):

cnum = getattr(self, 'cnum', str(nums[0]))
cnums = cnum.split('.')
- if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums:
- raise Errors.WafError('invalid compatibility version %s' % cnum)

libname = node.name
if libname.endswith('.dylib'):
- name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum)
+ name3 = libname.replace('.dylib', '.%s.dylib' % cnums[0])
name2 = libname.replace('.dylib', '.%s.dylib' % cnum)
else:
name3 = libname + '.' + self.vnum
47 changes: 33 additions & 14 deletions waflib/Build.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def __init__(self, **kw):
"""Amount of jobs to run in parallel"""

self.targets = Options.options.targets
"""List of targets to build (default: \*)"""
"""List of targets to build (default: \\*)"""

self.keep = Options.options.keep
"""Whether the build should continue past errors"""
Expand Down Expand Up @@ -753,10 +753,12 @@ def tgpost(tg):
else:
ln = self.launch_node()
if ln.is_child_of(self.bldnode):
Logs.warn('Building from the build directory, forcing --targets=*')
if Logs.verbose > 1:
Logs.warn('Building from the build directory, forcing --targets=*')
ln = self.srcnode
elif not ln.is_child_of(self.srcnode):
Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)', ln.abspath(), self.srcnode.abspath())
if Logs.verbose > 1:
Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)', ln.abspath(), self.srcnode.abspath())
ln = self.srcnode

def is_post(tg, ln):
Expand Down Expand Up @@ -1054,19 +1056,19 @@ def post_run(self):
def get_install_path(self, destdir=True):
"""
Returns the destination path where files will be installed, pre-pending `destdir`.
Relative paths will be interpreted relative to `PREFIX` if no `destdir` is given.
:rtype: string
"""
if isinstance(self.install_to, Node.Node):
dest = self.install_to.abspath()
else:
dest = Utils.subst_vars(self.install_to, self.env)
dest = os.path.normpath(Utils.subst_vars(self.install_to, self.env))
if not os.path.isabs(dest):
dest = os.path.join(self.env.PREFIX, dest)
dest = os.path.join(self.env.PREFIX, dest)
if destdir and Options.options.destdir:
dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep))
dest = Options.options.destdir.rstrip(os.sep) + os.sep + os.path.splitdrive(dest)[1].lstrip(os.sep)
return dest

def copy_fun(self, src, tgt):
Expand Down Expand Up @@ -1160,11 +1162,19 @@ def do_install(self, src, tgt, lbl, **kw):
# same size and identical timestamps -> make no copy
if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size:
if not self.generator.bld.progress_bar:
Logs.info('- install %s (from %s)', tgt, lbl)

c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE

Logs.info('%s- install %s%s%s (from %s)', c1, c2, tgt, c1, lbl)
return False

if not self.generator.bld.progress_bar:
Logs.info('+ install %s (from %s)', tgt, lbl)

c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE

Logs.info('%s+ install %s%s%s (from %s)', c1, c2, tgt, c1, lbl)

# Give best attempt at making destination overwritable,
# like the 'install' utility used by 'make install' does.
Expand Down Expand Up @@ -1221,14 +1231,18 @@ def do_link(self, src, tgt, **kw):
"""
if os.path.islink(tgt) and os.readlink(tgt) == src:
if not self.generator.bld.progress_bar:
Logs.info('- symlink %s (to %s)', tgt, src)
c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE
Logs.info('%s- symlink %s%s%s (to %s)', c1, c2, tgt, c1, src)
else:
try:
os.remove(tgt)
except OSError:
pass
if not self.generator.bld.progress_bar:
Logs.info('+ symlink %s (to %s)', tgt, src)
c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE
Logs.info('%s+ symlink %s%s%s (to %s)', c1, c2, tgt, c1, src)
os.symlink(src, tgt)
self.fix_perms(tgt)

Expand All @@ -1237,7 +1251,9 @@ def do_uninstall(self, src, tgt, lbl, **kw):
See :py:meth:`waflib.Build.inst.do_install`
"""
if not self.generator.bld.progress_bar:
Logs.info('- remove %s', tgt)
c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE
Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1)

#self.uninstall.append(tgt)
try:
Expand All @@ -1257,7 +1273,9 @@ def do_unlink(self, src, tgt, **kw):
"""
try:
if not self.generator.bld.progress_bar:
Logs.info('- remove %s', tgt)
c1 = Logs.colors.NORMAL
c2 = Logs.colors.BLUE
Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1)
os.remove(tgt)
except OSError:
pass
Expand Down Expand Up @@ -1318,7 +1336,8 @@ def build(bld):
lst = []
for env in self.all_envs.values():
lst.extend(self.root.find_or_declare(f) for f in env[CFG_FILES])
for n in self.bldnode.ant_glob('**/*', excl='.lock* *conf_check_*/** config.log c4che/*', quiet=True):
excluded_dirs = '.lock* *conf_check_*/** config.log %s/*' % CACHE_DIR
for n in self.bldnode.ant_glob('**/*', excl=excluded_dirs, quiet=True):
if n in lst:
continue
n.delete()
Expand Down
2 changes: 1 addition & 1 deletion waflib/ConfigSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import copy, re, os
from waflib import Logs, Utils
re_imp = re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$', re.M)
re_imp = re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$', re.M)

class ConfigSet(object):
"""
Expand Down
46 changes: 32 additions & 14 deletions waflib/Configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def init_dirs(self):
self.bldnode.mkdir()

if not os.path.isdir(self.bldnode.abspath()):
conf.fatal('Could not create the build directory %s' % self.bldnode.abspath())
self.fatal('Could not create the build directory %s' % self.bldnode.abspath())

def execute(self):
"""
Expand Down Expand Up @@ -180,6 +180,7 @@ def execute(self):
env.hash = self.hash
env.files = self.files
env.environ = dict(self.environ)
env.launch_dir = Context.launch_dir

if not (self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN') or getattr(Options.options, 'no_lock_in_run')):
env.store(os.path.join(Context.run_dir, Options.lockfile))
Expand Down Expand Up @@ -438,7 +439,7 @@ def find_program(self, filename, **kw):

var = kw.get('var', '')
if not var:
var = re.sub(r'[-.]', '_', filename[0].upper())
var = re.sub(r'\W', '_', filename[0].upper())

path_list = kw.get('path_list', '')
if path_list:
Expand Down Expand Up @@ -507,23 +508,27 @@ def find_binary(self, filenames, exts, paths):
@conf
def run_build(self, *k, **kw):
"""
Create a temporary build context to execute a build. A reference to that build
context is kept on self.test_bld for debugging purposes, and you should not rely
on it too much (read the note on the cache below).
The parameters given in the arguments to this function are passed as arguments for
a single task generator created in the build. Only three parameters are obligatory:
Create a temporary build context to execute a build. A temporary reference to that build
context is kept on self.test_bld for debugging purposes.
The arguments to this function are passed to a single task generator for that build.
Only three parameters are mandatory:
:param features: features to pass to a task generator created in the build
:type features: list of string
:param compile_filename: file to create for the compilation (default: *test.c*)
:type compile_filename: string
:param code: code to write in the filename to compile
:param code: input file contents
:type code: string
Though this function returns *0* by default, the build may set an attribute named *retval* on the
Though this function returns *0* by default, the build may bind attribute named *retval* on the
build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.
This function also provides a limited cache. To use it, provide the following option::
The temporary builds creates a temporary folder; the name of that folder is calculated
by hashing input arguments to this function, with the exception of :py:class:`waflib.ConfigSet.ConfigSet`
objects which are used for both reading and writing values.
This function also features a cache which is disabled by default; that cache relies
on the hash value calculated as indicated above::
def options(opt):
opt.add_option('--confcache', dest='confcache', default=0,
Expand All @@ -534,10 +539,24 @@ def options(opt):
$ waf configure --confcache
"""
lst = [str(v) for (p, v) in kw.items() if p != 'env']
h = Utils.h_list(lst)
buf = []
for key in sorted(kw.keys()):
v = kw[key]
if isinstance(v, ConfigSet.ConfigSet):
# values are being written to, so they are excluded from contributing to the hash
continue
elif hasattr(v, '__call__'):
buf.append(Utils.h_fun(v))
else:
buf.append(str(v))
h = Utils.h_list(buf)
dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)

cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None))

if not cachemode and os.path.exists(dir):
shutil.rmtree(dir)

try:
os.makedirs(dir)
except OSError:
Expand All @@ -548,7 +567,6 @@ def options(opt):
except OSError:
self.fatal('cannot use the configuration test folder %r' % dir)

cachemode = getattr(Options.options, 'confcache', None)
if cachemode == 1:
try:
proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
Expand Down Expand Up @@ -588,7 +606,7 @@ def options(opt):
else:
ret = getattr(bld, 'retval', 0)
finally:
if cachemode == 1:
if cachemode:
# cache the results each time
proj = ConfigSet.ConfigSet()
proj['cache_run_build'] = ret
Expand Down
24 changes: 17 additions & 7 deletions waflib/Context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@
Classes and functions enabling the command system
"""

import os, re, imp, sys
import os, re, sys
from waflib import Utils, Errors, Logs
import waflib.Node

if sys.hexversion > 0x3040000:
import types
class imp(object):
new_module = lambda x: types.ModuleType(x)
else:
import imp

# the following 3 constants are updated on each new release (do not touch)
HEXVERSION=0x2000c00
HEXVERSION=0x2001a00
"""Constant updated on new releases"""

WAFVERSION="2.0.12"
WAFVERSION="2.0.26"
"""Constant updated on new releases"""

WAFREVISION="54841218840ffa34fddf834680a5a17db69caa12"
WAFREVISION="0fb985ce1932c6f3e7533f435e4ee209d673776e"
"""Git revision when the waf version is updated"""

WAFNAME="waf"
"""Application name displayed on --help"""

ABI = 20
"""Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)"""

Expand Down Expand Up @@ -134,7 +144,7 @@ def foo(ctx):
:type fun: string
.. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext
:top-classes: waflib.Context.Context
"""

errors = Errors
Expand Down Expand Up @@ -613,7 +623,7 @@ def load_special_tools(self, var, ban=[]):
is typically called once for a programming language group, see for
example :py:mod:`waflib.Tools.compiler_c`
:param var: glob expression, for example 'cxx\_\*.py'
:param var: glob expression, for example 'cxx\\_\\*.py'
:type var: string
:param ban: list of exact file names to exclude
:type ban: list of string
Expand Down Expand Up @@ -678,7 +688,7 @@ def load_module(path, encoding=None):

def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True):
"""
Importx a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools`
Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools`
:type tool: string
:param tool: Name of the tool
Expand Down
9 changes: 6 additions & 3 deletions waflib/Logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ def format(self, rec):
if rec.levelno >= logging.INFO:
# the goal of this is to format without the leading "Logs, hour" prefix
if rec.args:
return msg % rec.args
try:
return msg % rec.args
except UnicodeDecodeError:
return msg.encode('utf-8') % rec.args
return msg

rec.msg = msg
Expand Down Expand Up @@ -276,9 +279,9 @@ def error(*k, **kw):

def warn(*k, **kw):
"""
Wraps logging.warn
Wraps logging.warning
"""
log.warn(*k, **kw)
log.warning(*k, **kw)

def info(*k, **kw):
"""
Expand Down
3 changes: 1 addition & 2 deletions waflib/Node.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def ant_matcher(s, ignorecase):
if k == '**':
accu.append(k)
else:
k = k.replace('.', '[.]').replace('*','.*').replace('?', '.').replace('+', '\\+')
k = k.replace('.', '[.]').replace('*', '.*').replace('?', '.').replace('+', '\\+')
k = '^%s$' % k
try:
exp = re.compile(k, flags=reflags)
Expand Down Expand Up @@ -595,7 +595,6 @@ def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remov
:rtype: iterator
"""
dircont = self.listdir()
dircont.sort()

try:
lst = set(self.children.keys())
Expand Down
Loading

0 comments on commit 553ca1e

Please sign in to comment.