Skip to content

Commit

Permalink
Add handling for multiline find_package
Browse files Browse the repository at this point in the history
Previously support for cmake's find_package parsing was only able to
handle single line entries. This change adds support for multiline
versions and allows for module namespacing (currently qt6 and kf6
support is available).

The change for cmake_modules shows this namespacing in use.

Signed-off-by: William Douglas <[email protected]>
  • Loading branch information
bryteise committed Mar 15, 2024
1 parent ec9d44c commit 61973a3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
26 changes: 25 additions & 1 deletion autospec/buildreq.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,21 +483,45 @@ def parse_r_description(self, filename, packages):
def set_build_req(self, config):
"""Add build requirements based on the build pattern."""

def findpackage_parse_lines(self, fp_line, line_iter, cmake_modules):
"""Parse find_package multiline segment of the line_iter."""
qt6module = re.compile(r"^[^#]*find_package\(\s*\bQt6.*", re.I)
kf6module = re.compile(r"^[^#]*find_package\(\s*\bKF6.*", re.I)
ns = ''
if qt6module.search(fp_line):
ns = 'qt6'
elif kf6module.search(fp_line):
ns = 'kf6'
while True:
ln = next(line_iter).strip()
if not ln:
continue
modules = ln.strip(')').split(' ')
for module in modules:
if module:
if pkg := cmake_modules.get(f"{ns}.{module}"):
self.add_buildreq(pkg)
if ')' in ln:
break

def parse_cmake(self, filename, cmake_modules, conf32):
"""Scan a .cmake or CMakeLists.txt file for what's it's actually looking for."""
findpackage = re.compile(r"^[^#]*find_package\((\w+)\b.*\)", re.I)
findpackage_multiline = re.compile(r"^[^#]*find_package\((\w+)\b.*", re.I)
pkgconfig = re.compile(r"^[^#]*pkg_check_modules\s*\(\w+ (.*)\)", re.I)
pkg_search_modifiers = {'REQUIRED', 'QUIET', 'NO_CMAKE_PATH',
'NO_CMAKE_ENVIRONMENT_PATH', 'IMPORTED_TARGET'}
extractword = re.compile(r'(?:"([^"]+)"|(\S+))(.*)')

with util.open_auto(filename, "r") as f:
lines = f.readlines()
lines = iter(f.readlines())
for line in lines:
if match := findpackage.search(line):
module = match.group(1)
if pkg := cmake_modules.get(module):
self.add_buildreq(pkg)
elif findpackage_multiline.search(line):
self.findpackage_parse_lines(line, lines, cmake_modules)

if match := pkgconfig.search(line):
rest = match.group(1)
Expand Down
18 changes: 17 additions & 1 deletion autospec/cmake_modules
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ Python3, python3-dev
PythonInterp, python3
PythonLibs, python3-dev
QGpgme, gpgme-dev gpgme-extras
QHelpGenerator, extra-cmake-modules qttools-dev
QHelpGenerator, extra-cmake-modules qt6tools-dev
QMobipocket, kdegraphics-mobipocket-dev
Qca-qt5, qca-qt5-dev
Qt3DTests, qt6base-dev
Expand Down Expand Up @@ -901,6 +901,19 @@ igsc, igsc-dev
json-c, json-c-dev
kColorPicker, kcolorpicker-dev
kImageAnnotator, kimageannotator-dev
kf6.KIO, kio-dev
kf6.I18n, ki18n-dev
kf6.CoreAddons, kcoreaddons-dev
kf6.Config, kconfig-dev
kf6.Crash, kcrash-dev
kf6.DBusAddons, kdbusaddons-dev
kf6.Notifications, knotifications-dev
kf6.Runner, krunner-dev
kf6.Purpose, purpose-dev
kf6.FileMetaData, kfilemetadata-dev
kf6.JobWidgets, kjobwidgets-dev
kf6.Service, kservice-dev
kf6.StatusNotifierItem, kstatusnotifieritem-dev
kim-api, kim-api-data
leveldb, leveldb-dev
libavif, libavif-dev
Expand All @@ -926,6 +939,9 @@ pugixml, pugixml-dev
pybind11, pypi(pybind11)
qt5xdg, libqtxdg-data
qt5xdgiconloader, libqtxdg-data
qt6.Gui, qt6base-dev
qt6.DBus, qt6base-dev
qt6.Widgets, qt6base-dev
qtxdg-tools, qtxdg-tools-data
rabbitmq-c, rabbitmq-c-dev
realsense2, librealsense-dev
Expand Down
27 changes: 26 additions & 1 deletion tests/test_buildreq.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,20 +621,45 @@ def test_parse_cmake_find_package(self):
"valid": "valid",
"valid_but_commented": "valid_but_commented",
"different_name": "another_name",
"qt6.module1": "qt6module1",
"qt6.module2": "qt6module2",
"kf6.module3": "kf6module3",
"kf6.module4": "kf6module4",
".module5": "namodule5",
".module6": "namodule6"
}
content = '''
find_package(valid)
#find_package(foo)
# find_package(valid_but_commented)
find_package(different_name)
find_package(Qt6 stuff
module1
module2)
find_package(KF6 stuff
module3
module4
)
find_package(NOT_HANDLED_NAMESPACE stuff
module5
module6
)
'''
with tempfile.TemporaryDirectory() as tmpd:
with open(os.path.join(tmpd, 'fname'), 'w') as f:
f.write(content)
self.reqs.parse_cmake(os.path.join(tmpd, 'fname'), cmake_modules, False)

self.assertEqual(self.reqs.buildreqs,
set(['valid', 'another_name']))
set(['valid',
'another_name',
'qt6module1',
'qt6module2',
'kf6module3',
'kf6module4',
'namodule5',
'namodule6']))

def test_r_desc_field_begin(self):
"""Test parsing of the first R description field."""
Expand Down

0 comments on commit 61973a3

Please sign in to comment.