Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugins: qmake #463

Merged
merged 43 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
229eaaf
plugins: qmake
ScarlettGatelyMoore May 24, 2023
93f3aa7
lint: autoformat
lengau May 25, 2023
edd1683
Update craft_parts/plugins/qmake_plugin.py
ScarlettGatelyMoore May 25, 2023
6283f2f
Update tests/unit/plugins/test_qmake_plugin.py
ScarlettGatelyMoore May 25, 2023
de9f811
lint: manual linting fixes
lengau May 25, 2023
281fd5c
Merge branch 'sgmoore/add_qmake_plugin' into aml_qmake
lengau May 25, 2023
ed12228
plugin: qmake - fix black tests and add myself to copyright.
ScarlettGatelyMoore May 25, 2023
80a9db6
Merge branch 'sgmoore/add_qmake_plugin' into aml_qmake
lengau May 25, 2023
3bd056f
Merge pull request #1 from lengau/aml_qmake
ScarlettGatelyMoore May 26, 2023
9af7da5
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore May 30, 2023
5de8bba
plugins: qmake: add support for qt6
ScarlettGatelyMoore May 30, 2023
96cd18e
Revert "plugins: qmake: add support for qt6"
ScarlettGatelyMoore May 30, 2023
bd52531
plugins: qmake: add support for qt6
ScarlettGatelyMoore May 30, 2023
9def6a6
plugin: qmake: fix linters ( black )
ScarlettGatelyMoore May 30, 2023
4962c74
plugins: qmake: fix tests
ScarlettGatelyMoore May 30, 2023
f65966f
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore May 31, 2023
3c8d605
plugins: qmake: fix qmake ruff tests
ScarlettGatelyMoore Jun 2, 2023
7d41913
plugin: qmake: fix ruff test by defining qt6 tests.
ScarlettGatelyMoore Jun 2, 2023
20eac62
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Jun 5, 2023
f7bb256
plugins: qmake, fix missing comma
ScarlettGatelyMoore Jun 7, 2023
96f32a3
plugin: qmake: fix function name in test.
ScarlettGatelyMoore Jun 7, 2023
652052a
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Jun 7, 2023
7525c13
plugin: qmake: try int for the major version
ScarlettGatelyMoore Jun 7, 2023
3a42ae0
plugins: qmake: add pluginproperties for out of source build property
ScarlettGatelyMoore Jun 8, 2023
0b3d31d
plugin: qmake: fix syntax
ScarlettGatelyMoore Jun 12, 2023
171d973
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Jun 13, 2023
95b3b5e
qmake_plugin: fix out of source build function
ScarlettGatelyMoore Aug 18, 2023
3fa1557
qmake plugin: fix imports
ScarlettGatelyMoore Aug 22, 2023
33f5183
qmake plugin: fix ruff linter
ScarlettGatelyMoore Aug 23, 2023
5416f2f
qmake_plugin: fix formatting in unit test
ScarlettGatelyMoore Aug 24, 2023
210880d
qmake plugin: fix copyright consistancy.
ScarlettGatelyMoore Aug 25, 2023
b57d6b5
qmake plugin: update licence to LGPL
ScarlettGatelyMoore Aug 25, 2023
143a9d0
qmake plugin: append source to configure command before conditional a…
ScarlettGatelyMoore Aug 25, 2023
d379d35
Merge branch 'main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Aug 25, 2023
b545d96
qmake plugin: fix formatting errors on test
ScarlettGatelyMoore Aug 25, 2023
0b79157
Revert "qmake plugin: append source to configure command before condi…
ScarlettGatelyMoore Aug 28, 2023
a0e4e04
Fix extra space in build command
ScarlettGatelyMoore Aug 31, 2023
230e72b
qmake plugin: fix configure command with suggestion from cmatsuoka, t…
ScarlettGatelyMoore Aug 31, 2023
cb7b2ca
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Sep 1, 2023
a03327f
Merge branch 'canonical:main' into sgmoore/add_qmake_plugin
ScarlettGatelyMoore Oct 2, 2023
02d38cb
Add missing @overrides
ScarlettGatelyMoore Oct 2, 2023
8468c73
style: lint fixes
lengau Oct 30, 2023
52c6e74
test: fix qmake plugin tests
lengau Oct 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
pip install -e .
- name: Install additional test dependencies
run: |
sudo apt install -y ninja-build cmake scons
sudo apt install -y ninja-build cmake scons qt5-qmake
# Build Chisel: needs a newer version of go than is available in Ubuntu 20.04
sudo snap install --classic --channel=latest/stable go
git clone https://github.com/canonical/chisel.git chisel-tmp
Expand Down
2 changes: 2 additions & 0 deletions craft_parts/plugins/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .npm_plugin import NpmPlugin
from .properties import PluginProperties
from .python_plugin import PythonPlugin
from .qmake_plugin import QmakePlugin
from .rust_plugin import RustPlugin
from .scons_plugin import SConsPlugin

