如何将 C++ Gtkmm 从 Linux 交叉编译到 Windows?

如何解决如何将 C++ Gtkmm 从 Linux 交叉编译到 Windows?

有一段时间我在学习 C++,我一直在寻找一些跨平台、易于使用的 GUI,我选择了 Gtkmm。

我已经为我的公司在 Linux 下使用 Gtkmm 制作了我的第一个应用程序。使用空地的体验很顺利。在 Linux 下一切正常,但是当我开始在 Windows 下编译它时,问题开始出现。最后,经过一些代码更改后,我能够在 Windows 下编译它并且“工作”了。

现在我想在Linux下交叉编译它,这是不可能的。我发现的每个指南和帖子都非常陈旧,提供的信息不准确,经常有损坏的链接和其中提到的工具不存在。

有人有过类似的经历吗?制作应用花了我几个小时,而处理所有这些废话已经浪费了我 2 周的生活,但它仍然无法正常工作。

我怎样才能做到这一点?

解决方法

我自己还没有做过,但我相信 Meson Build System 可以帮助你。这是一个使用 GTK 的 simple example。有一些成功的应用程序使用它在 Linux 和 Windows 之间进行交叉编译,例如 gedit。你可以看看 their repo 这是一个很好的例子。

似乎 Gtkmm 在 their repo 中也有一些例子。

,

您不必自己交叉编译 Gtkmm,您可以从 MSYS2 repos 获得预构建的二进制文件。或者,如果您坚持自己构建它,您可能需要查看 MSYS2 的 build scripts

即使在 Wine 下,MSYS2 的包管理器也不能在 Linux 上运行,因此您必须手动下载包及其依赖项。

由于工作量太大,我制作了 a small script 来为您完成。

  • 安装 makewgettarzstd

  • git clone https://github.com/holyblackcat/quasi-msys2

  • cd quasi-msys2

  • 现在您可以搜索包:make list-all | grep gtkmm

    我看到以下软件包可用:

    mingw-w64-x86_64-gtkmm
    mingw-w64-x86_64-gtkmm3
    mingw-w64-x86_64-gtkmm4
    
  • 让我们安装 Gtkmm4:make install _gtkmm4(包名中的 mingw-w64-x86_64- 前缀可以替换为 _

    这会将所有内容下载到当前目录。脚本完成后,您的库将位于 ./root/ 中。

如果您已经安装了 MinGW 并且对使用它感到满意,您可以到此为止。

但如果没有,这个 repo 也可以帮助设置与 Clang 的交叉编译(或在 Wine 下运行的 MSYS2 的 GCC/Clang,但它们对于任何实际使用来说都太慢了)。

  • 安装 Clang(来自包管理器的常规 Linux 版本;Clang 的任何发行版都能够交叉编译)

  • 安装 Wine

  • 确定 Clang 二进制文件的命名方式。如果只是clang,则执行export WIN_CLANG_VER=NONE。如果它带有版本后缀,例如clang-11,做export WIN_CLANG_VER=11

  • make install _gcc 因为 Clang 需要 MinGW 的标准库(和其他东西)来交叉编译。

  • 符号链接 /mingw64 到安装目录。 (这是可选的,否则 MSYS2 库的 pkg-config 可能会给您错误的路径,这可能会或可能不会通过将 --define-prefix 传递给它来修复。)

    sudo ln -nfs "/<your path here>/quasi-msys2/root/mingw64" /mingw64
    
  • env/shell.sh 打开一个新的 shell,环境变量准备交叉编译。稍后您可以exit返回到原始外壳。

    这将执行一些其他初始化,除其他外,它可能会要求您输入 sudo 密码以临时配置内核以使用 Wine 透明地运行 Windows 可执行文件。这是推荐的,但不是绝对必要的,如果你想避免它,请参阅自述文件。

  • https://developer.gnome.org/gtkmm-tutorial/stable/sec-helloworld.html.en

    复制粘贴一个 hello world 示例
  • 我将使用 pkg-config 来获取正确的编译器和链接器标志。首先,我们需要弄清楚在 pkg-config 中 Gtkmm 究竟是如何命名的:

    pkg-config --list-all | grep gtkmm
    

    这给了我:

    gtkmm-4.0                      gtkmm - C++ binding for the GTK+ toolkit
    
  • 现在您可以使用 win-clang++ `pkg-config --cflags --libs gtkmm-4.0` ...

    构建示例

    win-clang++ 是我的存储库提供的原生 Clang 的包装器,为它添加了必要的交叉编译标志。

    似乎 Gtkmm 使用的是 C++17,所以我还必须添加 -std=c++17

    我最终得到的命令是:

    win-clang++ helloworld.cc main.cc `pkg-config --cflags --libs gtkmm-4.0` -std=c++17
    

    这会从 Gtkmm 标头中发出一些警告,但成功生成 a.exe

  • 最后,使用 ./a.exe 运行生成的二进制文件。

    重新启动后第一次使用 Wine 时,启动应用程序可能需要一段时间,所以请耐心等待。

    结果如下:

    pic

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?