MSYS2编译C/C++程序

简介: MSYS2编译C/C++程序

实际上使用 MSYS2 编译 C/C++ 跟用 MinGW 编译 C/C++ 是一样的。msys2 里面也是使用的 MinGW,不过 msys2 配套的工具会更丰富一点。

而且 msys2 可以轻松继承 vs2019 的环境变量,使用 cl.exe 来编译。这样就能使用 shell 跟 Makefile 来调用 MSVC 编译项目。

看一下 msys64 里面的文件,发现他里面有个 mingw64 的文件夹,如下:

这些命令,就是从 MinGW 项目拷贝过来的。



下面演示一下如何在 msys2 环境下 编译 C/C++ 项目。

打开普通的命令行窗口,进入 C:\msys64 目录,执行 以下命令:

cd C:\msys64
.\msys2_shell.cmd -mingw32

就会弹出一个新的窗口,这个新的命令行窗口 就是 msys2 的运行环境,这个命令行窗口是使用 mintty 实现的。

上面命令参数 -mingw32 是指使用 32 的的 mingw,也就是 gcc 编译出来的 exe 会是 32 位的。 -mingw64 就是 64 位。


我在我的用户目录下 创建一个 c-single 目录,然后创建一个 hello.c ,演示一下 用 在 msys2 的环境用 gcc。

hello.c 代码如下:

#include <stdio.h>
int main()
{
    printf("hello ffmpeg \r\n");
    return 0;
}

编译命令如下:

gcc -o hello.exe hello.c

上面我简写了,把编译链接一条命令处理完。

上图中,我用了 windows 的 dumpbin.exe ,为什么能用这个命令,是因为我 修改了 msys2_shell.cmd 里面的 MSYS2_PATH_TYPE ,如下:

这样,执行 .\msys2_shell.cmd -mingw32 命令的时候 就会继承 当前窗口的环境变量,这样 之前 窗口能用的命令,我在 msys2 里面都能使用。

也可以使用参数 -use-full-path 来设置 MSYS2_PATH_TYPE 为 inherit。

借助继承当前窗口环境变量的这个原理,我们如果用 x64 Native Tools Command Prompt for VS 2019 窗口执行 msys2_shell.cmd,那在 msys2 里面就可以调 cl.exe 跟 link.exe 了,如下:

上图中,我 没有指定 -mingw32 ,因为我不需要用到 gcc,如果没指定 -mingw32,默认 gcc 是 64位。

然后,因为我是在 64位的 vs2019 窗口打开的 msys2 ,所以 cl.exe 也是 64位的。如果需要 在 msys2 中使用 32位的 msvc ,需要用 x86 Native Tools Command Prompt for VS 2019 来执行 msys2_shell.cmd,这样 msys2 继承的就是 32位的 MSVC。

msys2 的特性是继承,你当前窗口是什么环境,他继承的就是什么环境。


cl.exe 可以用,那编译 hello.c 肯定没问题,但是这样没意思,我们写一个 makefile 来编译 hello.c 。

由于 vs2019 的link.exe 跟 MinGW 的 link.exe 会冲突,如下:

上图中, /usr/bin/link.exe 比 vs2019 的link.exe 优先级更高,所以直接 用 link.exe 命令会有问题,可以直接写 vs2019 的绝对路径,但是比较长,所以我新建了一个 mslink 脚本,这个脚本会优选使用 跟 cl.exe 同目录的 link.exe,内容如下:

#!/bin/sh
LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
if [ -x "$LINK_EXE_PATH" ]; then
    "$LINK_EXE_PATH" $@
else
    link.exe $@
fi
exit $?

然后 执行以下命令 赋予 mslink 执行的权限:

chmod 755 mslink

然后就可以新建一个 makefile 文件,内容如下

hello2.exe: hello.obj
    ./mslink -out:hello2.exe hello.obj
hello.obj: hello.c
    cl.exe -c hello.c

然后 执行 make 命令,即可编译出来 hello2.exe,如下:

后面 FFmpeg 的 MSVC 版本也是通过这种方式来编译出来的,在 msys2 里面用 makefile 跟 cl.exe 。


目录
相关文章
|
26天前
|
自然语言处理 编译器 C语言
为什么C/C++编译腰要先完成汇编
C/C++ 编译过程中先生成汇编语言是历史、技术和实践的共同选择。历史上,汇编语言作为成熟的中间表示方式,简化了工具链;技术上,分阶段编译更高效,汇编便于调试和移植;实践中,保留汇编阶段降低了复杂度,增强了可移植性和优化能力。即使在现代编译器中,汇编仍作为重要桥梁,帮助开发者更好地理解和优化代码。
53 25
为什么C/C++编译腰要先完成汇编
|
3月前
|
自然语言处理 编译器 Linux
|
3月前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
|
4月前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
67 0
Linux c/c++之多文档编译
|
4月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
272 22
|
4月前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
114 2
|
5月前
|
C++
【C++基础】程序流程结构详解
这篇文章详细介绍了C++中程序流程的三种基本结构:顺序结构、选择结构和循环结构,包括if语句、三目运算符、switch语句、while循环、do…while循环、for循环以及跳转语句break、continue和goto的使用和示例。
94 2
|
6月前
|
PHP C++ Python
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
158 0
|
6月前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
67 0
|
1天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。