要知道,GCC 官网提供的 GCC 编译器是
无法直接安装到 Windows 平台上的
,如果我们想在 Windows 平台使用 GCC 编译器,可以安装GCC 的移植版本
。
MinGW 和 Cygwin
。直接生成可运行 Windows 平台上的可执行程序
,相比后者体积更小,使用更方便
;完整的 Linux 环境
,借助它不仅可以在 Windows 平台上使用 GCC 编译器,理论上可以运行 Linux 平台上所有的程序
。有更高的需求(例如运行 POSIX
应用程序),就选择安装 Cygwin。如仅 Windows
平台上使用 GCC,可以使用 MinGW 或者 Cygwi
注意
:搭建GCC编译环境时,一定要选择正确的GCC编译版本(32位和64位)
。如果你本地安装的JDK是64位的,那么选择64位GCC,否则选择32位。这是为了使得编译后的库文件跟JVM的位一致,否则后面JVM无法调用dll(或so)而抛出异常
。
java.lang.UnsatisfiedLinkError: E:\dev_tools\jdk\jdk1.8.0_181\bin\HelloJNI.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
因此
http://sourceforge.net/projects/mingw/ #32位
https://sourceforge.net/projects/mingw-w64/ #64位
1.打开下载好的mingw-get-setup.exe
,这里选择安装目录为E:\dev_tools\MinGW
2.下载安装gcc/g++
gcc/g++
。勾选mingw32-gcc-g++-bin
,点击Apply Changes
,下载安装gcc/g++
。Installation -> Apply Changes
,弹出如下对话框:3.配置环境变量
Path
,添加一个环境变量E:\dev_tools\MinGW\bin
,具体为MinGW根目录下的\bi
n目录,用英文分号 ;
隔开。4.检验是否成功下载安装gcc/g++
1.在步骤2(下载安装gcc/g++)时,出现部分package无法成功下载:
libgmp-6.1.2-2-mingw32-dll-10.tar.xz
,libmpfr-3.1.5-1-mingw32-dll-4.tar.xz
,两个package包,从而导致在进行g++编译的时候出现重要组件libgmp-10.dll
与libmpfr-4.dll
的丢失。解决方案:
Dev-cpp、Code Blocks
路径下拷贝这两个package包,其路径为MinGW根目录下的\var\cache\mingw-get\packages。
libgmp-10.dll
与libmpfr-4.dll
复制到MinGW根目录下的\bin
。3.配置环境变量
Path
,添加一个环境变量E:\dev_tools\MinGW64\bin
,具体为MinGW根目录下的\bi
n目录,用英文分号 ;
隔开。4.检验是否成功下载安装gcc/g++
以运行一个 C 语言程序为例(存储路径为:D:\demo.c)
#include
#include
int main(){
printf("Hello, World!");
system("pause");
return 0;
}
在此基础上,在命令行窗口中执行如下指令:
C:\Users\mengma>gcc D:\demo.c -o D:\demo.exe
其会在 D 盘生成一个 demo.exe 可执行文件,找到该文件并双击,即可看到程序的执行结果:
Hello, World!
在gcc环境准备好的条件下,接下来使用下面的命令将c生成dll动态链接库:
gcc -m64 -Wl,--add-stdcall-alias -I"D:\Program Files\Java\jdk1.8.0_261\include"
-I"D:\Program Files\Java\jdk1.8.0_261\include\win32"
-shared -o MyNativeDll.dll JniTestImpl.c
简单的解释一下各个参数的含义:
-m64
:将c代码编译为64位的应用程序-Wl,--add-stdcall-alias
:-Wl表示将后面的参数传递给连接程序,参数--add-stdcall-alias
表示带有标准调用后缀@NN
的符号会被剥掉后缀后导出-I
:指定头文件的路径,在生成的头文件代码中引入的jni.h就在这个目录下-shared
:指定生成动态链接库,如果不使用这个标志那么外部程序将无法连接-o
:指定目标的名称,这里将生成的动态链接库命名为MyNativeDll.dllJniTestImpl.c
:被编译的源程序文件名,当前文件为c在指令的执行过程中,都做了什么事呢,可以参考下面这张图:
在执行过程中,以.c源代码
和.h头文件
作为源文件
,先进行了预处理、编译、汇编的操作,图中省略了这一阶段产生的一些中间文件,编译完成后生成的.o二进制文件相对重要
,依赖这个文件,最终生成动态链接库。
gcc 是GNU Compiler Collection
,原名为Gun C语言编译器
,因为它原本只能处理C语言,但gcc很快地扩展,包含很多编译器(C、C++、Objective-C、Ada、Fortran、 Java)
,可以说gcc是GNU编译器集合。
g++ 是C++编译器
cc 是 Unix系统
的C Compile
,一个是古老的 C 编译器
。而Linux 下 cc 一般是一个符号连接,指向 gcc
;可以通过 $ ls -l /usr/bin/cc
来简单察看,该变量是 make 程序的内建变量,默认指向 gcc 。 cc 符号链接和变量存在的意义在于源码的移植性,可以方便的用 gcc 来编译老的用cc编译的Unix软件,甚至连 makefile 都不用改在,而且也便于 Linux 程序在 Unix下 编译。
CC 则一般是 makefile 里面的一个名字标签,即宏定义,表示采用的是什么编译器(如:CC = gcc)。
误区一:gcc只能编译C代码,g++只能编译C++代码。
gcc两者都可以,但请注意:
误区二:gcc不会定义__cplusplus宏,而g++会
误区三:编译只能用gcc,链接只能用g++
gcc -lstdc++
。因为gcc命令不能自动和C++程序使用的库联接
,所以通常使用g++来完成联接
。但在编译阶段,g++会自动调用gcc
,二者等价。MinGW下载和安装教程
windows下安装MinGW及C++的环境配置