使用 mingw-w64 和 cmake 构建 32 位和 64 位应用程序
Posted
技术标签:
【中文标题】使用 mingw-w64 和 cmake 构建 32 位和 64 位应用程序【英文标题】:Building 32Bit and 64Bit application uitilizing mingw-w64 and cmake 【发布时间】:2021-12-01 19:30:59 【问题描述】:我需要在 32 位和 64 位的 windows (dll) 上构建一个共享库。 编译用cmake控制,编译器是mingw64
This is my cmake file:
#64Bit Build (works fine)
ADD_LIBRARY(mylib SHARED mylib.c)
SET_TARGET_PROPERTIES(mylib PROPERTIES PREFIX "")
target_link_options(mylib PUBLIC -Wl,--exclude-all-symbols -s -Wl,--gc-sections -Wl,-Map=output.map )
#32Bit Build (linking issues)
ADD_LIBRARY(mylib32 SHARED mylib.c)
SET_TARGET_PROPERTIES(mylib32 PROPERTIES PREFIX "" COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
target_link_options(mylib32 PUBLIC --verbose -Wl,--exclude-all-symbols -s -Wl,--gc-sections -Wl,-Map=output.map)
由于许多链接库的 32 位不兼容,我在链接过程中收到很多投诉。 当我像这样专门将 32Bit 库添加到搜索路径时,我可以减少投诉量:
target_link_options(mylib32 PUBLIC --verbose -Wl,--exclude-all-symbols -s -Wl,--gc-sections -Wl,-Map=output.map -L/msys64/mingw32/lib -L/msys64/mingw32/i686-w64-mingw32/lib -L/msys64/mingw32/lib/gcc/i686-w64-mingw32/10.3.0)
但仍然存在一些不兼容问题:例如始终从 64Bit mingw 路径链接的 dllcrt.a, 这似乎有点硬编码到 gcc/ld 中。
我什至尝试使用一个空的规范字段,结果也没有:
target_link_options(mylib32 PUBLIC -specs=myspe --verbose -Wl,--exclude-all-symbols -s -Wl,--gc-sections -Wl,-Map=output.map -L/msys64/mingw32/lib -L/msys64/mingw32/i686-w64-mingw32/lib -L/msys64/mingw32/lib/gcc/i686-w64-mingw32/10.3.0)
我收到的典型错误消息:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld .exe: i386:x86-64 架构的输入文件`C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../.. /x86_64-w64-mingw32/lib/dllcrt2.o' 与 i386 输出不兼容
【问题讨论】:
您对 32 位和 64 位可执行文件使用相同的编译器吗? 是的,相同的编译器, 为什么不为 32 位可执行文件使用 32 位编译器? 据我所知,使用 cmake 为同一个项目维护 2 个构建环境非常复杂。使用“-m32”生成 i386 输出似乎是一个常见的用例,所以最初它看起来是一种更简单的方法。 如果编译器启用了multilib
,那么-m32
将工作,因为32 位库也将包括在内。不确定是否还有人为 mingw 构建 multilib 编译器。
【参考方案1】:
我刚刚为我的案例找到了解决方案:
crt* 是启动代码,在库的情况下不需要。
所以我添加了-nostartfiles
标志,我的库链接很好。
我想如果关闭应用程序,可能可以手动链接 32 位启动文件作为一种解决方法。
SET_TARGET_PROPERTIES(amprio_seednkey32 PROPERTIES PREFIX "" COMPILE_FLAGS "-m32 -nostartfiles" LINK_FLAGS "-m32 -nostartfiles")
无论如何,这一切都感觉像是一个肮脏的解决方法,我仍然想知道使用 mingw-w64 链接 32Bit 和 64Bit 的最佳方法是什么。
【讨论】:
以上是关于使用 mingw-w64 和 cmake 构建 32 位和 64 位应用程序的主要内容,如果未能解决你的问题,请参考以下文章
未定义的参考链接 yaml-cpp 程序与 mingw-w64 + cmake
Windows下的 C++ 编译工具(MinGW-w64 + CMake)
ubuntu32bit的系统如何配置mingw-w64的交叉编译toolchain?