Skip to content

Commit

Permalink
Merge branch 'master' into fix_fortran_fpic
Browse files Browse the repository at this point in the history
  • Loading branch information
bdbaddog authored Sep 5, 2023
2 parents 0f4a646 + cbd156d commit 5704fb1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 39 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
file an error. It has issued a warning since 3.0, with "warn instead
of fail" deprecated since 3.1. Fixes #3958.
- Minor (non-functional) cleanup of some tests, particuarly test/MSVC.
- Added more error handling while reading msvc config cache.
(Enabled/specified by SCONS_CACHE_MSVC_CONFIG).
The existing cache will be discarded if there's a decode error reading it.
It's possible there's a race condition creating this issue it in certain CI builds.

From Jonathon Reinhart:
- Fix another instance of `int main()` in CheckLib() causing failures
Expand Down
5 changes: 4 additions & 1 deletion RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ FIXES
- FORTRAN: Fix gfortran tool initialization. Defaults to using binary named gfortran
as would be expected, and properly set's SHFORTRAN flags to include -fPIC
where previously it was only doing so for the other fortran versions (F77,..)

- MSCommon: Added more error handling while reading msvc config cache.
(Enabled/specified by SCONS_CACHE_MSVC_CONFIG).
The existing cache will be discarded if there's a decode error reading it.
It's possible there's a race condition creating this issue it in certain CI builds.

IMPROVEMENTS
------------
Expand Down
85 changes: 47 additions & 38 deletions SCons/Tool/MSCommon/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def debug(x, *args):


# SCONS_CACHE_MSVC_CONFIG is public, and is documented.
CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG')
CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG', '')
if CONFIG_CACHE in ('1', 'true', 'True'):
CONFIG_CACHE = os.path.join(os.path.expanduser('~'), 'scons_msvc_cache.json')

Expand All @@ -113,50 +113,59 @@ def debug(x, *args):
if os.environ.get('SCONS_CACHE_MSVC_FORCE_DEFAULTS') in ('1', 'true', 'True'):
CONFIG_CACHE_FORCE_DEFAULT_ARGUMENTS = True

def read_script_env_cache():
def read_script_env_cache() -> dict:
""" fetch cached msvc env vars if requested, else return empty dict """
envcache = {}
if CONFIG_CACHE:
p = Path(CONFIG_CACHE)
if not CONFIG_CACHE or not p.is_file():
return envcache
with p.open('r') as f:
# Convert the list of cache entry dictionaries read from
# json to the cache dictionary. Reconstruct the cache key
# tuple from the key list written to json.
try:
p = Path(CONFIG_CACHE)
with p.open('r') as f:
# Convert the list of cache entry dictionaries read from
# json to the cache dictionary. Reconstruct the cache key
# tuple from the key list written to json.
envcache_list = json.load(f)
if isinstance(envcache_list, list):
envcache = {tuple(d['key']): d['data'] for d in envcache_list}
else:
# don't fail if incompatible format, just proceed without it
warn_msg = "Incompatible format for msvc cache file {}: file may be overwritten.".format(
repr(CONFIG_CACHE)
)
SCons.Warnings.warn(MSVCCacheInvalidWarning, warn_msg)
debug(warn_msg)
except FileNotFoundError:
# don't fail if no cache file, just proceed without it
pass
envcache_list = json.load(f)
except json.JSONDecodeError:
# If we couldn't decode it, it could be corrupt. Toss.
with suppress(FileNotFoundError):
p.unlink()
warn_msg = "Could not decode msvc cache file %s: dropping."
SCons.Warnings.warn(MSVCCacheInvalidWarning, warn_msg % CONFIG_CACHE)
debug(warn_msg, CONFIG_CACHE)
else:
if isinstance(envcache_list, list):
envcache = {tuple(d['key']): d['data'] for d in envcache_list}
else:
# don't fail if incompatible format, just proceed without it
warn_msg = "Incompatible format for msvc cache file %s: file may be overwritten."
SCons.Warnings.warn(MSVCCacheInvalidWarning, warn_msg % CONFIG_CACHE)
debug(warn_msg, CONFIG_CACHE)

return envcache


def write_script_env_cache(cache) -> None:
""" write out cache of msvc env vars if requested """
if CONFIG_CACHE:
try:
p = Path(CONFIG_CACHE)
with p.open('w') as f:
# Convert the cache dictionary to a list of cache entry
# dictionaries. The cache key is converted from a tuple to
# a list for compatibility with json.
envcache_list = [{'key': list(key), 'data': data} for key, data in cache.items()]
json.dump(envcache_list, f, indent=2)
except TypeError:
# data can't serialize to json, don't leave partial file
with suppress(FileNotFoundError):
p.unlink()
except OSError:
# can't write the file, just skip
pass
if not CONFIG_CACHE:
return

p = Path(CONFIG_CACHE)
try:
with p.open('w') as f:
# Convert the cache dictionary to a list of cache entry
# dictionaries. The cache key is converted from a tuple to
# a list for compatibility with json.
envcache_list = [{'key': list(key), 'data': data} for key, data in cache.items()]
json.dump(envcache_list, f, indent=2)
except TypeError:
# data can't serialize to json, don't leave partial file
with suppress(FileNotFoundError):
p.unlink()
except OSError:
# can't write the file, just skip
pass

return


_is_win64 = None
Expand Down Expand Up @@ -381,7 +390,7 @@ def parse_output(output, keep=KEEPLIST):
# rdk will keep the regex to match the .bat file output line starts
rdk = {}
for i in keep:
rdk[i] = re.compile('%s=(.*)' % i, re.I)
rdk[i] = re.compile(r'%s=(.*)' % i, re.I)

def add_env(rmatch, key, dkeep=dkeep) -> None:
path_list = rmatch.group(1).split(os.pathsep)
Expand Down

0 comments on commit 5704fb1

Please sign in to comment.