https://codeberg.org/interpeer/packeteer.git
Tip revision: 092479b6baa5d97324ade24dc04f8031f0a4e86f authored by Jens Finkhaeuser on 05 May 2023, 07:19:00 UTC
Merge branch 'main' of codeberg.org:interpeer/packeteer
Merge branch 'main' of codeberg.org:interpeer/packeteer
Tip revision: 092479b
conanfile.py
import os
from conan import ConanFile
from conan.tools.meson import MesonToolchain, Meson
from conan.tools.layout import basic_layout
from conan.tools.files import copy
from conan.tools import scm
def get_meson_build(filename = 'meson.build'):
if hasattr(get_meson_build, '__cache'):
return getattr(get_meson_build, '__cache')
try:
import os
from mesonbuild import mparser, mesonlib
fn = os.path.join(os.getcwd(), filename)
with open(fn, encoding='utf-8') as f:
ast = mparser.Parser(f.read(), filename).parse()
setattr(get_meson_build, '__cache', ast)
return ast
except:
return None
def _recurse_ast_lines(lines, nodes):
from mesonbuild import mparser
for cur in lines:
found = False
for node_type, node_name in nodes:
if isinstance(cur, node_type):
# Match, but depending on node_type we may have some different
# thing to do.
if node_type == mparser.FunctionNode:
if cur.func_name == node_name:
found = True
yield cur
elif node_type == mparser.MethodNode:
if cur.name == node_name:
found = True
yield cur
if not found:
if isinstance(cur, mparser.IfClauseNode):
for ifb in cur.ifs:
for entry in _recurse_ast_lines(ifb.block.lines, nodes):
yield entry
if isinstance(cur.elseblock, mparser.CodeBlockNode):
for entry in _recurse_ast_lines(cur.elseblock.lines, nodes):
yield entry
elif isinstance(cur, mparser.AssignmentNode):
for entry in _recurse_ast_lines([cur.value], nodes):
yield entry
def recurse_find(filename, nodes):
ast = get_meson_build(filename)
if ast is None:
return
for entry in _recurse_ast_lines(ast.lines, nodes):
yield entry
def get_project(filename = 'meson.build'):
from mesonbuild import mparser
for node in recurse_find(filename, [(mparser.FunctionNode, 'project')]):
return node
return None
def get_repo(filename = 'meson.build'):
from mesonbuild import mparser
for node in recurse_find(filename, [(mparser.MethodNode, 'set_quoted')]):
key, value = node.args.arguments
if key.value.endswith('_PACKAGE_URL'):
return value.value
return None
def get_libs(filename = 'meson.build'):
res = {
'shared': [],
'static': [],
'both': [],
}
from mesonbuild import mparser
nodes = [
(mparser.FunctionNode, 'shared_library'),
(mparser.FunctionNode, 'static_library'),
(mparser.FunctionNode, 'library'),
]
for node in recurse_find(filename, nodes):
key = 'both'
if node.func_name == 'shared_library':
key = 'shared'
elif node.func_name == 'static_library':
key = 'static'
res[key].append(node.args.arguments[0].value)
return res
def get_author():
try:
with open('AUTHORS', 'r') as fh:
return fh.readlines()[0].strip()
except:
return None
def get_package():
proj = get_project()
if proj is None:
return None
return proj.args.arguments[0].value
def get_version():
proj = get_project()
if proj is None:
return None
for key, value in proj.args.kwargs.items():
if key.value != 'version':
continue
return value.value
def get_git_ref(conanfile):
git = scm.Git(conanfile)
return git.get_commit()[:8]
def get_full_version(conanfile):
try:
return f'{get_version()}+{get_git_ref(conanfile)}'
except:
return None
class Package(ConanFile):
generators = ('PkgConfigDeps', 'CMakeDeps')
settings = ('os', 'arch', 'compiler', 'build_type')
name = get_package()
url = get_repo()
author = get_author()
@property
def description(self):
return self.conan_data['description']
@property
def topics(self):
return self.conan_data['topics']
@property
def license(self):
return self.conan_data['license']
@property
def homepage(self):
return self.conan_data['homepage']
@property
def version(self):
if not hasattr(self, '__version') or not self.__version:
self.__version = get_full_version(self)
return self.__version
@version.setter
def version(self, value):
print('setting to', value)
self.__version = value
# Binary configuration
options = {'shared': [True, False]}
default_options = {'shared': False}
# Sources are located in the same place as this recipe, copy them to the recipe
exports = (
"LICENSE",
"codemeta.json",
"AUTHORS",
"meson.build", # XXX Need this also here for project definitions
)
exports_sources = (
"meson.build",
"meson_options.txt",
".oclint",
"build-config.h.in",
"include/*",
"lib/*",
"ext/*",
"util/*",
"benchmarks/*",
"vendor/*",
"test/*",
"examples/*",
"subprojects/*.wrap",
)
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def build_requirements(self):
self.tool_requires('pkgconf/[>=1.9]')
def requirements(self):
for req in self.conan_data.get('requires', []):
self.requires(req)
def layout(self):
basic_layout(self)
def generate(self):
tc = MesonToolchain(self)
tc.project_options['libdir'] = 'lib'
tc.project_options['build_extras'] = 'false'
tc.generate()
def build(self):
meson = Meson(self)
meson.configure()
meson.build()
def package(self):
meson = Meson(self)
meson.install()
def package_info(self):
self.cpp_info.set_property("pkg_config_name", self.name)
libs = get_libs()
self.cpp_info.libs = []
if self.options.shared:
self.cpp_info.libs = list(set(libs['shared'] + libs['both']))
else:
self.cpp_info.libs = list(set(libs['static'] + libs['both']))
if __name__ == '__main__':
package = get_package()
version = get_full_version(None)
print(f'Detected package: {package}-{version}')
repo = get_repo()
print(f'Detected repo: {repo}')
author = get_author()
print(f'Detected author: {author}')
libs = get_libs()
print('Detected libs:')
for key, value in libs.items():
print(f' {key}:')
for v in value:
print(f' {v}')