当前位置:首页 » 《随便一记》 » 正文

Ubuntu 用gcc/CMakefile编译器 编译、运行c语言程序

19 人参与  2024年04月18日 11:23  分类 : 《随便一记》  评论

点击全文阅读


目录

一. 在Ubuntu系统下用c语言编写一个简单的输出hello world 的程序,并编译、运行。

1.1 gcc/g++简介

1.2 c++程序输出 Hello World:

1.3 c语言程序输出 Hello World:

二. 编写一个主程序文件main1.c和一个子程序文件sub1.c,实现函数间的调用

2.1  编写sub1.c 和main1.c 函数

2.1.1 编写sub1.c函数

2.1.2 编写main1.c函数,赋值a=3,b=2

2.2   将sub1.c程序封装为动态库或者静态库

​2.2.1  生成静态库

2.2.1  生成动态库

2.2.3 动态库和静态库的区别

三.  在windows下系统下用DVC++编程实现

3.1 编辑主程序

3.2 编辑子程序

 3.3 运行效果

四.  用CMakefile方式编程主程序

4.1 CMakefile 简介

4.2 创建CMakeListss.txt

4.3 在CMakeLists.txt中添加添加可执行文件,给sub1.c添加静态库,并添加链接

4.4 执行 CMakeLists.txt,并查看是否生成上述文件

4.5 分别执行连接动态库和静态库的可执行文件

五. 总结


 

 

一. 在Ubuntu系统下用c语言编写一个简单的输出hello world 的程序,并编译、运行。

1.1 gcc/g++简介

      gcc/g++都是GUN开发的编译器,前者用于对c语言程序的编译,后者用于对c++程序的编译。

其语法格式大同小异。

常用命令:

-E    只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面。例子用法:       gcc -E hello.c > pianoapan.txt       gcc -E hello.c | more       慢慢看吧,一句`hello word`也要预处理成800行的代码。     -S       只激活预处理和编译,就是指把文件编译成为汇编代码。例子用法:     gcc -S hello.c       将生成.s的汇编代码,可以用文本编辑器查看。    -c        只激活预处理,编译,和汇编,也就是他只把程序做成obj文件。例子用法:       gcc -c hello.c       将生成.o的目标文件(object file)。 -o    指定目标名称,缺省的时候,gcc/g++编译出来的文件是a.out。例子如下:       g++ -o hello.out hello.cpp    g++ -o hello.asm -S hello.cpp   

目录选项: 

-I[dir]    在你是用#include "file"的时候,gcc/g++会先在当前目录查找你所指定的头文件,如果没有找到,会到系统默认的头文件目录找。如果使用-I指定了目录,编译器会先在指定的目录查找,然后再去系统默认头文件目录查找。对于#include <file>,gcc/g++会到-I指定的目录查找,查找不到,然后再到系统默认的头文件目录查找。-include [file]    相当于“#include”,用于包含某个代码,简单来说,就是编译某个文件,需要另一个文件的时候,就可以       用它设定,功能就相当于在代码中使用#include。例子用法:       gcc hello.c -include /root/pianopan.h   -I-    就是取消前一个参数的功能,所以一般在-Idir之后使用   -idirafter [dir]       在-I的目录里面查找失败,将到目录dir里面查找。-iprefix [prefix],-iwithprefix [dir]    一般一起使用,当-I的目录查找失败,会到prefix+dir下查找。-L[dir]       编译的时候,指定搜索库的路径。比如你自己的库,可以用它指定目录,不然编译器将只在标准库的    目录找。这个dir就是目录的名称。-l[library]        指定编译的时使用的库,例子用法       gcc -lcurses hello.c       使用curses库编译连接,生成程序。 

更多命令可在ubuntu终端中输入 man gcc 查看

1.2 c++程序输出 Hello World:

首先创建一个文件          格式:  nano+文件名

8083d9f08bf14068aad0848e16c1fbfd.png在所创的文件中输入c++代码:

#include<iostream>using namespace std;int main(){   cout<<"Hello World!"<<endl;   return 0;}

21ea2f150291440d9965379d41fb6736.png

退出并保存文件。

g++ a -o b   将a文件用c++的编译方式编译出名字b的可执行文件

用g++编译该文件

g++ Hello_World.c -o Hello_World.cpp

用 ls 查看是否生成可执行文件,并运行。

265c6014b81941b99e12161424ec88c4.png运行Hello_World.cpp 文件

0cf710ac064d42a2851e78cd1a68175e.png运行后输出了  Hello World!

 


 

1.3 c语言程序输出 Hello World:

若用c语言,需要用gcc进行编译,语法相差不大

首先创建一个文本文件

7e240fbfc0654f0ab24aeb226d3c970f.png

在文件中输入c语言代码

#include  <stdio.h>int main(){ printf("%s\n","Hello World!"); return 1;}

保存文件,并编译文件为可执行文件 

bcfebb41b4be49f8a88fa48ceba6a3b6.png

查看是否生成可执行文件

b00ceb1128f347468f1ae2de2135acc4.png

运行可执行文件

e7488952c8c44812bf873a2c11aec2d0.png

输出Hello World!

二. 编写一个主程序文件main1.c和一个子程序文件sub1.c,实现函数间的调用

要求:子程序包含算术运算函数float  x2x(int a,int b),此函数功能对输入两个整数作运算,结果返回浮点数;主函数定义并赋值两个整形变量,然后调用x2x函数,将结果打印出来。

思路:先编写sub1.c程序,再将封装为库函数,在主函数中引用sub1.c的头文件,调用其库函数。

