MSYS2是MSYS的升级版,集成了pacman和Mingw-w64的Cygwin升级版,提供了Mingw-w64的GNU工具,包括GCC,同时移植了Arch Linux的软件包管理系统pacman,具备了Cygwin的POSIX API,理论上在Linux上的程序使用Cygwin重新编译就可以在Windows上运行。
Cygwin可以带给我们像Bash、Autotools、make、git、gcc、gdb上的Linux平台工具。Cygwin编译的程序不是太兼容原生的Windows程序,但是有了mingw之后编译的程序可以很好的相互兼容。
MSYS2包含了许多环境/子系统,首先我们需要做的就是决定使用哪一个环境,默认建议采用MINGW64环境。各个环境之间的差异就是默认的编译器、链接器不同。
MSYS环境包含了unix-linke/cygwin(提供 Linux Programming API)基础工具,主要位于/usr环境下。所有其他的环境像mingw64、mingw32之类的环境都是基于MSYS环境。比如MINGW64的$PATH
ucrt
Universal C Runtime is a newer version which is also used by Microsoft Visual Studio by default. It should work and behave as if the code was compiled with MSVC.
msvcrt
Microsoft Visual C++ Runtime is available by default on all Microsoft Windows versions, but due to backwards compatibility issues is stuck in the past, not C99 compatible and is missing some features.
cygwin
libstdc++
libc++ is part of clang project.They are compatible for C++17 and older versions, but C++20 implementation is not ready, so they have differences in implemented features, we’ll have to wait until they are done.
libc++
libstdc++ is part of GCC project.They are compatible for C++17 and older versions, but C++20 implementation is not ready, so they have differences in implemented features, we’ll have to wait until they are done.
坦白讲这里的toolchain实际上是Group Packages。
- mingw-w64-clang-aarch64-toolchain -> clangarm64
- mingw-w64-clang-i686-toolchain -> clang32
- mingw-w64-clang-x86_64-toolchain -> clang64
- mingw-w64-i686-toolchain -> mingw32
- mingw-w64-x86_64-toolchain -> mingw64
- mingw-w64-ucrt-x86_64-toolchain -> ucrt64
- mingw-w64-cross-clang-toolchain -> 这里的交叉编译实际上是64位和32位之间的编译
- mingw-w64-cross-toolchain
- mingw-w64-cross-ucrt-toolchain
GCC Toolchain based environment
MSYS(x86_64) MINGW64(x86_64) MINGW32(i686) UCRT64(x86_64)
use the GNU linker and the GNU C++ library. LD Linker,libstdc++
LLVM Toolchain based environment
CLANG32(i686) CLANG64(x86_64) CLANGARM64(aarch64)
only use LLVM tools,LLD is faster than LD, but does not support all the features LD supports LLD linker,libc++
Cygwin是一个在windows上使用模拟Linux工具的小型系统。msys2结合pacman和cygwin生成了多套构建工具。但是就是由于Unix和Windows环境区别,其路径是需要转换的。
cygpath -u C:\\foo # /c/foo windows => unix path
cygpath -m /mingw64/bin # C:/msys64/minw64/bin unix path => windows
cygpath -w /mingw64/bin # C:\msys64\mingw64\bin unix path => windows
python3 -c "import sys; print(sys.argv)" --dir=/foo:/bla # \\版本Windows路径
MSYS2_ARG_CONV_EXCL='--dir=' python3 -c "import sys; print(sys.argv)" --dir=/foo # 除去--dir=开头的参数不进行转换
MYVAR=/foo python3 -c "import os; print(os.environ['MYVAR'])" # /版本Windows路径
MYVAR=/foo:/bar python3 -c "import os; print(os.environ['MYVAR'])" # \版本Windows路径
MSYS2_ENV_CONV_EXCL='MYVAR' MYVAR=/foo python3 -c "import os; print(os.environ['MYVAR']) # 禁止转换行为
由C语言写成的工具,二进制包采用tar.zst for zstd compression,采用.pkg作为前缀暗示其为Pacman包,.pkg.tar.zst
Paths | cONTENTS |
---|---|
/bin,/dev,/home,/opt,/proc,/tmp,/var | essential POSIX stuff |
/usr,/etc | msys2 system |
/mingw32,/mingw64 | mingw system |
/c,/d,… | mount points for Windows drives |
/.xml,/maintenancetool. | (un)installer |
/aurebase.bat,/msys2_shell.cmd,/msys2.ico | shell entry points |
@REM Make sure start with ucrt64 msys2 env
pacman -Syu # 更新基础包
pacman -S mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-qt-creator mingw-w64-ucrt-x86_64-qt5 mingw-w64-ucrt-x86_64-opencv mingw-w64-ucrt-x86_64-cgal mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-gdal mingw-w64-ucrt-x86_64-proj mingw-w64-ucrt-x86_64-glog mingw-w64-ucrt-x86_64-ceres-solver mingw-w64-ucrt-x86_64-geographiclib mingw-w64-ucrt-x86_64-libtiff mingw-w64-ucrt-x86_64-laszip mingw-w64-ucrt-x86_64-nlohmann-json mingw-w64- --needed
@REM Default Eigen 3.4.0 conflict with ceres solver
pacman -U https://mirror.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-eigen3-3.3.9-1-any.pkg.tar.zst
pacman 安装某个包可以像Anaconda cloud 一样进行安装,详情参考网址
pacman -Ss mingw-w64-x86_64 sqlite # arch + package name
pacman -Si meson | grep '^Licenses' # 匹配指定字段和信息,中文需要采用中文进行匹配
pacman -Qi meson | grep '^Licenses' # 匹配指定字段和信息,中文需要采用中文进行匹配
pacman -Ql meson | grep -E "/share/licenses/.+/.+" # 指定路径下的文件
pacman -Ql <name of the package> # 显示所有文件
pacman -Qs mingw-w64-x86_64 sqlite # arch + package name
pacman -S <name of the package>
# msys2-launcher-git -> virtual package names
pacman -S <virtual package names and package group names> # base-devel -> package group names
pacman -Ss <name_pattern> # 正则匹配方式安装
pacman -U <packagefile.tar.zst> # 安装独立的包,需要自己解决依赖,可以是.zst或者.xz结尾
pacman -U <packagefile.tar.xz>
package -R <name of the package> # but not its dependencies nor any files produced by running it
pactree mingw-w64-x86_64-gettext
pacman -Qi mingw-w64-x86_64-gettext
pacman -Qo <full file path> # 大小写敏感、需要带后缀、只查找已经安装的包
# 注意大小写、后缀名
pacman -Fy # update package database
pacman -F <filename> # 从远程仓库中进行查找
pacman -Fx <filename> # 子字符串匹配
pacman -Syuu
pacman -Suu # 更新剩余的包
pacman -S vim
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
pacman -S mingw-w64_x86_64-cmake
pacman -Qi mingw-w64-x86_64-cmake-doc-qt # 查看详细信息
pacman -Q mingw-w64-x86_64-cmake-doc-qt # 查看安装基本信息
msys配置基础开发包
pacman -S --needed base-devel
撰写属于自己的PKGBUILD
makepkg-mingw --cleanbuild --syncdeps --force --noconfirm # 生成*.pkg.tar.zst包
makepkg-mingw只是makepkg的一个封装,它能为不同的环境构建相同的包多次。这点与Arch Linux稍微有点不同。
注意License的安装msys约定为/share/licenses//
安装生成的包到本地
pacman -U *.pkg.tar.zst # 该包可以是网址
补充
makepkg-mingw 还有如下有用的选项
由于各个环境有属于自己的包前缀。因此,需要一个技巧可以解决上述的问题,即只需要使用后缀就可以安装。
pacman -S pactoys # 安装工具
pacman -S cmake:x # x64_x86 architecture
pacman -S cmake:m # i686 and x64_86 architecture
pacman -S cmake:i # i686 architecture
pacman -S cmake:p # ucrt environment
cmake -G Ninja # 使用ninja
cmake -G "MSYS Makefiles" # 使用cygwin的make工具
cmake -G "MinGW Makefiles" # 使用mingw32-make工具生成
msys2的主仓库服务器位于德国,包含了许多pacman数据库和包数据。该主服务器同步到全世界其他镜像服务器中进行发布。
主仓库
repo.msys2.org # rsync https
mirror.msys2.org # 根据位置重定向到Tier 1适合的镜像
Tier 1 Mirrors
每天至少从主仓库拉取一次,非常可靠和高速。中国的哈尔滨工业大学、南京大学、中国科大、北京外国语都有 Tier 1 镜像站。
Tier 2 Mirrors
定期更新一次,阿里云有 Tier 2 镜像站,上海交大有
由于Mingw版本的cpython不兼容正常版本的cpython,所以msys2社区维护了一个mingw版本的python。这意味着pypi安装不再可靠,所有的Python相关包需要使用mingw版本的python进行重新编译之后方可使用。
输出安装包到文本文件中
pacman -Qqe | xargs echo > /d/packages.txt ; exit # 导出所有的包并退出shell
移动原系统缓存保存再卸载原版本msys2系统
msys64/var/cache/pacman/pkg -> 替换为 msys64.old/var/cache/pacman/pkg
更新包数据源
pacman -Sy # 更新数据源
pacman --needed -S bash pacman pacman-mirrors msys2-runtime # 更新核心组件
安装之前系统的包
pacman -S --needed $(cat /d/packages.txt)
mingw32-make
msys2提供了两套系统make系统,一套系统是原生的make,即cygwin类Unix系统,一套是mingw32-make工具,make适用于大部分的Makefile,mingw32-make(GNU make)只适用于自己的Makefile。
使用GNU make检测MSYS版本
msys_version := $(if $(findstring Msys, $(shell uname -o)),$(word 1, $(subst ., ,$(shell uname -r))),0)
$(info The version of MSYS you are running is $(msys_version) (0 meaning not MSYS at all))
代码中的站台检查
Identifier | platforms | usage |
---|---|---|
_WIN32 | mingw,msvc | C code (#ifdef ... ) |
_WIN64 | 64-bit mingw,64-bit msvc | C code (#ifdef ... ) |
_CYGWIN_ | msys2,cygwin | C code (#ifdef ... ) |
_MSYS_ | msys2 | C code (#ifdef ... ) |
x86_64-pc-msys2 | 64-bit msys2 | Build scripts (if [ $host = '...' ] ) |
i686-pc-msys2 | 32-bit msys2 | Build scripts (if [ $host = '...' ] ) |
x86_64-w64-mingw32 | 64-bit mingw | Build scripts (if [ $host = '...' ] ) |
i686-w64-mingw32 | 32-bit mingw | Build scripts (if [ $host = '...' ] ) |
cygwin | msys2 | Python (sys.platform ) |
win32 | mingw | Python (sys.platform ) |
= ‘…’ ]) | | x86_64-w64-mingw32 | 64-bit mingw | Build scripts (
if [ $host = ‘…’ ]) | | i686-w64-mingw32 | 32-bit mingw | Build scripts (
if [ $host = ‘…’ ]) | | cygwin | msys2 | Python (
sys.platform) | | win32 | mingw | Python (
sys.platform`) |