【发布时间】:2021-01-12 20:29:28
【问题描述】:
我有一个开源游戏项目,主要是在 Ubuntu 下开发的。最近我把它移植到了 Windows 上,只做了一些小的调整,然后为 Windows 构建了它,因为我只使用了跨平台的库和功能。
为了构建它,最初我使用来自 Ubuntu 19.04 存储库的 MinGW-w64 进行交叉编译,它的工作原理非常棒。这是它报告的版本:
$ x86_64-w64-mingw32-g++-posix --version
x86_64-w64-mingw32-g++-posix (GCC) 9.2-posix 20191008
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
当我更新到 Ubuntu 20.04 时,MinGW-w64 的版本号有一个小凸起:
$ x86_64-w64-mingw32-g++-posix --version
x86_64-w64-mingw32-g++-posix (GCC) 9.3-posix 20200320
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
更新破坏了我的构建,因为新版本的 MinGW-w64 生成的可执行文件不起作用。在 Windows 机器上执行时,无法从其 DLL 依赖项中找到符号,并且出现以下弹出错误:
应该翻译成英文版的错误信息为(填充变量):
glome.exe - 未找到入口点
程序入口点 ogg_page_bos 无法位于动态链接库 «path to glome.exe» 中。
这里需要注意的有趣点是:
- 它将 glome.exe 视为一个 DLL,与我在网上找到的所有错误实例不同,它将可执行文件放在标题上,但实际 DLL 在消息正文中;
- 可以在配套文件 libogg-0.dll 中找到所需的符号;
- 如果我用 Wine 在 Linux 上运行它,它可以工作;
- 如果我将二进制 glome.exe 与 Ubuntu 19.10 中的内置文件交换,它可以工作;
- 两个版本(Ubuntu 19.10 和 Ubuntu 20.04)使用由 CMake 生成的完全相同的编译器参数。
这是编译游戏的其中一个文件的命令行(文件很多,但编译方式都一样):
cd /home/lucas/glome/ubuntu-20.04-win-build/src/sdl && /usr/bin/x86_64-w64-mingw32-g++-posix @CMakeFiles/glome.dir/includes_CXX.rsp -march=haswell -mtune=generic -Ofast -fno-fat-lto-objects -flto=12 -I/home/lucas/glome/windows-deps/opusfile/include/opus/ -I/home/lucas/glome/windows-deps/opus/include/opus/ -I/home/lucas/glome/windows-deps/libogg/include/ogg/ -I/home/lucas/glome/windows-deps/glew-2.1.0/include/ -I/home/lucas/glome/windows-deps/OpenAL-1.1-SDK/include -I/home/lucas/glome/windows-deps/libogg/include -I/home/lucas/glome/windows-deps/SDL2-2.0.12/include/ -I/home/lucas/glome/windows-deps/boost_1_72_0/ -g -std=gnu++17 -o CMakeFiles/glome.dir/input.cpp.obj -c /home/lucas/glome/src/src/sdl/input.cpp
其中CMakeFiles/glome.dir/includes_CXX.rsp 仅包含-I 指令:
-I/home/lucas/glome/src/src/common/. -I/home/lucas/glome/src/external/concurrentqueue -I/home/lucas/glome/ubuntu-20.04-win-build/src -I/home/lucas/glome/src/src/sdl
可执行文件的链接命令是:
/usr/bin/x86_64-w64-mingw32-g++-posix -march=haswell -mtune=generic -Ofast -fno-fat-lto-objects -flto=12 -I/home/lucas/glome/windows-deps/opusfile/include/opus/ -I/home/lucas/glome/windows-deps/opus/include/opus/ -I/home/lucas/glome/windows-deps/libogg/include/ogg/ -I/home/lucas/glome/windows-deps/glew-2.1.0/include/ -I/home/lucas/glome/windows-deps/OpenAL-1.1-SDK/include -I/home/lucas/glome/windows-deps/libogg/include -I/home/lucas/glome/windows-deps/SDL2-2.0.12/include/ -I/home/lucas/glome/windows-deps/boost_1_72_0/ -g -Wl,--whole-archive CMakeFiles/glome.dir/objects.a -Wl,--no-whole-archive -o glome.exe -Wl,--out-implib,libglome.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/glome.dir/linklibs.rsp
其中CMakeFiles/glome.dir/linklibs.rsp 包含:
../common/libcommon.a -lopengl32 -lglu32 -march=haswell -mtune=generic -Ofast -fno-fat-lto-objects -flto=12 -I/home/lucas/glome/windows-deps/opusfile/include/opus/ -I/home/lucas/glome/windows-deps/opus/include/opus/ -I/home/lucas/glome/windows-deps/libogg/include/ogg/ -I/home/lucas/glome/windows-deps/glew-2.1.0/include/ -I/home/lucas/glome/windows-deps/OpenAL-1.1-SDK/include -I/home/lucas/glome/windows-deps/libogg/include -I/home/lucas/glome/windows-deps/SDL2-2.0.12/include/ -I/home/lucas/glome/windows-deps/boost_1_72_0/ /home/lucas/glome/windows-deps/OpenAL-1.1-SDK/libs/Win64/OpenAL32.lib /home/lucas/glome/windows-deps/glew-2.1.0/lib/Release/x64/glew32.lib /home/lucas/glome/windows-deps/opusfile/lib/libopusfile.a /home/lucas/glome/windows-deps/opus/lib/libopus.dll.a /home/lucas/glome/windows-deps/libogg/lib/libogg.dll.a -L/home/lucas/glome/windows-deps/SDL2-2.0.12/lib/x64/ -lSDL2main -lSDL2 -static-libgcc -static-libstdc++ -Wl,-allow-multiple-definition -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
除了路径(ubuntu-20.04-win-build vs ubuntu-19.10-win-build)之外,编译和链接命令完全相同,由相同的CMakeLists.txt生成相同的参数。
问题:
- 为什么 Ubuntu 20.04 build 可以在 Wine 上运行,但不能在 Windows 上运行,而 Ubuntu 19.10 build 可以同时在这两种情况下运行?
- 如何修复 Ubuntu 20.04 版本以在 Windows 上运行?
【问题讨论】:
-
你试过用MSVC(微软的编译器)编译吗?
-
它需要更多的移植(因为它缺少 GNU getopt),但是是的,另一个开发人员设法在 Visual Studio 中构建了它。它的工作原理类似于 MinGW-w64 9.2。但相关性是什么?
-
MingGW 存在一些错误,因为它基于 GCC,而 GCC 旨在在类 Unix 系统上运行,而不是在 Windows 上运行。
-
@Ivella getopt(来自software.frodo.looijaard.name/getopt/download.php)使用 MinGW-w64 构建。您应该构建并使用它。
-
@AkibAzmain GCC 是一个针对许多平台的非常通用的编译器,而 MinGW-w64 GCC 是一个非常可靠的编译器,可以生成本机 Windows 可执行文件。
标签: c++ windows dll cross-compiling mingw-w64