Linux学习记录--程序编译与函数库
2014-04-06 09:58
567 查看
程序编译与函数库
前面提到过对于机器来说只能识别0,1,我们如果让机器运行必须输入机器能够识别的语言,可是机器语言不利于人们使用可理解,因此科学家就开发出人类能看的懂的程序语言,然后再创造出“编译器”将程序语言转换为机器语言。C语言就是我们能够看懂的机器语言,gcc就是Linux下编译器。我们通常C语言写的程序通过gcc编译后,就能成为机器能够识别的语言gcc程序编译
如果LINUX 系统中为安装GCC编译器,可以使用下面命令安装[root@bogon ~]# yum install gccgcc常用语法
语法:gcc –c file.c仅将源代码编译成目标文件。并不会进行链接以及生成可执行文件gcc –o 执行文件名 源代码文件直接生成指定名称的执行文件。但不会生成目标文件
gcc –o 执行文件名 目标文件通过目标文件生成可执行文件
gcc [其他编译操作] –L库文件路径查找库文件的路径默认是/usr/lib 与/ib
gcc [其他编译操作] –I包含文件路径查找包含文件的路径默认是/usr/include
gcc [其他编译操作] –Wall更加严谨的编译方式,会输出很多警告信息
gcc -O [其他编译操作]编译时依据操作环境优化执行速度
gcc [其他编译操作] –l库文件名称编译时引入其他的库文件,其中库文件lib与扩展名不需要写。如引入libm.so文件,可写成-lm
单一程序编译
1. 编写C语言程序l[root@bogon code]# vim hello.c #include <stdio.h> int main(void) { printf("hello world!"); }
2. 编译
[root@bogon code]# gcc hello.c [root@bogon code]# ll hello.c a.out -rwxr-xr-x 1 root root 4947 04-05 16:07 a.out -rw-r--r-- 1 root root 66 04-05 16:07 hello.c
说明:默认gcc编译器编译出来的执行文件a.out, 可以使用-o来制定编译后生产的执行文件名称
[root@bogon code]# gcc -o hello hello.c [root@bogon code]# ll hello -rwxr-xr-x 1 root root 4947 04-05 16:11 hello
3. 执行
[root@bogon code]# ./a.out hello world! [root@bogon code]# ./hello hello world!
多文件程序编译
假设我们有A.c ,B.c两个程序文件,并且他们之间存在函数调用,那么当其中有一个文件更改了。是不是需要将这两个文件都重新编译?当然不需要,这就需要引入目标文件目标文件:编译器编译源代码后生成的文件,目标文件从结构上讲,它是已经编译后的可执行文件格式,只是没有经过链接的过程。接着上面的说,当B.c文件更改时,我们执行重新编译B文件生产目标文件。再讲整体链接即可1. 编写C语言程序
File:A.c #include <stdio.h> #include “B.c” int main () { printf("这是第一个文件\n"); method(); } File:B.c #include <stdio.h> void method(void) { printf("这是第二个文件!\n";) }2. 编译
root@bogon code]# gcc -c A.c B.c -I./ [root@bogon code]# ll -rw-r--r-- 1 root root 81 04-05 16:35 A.c -rw-r--r-- 1 root root 912 04-05 16:35 A.o -rw-r--r-- 1 root root 80 04-05 16:34 B.c -rw-r--r-- 1 root root 860 04-05 16:35 B.o3. 链接
[root@bogon code]# gcc -o result A.o B.o4. 执行
[root@bogon code]# ./result 这是第一个文件 这是第二个文件!5. 更改B.c文件
#include <stdio.h> void method(void) { printf("这是更改后第二个文件!\n";) }6. 重新编译链接执行
[root@bogon code]# gcc -c B.c =>只编译了B这个文件 [root@bogon code]# gcc -o result A.o B.o [root@bogon code]# ./result 这是第一个文件 这是更改后第二个文件!
调用外部函数库
1. 编写C语言程序#include<stdio.h> #include<math.h> int main () { float val=sin(3.14); printf("val值是:%f\n",val); }2. 编译与执行
[root@bogon code]# gcc -o sinmath sinmath.c -lm [root@bogon code]# ./sinmath val值是:0.001593
函数库介绍
函数库依照是否编译到程序内部可分为静态函数库:通常以.a为扩展名,编译时会整合到程序文件中动态函数库:通常以.so为扩展名,编译时会不会整合到程序文件中,只是在程序文件中存在一个指向的位置因此程序执行时是不需要静态函数库的,但是需要动态函数库,使用动态函数库的好处再在可以减少程序文件的大小动态函数库加载内存我们知道内存的访问速度是硬盘的好几倍,如果先将动态函数库加载到内存中,那么在使用动态函数库时就会,就会提高很多效率
语法:ldconfig[-f 需要缓存函数库信息所在文件] [-C 已缓存函数库信息所在文件] ldconfig –p 列出已缓存函数库信息
需要缓存函数库信息所在文件:在这个文件中记录所有需要缓存的的函数库默认值是/etc/ ld.so.conf
举例:查看下我的系统下缓存的函数库
[root@bogon etc]# vim ld.so.conf include ld.so.conf.d/*.conf [root@bogon etc]# cd ld.so.conf.d/ [root@bogon ld.so.conf.d]# ll -rw-r--r-- 1 root root 15 2013-01-23 mysql-i386.conf -rw-r--r-- 1 root root 17 2013-01-09 openais-athlon.conf -rw-r--r-- 1 root root 20 2012-08-20 qt-i386.conf -rw-r--r-- 1 root root 276 02-22 19:23 vmware-tools-libraries.conf -rw-r--r-- 1 root root 19 2013-08-07 xulrunner-32.conf [root@bogon ld.so.conf.d]# vim mysql-i386.conf [root@bogon ld.so.conf.d]# ll /usr/lib/mysql lrwxrwxrwx 1 root root 26 02-18 20:03 libmysqlclient_r.so.15 -> libmysqlclient_r.so.15.0.0 -rwxr-xr-x 1 root root 1460684 2013-01-23 libmysqlclient_r.so.15.0.0 lrwxrwxrwx 1 root root 24 02-18 20:03 libmysqlclient.so.15 -> libmysqlclient.so.15.0.0 -rwxr-xr-x 1 root root 1452764 2013-01-23 libmysqlclient.so.15.0.0 -rwxr-xr-x 1 root root 13220 2013-01-23 mysqlbug -rwxr-xr-x 1 root root 6215 2013-01-23 mysql_config
已缓存函数库信息所在文件:这个文件中记录了已经缓存的函数库,默认文件为/etc/ld.so.cache ,通过-p查询到的信息就是从这个文件读取而来
举例:查看所有已缓存的函数库
[root@bogon ld.so.conf.d]# ldconfig -p|more 947 libs found in cache `/etc/ld.so.cache' libz.so.1 (libc6) => /lib/libz.so.1 libz.so.1 (libc6) => /usr/lib/libz.so.1 libx11globalcomm.so.1 (libc6) => /usr/lib/libx11globalcomm.so.1 ……..查看程序所包含的动态函数库语法:ldd –v文件名-v:列出所有函数库信息
举例:
[root@bogon ld.so.conf.d]# ldd /usr/bin/passwd linux-gate.so.1 => (0x00ddc000) libuser.so.1 => /usr/lib/libuser.so.1 (0x007c5000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x05c74000) ……
make编译
如果一个程序中有很多文件,那么还像上面那样讲每个文件列出来在进行编译就会很麻烦。因此这种时候就需要使用make工具了Make编译好处简化编译时所需的指令若在编译完成后,修改了某个源文件,只会针对修改的文件编译
Make使用方法Make是有个二进制文件,其会查找当前目录下的Makefile文件,根据其里面定义的内容执行操作。 Makefile里面包含了若干目标与操作
其基本关于规则如下目标:<tab>操作
REST2HTML=html.py --compact-lists --date --generator all: user_manual.html dev_manual.html user_manual.html: user_manual.rst $(REST2HTML) user_manual.rst user_manual.html dev_manual.html: dev_manual.rst $(REST2HTML) dev_manual.rst dev_manual.html clean: rm *.html
以上内容分为三个目标all,user_manual.html,clean,其下面分别对应的是其操作我们可以通过make 后面参数为目标进行执行。如:make clean
Tarball的安装
由于Unix like具有很多种。因此一个软件安装包不可能适用所有所本,因此有时我们需要根据软件提供者提供的源码自行编译,以满足在自己的操作系统上运行大部分软件开发包编译与安装的流程大致是这样的1. 讲压缩文件解压缩2. 解压缩后执行里面的configure文件,其作用就是建立makefile文件3. Make clean:清理一些上次操作的残留4. Make :默认操作进行编译的行为5. Make install:安装
说明:安装前如果有安装文档最好先查阅3-4步骤 不一定都存在。可查看makefile内容判断具体包括哪些目标
举例:
[root@bogon shared]# tar -zxvf ntp-4.2.4p7.tar.gz -C /tmp ….. [root@bogon ntp-4.2.4p7]# ./configure --prefix=/usr/loacl/ntp => --prefix=/usr/loacl/ntp为指定安装目录 [root@bogon ntp-4.2.4p7]# ll Makefile -rw-r--r-- 1 root 6011 23950 04-05 21:40 Makefile =>生成了Makefile文件 root@bogon ntp-4.2.4p7]# ll Makefile root@bogon ntp-4.2.4p7]# make clean root@bogon ntp-4.2.4p7]# make root@bogon ntp-4.2.4p7]# make install
相关文章推荐
- Linux学习记录--程序编译与函数库
- 学习记录:linux下将C程序编译为汇编程序进行分析
- 【编译原理】学习记录1_程序编译过程
- 我的学习记录--Linux (CentOS) 程序安装包管理,rpm
- 第一次 Linux 环境下的程序编译与链接记录
- 我的学习记录--Linux (CentOS) 程序安装包管理,yum
- linux64编译32程序记录 - 赤色 - 博客园
- Linux学习记录--内核|内核模块编译
- 第一次学习Linux下编译C程序
- FileGDB API for linux 学习系列之二,编译Display例子程序
- [技术学习]在Linux平台学习Windows开发技术(一)----编译第一个MFC程序
- linux下所有用到dlopen类似函数的程序编译
- (一)OpenCV学习笔记——Linux下编译运行opencv程序
- Opencv学习1: 在Linux下编译运行第一个opencv程序
- Linux巩固记录(5) hadoop 2.7.4下自己编译代码并运行MapReduce程序
- FileGDB API for linux 学习系列之一,编译例子程序
- Linux学习记录--内核|内核模块编译 推荐
- Linux学习——gcc编译C程序
- 64位Linux环境 编译32位汇编程序(外链C库函数)
- MATLAB学习笔记 函数记录(一)