Commit cb83342a authored by Sandro Knauß's avatar Sandro Knauß Committed by Ben Cooksley

Move settings for abi-complience-checker to own yaml file.

This allows for some repositories, like akonadi-search, which need special settings for creating a ABI dump, to have those settings.

Differential Revision:
parent 28d3f7b1
import os
import re
import argparse
import logging
import os
import pathlib
import argparse
import tempfile
import re
import subprocess
import sys
import tempfile
import yaml
from collections import defaultdict
from typing import Dict, List, Union, Set
from helperslib import CommonUtils, ToolingSettings
from helperslib import Packages, EnvironmentHandler
# Make sure logging is ready to go
ACCXMLTMPL = """<version>{version}</version>
def cmake_parser(lines: List) -> Dict:
"""A small cmake parser, if you search for a better solution think about using
a proper one based on ply.
......@@ -102,9 +123,10 @@ def cmake_parser(lines: List) -> Dict:
# This class stores information on the library in question and assists in extracting information concerning it
class Library:
# Make sure we initialize everything we are going to need
def __init__(self, name: str) -> None:
def __init__(self, name: str, accSettings: Dict) -> None:
# name of the library = name # type: str
self.accSettings = accSettings # type: Dict
# The raw cmake Parser output, available for debugging purposes
# see cmake_parser function for the return value
......@@ -208,7 +230,10 @@ class Library:
version = self.version
headers = set() # type: Set[str]
libs = set() # type: Set[str]
additionalIncludes = set() # type: Set[str]
skipIncludePaths = set(self.accSettings['skip_include_paths']) # type: Set[str]
additionalIncludes = set(self.accSettings['add_include_paths']) # type: Set[str]
gccOptions = set(self.accSettings['gcc_options']) # type: Set[str]
# list of general include directories
prefixHeaders = [os.path.abspath(i) for i in buildEnvironment.get('CMAKE_PREFIX_PATH').split(":")]
......@@ -233,32 +258,24 @@ class Library:
# Now we can go ahead and generate the XML file for abi-compliance-checker
xml = """
""".format(version=version, headers="\n".join(headers), libs="\n".join(libs), additionalIncludes="\n".join(additionalIncludes)) # replace with f-String in Python 3.6
def _(l):
return "\n ".join(l)
xml = ACCXMLTMPL.format(version=version,
# Write the generated XML out to a file to pass to abi-compliance-checker
# We will give this to abi-compliance-checker using it's --dump parameter
with open("{version}.xml".format(version=version),"w") as f: # replace with f-String in python 3.6
# acc is compatible for C/C++ as Qt using C++11 and -fPic we need to set the gcc settings explitly
subprocess.check_call(["abi-compliance-checker", "-gcc-options", "-std=c++11 -fPIC", "-l",, "--dump",], env=runtimeEnvironment)
# acc is compatible for C/C++ (but --lang C++ doesn't remove the warning about C++ only settings).
subprocess.check_call(["abi-compliance-checker", "--lang", "C++", "-l",, "--dump",], env=runtimeEnvironment)
# Parse the command line arguments we've been given
parser = argparse.ArgumentParser(description='Utility to create abi checker tarballs.')
......@@ -273,6 +290,13 @@ arguments = parser.parse_args()
# Make sure we have an environment ready for executing commands
buildEnvironment = EnvironmentHandler.generateFor( installPrefix=arguments.usingInstall )
# get acc settings
localMetadataPath = os.path.join( CommonUtils.scriptsBaseDirectory(), 'local-metadata', 'abi-compliance-checker.yaml' )
accSettings = ToolingSettings.Loader( arguments.project, arguments.platform )
accSettings.loadSpecificationFile( localMetadataPath )
# Get ready to start searching for libraries
foundLibraries = []
......@@ -283,7 +307,7 @@ with open(arguments.buildLog, encoding='utf-8') as log:
for line in log.readlines():
match = cmakeConfig.match(line)
if match:
foundLibrary = Library( )
foundLibrary = Library(, accSettings )
# Initialize the archive manager
......@@ -333,7 +357,7 @@ for library in foundLibraries:
ourArchive.storePackage(packageName, fileName, scmRevision, extraMetadata)
except subprocess.CalledProcessError as e:
retval = e.returncode
logging.error("abi-complience-checker exited with {retval}".format(retval=retval))
logging.error("abi-compliance-checker exited with {retval}".format(retval=retval))
# We had an issue with one of the ABIs
if retval != 0:
import fnmatch
import copy
import os
import yaml
from typing import Dict, Union, List
from helperslib import Buildable, CommonUtils
# Class to make it convenient to read configs for working with settings for tooling
class Loader(object):
def __init__(self, project: str, platform: str) -> None:
self.project = project
self.platform = platform
self.config = dict()
# Initialise the dependnecy resolver
self.resolver = Buildable.DependencyResolver()
# Ask the resolver to load the list of projects...
projectsTreeLocation = os.path.join( CommonUtils.scriptsBaseDirectory(), 'repo-metadata', 'projects' )
self.resolver.loadProjectsFromTree( projectsTreeLocation )
self.resolverProject = self.resolver.retrieveProject( project )
# Allow fetching our config
def __getitem__(self, name: str) -> Union[List, str, Dict]:
# Do we know about this attribute?
if name in self.config:
# Then return it
return self.config[name]
# We don't know about it
raise KeyError
# Load the given specification file
def loadSpecificationFile(self, configFileLocation: str):
# Does the file exist?
# If it does not, then we don't need to do anything else
if not os.path.isfile( configFileLocation ):
# Load the file now
with open( configFileLocation, 'r' ) as configFile:
# Parse the YAML file
projectConfig = yaml.load( configFile )
entries = []
for key in projectConfig:
if fnmatch.fnmatch( self.resolverProject.path, key ):
entries.append( key )
# sorting all entries - the entries at the end overwrites the former settings
# len is efficient, but would fail if we have single letter repo names
entries.sort( key=len )
self.config = dict()
for entry in entries:
content = projectConfig[entry]
self.config.update( content['general'] )
self.config.update( content[self.platform] ) # try to load platform specific settings
except KeyError:
# This file is used to specify the builds of abi-compliance-checker.
# So far following settings are used:
# - gcc_options:
# specify the gcc options to build of headers
# - skip_include_paths:
# list pf paths to exclude from searching for headers
# - add_include_paths:
# list of paths to search for headers
# for more information about the settings: abi-compliance-checker --info
- "-std=c++11"
- "-fPIC"
- /usr/lib/python3.6/site-packages/utils/fake_libc_include
- /usr/include/clang/AST
- /usr/lib64/clang/6.0.1/include
- /usr/lib64/qt5/mkspecs/linux-g++
# "SUSEQt5.10": # special settings for one platform
# gcc_options:
# - something
# - nextsetting
# "kde/*": # special settings for all repos in kde (fnmatch)
# general:
# add_include_paths:
# - special1
- "-std=c++11"
- "-fPIC"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment