Windows跨平台编译小记

本文简单记录windows跨平台编译相关的备忘事项,主要分系统安装环境配置两大部分,不涉及如何编写c/c++代码中的兼容部分,默认需要编译的c/c++代码是跨平台兼容的(感慨一下golang的交叉编译是真简单)

早期会有一些使用cygwin来实现交叉编译的项目,现阶段推荐直接上wsl,由微软官方维护成熟度相当高,先确定控制面板—>程序和功能—>启用或关闭Windows功能中已经开启相关功能:

开启wsl功能
开启wsl功能

然后直接在Microsoft Store中安装即可,比如我选用的Ubuntu 22.04如图:

ubuntu2204
ubuntu2204

如果是从wsl1升级到wsl2,或直接安装wsl2,则需要启用虚拟化,在PowerShell中输入:

powershell

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

此时需确认控制面板—>程序和功能—>启用或关闭Windows功能中的Hyper-V已经勾选:

Hyper-V开启
Hyper-V开启

只需要wsl1的话,可以不用开启Hyper-V,另外wsl1wsl2之间可以直接转换,比如:

bash

# 转换Ubuntu-22.04到wsl1
wsl --set-version Ubuntu-22.04 1
# 设置默认版本为1
wsl --set-default-version 1

似乎wsl2因为虚拟化会多占用一些内存,wsl常用的命令还有:

bash

# 升级
wsl --update
# 关停
wsl --shutdown
# 默认root登录
ubuntu2204 config --default-user root

原理是基于wsl来实现的嵌套虚拟化,折腾一圈以后确实能运行,本文封面就是运行效果图,就是性能堪忧,如果不是机器配置很好还是建议通过vmware来安装mac省时省力

如果是基于wsl安装mac的话必须是wsl2而且要开启kvm嵌套虚拟化,主要流程大致参考以下教程:

https://boxofcables.dev/accelerated-kvm-guests-on-wsl-2/

https://dev.to/nicole/running-macos-on-windows-10-with-wsl2-kvm-and-qemu-21e1

https://nextgentips.com/2022/04/20/how-to-install-and-configure-qemu-7-on-ubuntu-20-04/

首先是在wsl中的常规环境配置:

bash

sudo apt update && sudo apt -y upgrade
sudo apt -y install build-essential libncurses-dev bison flex libssl-dev libelf-dev cpu-checker qemu-kvm aria2

然后从此处下载并重新编译wsl的内核,编译前定制化内核参数:

bash

cp Microsoft/config-wsl .config
make menuconfig  # 通过GUI选择

或者直接编辑配置文件,主要就是以下这些参数:

ini

KVM_GUEST=y
CONFIG_KVM=y
CONFIG_KVM_INTEL=m
CONFIG_VHOST_NET=y
CONFIG_VHOST=y

完了以后编译和配置:

bash

make -j
sudo make modules_install
cp arch/x86/boot/bzImage /mnt/c/Users/<username>/bzImage
nano /mnt/c/Users/<username>/.wslconfig

在配置文件中开启嵌套虚拟化和GUI支持,比如我的配置文件:

ini

[wsl2]
kernel=C:\\Users\\<username>\\bzImage
guiApplications=true
nestedVirtualization=true
# debugConsole=true
# pageReporting=true
# kernelCommandLine=intel_iommu=on iommu=pt kvm.ignore_msrs=1 kvm-intel.nested=1 kvm-intel.ept=1 kvm-intel.emulate_invalid_guest_state=0 kvm-intel.enable_shadow_vmcs=1 kvm-intel.enable_apicv=1
# memory=8GB
# processors=8

完成以后重启一下:

bash

wsl.exe --shutdown Ubuntu && wsl.exe -d Ubuntu

然后配置kvm参数:

bash

nano /etc/modprobe.d/kvm-nested.conf

写入:

ini

options kvm-intel nested=1
options kvm-intel enable_shadow_vmcs=1
options kvm-intel enable_apicv=1
options kvm-intel ept=1

加载并测试:

bash

sudo modprobe kvm_intel && kvm-ok
cat /sys/module/kvm_intel/parameters/nested

主要参考了以下几个链接:

https://nextgentips.com/2022/04/20/how-to-install-and-configure-qemu-7-on-ubuntu-20-04/

https://ubunlog.com/zh-CN/如何在ubuntu上安装qemu虚拟化软件/

https://github.com/foxlet/macOS-Simple-KVM

https://github.com/kholia/OSX-KVM

https://github.com/arkane-systems/genie

实测搭配最后两个链接mac版本会新一些,细节太多了,如果是CPU跑的话会很慢很慢,来看如何开启GPU支持

windows11上搭配wsl2可以支持原生GUI,甚至可以在wsl2中调用GPU,可以说是非常黑科技了,请按需自行参考:

https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps

https://learn.microsoft.com/en-us/windows/ai/directml/gpu-cuda-in-wsl

https://docs.nvidia.com/cuda/wsl-user-guide/index.html#getting-started-with-cuda-on-wsl

https://ubuntu.com/tutorials/enabling-gpu-acceleration-on-ubuntu-on-wsl2-with-the-nvidia-cuda-platform#1-overview

坑也居多,什么字体不对、闪退、运行慢,问题一大把,全部测完跑起来以后发现太慢了,最后还是决定用vmware来启用mac

实测无论是否开启Hyper-V都可以执行VMware Workstation Pro 16,但测试下来似乎不开的时候vmware运行会更省内存一些,配置时虚拟核心数建议要少于机器可用核心数,尤其是虚拟化mac