2.1  编写sub1.c 和main1.c 函数

2.1.1 编写sub1.c函数

#include <stdio.h>float x2x(int a,int b){     float x=(float)a;     float y=(float)b;     return x/y;}

2.1.2 编写main1.c函数,赋值a=3,b=2

#include "sub1.h"void main(){  int a=3,b=2;  printf("%f", x2x(3,2));}

2.2 将sub1.c程序封装为动态库或者静态库

先将其转为 .o 二进制文件

gcc -c sub1.c

查看是否生成sub1.o文件

5d483ea7de4e4b28abf8eb33367caba2.png2.2.1  生成静态库

ar -crv lib+库名.a  +所用程序

302e19e9fe054f57b45d58c0f9f5bc20.png

 当前目录下生成libsub.a静态库文件a62b7154ef6d415e8b092f01ac56b0f2.png

对主程序进行编译,编译需要用到刚才生成的库

a86e2a3a29a843cd87a8f9d6f2d3e5eb.png

当前目录生成了名为main1的可执行文件,运行并查看结果:

 

c04952ce8aae47919c76ed2986aef876.png

输出结果为1.500000

2.2.1  生成动态库

生成动态库的方法跟静态库的方法类似

gcc  -shared -fPIC -o lib+库名.so 所用程序72f4f6872c1b425b9c896c2f417aa93e.png

当前目录下生成libsub1.so动态库文件

a62b7154ef6d415e8b092f01ac56b0f2.png

用此库将main1.c文件编译为可执行文件

acac9e4be2024c41a43fd8f0a046db0c.png

执行当前目录下生成的main_1可执行文件

189a5b22158c44deaf50dd66db1e0335.png

同样输出了结果1.500000

2.2.3 动态库和静态库的区别

       在Linux中,库函数分为静态库和动态库两种。静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用后都会生成一个副本,而动态库则只有一个副本,更省空间。

三.  在windows下系统下用DVC++编程实现

3.1 编辑主程序

e0f72e46061c47e092928567ddbd89ad.png

3.2 编辑子程序

d45ddbe983c64108ab18b1e0f92e24a7.png

 3.3 运行效果

64db26b78e774779af1cd200c0f7927e.png

四.  用CMakefile方式编程主程序

4.1 CMakefile 简介

        理论上,任意一个c语言程序都可以用gcc来编译。但是当程序规模越来越大时,一个工程可能有许多个文件夹和源文件,这时输入的编译命令就越来越长。通常,一个小型的c语言项目可能含有几十类,各类间还存在着复杂的依赖关系。其中一部分要编译为可执行文件。另一部分编译成库文件。如果仅靠gcc命令,则需要输入大量的编译指令,整个编译过程会变得异常繁琐。因此对于c项目,使用一些工程管理工具会更加高效。在历史上,工程师们曾使用makefile进行自动编译,但是cmake比它更加方便。并且cmake在工程上广泛应用。总之,cmake是用来管理源代码的工具,可以对源代码进行编译、生成库等。

4.2 创建CMakeListss.txt

CMakeLists.txt文件用来告诉cmake要对目录下的文件做什么事情。

6befa3df3ee548809b1df28a6faa74d0.png

第一句是要求cmake编译器的最小版本

第二句是创建一个工程文件名为D

4.3 在CMakeLists.txt中添加添加可执行文件,给sub1.c添加静态库,并添加链接

5a26d5a9980b4743ad49a5a0d6df35c7.png

 

 1. 将main1.c转为名为main2的可执行文件

2. 将main1.c转为名为main3的可执行文件

3. 将sub1.c封装为名为libsub1的静态库

4. 将sub1.c封装为名为libsub2的动态库

5. 生成的main2可执行文件与动态库进行连接

6. 生成的main3可执行文件与静态库进行连接

4.4 执行 CMakeLists.txt,并查看是否生成上述文件

调用cmake对该工程进行cmake编译

e7b08a37b6bc49d0afa547714c70d011.png

cmake会输出一些编译信息,然后再当前目录下生成一些中间文件,其中最重要的就是MakeFile。

由于其是自动生成的,不用修改它。现在用make对该工程进行编译:

2abbd420b3e0443b819e55ab9f4bb3bb.png

查看生成的文件

ae21e6b9568f4f2e9c1fc7f943ea5b88.png

 生成了main2 main3 可执行文件,liblibsub1.a静态库 以及liblibsub2.so动态库

4.5 分别执行连接动态库和静态库的可执行文件

运行生成的main2 和main3文件55b2ef3b97c8462a8c9ed6c8c1089f25.png

都输出1.500000

五. 总结

1. 在ubuntu18环境下,可以用gcc对c语言程序进行编译和运行,用g++可以对c++语言程序进行编译和运行。

2. ubuntu环境下用gcc编译一个文件比较简单,只需将程序转为二进制可执行文件即可,但是在运用到函数之间的调用的时候,即运用到库时,较为复杂。

3. windows环境下对c语言的编写和运行也是同样的步骤,但是windows系统中用到的DEV C++是集成开发的软件,比较迅速、方便。 ubuntu中也有IDE软件,比如KDV。

4. 在执行很多程序之间的相互调用时候,gcc生成库较为复杂,用Makefile的方式比较简便。

5. ubuntu中的库分为静态库和动态库,运用动态库更加节省空间。

PS:参考资料:  g++入门教程 - 码农教程 (manongjc.com)

                          《视觉SLAM十四讲从理论到实践》第二版  高翔 张涛 刘毅 颜沁睿 著

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/96991.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1