Expand All @@ -58,6 +59,7 @@
"nil": NilPlugin,
"npm": NpmPlugin,
"python": PythonPlugin,
"qmake": QmakePlugin,
"rust": RustPlugin,
"scons": SConsPlugin,
}
Expand Down
118 changes: 118 additions & 0 deletions craft_parts/plugins/qmake_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2020-2023 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
ScarlettGatelyMoore marked this conversation as resolved.
Show resolved Hide resolved
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""The qmake plugin."""

from typing import Any, Dict, List, Set, cast

from .base import Plugin, PluginModel, extract_plugin_properties
from .properties import PluginProperties


class QmakePluginProperties(PluginProperties, PluginModel):
"""The part properties used by the qmake plugin."""

qmake_parameters: List[str] = []
qmake_project_file: str = ""

# part properties required by the plugin
source: str

@classmethod
def unmarshel(cls, data: Dict[str, Any]):
ScarlettGatelyMoore marked this conversation as resolved.
Show resolved Hide resolved
"""Populate class attributes from the part specification.

:param data: A dictionary containing part properties.

:return: The populated plugin properties data object.

:raise pydantic.ValidationError: If validation fails.
"""
plugin_data = extract_plugin_properties(
data, plugin_name="qmake", required=["source"]
)
return cls(**plugin_data)


class QMakePlugin(Plugin):
"""The qmake plugin is useful for building qmake-based parts.

These are projects that are built using .pro files.

This plugin uses the common plugin keywords as well as those for "sources".
For more information check the 'plugins' topic for the former and the
'sources' topic for the latter.

Additionally, this plugin uses the following plugin-specific keywords:

- qmake-parameters:
(list of strings)
additional options to pass to the qmake invocation.

