Up until this point, MinGW has been treated as a very special
case, even having its own sub-projects.

While this was perfectly reasonable back when lcitool was
introduced, now that we support cross-building as a first-class
concept in the Dockerfile generator it makes little sense for
MinGW builds not to make use of it.

Note that, as of this commit, MinGW is still considered somewhat
special: in particular, only the Dockerfile generator can treat
it like any other architecture, and everything else still needs
to use the sub-projects. In the longer run we'll want to expand
the first-class cross-building support to the rest of lcitool;
this is merely another step in that direction.

Signed-off-by: Andrea Bolognani <abolo...@redhat.com>
---
 guests/lcitool | 46 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/guests/lcitool b/guests/lcitool
index 37a0253..abc803b 100755
--- a/guests/lcitool
+++ b/guests/lcitool
@@ -93,6 +93,8 @@ class Util:
             "armv6l": "arm-linux-gnueabi",
             "armv7l": "arm-linux-gnueabihf",
             "i686": "i686-linux-gnu",
+            "mingw32": "i686-w64-mingw32",
+            "mingw64": "x86_64-w64-mingw32",
             "mips": "mips-linux-gnu",
             "mipsel": "mipsel-linux-gnu",
             "mips64el": "mips64el-linux-gnuabi64",
@@ -726,6 +728,7 @@ class Application:
         os_full = os_name + os_version
 
         pkgs = {}
+        cross_pkgs = {}
         pip_pkgs = {}
         keys = ["default", package_format, os_name, os_full]
 
@@ -746,6 +749,24 @@ class Application:
                 if pkgs[package] is None:
                     del pkgs[package]
 
+        if cross_arch:
+            cross_projects = []
+            for project in projects:
+                cross_project = project + "+" + cross_arch
+                if cross_project in facts["projects"]:
+                    cross_projects.extend([cross_project])
+
+            for project in cross_projects:
+                for package in self._projects.get_packages(project):
+                    for key in keys:
+                        if key in mappings[package]:
+                            cross_pkgs[package] = mappings[package][key]
+
+                    if package not in cross_pkgs:
+                        continue
+                    if cross_pkgs[package] is None:
+                        del cross_pkgs[package]
+
         pkg_align = " \\\n" + (" " * len("RUN " + package_manager + " "))
         pip_pkg_align = " \\\n" + (" " * len("RUN pip3 "))
 
@@ -753,6 +774,10 @@ class Application:
         varmap["package_manager"] = package_manager
         varmap["pkgs"] = pkg_align[1:] + 
pkg_align.join(sorted(set(pkgs.values())))
 
+        if cross_arch:
+            varmap["cross_abi"] = Util.native_arch_to_abi(cross_arch)
+            varmap["cross_pkgs"] = pkg_align[1:] + 
pkg_align.join(sorted(set(cross_pkgs.values())))
+
         if pip_pkgs:
             varmap["pip_pkgs"] = pip_pkg_align[1:] + 
pip_pkg_align.join(sorted(set(pip_pkgs.values())))
 
@@ -850,6 +875,15 @@ class Application:
 
             sys.stdout.write(script.format(**varmap))
 
+            if cross_arch:
+                # Intentionally a separate RUN command from the above
+                # so that the common packages of all cross-built images
+                # share a Docker image layer.
+                sys.stdout.write(textwrap.dedent("""
+                    RUN {package_manager} install -y {cross_pkgs} && \\
+                        {package_manager} clean all -y
+                """).format(**varmap))
+
         if "pip_pkgs" in varmap:
             sys.stdout.write(textwrap.dedent("""
                 RUN pip3 install {pip_pkgs}
@@ -859,7 +893,7 @@ class Application:
             ENV LANG "en_US.UTF-8"
         """).format(**varmap))
 
-        if cross_arch:
+        if cross_arch and package_format == "deb":
             sys.stdout.write(textwrap.dedent("""
                 ENV ABI "{cross_abi}"
                 ENV CONFIGURE_OPTS "--host={cross_abi} \\
@@ -867,6 +901,14 @@ class Application:
                 ENV PKG_CONFIG_LIBDIR "/usr/lib/{cross_lib}/pkgconfig"
             """).format(**varmap))
 
+        if cross_arch and package_format == "rpm":
+            sys.stdout.write(textwrap.dedent("""
+                ENV ABI "{cross_abi}"
+                ENV CONFIGURE_OPTS "--host={cross_abi} \\
+                                    --target={cross_abi}"
+                ENV PKG_CONFIG_LIBDIR 
"/usr/{cross_abi}/sys-root/mingw/lib/pkgconfig:/usr/{cross_abi}/sys-root/mingw/share/pkgconfig"
+            """).format(**varmap))
+
     def _action_dockerfile(self, args):
         mappings = self._projects.get_mappings()
         pip_mappings = self._projects.get_pip_mappings()
@@ -887,7 +929,7 @@ class Application:
         if package_format not in ["deb", "rpm"]:
             raise Exception("Host {} doesn't support Dockerfiles".format(host))
         if cross_arch:
-            if os_name != "Debian":
+            if os_name not in ["Debian", "Fedora"]:
                 raise Exception("Cannot cross compile on {}".format(os_name))
             if cross_arch == self._native_arch:
                 raise Exception("Cross arch {} should differ from native {}".
-- 
2.24.1

Reply via email to