NDK<第三篇>:gcc和g++(windows环境)

2022-10-21  本文已影响0人  NoBugException
1、wingw环境配置

【1】下载wingw

MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net

image.png

下载完成之后解压。

【2】配置环境变量

下载之后,将 mingw64 目录的 bin 目录的路径配置到环境变量中。

并且将 mingw32-make文件改成 make

2、gcc和g++的使用

【1】预处理

不输出文件:

    gcc -E Hello.cpp(同样适用于c文件)
    或
    g++ -E Hello.cpp(同样适用于c文件)

输出文件:(将预处理信息输出到Hello.i)

    gcc -E Hello.cpp -o Hello.i(同样适用于c文件)
    或
    g++ -E Hello.cpp -o Hello.i(同样适用于c文件)

【2】转换为汇编文件

不指定预处理文件:

    gcc -S Hello.cpp // 生成Hello.s文件(同样适用于c文件)
    gcc -S Hello.cpp -o Hello.s // 生成Hello.s文件(同样适用于c文件)
    或
    g++ -S Hello.cpp // 生成Hello.s文件(同样适用于c文件)
    g++ -S Hello.cpp -o Hello.s // 生成Hello.s文件(同样适用于c文件)

指定预处理文件:

    gcc -S Hello.i // 生成Hello.s文件(同样适用于c文件)
    gcc -S Hello.i -o Hello.s // 生成Hello.s文件(在windows上测试失败,并没有生成Hello.s,c文件也同样如此)
    或
    g++ -S Hello.i // 生成Hello.s文件(同样适用于c文件)
    g++ -S Hello.i -o Hello.s // 生成Hello.s文件(同样适用于c文件)

【3】编译(生成目标文件)

不指定汇编文件:

    gcc -c Hello.cpp // 生成目标文件Hello.o(同样适用于c文件)
    gcc -c Hello.cpp -o Hello.o // 生成目标文件Hello.o(同样适用于c文件)
    或
    g++ -c Hello.cpp // 生成目标文件Hello.o(同样适用于c文件)
    g++ -c Hello.cpp -o Hello.o // 生成目标文件Hello.o(同样适用于c文件)

指定汇编文件:

    gcc -c Hello.s // 生成目标文件Hello.o(同样适用于c文件)
    gcc -c Hello.s -o Hello.o // 生成目标文件Hello.o(同样适用于c文件)
    或
    g++ -c Hello.s // 生成目标文件Hello.o(同样适用于c文件)
    g++ -c Hello.s -o Hello.o // 生成目标文件Hello.o(同样适用于c文件)

【4】链接(生成可执行文件)

不指定目标文件:

    gcc Hello.cpp // 链接失败,不能生成可执行文件(适用于c文件,生成a.exe)
    gcc Hello.cpp -o Hello // 链接失败,不能生成可执行文件(适用于c文件,生成Hello.exe)
    gcc Hello.cpp -o Hello.exe // 链接失败,不能生成可执行文件(适用于c文件,生成Hello.exe)
    gcc -o Hello Hello.cpp // 链接失败,不能生成可执行文件(适用于c文件,生成Hello.exe)
    或
    g++ Hello.cpp // 生成a.exe文件(适用于c文件,生成a.exe)
    g++ Hello.cpp -o Hello // 生成Hello.exe文件(适用于c文件,生成Hello.exe)
    g++ Hello.cpp -o Hello.exe // 生成Hello.exe文件(适用于c文件,生成Hello.exe)
    g++ -o Hello Hello.cpp // 生成Hello.exe文件(适用于c文件,生成Hello.exe)
    g++ -o Hello.exe Hello.cpp // 生成Hello.exe文件(适用于c文件,生成Hello.exe)

指定目标文件:

    gcc Hello.o // 链接失败,不能生成可执行文件(适用于c文件,生成a.exe)
    gcc Hello.o -o Hello // 链接失败,不能生成可执行文件(适用于c文件,生成Hello.exe)
    gcc Hello.o -o Hello.exe // 链接失败,不能生成可执行文件(适用于c文件,生成Hello.exe)
    或
    g++ Hello.o // 生成a.exe文件(适用于c文件,生成a.exe)
    g++ Hello.o -o Hello // 生成Hello.exe文件(适用于c文件,生成Hello.exe)
    g++ Hello.o -o Hello.exe // 生成Hello.exe文件(适用于c文件,生成Hello.exe)

【5】执行可执行文件

.\Hello
或
.\Hello.exe
3、gcc/g++多文件多目录

同目录多文件的情况下:

gcc Hello.c A.c B.c -o Hello
或使用通配符:
gcc *.c -o Hello