- qmake-project-file:
(string)
the qmake project file to use. This is usually only needed if
qmake can not determine what project file to use on its own.
"""

properties_class = QmakePluginProperties

def get_build_snaps(self) -> Set[str]:
"""Return a set of required snaps to install in the build environment."""
return set()

def get_build_packages(self) -> Set[str]:
"""Return a set of required packages to install in the build environment."""
build_packages = {"g++", "make", "qt5-qmake"}

return build_packages

def get_build_environment(self) -> Dict[str, str]:
"""Return a dictionary with the environment to use in the build step."""
return {"QT_SELECT": "qt5"}
ScarlettGatelyMoore marked this conversation as resolved.
Show resolved Hide resolved

def get_build_commands(self) -> List[str]:
"""Return a list of commands to run during the build step."""
options = cast(QmakePluginProperties, self._options)

qmake_configure_command = [
"qmake",
'QMAKE_CFLAGS+="${CFLAGS:-}"',
'QMAKE_CXXFLAGS+="${CXXFLAGS:-}"',
'QMAKE_LFLAGS+="${LDFLAGS:-}"',
] + options.qmake_parameters

if options.qmake_project_file:
qmake_configure_command.append(
[
f'"{self._part_info.part_src_dir}"',
"/",
cmatsuoka marked this conversation as resolved.
Show resolved Hide resolved
f'"{options.qmake_project_file}"',
]
)
else:
qmake_configure_command.append(f'"{self._part_info.part_src_dir}"')
ScarlettGatelyMoore marked this conversation as resolved.
Show resolved Hide resolved

return [
" ".join(qmake_configure_command),
f"env -u CFLAGS -u CXXFLAGS make -j{self._part_info.parallel_build_count}",
f"make install INSTALL_ROOT={self._part_info.part_install_dir}",
]

@property
def out_of_source_build(self) -> bool:
"""Return whether the plugin performs out-of-source-tree builds."""
return True
2 changes: 2 additions & 0 deletions tests/unit/plugins/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
NilPlugin,
NpmPlugin,
PythonPlugin,
QmakePlugin,
RustPlugin,
)

Expand All @@ -57,6 +58,7 @@ class TestGetPlugin:
("nil", NilPlugin, {}),
("npm", NpmPlugin, {"source": "."}),
("python", PythonPlugin, {"source": "."}),
("qmake", QmakePlugin, {"source": "."}),
("rust", RustPlugin, {"source": "."}),
],
)
Expand Down
106 changes: 106 additions & 0 deletions tests/unit/plugins/test_qmake_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2020-2022 Canonical Ltd.
ScarlettGatelyMoore marked this conversation as resolved.
Show resolved Hide resolved
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from pathlib import Path

import pytest

from craft_parts.infos import PartInfo, ProjectInfo
from craft_parts.parts import Part
from craft_parts.plugins.qmake_plugin import QMakePlugin


@pytest.fixture
def setup_method_fixture():
def _setup_method_fixture(new_dir, properties=None):
if properties is None:
properties = {}
properties["source"] = "."
plugin_properties = QMakePlugin.properties_class.unmarshal(properties)
part = Part("foo", {})

project_info = ProjectInfo(application_name="test", cache_dir=new_dir)
project_info._parallel_build_count = 42

part_info = PartInfo(project_info=project_info, part=part)
part_info._part_install_dir = Path("install/dir")

return QMakePlugin(properties=plugin_properties, part_info=part_info)

yield _setup_method_fixture


class TestPluginQMakePlugin:
"""QMake plugin tests."""

def test_get_build_snaps(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir)
assert plugin.get_build_snaps() == set()

def test_get_build_packages_default(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir)
assert plugin.get_build_packages() == {
"g++",
"make",
"qt5-qmake",
}

def test_get_build_environment(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir)

assert plugin.get_build_environment() == {
"QT_SELECT": "qt5",
}

def test_get_build_commands_default(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir)

assert plugin.get_build_commands() == [
f"qmake QMAKE_CFLAGS+=${CFLAGS:-} QMAKE_CXXFLAGS+=${CXXFLAGS:-} QMAKE_LFLAGS+=${LDFLAGS:-}",
f"env -u CFLAGS -u CXXFLAGS make -j{self._part_info.parallel_build_count}",
f"make install INSTALL_ROOT={self._part_info.part_install_dir}",
]

def test_get_build_commands_qmake_project_file(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir, properties={"qmake_project_file": "hello.pro"})

assert plugin.get_build_commands() == [
f"qmake QMAKE_CFLAGS+=${CFLAGS:-} QMAKE_CXXFLAGS+=${CXXFLAGS:-} \
QMAKE_LFLAGS+=${LDFLAGS:-} {self._part_info.part_src_dir}/hello.pro",
f"env -u CFLAGS -u CXXFLAGS make -j{self._part_info.parallel_build_count}",
f"make install INSTALL_ROOT={self._part_info.part_install_dir}",
]

def test_get_build_commands_cmake_parameters(self, setup_method_fixture, new_dir):
qmake_parameters = [
"QMAKE_LIBDIR+=/foo",
]

plugin = setup_method_fixture(new_dir, {"qmake-parameters": qmake_parameters})

assert plugin.get_build_commands() == [
(
f"qmake QMAKE_CFLAGS+=${CFLAGS:-} QMAKE_CXXFLAGS+=${CXXFLAGS:-} QMAKE_LFLAGS+=${LDFLAGS:-}",
f'{" ".join(qmake_parameters)}'
),
f"env -u CFLAGS -u CXXFLAGS make -j{self._part_info.parallel_build_count}",
f"make install INSTALL_ROOT={self._part_info.part_install_dir}",
]

def test_get_out_of_source_build(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(new_dir)

assert plugin.get_out_of_source_build() is True