Skip to content

Commit

Permalink
plugins: qmake: add support for qt6
Browse files Browse the repository at this point in the history
  • Loading branch information
ScarlettGatelyMoore committed May 30, 2023
1 parent 9af7da5 commit 5de8bba
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 13 deletions.
39 changes: 31 additions & 8 deletions craft_parts/plugins/qmake_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class QmakePluginProperties(PluginProperties, PluginModel):

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

# part properties required by the plugin
source: str
Expand Down Expand Up @@ -67,6 +68,11 @@ class QmakePlugin(Plugin):
(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.
- qmake_major_version:
(string)
set the qt major version. This is only needed to support qt6 builds.
Version 5 is default.
"""

properties_class = QmakePluginProperties
Expand All @@ -77,24 +83,41 @@ def get_build_snaps(self) -> Set[str]:

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"}
options = cast(QmakePluginProperties, self._options)

if options.qmake_major_version == "6":
build_packages = {"g++", "make", "qmake6"}
else:
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"}
options = cast(QmakePluginProperties, self._options)

if options.qmake_major_version == "6":
return {"QT_SELECT": qt6}
else:
return {"QT_SELECT": "qt5"}

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_major_version == "6":
qmake_configure_command = [
"qmake6",
'QMAKE_CFLAGS+="${CFLAGS:-}"',
'QMAKE_CXXFLAGS+="${CXXFLAGS:-}"',
'QMAKE_LFLAGS+="${LDFLAGS:-}"',
] + options.qmake_parameters
else:
qmake_configure_command = [
"qmake",
'QMAKE_CFLAGS+="${CFLAGS:-}"',
'QMAKE_CXXFLAGS+="${CXXFLAGS:-}"',
'QMAKE_LFLAGS+="${LDFLAGS:-}"',
] + options.qmake_parameters

if options.qmake_project_file:
qmake_configure_command.extend(
Expand Down
154 changes: 154 additions & 0 deletions tests/integration/plugins/test_qmake.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2022 Canonical Ltd.
#
# 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/>.

import subprocess
import textwrap
from pathlib import Path

import pytest
import yaml

from craft_parts import LifecycleManager, Step


@pytest.mark.parametrize(
"prefix,install_path",
[
(None, "usr/local/bin"),
("", "bin"),
("/usr/local", "usr/local/bin"),
("/something/else", "something/else/bin"),
],
)
def test_qmake_plugin(new_dir, prefix, install_path):
parts_yaml = textwrap.dedent(
"""\
parts:
foo:
plugin: qmake
source: .
"""
)

parts = yaml.safe_load(parts_yaml)

Path("qmake.build").write_text(
textwrap.dedent(
"""\
project('qmake-hello', 'c')
executable('hello', 'hello.c', install : true)
"""
)
)

Path("hello.c").write_text(
textwrap.dedent(
"""\
#include <stdio.h>
int main()
{
printf(\"hello world\\n\");
return 0;
}
"""
)
)

Path("hello.pro").write_text(
textwrap.dedent(
"""\
CONFIG = console release
SOURCES += hello.c
target.path = /bin/
INSTALLS += target
"""
)
)

lf = LifecycleManager(parts, application_name="test_qmake", cache_dir=new_dir)
actions = lf.plan(Step.PRIME)

with lf.action_executor() as ctx:
ctx.execute(actions)

binary = Path(lf.project_info.prime_dir, install_path, "qmake-hello")

output = subprocess.check_output([str(binary)], text=True)
assert output == "hello world\n"


@pytest.mark.parametrize(
"prefix,install_path",
[
(None, "usr/local/bin"),
("", "bin"),
("/usr/local", "usr/local/bin"),
("/something/else", "something/else/bin"),
],
)
def test_qmake_plugin_subdir(new_dir, prefix, install_path):
"""Verify qmake builds with a source subdirectory."""
parts_yaml = textwrap.dedent(
"""\
parts:
foo:
plugin: qmake
source: .
source-subdir: test-subdir
"""
)

parts = yaml.safe_load(parts_yaml)

source_subdir = Path("test-subdir")
source_subdir.mkdir(parents=True)

(source_subdir / "hello.c").write_text(
textwrap.dedent(
"""\
#include <stdio.h>
int main()
{
printf(\"hello world\\n\");
return 0;
}
"""
)
)

(source_subdir / "hello.pro").write_text(
textwrap.dedent(
"""\
CONFIG = console release
SOURCES += hello.c
target.path = /bin/
INSTALLS += target
"""
)
)

lf = LifecycleManager(parts, application_name="test_qmake", cache_dir=new_dir)
actions = lf.plan(Step.PRIME)

with lf.action_executor() as ctx:
ctx.execute(actions)

binary = Path(lf.project_info.prime_dir, install_path, "qmake-hello")

output = subprocess.check_output([str(binary)], text=True)
assert output == "hello world\n"
6 changes: 3 additions & 3 deletions tests/integration/sources/test_rpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ def sample_rpm(tmp_path: Path) -> Path:
Release: 0
Summary: A sample package
License: GPL
%description
A little sample package!
%install
mkdir -p %{buildroot}/etc
bash -c "echo Sample contents > %{buildroot}/etc/sample.txt"
%files
/etc/sample.txt
"""
Expand Down
35 changes: 33 additions & 2 deletions tests/unit/plugins/test_qmake_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,33 @@ def test_get_build_packages_default(self, setup_method_fixture, new_dir):
"qt5-qmake",
}

def test_get_build_environment(self, setup_method_fixture, new_dir):
def test_get_build_packages_qt6(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(
new_dir, properties={"qmake_major_version": "6"}
)

assert plugin.get_build_packages() == {
"g++",
"make",
"qmake6",
}

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

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

def test_get_build_environment_qt6(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(
new_dir, properties={"qmake_major_version": "6"}
)

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

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

Expand All @@ -75,6 +95,17 @@ def test_get_build_commands_default(self, setup_method_fixture, new_dir):
f"make install INSTALL_ROOT={plugin._part_info.part_install_dir}",
]

def test_get_build_commands_qt6(self, setup_method_fixture, new_dir):
plugin = setup_method_fixture(
new_dir, properties={"qmake_major_version": "6"}
)

assert plugin.get_build_commands() == [
"qmake6 QMAKE_CFLAGS+=${CFLAGS:-} QMAKE_CXXFLAGS+=${CXXFLAGS:-} QMAKE_LFLAGS+=${LDFLAGS:-}",
f"env -u CFLAGS -u CXXFLAGS make -j{plugin._part_info.parallel_build_count}",
f"make install INSTALL_ROOT={plugin._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"}
Expand All @@ -87,7 +118,7 @@ def test_get_build_commands_qmake_project_file(self, setup_method_fixture, new_d
f"make install INSTALL_ROOT={plugin._part_info.part_install_dir}",
]

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

0 comments on commit 5de8bba

Please sign in to comment.