MSYS2
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
Architecture
- x86_64 -> (64 bit)
- i686
- aarch64
C Library
-
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
C++ Library
-
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
坦白讲这里的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转换
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
- python脚本转换
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']) # 禁止转换行为
Pacman
由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 |
配置LinSAR环境
@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安装包组件介绍
相关网址
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> # 子字符串匹配
Windows配置
更新包数据库和基础包
pacman -Syuu
更新基础包
pacman -Suu # 更新剩余的包
安装cygwin基础包
pacman -S vim
安装mingw-w64 GCC
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
安装cmake
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 # 查看安装基本信息
源码配置为pacman包
-
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 还有如下有用的选项
- –install 在build完成之后立刻进行安装
- –rmdeps 移除安装所需要的所有依赖
- –help 更多的选项
tips
安装pacman包技巧
由于各个环境有属于自己的包前缀。因此,需要一个技巧可以解决上述的问题,即只需要使用后缀就可以安装。
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
MSYS2中使用CMake
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 镜像站,上海交大有
Python
由于Mingw版本的cpython不兼容正常版本的cpython,所以msys2社区维护了一个mingw版本的python。这意味着pypi安装不再可靠,所有的Python相关包需要使用mingw版本的python进行重新编译之后方可使用。
Reinstall msys2系统
-
输出安装包到文本文件中
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)
Porting
-
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`) |