【代码移植】Linux C/C++代码程序移植到Windows系统平台技术汇总与经验分享
UNIX/Linux/POSIX代码程序移植到Windows系统平台技术汇总与经验分享
图片来源
Linux to Windows代码移植技术路线
目录
MinGW
MinGW/MinGW-W64是用Windows原生系统API实现的,在Windows上运行的GCC编译工具链,可以编译出Windows原生应用程序。
MinGW编译工具链的生态位和微软官方的MSVC类似。
优点
- MinGW编译出的程序有能力直接在Windows系统中运行,不依赖外部库文件,并且运行效率很高。
缺点
- MinGW工具链遵循Windows系统的ABI,有些定义与行为和Linux系统不一致。如long数据类型的字节长度。
- MinGW不支持许多Linux的系统头文件与系统调用,需要修改代码,把Linux系统调用翻译为Windows系统调用。
注意事项
MinGW和MSVC / VS依赖的C标准库相同,均为MSVCRT.DLL / UCRT.DLL。这意味着
- 使用微软的MSVC或VS构建C/C++程序时,可以直接链接MinGW构建的C库。
- 使用MinGW构建C/C++程序时,可以直接链接MSVC或VS构建的C库。
MinGW和MSVC / VS依赖的C++标准库不同,且两者的函数符号命名方式不一致,这意味着
- 使用微软的MSVC或VS构建C++程序时,不能链接MinGW构建的C++库。
- 使用MinGW构建C++程序时,不能链接MSVC或VS构建的C++库。
代表项目
- MSYS2
- https://www.msys2.org/
- MinGW-W64
- https://www.mingw-w64.org/
Cygwin
从概念上来说,Cygwin是一个在Windows上运行的POSIX环境(可以理解为类Linux环境)。Cygwin为用户提供了各种POSIX系统调用和系统头文件,用户可以像使用Linux系统一样使用Cygwin。
从实现上来说,Cygwin库提供了一个中间层,用来把POSIX系统调用翻译成Windows系统调用。
传统的Linux发行版由“Linux系统内核”与“发行版定制的外围软件”这两部分组成。某种程度上,也可以把Cygwin理解为一个特别的Linux发行版,它的内核为“被中间层包裹的Windows内核”,外围软件为“Cygwin定制的外围软件”。
优点
- Cygwin提供了一个POSIX兼容的环境,因此Linux代码无需经过太多修改,即可在Cygwin中进行编译。
- 不同于MinGW,Cygwin使用LP64数据模型。long类型大小为8个字节,和Linux系统保持一致。
缺点
- 编译出的可执行文件必须动态依赖于Cygwin动态库(作为中间层翻译)。
- 由于引入了中间层,编译出的可执行文件运行效率低下。
- Windows的多线程/进程实现逻辑与Linux有很大差别,使用Cygwin编译出的多线程/进程程序,运行时可能会出现问题。
注意事项
程序无法同时链接到Cygwin动态库与 MSVCRT.DLL / UCRT.DLL,二者互斥。这意味着
- 你使用Cygwin开发的程序库,只能用于同样基于Cygwin开发的程序,不能被MinGW / MSVC / VS开发的程序使用。
代表项目
- Cygwin
- https://www.cygwin.com/
- MSYS2(其中的MSYS环境)
- https://www.msys2.org/
模拟器/虚拟机
通过动态二进制翻译技术,模拟出指定架构的处理器的行为。
优点
- 项目可以在Linux系统中事先构建好。项目程序运行时,只需要为模拟器/虚拟机提供构建好的Linux原生二进制文件与其所需的运行时环境。
缺点
- 不支持某些系统调用或指令。
- 运行效率较低。
- 该技术路线较为复杂,涉及环节多,不稳定因素多。
代表项目
- QEMU(在MSYS2中安装与运行)
- https://www.qemu.org/
- https://packages.msys2.org/base/mingw-w64-qemu
- jart/blink(在Cygwin中编译、安装与运行)
- https://github.com/jart/blink
Cosmopolitan
Cosmopolitan项目包含了一套Cosmopolitan C标准库和一套Cosmocc编译工具链。其编译出的二进制文件符合POSIX标准,并且可以原生运行在多个硬件架构(AMD64 + ARM64)的多种平台上(Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS)。Cosmopolitan让C语言拥有了“一次编译,到处运行”的能力。
优点
- 只需要一套源码,使用Cosmopolitan编译出二进制文件,这些二进制文件可以在多个硬件架构和多个平台上原生运行。目前Cosmopolitan官方已经成功构建了Bash、Python、SQLite3、Vim、Lua等许多项目。
- 遵循System V ABI,使用LP64数据模型。
缺点
- 不支持某些系统调用或指令。
- 该项目很年轻,仍在积极开发中。目前主要支持使用autotools作为构建工具的项目。
代表项目
- jart/cosmopolitan
- https://justine.lol/cosmopolitan/index.html
- https://github.com/jart/cosmopolitan
代码移植技巧
对于MinGW技术路线,下面列举了一些常见的Linux系统头文件,以及它们的Windows实现或对应物。
使用的C库为微软实现的MSCVRT或UCRT,C++库为MinGW实现的libstdc++。此外,还需要使用到Windows的系统API。
微软官方 UNIX代码移植指南
UNIX Code Migration Guide | Microsoft Learn
sys/resource.h
- https://github.com/JellyBrick/sys-resource-win
- https://github.com/openvswitch/ovs/blob/master/include/windows/sys/resource.h
- https://github.com/openvswitch/ovs/blob/master/lib/getrusage-windows.c
sys/mman.h
- https://github.com/alitrack/mman-win32
dirent.h
- https://github.com/tronkko/dirent
dlfcn.h
- https://github.com/dlfcn-win32/dlfcn-win32
- https://packages.msys2.org/package/mingw-w64-ucrt-x86_64-dlfcn
execinfo.h
- https://github.com/ianlancetaylor/libbacktrace
性能对比
- 硬件
- 处理器: 英特尔 酷睿 i5-7300HQ @ 2.50GHz 四核四线程
- 内存: 16GB DDR4 2400MHz ( 8GB + 8GB )
- 操作系统
- 名称:Microsoft Windows 11 家庭版 Insider Preview
- 版本:10.0.27749 Build 27749
- MSVC
- VS构建工具版本:Visual Studio Build Tools 2022 17.12.3
- MSVC版本:MSVC v143 - VS 2022 C++ x64/x86 build tools
- WSL2 Ubuntu 20.04.2 LTS
- 内核版本(
uname -r
):5.15.167.4-microsoft-standard-WSL2 - GCC版本(
gcc --version
):9.4.0
- 内核版本(
- MSYS2 UCRT64
- 内核版本:3.5.4-0bc1222b.x86_64
- GCC版本:14.2.0
- Cygwin
- 内核版本:3.4.9-1.x86_64
- GCC版本:11.4.0
google/benchmark
- 项目链接:https://github.com/google/benchmark
- 测试时的提交节点:
d5fad6b
- 依赖:
CMake >= 3.10
# 克隆最新的仓库
git clone https://github.com/google/benchmark.git
# 进入项目的根目录
cd benchmark
# 创建构建目录"build/"
cmake -E make_directory "build"
# 配置项目的CMake参数;下载依赖;生成构建系统的相关文件(如Makefile)
cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
# 对于MSYS2 UCRT64环境,在下一步构建时,可能会触发GCC的"maybe-uninitialize"提示。若要顺利进行构建,请执行以下被注释掉的命令,将BENCHMARK_ENABLE_WERROR设置为off
# cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release -DBENCHMARK_ENABLE_WERROR=off ../
# 进行多线程构建,生成Release版本的二进制文件
cmake --build "build" --config Release -j 4
# 运行一系列测试,观察测试是否成功,观察完成测试所需的时间
cmake -E chdir "build" ctest --build-config Release
冷启动连续运行10次的耗时记录(单位:秒)
MSVC | WSL2 Ubuntu 20.04 | MSYS2 UCRT64 | Cygwin |
---|---|---|---|
45.67 | 12.13 | 24.73 | 23.06 |
43.59 | 11.60 | 23.15 | FAILED** |
FAILED* | 11.62 | 24.56 | 24.51 |
44.00 | 11.69 | 19.17 | 24.40 |
52.11 | 11.72 | 21.47 | 22.54 |
45.78 | 11.64 | 18.05 | 24.98 |
46.15 | 11.62 | 19.40 | FAILED** |
45.02 | 11.68 | 17.95 | 21.45 |
43.57 | 11.64 | FAILED** | 23.62 |
43.82 | 11.52 | 18.14 | 34.55 |
*FAILED: 62 - user_counters_tabular_test
**FAILED: 67 - complexity_benchmark
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)