mirror of
https://github.com/clearlinux/autospec.git
synced 2026-06-16 02:45:56 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b5d8cf5341 | |||
| cd8d0065aa | |||
| 6aaa12ff76 | |||
| 65cf152900 | |||
| 99a7985f29 | |||
| 9594167cc7 | |||
| c62c42a21d | |||
| a88ffdc2a7 | |||
| 936534a889 |
@@ -0,0 +1,7 @@
|
||||
## DISCONTINUATION OF PROJECT.
|
||||
|
||||
This project will no longer be maintained by Intel.
|
||||
|
||||
Intel will not provide or guarantee development of or support for this project, including but not limited to, maintenance, bug fixes, new releases or updates. Patches to this project are no longer accepted by Intel. If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the community, please create your own fork of the project.
|
||||
|
||||
Contact: webadmin@linux.intel.com
|
||||
@@ -155,7 +155,7 @@ def is_file_valid(path):
|
||||
|
||||
def dump_symbols(path):
|
||||
"""Get symbols from a file."""
|
||||
cmd = "nm --defined-only -g --dynamic \"{}\"".format(path)
|
||||
cmd = "nm --defined-only -g --dynamic \"{}\" | c++filt".format(path)
|
||||
lines = None
|
||||
|
||||
ret = set()
|
||||
|
||||
@@ -277,6 +277,9 @@ def package(args, url, name, archives, workingdir):
|
||||
# specfile template is assumed "correct" and any failures need to be manually addressed
|
||||
break
|
||||
filemanager.load_specfile(specfile)
|
||||
if 'license' in specfile.packages and not conf.config_opts['has_license']:
|
||||
conf.config_opts['has_license'] = True
|
||||
conf.rewrite_config_opts()
|
||||
specfile.write_spec()
|
||||
filemanager.newfiles_printed = 0
|
||||
mock_chroot = "/var/lib/mock/clear-{}/root/builddir/build/BUILDROOT/" \
|
||||
@@ -297,6 +300,10 @@ def package(args, url, name, archives, workingdir):
|
||||
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
|
||||
print_build_failed()
|
||||
sys.exit(1)
|
||||
elif 'license' not in specfile.packages and conf.config_opts['has_license']:
|
||||
print_fatal("package -license subpackage deleted")
|
||||
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
|
||||
sys.exit(1)
|
||||
elif os.path.isfile("README.clear"):
|
||||
try:
|
||||
print("\nREADME.clear CONTENTS")
|
||||
|
||||
@@ -215,6 +215,8 @@ class Build(object):
|
||||
elif infiles == 1 and "not matching the package arch" not in line:
|
||||
# exclude blank lines from consideration...
|
||||
file = line.strip()
|
||||
if file in ("/usr", "/usr/"):
|
||||
self.must_restart += 1
|
||||
if file and file[0] == "/":
|
||||
filemanager.push_file(file, content.name)
|
||||
|
||||
|
||||
@@ -709,6 +709,7 @@ class Requirements(object):
|
||||
"""Use pypi for getting package requires and metadata."""
|
||||
# First look for a local override
|
||||
pypi_json = ""
|
||||
pypi_name = pypidata.get_pypi_name(name)
|
||||
pypi_file = os.path.join(config.download_path, "pypi.json")
|
||||
if os.path.isfile(pypi_file):
|
||||
with open(pypi_file, "r") as pfile:
|
||||
@@ -716,16 +717,20 @@ class Requirements(object):
|
||||
else:
|
||||
# Try and grab the pypi details for the package
|
||||
if config.alias:
|
||||
name = config.alias
|
||||
pypi_name = pypidata.get_pypi_name(name)
|
||||
pypi_name = config.alias
|
||||
pypi_name = pypidata.get_pypi_name(pypi_name)
|
||||
pypi_json = pypidata.get_pypi_metadata(pypi_name)
|
||||
if pypi_json:
|
||||
if not pypi_json:
|
||||
self.pypi_provides = pypi_name
|
||||
else:
|
||||
try:
|
||||
package_pypi = json.loads(pypi_json)
|
||||
except json.JSONDecodeError:
|
||||
package_pypi = {}
|
||||
package_pypi = {"name": pypi_name}
|
||||
if package_pypi.get("name"):
|
||||
self.pypi_provides = package_pypi["name"]
|
||||
else:
|
||||
self.pypi_provides = pypi_name
|
||||
if package_pypi.get("requires"):
|
||||
for pkg in package_pypi["requires"]:
|
||||
self.add_requires(f"pypi({pkg})", config.os_packages, override=True, subpkg="python3")
|
||||
|
||||
@@ -193,6 +193,7 @@ class Config(object):
|
||||
"no_glob": "Do not use the replacement pattern for file matching",
|
||||
"allow_exe": "Allow Windows executables (*.exe, *.dll) to be packaged",
|
||||
"use_ninja": "Use ninja build files",
|
||||
"has_license": "Require license subpackage for successful build",
|
||||
}
|
||||
# simple_pattern_pkgconfig patterns
|
||||
# contains patterns for parsing build.log for missing dependencies
|
||||
|
||||
@@ -71,14 +71,8 @@ def sanitize_counts():
|
||||
"""Validate test counts are within sane bounds."""
|
||||
global total_tests
|
||||
global total_pass
|
||||
global total_fail
|
||||
global total_xfail
|
||||
global total_skip
|
||||
global counted_tests
|
||||
global counted_pass
|
||||
global counted_fail
|
||||
global counted_xfail
|
||||
global counted_skip
|
||||
if total_tests > 0 and total_pass == 0:
|
||||
total_pass = total_tests - total_fail - total_skip - total_xfail
|
||||
|
||||
@@ -170,7 +164,6 @@ def parse_log(log, pkgname=''):
|
||||
global total_fail
|
||||
global total_xfail
|
||||
global total_skip
|
||||
global counted_tests
|
||||
global counted_pass
|
||||
global counted_fail
|
||||
global counted_xfail
|
||||
|
||||
+1
-6
@@ -55,8 +55,6 @@ def add_license(lic, translations, blacklist):
|
||||
presence in the blacklist. Returns False if no license were added, True
|
||||
otherwise.
|
||||
"""
|
||||
global licenses
|
||||
global license_files
|
||||
lic = lic.strip().strip(',')
|
||||
result = False
|
||||
|
||||
@@ -177,7 +175,7 @@ def scan_for_licenses(srcdir, config, pkg_name):
|
||||
"about_bsd.txt"]
|
||||
# look for files that start with copying or licen[cs]e (but are
|
||||
# not likely scripts) or end with licen[cs]e
|
||||
target_pat = re.compile(r"^((copying)|(licen[cs]e)|(e[dp]l-v\d+))|(licen[cs]e)(\.(txt|xml))?$")
|
||||
target_pat = re.compile(r"^((copying)|(licen[cs]e)|(e[dp]l-v\d+))|(licen[cs]e)(\.(txt|xml))?|(intel simplified software license.*\.txt)$")
|
||||
for dirpath, dirnames, files in os.walk(srcdir):
|
||||
for name in files:
|
||||
if name.lower() in targets or target_pat.search(name.lower()):
|
||||
@@ -208,9 +206,6 @@ def scan_for_licenses(srcdir, config, pkg_name):
|
||||
|
||||
def load_specfile(specfile):
|
||||
"""Get licenses from the specfile content."""
|
||||
global licenses
|
||||
global license_files
|
||||
global hashes
|
||||
specfile.licenses = licenses if licenses else [default_license]
|
||||
specfile.license_files = sorted(license_files)
|
||||
specfile.hashes = hashes
|
||||
|
||||
@@ -96,7 +96,7 @@ class GPGCli(object):
|
||||
util.write_out(os.path.join(_gpghome, 'gpg.conf'), GNUPGCONF)
|
||||
if pubkey is not None:
|
||||
args = self.args + ['--import', pubkey]
|
||||
output, err, code = self.exec_cmd(args)
|
||||
_, err, code = self.exec_cmd(args)
|
||||
if code == -9:
|
||||
raise Exception('Command {} timeout after {} seconds'.format(' '.join(args), CMD_TIMEOUT))
|
||||
elif code != 0:
|
||||
@@ -212,16 +212,15 @@ class Verifier(object):
|
||||
@staticmethod
|
||||
def calc_sum(filepath, digest_algo):
|
||||
"""Use digest_algo to calculate block sum of a file."""
|
||||
BLOCK_SIZE = 4096
|
||||
block_size = 4096
|
||||
with open(filepath, 'rb') as fp:
|
||||
digest = digest_algo()
|
||||
for block in iter(lambda: fp.read(BLOCK_SIZE), b''):
|
||||
for block in iter(lambda: fp.read(block_size), b''):
|
||||
digest.update(block)
|
||||
return digest.hexdigest()
|
||||
|
||||
def print_result(self, result, err_msg=''):
|
||||
"""Display verification results."""
|
||||
global EMAIL
|
||||
package_name = ''
|
||||
if self.url is not None:
|
||||
package_name = os.path.basename(self.url)
|
||||
|
||||
+12
-5
@@ -27,6 +27,15 @@ def pkg_search(name):
|
||||
return False
|
||||
|
||||
|
||||
def fixup_pypi_prefix(name):
|
||||
"""Try and chop off the 'pypi-' or 'python-' prefix for names."""
|
||||
name = name.lower().replace('-', '_')
|
||||
for prefix in ["pypi_", "python_"]:
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix):]
|
||||
return name
|
||||
|
||||
|
||||
def get_pypi_name(name, miss=False):
|
||||
"""Try and verify the pypi name for a given package name."""
|
||||
# normalize the name for matching as pypi is case insensitve for search
|
||||
@@ -35,11 +44,9 @@ def get_pypi_name(name, miss=False):
|
||||
if pkg_search(name):
|
||||
return name
|
||||
# Maybe we have a prefix
|
||||
for prefix in ["pypi_", "python_"]:
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix):]
|
||||
if pkg_search(name):
|
||||
return name
|
||||
name = fixup_pypi_prefix(name)
|
||||
if pkg_search(name):
|
||||
return name
|
||||
# Some cases where search fails (Sphinx)
|
||||
# Just try the name we were given
|
||||
if miss:
|
||||
|
||||
+57
-4
@@ -37,9 +37,9 @@ AVX512_CFLAGS = "-march=x86-64-v4 -mprefer-vector-width=512"
|
||||
AVX512_FCFLAGS = "-march=x86-64-v4 -mprefer-vector-width=256"
|
||||
AVX512_LCFLAGS = "-march=x86-64-v4"
|
||||
AVX512_LFLAGS = "-Wl,-z,x86-64-v4"
|
||||
APX_CFLAGS = "-march=x86-64-v3 -mapxf -mavx10.1"
|
||||
APX_LCFLAGS = "-march=x86-64-v3"
|
||||
APX_LFLAGS = "-Wl,-z,x86-64-v3"
|
||||
APX_CFLAGS = "-march=x86-64-v4 -mapxf"
|
||||
APX_LCFLAGS = "-march=x86-64-v4"
|
||||
APX_LFLAGS = "-Wl,-z,x86-64-v4"
|
||||
|
||||
|
||||
class Specfile(object):
|
||||
@@ -1166,7 +1166,7 @@ class Specfile(object):
|
||||
self.write_build_prepend()
|
||||
self._write_strip("GOAMD64=v3")
|
||||
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
|
||||
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
|
||||
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
|
||||
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
|
||||
self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {APX_CFLAGS} "')
|
||||
self._write_strip(f'LDFLAGS="$CLEAR_INTERMEDIATE_LDFLAGS {APX_LCFLAGS} "')
|
||||
@@ -1806,6 +1806,59 @@ class Specfile(object):
|
||||
|
||||
self.write_cmake_install()
|
||||
|
||||
def write_qmake5_pattern(self):
|
||||
"""Write qmake5 build pattern to spec file."""
|
||||
extra_qmake_args = ""
|
||||
if self.config.config_opts['use_clang']:
|
||||
extra_qmake_args = "-spec linux-clang "
|
||||
if self.config.config_opts['use_lto']:
|
||||
extra_qmake_args += "-config ltcg -config fat-static-lto "
|
||||
else:
|
||||
extra_qmake_args += "QMAKE_CFLAGS+=-fno-lto QMAKE_CXXFLAGS+=-fno-lto "
|
||||
|
||||
self.write_prep()
|
||||
self._write_strip("%build")
|
||||
self.write_build_prepend()
|
||||
self.write_proxy_exports()
|
||||
self._write_strip("export LANG=C.UTF-8")
|
||||
self.write_variables()
|
||||
|
||||
if self.config.subdir:
|
||||
self._write_strip("pushd " + self.config.subdir)
|
||||
|
||||
self._write_strip('export QMAKE_CFLAGS="$CFLAGS"')
|
||||
self._write_strip('export QMAKE_CXXFLAGS="$CXXFLAGS"')
|
||||
self._write_strip('export QMAKE_LFLAGS="$LDFLAGS"')
|
||||
self._write_strip('export QMAKE_LIBDIR=/usr/lib64')
|
||||
self._write_strip('export QMAKE_CFLAGS_RELEASE=')
|
||||
self._write_strip('export QMAKE_CXXFLAGS_RELEASE=')
|
||||
|
||||
# Add the qtbase tools to the path
|
||||
self._write_strip('export PATH=/usr/lib64/qt5/bin:$PATH')
|
||||
|
||||
if self.config.make_command:
|
||||
qmake = self.config.make_command
|
||||
else:
|
||||
qmake = "qmake"
|
||||
self._write_strip(f"{qmake} {extra_qmake_args} {self.config.extra_configure}")
|
||||
self._write_strip("test -r config.log && cat config.log")
|
||||
self.write_make_line()
|
||||
|
||||
if self.config.subdir:
|
||||
self._write_strip("popd")
|
||||
|
||||
if self.config.config_opts['use_avx2']:
|
||||
self._write_strip("pushd ../buildavx2/" + self.config.subdir)
|
||||
self._write(f"{qmake} 'QT_CPU_FEATURES.x86_64 += avx avx2 bmi bmi2 f16c fma lzcnt popcnt'\\\n")
|
||||
self._write(f' QMAKE_CFLAGS+="{AVX2_CFLAGS} {AVX2_LFLAGS}" QMAKE_CXXFLAGS+="{AVX2_CFLAGS} {AVX2_LFLAGS}" \\\n')
|
||||
self._write(f' QMAKE_LFLAGS+="{AVX2_LCFLAGS}" {extra_qmake_args} {self.config.extra_configure}\n')
|
||||
self.write_make_line()
|
||||
self._write_strip("popd")
|
||||
|
||||
self.write_build_append()
|
||||
self._write_strip("\n")
|
||||
self.write_make_install()
|
||||
|
||||
def write_qmake_pattern(self):
|
||||
"""Write qmake build pattern to spec file."""
|
||||
extra_qmake_args = ""
|
||||
|
||||
@@ -156,7 +156,6 @@ def _file_write(self, s):
|
||||
|
||||
def translate(package):
|
||||
"""Convert terms to their alternate definition."""
|
||||
global dictionary
|
||||
for item in dictionary:
|
||||
if item.startswith(package + "="):
|
||||
return item.split("=")[1]
|
||||
|
||||
@@ -499,6 +499,95 @@ class TestBuildreq(unittest.TestCase):
|
||||
self.assertEqual(self.reqs.requires['python3'], pypi_requires)
|
||||
self.assertEqual(ssummary, summary)
|
||||
|
||||
def test_scan_for_configure_pypi_no_name_in_json(self):
|
||||
"""
|
||||
Test scan_for_configure when distutils is being used for the build
|
||||
pattern to test connecting to pypi but not getting a name back.
|
||||
"""
|
||||
orig_summary = buildreq.specdescription.default_summary
|
||||
orig_sscore = buildreq.specdescription.default_summary_score
|
||||
orig_pypi_name = buildreq.pypidata.get_pypi_name
|
||||
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
|
||||
name = "pypi-name"
|
||||
content = json.dumps({})
|
||||
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
|
||||
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content)
|
||||
with tempfile.TemporaryDirectory() as tmpd:
|
||||
conf = config.Config(tmpd)
|
||||
conf.config_opts['use_ninja'] = False
|
||||
os.mkdir(os.path.join(tmpd, 'subdir'))
|
||||
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
|
||||
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
|
||||
|
||||
post_summary = buildreq.specdescription.default_summary
|
||||
buildreq.specdescription.default_summary = orig_summary
|
||||
buildreq.specdescription.default_summary_score = orig_sscore
|
||||
buildreq.pypidata.get_pypi_name = orig_pypi_name
|
||||
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
|
||||
|
||||
self.assertEqual(self.reqs.pypi_provides, "name")
|
||||
self.assertEqual(post_summary, orig_summary)
|
||||
|
||||
def test_scan_for_configure_pypi_no_json(self):
|
||||
"""
|
||||
Test scan_for_configure when distutils is being used for the build
|
||||
pattern to test being unable to connect to pypi.
|
||||
"""
|
||||
orig_summary = buildreq.specdescription.default_summary
|
||||
orig_sscore = buildreq.specdescription.default_summary_score
|
||||
orig_pypi_name = buildreq.pypidata.get_pypi_name
|
||||
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
|
||||
name = "pypi-name"
|
||||
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
|
||||
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value="")
|
||||
with tempfile.TemporaryDirectory() as tmpd:
|
||||
conf = config.Config(tmpd)
|
||||
conf.config_opts['use_ninja'] = False
|
||||
os.mkdir(os.path.join(tmpd, 'subdir'))
|
||||
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
|
||||
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
|
||||
|
||||
post_summary = buildreq.specdescription.default_summary
|
||||
buildreq.specdescription.default_summary = orig_summary
|
||||
buildreq.specdescription.default_summary_score = orig_sscore
|
||||
buildreq.pypidata.get_pypi_name = orig_pypi_name
|
||||
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
|
||||
|
||||
self.assertEqual(self.reqs.pypi_provides, "name")
|
||||
self.assertEqual(post_summary, orig_summary)
|
||||
|
||||
def test_scan_for_configure_pypi_bad_json(self):
|
||||
"""
|
||||
Test scan_for_configure when distutils is being used for the build
|
||||
pattern to test being given bad json data.
|
||||
"""
|
||||
orig_summary = buildreq.specdescription.default_summary
|
||||
orig_sscore = buildreq.specdescription.default_summary_score
|
||||
orig_pypi_name = buildreq.pypidata.get_pypi_name
|
||||
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
|
||||
orig_json_loads = buildreq.json.loads
|
||||
name = "pypi-name"
|
||||
content = json.dumps({})
|
||||
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
|
||||
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content)
|
||||
buildreq.json.loads = MagicMock(side_effect=json.JSONDecodeError("", "", 0))
|
||||
with tempfile.TemporaryDirectory() as tmpd:
|
||||
conf = config.Config(tmpd)
|
||||
conf.config_opts['use_ninja'] = False
|
||||
os.mkdir(os.path.join(tmpd, 'subdir'))
|
||||
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
|
||||
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
|
||||
|
||||
post_summary = buildreq.specdescription.default_summary
|
||||
buildreq.specdescription.default_summary = orig_summary
|
||||
buildreq.specdescription.default_summary_score = orig_sscore
|
||||
buildreq.pypidata.get_pypi_name = orig_pypi_name
|
||||
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
|
||||
buildreq.json.loads = orig_json_loads
|
||||
|
||||
self.assertEqual(self.reqs.pypi_provides, "name")
|
||||
self.assertEqual(post_summary, orig_summary)
|
||||
|
||||
def test_scan_for_configure_pypi_override(self):
|
||||
"""
|
||||
Test scan_for_configure when distutils is being used for the build
|
||||
|
||||
Reference in New Issue
Block a user