如果将头文件放入单独的文件夹中(header文件夹):
gcc -I header *.c -o Hello
4、gcc/g++常用编译选项
【1】-o FILE: 指定输出文件名,在编译为目标代码时,这一选项不是必须的。
        如果FILE没有指定,缺省文件名是a.out;
【2】-c: 只编译生成目标文件,不链接;
【3】-Wall: 允许发出gcc能提供的所有有用的警告,也可以用-W(warning)来标记指定的警告;
    g++ -W Hello.o -o Hello
    g++ -Wall Hello.o -o Hello
【4】-Werror: 把所有警告转换为错误,以在警告发生时中止编译过程;
    g++ -Werror Hello.o -o Hello
【5】-v: 显示在编译过程的每一步中用到的命令;
    g++ -v Hello.o -o Hello
【6】-static: 链接静态库,即执行静态链接,g++默认是链接动态库,如果需要链接静态库需要使用本选项进行指定;
【7】-g: 在可执行程序中包含标准调试信息, 使用该选项生成的可执行文件可以用gdb工具进行调试;
【8】-w: 关闭所有警告,建议不要使用该选项
【9】-shared: 生成共享目标文件。通常用在建立共享库时;
【10】-On: 这是一个优化选项,如果在编译时指定该选项,则编译器会根据n的值(n取0到3之间)对代码进行不同程度的优化,其中-O0 表示不优化,n的值越大,优化程度越高;
【11】-L: 库文件依赖选项,该选项用于指定编译的源程序依赖的库文件路径,库文件可以是静态链接库,也可以是动态链接库,linux系统默认的库路径是/usr/lib,如果需要的库文件不在这个路径下就要用-L指定
    g++  foo.cpp  -L/home/lib  -lfoo  -o   foo
【12】-I: 该选项用于指定编译程序时依赖的头文件路径,linux平台默认头文件路径在/usr/include下,如果不在该目录下,则编译时需要使用该选项指定头文件所在路径
    gcc  foo.cpp  -I/home/include   -o  foo
5、动态库和静态库

【1】生成动态库

动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库。Linux中后缀名为“.so”。
动态库节省空间:如果一个动态库被两个程序调用,那么这个动态库只需要在内存中。

【1】分步骤生成动态库

    g++ -fPIC -c Hello.cpp -o Hello.o
    g++ -shared -o libHello.so Hello.o

【2】一步生成动态库

    g++ -fPIC -shared -o libHello.so Hello.o
    或
    g++ -fPIC -shared -o libHello.so Hello.cpp

【2】生成静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。Linux中后缀名为”.a”。
静态库节省时间:不需要再进行动态链接,需要调用的代码直接就在代码内部。

ar -crv libHello.a Hello.o
或
ar -crv libHello.a Hello.cpp

【3】链接静态库(生成可执行文件)

g++ Hello.cpp -o Hello -static -L. -l Hello
-L指定库目录,.表示当前目录。
-l Hello 指定libHello.a静态库。

【4】-I 添加搜索头文件的路径(大写i)

系统默认头文件搜索路径大致为

当前目录(如果是双引号包含的话) -->  /usr/include   --> /usr/local/include

// 添加/home/include 到搜索路径
g++ test.cpp -I/home/include 

【5】-L 指定要链接的库所在目录,-l 指定路径寻找库文件

链接时库搜索路径  /lib  -->  /usr/lib   -->/usr/local/lib
运行时库搜索路径 /lib --> /usr/lib   

// -L 将/lib 添加到库搜索目录,
// -l 将 libmt.so 库文件链接到项目 
g++ test.cpp -L/usr/local/lib  -lfmt

【6】查看可执行文件符号

nm main

【7】默认优先使用动态库

gcc main.c -L. -lTest -o main

【8】强制使用静态库

#-Wl 表示传递给 ld 链接器的参数
#最后的 -Bdynamic 表示 默认仍然使用动态库 
gcc main.c -L. -Wl,-Bstatic  -lTest -Wl,-Bdynamic -o main

【9】打包 .a 到so

#打包 .a 到so
#--whole-archive: 将未使用的静态库符号(函数实现)也链接进动态库 
#--no-whole-archive : 默认,未使用不链接进入动态库
gcc -shared -o libMain.so -Wl,--whole-archive libMain.a -Wl,--no-whole-archive

【10】其它命令

--sysroot=XX
使用XX作为这一次编译的头文件与库文件的查找目录,查找下面的 usr/include usr/lib 目录。

g++ --sysroot=C:\Users\94317\AppData\Local\Android\ndk\android-ndk-r20b\sysroot Hello.cpp

-isysroot XX
头文件查找目录,覆盖--sysroot ,查找 XX/usr/include

-isystem XX
指定头文件查找路径(直接查找根目录)

-IXX
头文件查找目录

优先级:
-I -> -isystem -> sysroot

【本章完...】

上一篇下一篇

猜你喜欢

热点阅读