我使用的VMware Workstation Pro的激活密钥来自:

https://www.ghxi.com/vmware15.html/comment-page-3?__SAKURA=37750654246631d6937bf3d47cf3d5c561538942794_134031

下载的话通过官方链接就行了,注意直接安装完是不能虚拟化mac的,还需要装一下插件:

https://www.jianshu.com/p/1b9aa98b2f44

https://github.com/paolo-projects/unlocker

mac的镜像和安装教程则可以参考:

https://sysin.org/blog/macOS/

https://kiprey.github.io/2021/12/vmware_macos/

没有共享文件夹交互会非常困难,开启参考链接:

https://docs.vmware.com/cn/VMware-Workstation-Pro/16.0/com.vmware.ws.using.doc/GUID-AB5C80FE-9B8A-4899-8186-3DB8201B1758.html

https://blog.51cto.com/wangchunhai/2064769

注意我实测如果装ubuntu需要每次开机都执行:

bash

# linux 用 sudo -i 切到root权限挂载共享文件夹到用户路径,每次开机都要执行
/usr/bin/vmhgfs-fuse .host:/ /home/jim/share_folder -o subtype=vmhgfs-fuse,allow_other

vmware的网卡配置也是天坑,反正我最终照着这篇教程设置了一遍就能上网了。。。

https://zhuanlan.zhihu.com/p/130984945

如果还有问题需要多找找教程,细节太多了

这个比较简单,微软都已经做好了,打开下面这个链接:

https://visualstudio.microsoft.com/zh-hans/downloads/

下载Visual Studio 2022 生成工具,安装时选前两项就可以把msvc装上了,有必要的话配置一下环境变量,完成以后可以在终端确认:

msvc测试
msvc测试

这个更简单,我一般直接用gcc12当作默认编译器,打开wsl以后执行下面的命令即可:

bash

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update && sudo apt install gcc-12 g++-12
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 50

需要注意的是,默认的源http://archive.ubuntu.com国内速度堪忧,可以通过编辑文件/etc/apt/sources.list把地址替换成清华源http://mirrors.tuna.tsinghua.edu.cn来提升国内访问速度

gcc测试
gcc测试

到目前为止如果需要编译mac的软件还是需要切换到虚拟机里面,其实是有方案可以基于wsllinux教程编译mac软件的,这个方案就是osxcross

https://github.com/tpoechtrager/osxcross

非常强大简直闪瞎我,借助这个方案可以实现在windows上透过wsl直接给mac编译软件,mac虚拟机只用来做软件测试,直接可以把跨平台的交叉编译任务融合进windows的定时任务中,下面简单讲一下配置过程:

bash

# 首先你需要装好mac并把osxcross克隆一份到mac里面
# 按说明下载sdk,从这里:https://developer.apple.com/download/all/?q=xcode
# 然后需要安装sdk,我选择的是Command_Line_Tools_for_Xcode_13.4.dmg
# 装完以后执行:
./tools/gen_sdk_package_tools.sh

然后在wsl里也克隆一份代码,并把生成的.sdk.tar.xz移动到./osxcross/tarballs路径下,这里直接放一份示例的sdk文件,文件较大下载时请注意网络状况,下载后请自行解压缩:

接下来的操作不需要mac系统了,可以直接在wsl中操作,

bash

# 在wsl中获取源码并装好一堆依赖
cd /mnt/d/ && git clone https://github.com/tpoechtrager/osxcross.git
apt install libssl-dev patch lzma-dev libxml2-dev bash uuid-dev make
# 编译安装osxcross,提前在macos虚拟机中做好sdk已放到./osxcross/tarballs文件夹
cd /mnt/d/osxcross
apt install llvm-dev clang liblzma-dev pacman cmake bzip2s
./build.sh
# 继续编译安装gcc
apt install zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
./build_gcc.sh

编译完以后记得添加路径,甚至可以使用omp安装MacPorts的软件,

bash

# 参考:https://github.com/tpoechtrager/osxcross/blob/master/README.MACPORTS.md
# 为bin添加路径
export PATH=/mnt/d/osxcross/target/bin:$PATH
# 这里的版本和之前的sdk对齐
export MACOSX_DEPLOYMENT_TARGET=11.3
# 比如安装python的各个版本,参考路径示例:
# /mnt/d/osxcross/target/macports/pkgs/opt/local/Library/Frameworks/Python.framework/Versions/3.x/include/python3.x/
omp install python37
omp install python38
omp install python39
omp install python310
omp install python311

如果openssl报错的话,可以尝试编辑/etc/ssl/openssl.cnf,对照着把下面缺的部分补全:

shell

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

实测可行,完成以后可以查看效果,一般来说我还是o64-gcc用的多一些:

o64-gcc测试
o64-gcc测试

如果文件夹osxcross因各种原因移动或变更的话,尤其是从win中操作过,建议用wsl重新编译,不然可能出现各种各样奇怪的小问题

请尤其注意在以后的操作中,不要删除clang等已经安装好的依赖,不然会导致编译报错

在虚拟中使用mac时会涉及到常见软件的安装,个人感觉brew效果比较好:

bash

# 安装 homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

然后就可以简单安装一些常用软件,比如:

bash

# 安装graphviz和java
brew install graphviz java

以上几个方案测试下来,比较好的是基于windowswslosxcross实现交叉编译,并在wslvmware中调试编译后的程序,整体工作流比较顺滑,实现了一台windows电脑无缝同步编译跨平台软件