本文已参与 新人创作礼 活动,一起开启掘金创作之路
最近这段时间有接触到在linux下编译C++代码,生成动态链接库。其实之前在学校搞物联网竞赛做嵌入式的时候也有玩过,只不过现在都忘得差不多了,今天就来总结下如何在linux环境下编译C/C++代码吧,以及如何生成动态链接库。(PS:C/C++的速度是Python和perl所无法比拟的)
首先准备C/C++编译环境
# yum install gcc gcc-c++ -y //gcc和g++都是GNU组织的一个编译器。
编译C代码步骤
1、准备C文件:
# vim hellworld.c
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
第一句是包含头文件,头文件以.h结尾,stdio 指的是 "standard input & output",下面是一个main函数,返回int类型。该函数输出了helloword字符串,最后返回值是0,C语言的每一句都需要以;结尾
2、编译
标准的三步骤:
//预编译,生成已编译通过的C原始程序 *.i
# gcc -E helloworld.c -o helloworld.i
//编译,生成汇编语言原始程序 *.s
# gcc -S helloworld.i -o helloworld.s
//链接,生成可执行程序
# gcc -o helloworld helloworld.s
如果不想看到中间过程可以一步完成:
# gcc -o helloworld helloworld.c
gcc常用参数:
-E 激活预处理
-S 把文件编译成为汇编代码
-o 指定目标文件名
3、运行
# ./helloworld
编译C++代码步骤
1、准备C++文件:
# vim hellothread.cpp
2、编译
# g++ hellothread.cpp -lpthread -o hellothread
g++常用参数: -l 指定所使用到的函数库 -L 指定函数库所在的文件夹 -I 指定头文件所在的文件夹 -o 输出的可执行文件的文件名
3、运行
# ./hellothread //创建5个线程,输出“Hello Wuxi”
关于静态库和动态库
linux系统下的静态函数库的后缀是.a,动态库是.so。静态库和动态库的区别是:
-
静态库由一系列的.o文件组成,在链接过程中,这些.o文件与主要的目标文件一起生成目标文件,生成之后就不需要这些.o文件了;
-
动态库在链接过程中并没有用到具体函数使用,它是在程序的运行过程中才动态的调用。正如windows系统中,我们看到需要的.exe文件夹中,包含了各式各样的.dll文件(windows下的动态库),当然所需要的.dll文件也有一部分在系统的默认路径下。
实战:在ARM平台下将C++代码编译成动态链接库:
# g++ -I"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.aarch64/include" -I"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.aarch64/include/linux" -fPIC -shared -o YUtils.so YUtils.cpp\
注意这里的几个参数: -I 指定搜索头文件的路径,这里有用到java相关的头文件jni.h,所以需要指定java搜索路径路径,否则可能找不到相关头文件。(JNI即Java Native Interface,Java本地接口,是一个协议,主要作用为:实现Java调用c/c++代码(类库),或者C/C++调用Java代码) -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库 -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码,产生的代码中没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
好了,今天的分享就到这里了,希望对大家有所帮助,我们下期再见~~